-:    0:Source:/home/MPI/testing/mpich2/mpich2/src/mpid/ch3/src/mpid_startall.c
        -:    0:Graph:mpid_startall.gcno
        -:    0:Data:mpid_startall.gcda
        -:    0:Runs:535
        -:    0:Programs:80
        -:    1:/* -*- Mode: C; c-basic-offset:4 ; -*- */
        -:    2:/*
        -:    3: *  (C) 2001 by Argonne National Laboratory.
        -:    4: *      See COPYRIGHT in top-level directory.
        -:    5: */
        -:    6:
        -:    7:#include "mpidimpl.h"
        -:    8:/* FIXME: This bsend header shouldn't be needed (the function prototype
        -:    9:   should be in mpiimpl.h), to allow a devices MPID_Startall to use the
        -:   10:   MPIR_Bsend_isend function */
        -:   11:#include "../../../mpi/pt2pt/bsendutil.h"
        -:   12:
        -:   13:/* FIXME: Consider using function pointers for invoking persistent requests;
        -:   14:   if we made those part of the public request structure, the top-level routine
        -:   15:   could implement startall unless the device wanted to study the requests
        -:   16:   and reorder them */
        -:   17:
        -:   18:/* FIXME: Where is the memory registration call in the init routines, 
        -:   19:   in case the channel wishes to take special action (such as pinning for DMA)
        -:   20:   the memory? This was part of the design. */
        -:   21:
        -:   22:/* This macro initializes all of the fields in a persistent request */
        -:   23:#define MPIDI_Request_create_psreq(sreq_, mpi_errno_, FAIL_)		\
        -:   24:{									\
        -:   25:    (sreq_) = MPID_Request_create();				\
        -:   26:    if ((sreq_) == NULL)						\
        -:   27:    {									\
        -:   28:	MPIU_DBG_MSG(CH3_OTHER,VERBOSE,"send request allocation failed");\
        -:   29:	(mpi_errno_) = MPIR_ERR_MEMALLOCFAILED;				\
        -:   30:	FAIL_;								\
        -:   31:    }									\
        -:   32:									\
        -:   33:    MPIU_Object_set_ref((sreq_), 1);					\
        -:   34:    (sreq_)->cc   = 0;                                                  \
        -:   35:    (sreq_)->kind = MPID_PREQUEST_SEND;					\
        -:   36:    (sreq_)->comm = comm;						\
        -:   37:    MPIR_Comm_add_ref(comm);						\
        -:   38:    (sreq_)->dev.match.parts.rank = rank;				\
        -:   39:    (sreq_)->dev.match.parts.tag = tag;					\
        -:   40:    (sreq_)->dev.match.parts.context_id = comm->context_id + context_offset;	\
        -:   41:    (sreq_)->dev.user_buf = (void *) buf;				\
        -:   42:    (sreq_)->dev.user_count = count;					\
        -:   43:    (sreq_)->dev.datatype = datatype;					\
        -:   44:    (sreq_)->partner_request = NULL;					\
        -:   45:}
        -:   46:
        -:   47:	
        -:   48:/*
        -:   49: * MPID_Startall()
        -:   50: */
        -:   51:#undef FUNCNAME
        -:   52:#define FUNCNAME MPID_Startall
        -:   53:#undef FCNAME
        -:   54:#define FCNAME MPIDI_QUOTE(FUNCNAME)
        -:   55:int MPID_Startall(int count, MPID_Request * requests[])
     5615:   56:{
        -:   57:    int i;
        -:   58:    int rc;
     5615:   59:    int mpi_errno = MPI_SUCCESS;
        -:   60:    MPIDI_STATE_DECL(MPID_STATE_MPID_STARTALL);
        -:   61:
        -:   62:    MPIDI_FUNC_ENTER(MPID_STATE_MPID_STARTALL);
        -:   63:
    11278:   64:    for (i = 0; i < count; i++)
        -:   65:    {
     5663:   66:	MPID_Request * const preq = requests[i];
        -:   67:
        -:   68:	/* FIXME: The odd 7th arg (match.context_id - comm->context_id) 
        -:   69:	   is probably to get the context offset.  Do we really need the
        -:   70:	   context offset? Is there any case where the offset isn't zero? */
     5663:   71:	switch (MPIDI_Request_get_type(preq))
        -:   72:	{
        -:   73:	    case MPIDI_REQUEST_TYPE_RECV:
        -:   74:	    {
     2810:   75:		rc = MPID_Irecv(preq->dev.user_buf, preq->dev.user_count, preq->dev.datatype, preq->dev.match.parts.rank,
        -:   76:		    preq->dev.match.parts.tag, preq->comm, preq->dev.match.parts.context_id - preq->comm->recvcontext_id,
        -:   77:		    &preq->partner_request);
     2810:   78:		break;
        -:   79:	    }
        -:   80:	    
        -:   81:	    case MPIDI_REQUEST_TYPE_SEND:
        -:   82:	    {
       35:   83:		rc = MPID_Isend(preq->dev.user_buf, preq->dev.user_count, preq->dev.datatype, preq->dev.match.parts.rank,
        -:   84:		    preq->dev.match.parts.tag, preq->comm, preq->dev.match.parts.context_id - preq->comm->context_id,
        -:   85:		    &preq->partner_request);
       35:   86:		break;
        -:   87:	    }
        -:   88:		
        -:   89:	    case MPIDI_REQUEST_TYPE_RSEND:
        -:   90:	    {
     2768:   91:		rc = MPID_Irsend(preq->dev.user_buf, preq->dev.user_count, preq->dev.datatype, preq->dev.match.parts.rank,
        -:   92:		    preq->dev.match.parts.tag, preq->comm, preq->dev.match.parts.context_id - preq->comm->context_id,
        -:   93:		    &preq->partner_request);
     2768:   94:		break;
        -:   95:	    }
        -:   96:		
        -:   97:	    case MPIDI_REQUEST_TYPE_SSEND:
        -:   98:	    {
       12:   99:		rc = MPID_Issend(preq->dev.user_buf, preq->dev.user_count, preq->dev.datatype, preq->dev.match.parts.rank,
        -:  100:		    preq->dev.match.parts.tag, preq->comm, preq->dev.match.parts.context_id - preq->comm->context_id,
        -:  101:		    &preq->partner_request);
       12:  102:		break;
        -:  103:	    }
        -:  104:
        -:  105:	    case MPIDI_REQUEST_TYPE_BSEND:
        -:  106:	    {
        -:  107:		MPI_Request sreq_handle;
       38:  108:		MPIU_THREADPRIV_DECL;
        -:  109:
       38:  110:		MPIU_THREADPRIV_GET;
        -:  111:		
       38:  112:		MPIR_Nest_incr();
        -:  113:		{
       38:  114:		    rc = NMPI_Ibsend(preq->dev.user_buf, preq->dev.user_count,
        -:  115:				     preq->dev.datatype, preq->dev.match.parts.rank,
        -:  116:				     preq->dev.match.parts.tag, preq->comm->handle, 
        -:  117:				     &sreq_handle);
       38:  118:		    if (rc == MPI_SUCCESS)
        -:  119:		    {
       38:  120:			MPID_Request_get_ptr(sreq_handle, preq->partner_request);
        -:  121:		    }
        -:  122:		}
       38:  123:		MPIR_Nest_decr();
       38:  124:		break;
        -:  125:	    }
        -:  126:
        -:  127:	    default:
        -:  128:	    {
        -:  129:		/* --BEGIN ERROR HANDLING-- */
    #####:  130:		rc = MPIR_Err_create_code(MPI_SUCCESS, MPIR_ERR_FATAL, FCNAME, __LINE__, MPI_ERR_INTERN, "**ch3|badreqtype",
        -:  131:					  "**ch3|badreqtype %d", MPIDI_Request_get_type(preq));
        -:  132:		/* --END ERROR HANDLING-- */
        -:  133:	    }
        -:  134:	}
        -:  135:	
     5663:  136:	if (rc == MPI_SUCCESS)
        -:  137:	{
     5663:  138:	    preq->status.MPI_ERROR = MPI_SUCCESS;
     5663:  139:	    preq->cc_ptr = &preq->partner_request->cc;
        -:  140:	}
        -:  141:	/* --BEGIN ERROR HANDLING-- */
        -:  142:	else
        -:  143:	{
        -:  144:	    /* If a failure occurs attempting to start the request, then we 
        -:  145:	       assume that partner request was not created, and stuff
        -:  146:	       the error code in the persistent request.  The wait and test
        -:  147:	       routines will look at the error code in the persistent
        -:  148:	       request if a partner request is not present. */
    #####:  149:	    preq->partner_request = NULL;
    #####:  150:	    preq->status.MPI_ERROR = rc;
    #####:  151:	    preq->cc_ptr = &preq->cc;
    #####:  152:	    preq->cc = 0;
        -:  153:	}
        -:  154:	/* --END ERROR HANDLING-- */
        -:  155:    }
        -:  156:
        -:  157:    MPIDI_FUNC_EXIT(MPID_STATE_MPID_STARTALL);
     5615:  158:    return mpi_errno;
        -:  159:}
        -:  160:
        -:  161:/* FIXME:
        -:  162:   Move the routines that initialize the persistent requests into this file,
        -:  163:   since startall must be used with all of them */
        -:  164:
        -:  165:/*
        -:  166: * MPID_Send_init()
        -:  167: */
        -:  168:#undef FUNCNAME
        -:  169:#define FUNCNAME MPID_Send_init
        -:  170:#undef FCNAME
        -:  171:#define FCNAME MPIDI_QUOTE(FUNCNAME)
        -:  172:int MPID_Send_init(const void * buf, int count, MPI_Datatype datatype, int rank, int tag, MPID_Comm * comm, int context_offset,
        -:  173:		   MPID_Request ** request)
       35:  174:{
        -:  175:    MPID_Request * sreq;
       35:  176:    int mpi_errno = MPI_SUCCESS;
        -:  177:    MPIDI_STATE_DECL(MPID_STATE_MPID_SEND_INIT);
        -:  178:
        -:  179:    MPIDI_FUNC_ENTER(MPID_STATE_MPID_SEND_INIT);
        -:  180:
       35:  181:    MPIDI_Request_create_psreq(sreq, mpi_errno, goto fn_exit);
       35:  182:    MPIDI_Request_set_type(sreq, MPIDI_REQUEST_TYPE_SEND);
       35:  183:    if (HANDLE_GET_KIND(datatype) != HANDLE_KIND_BUILTIN)
        -:  184:    {
    #####:  185:	MPID_Datatype_get_ptr(datatype, sreq->dev.datatype_ptr);
    #####:  186:	MPID_Datatype_add_ref(sreq->dev.datatype_ptr);
        -:  187:    }
       35:  188:    *request = sreq;
        -:  189:
       35:  190:  fn_exit:    
        -:  191:    MPIDI_FUNC_EXIT(MPID_STATE_MPID_SEND_INIT);
       35:  192:    return mpi_errno;
        -:  193:}
        -:  194:
        -:  195:/*
        -:  196: * MPID_Ssend_init()
        -:  197: */
        -:  198:#undef FUNCNAME
        -:  199:#define FUNCNAME MPID_Ssend_init
        -:  200:#undef FCNAME
        -:  201:#define FCNAME MPIDI_QUOTE(FUNCNAME)
        -:  202:int MPID_Ssend_init(const void * buf, int count, MPI_Datatype datatype, int rank, int tag, MPID_Comm * comm, int context_offset,
        -:  203:		    MPID_Request ** request)
       12:  204:{
        -:  205:    MPID_Request * sreq;
       12:  206:    int mpi_errno = MPI_SUCCESS;
        -:  207:    MPIDI_STATE_DECL(MPID_STATE_MPID_SSEND_INIT);
        -:  208:
        -:  209:    MPIDI_FUNC_ENTER(MPID_STATE_MPID_SSEND_INIT);
        -:  210:
       12:  211:    MPIDI_Request_create_psreq(sreq, mpi_errno, goto fn_exit);
       12:  212:    MPIDI_Request_set_type(sreq, MPIDI_REQUEST_TYPE_SSEND);
       12:  213:    if (HANDLE_GET_KIND(datatype) != HANDLE_KIND_BUILTIN)
        -:  214:    {
    #####:  215:	MPID_Datatype_get_ptr(datatype, sreq->dev.datatype_ptr);
    #####:  216:	MPID_Datatype_add_ref(sreq->dev.datatype_ptr);
        -:  217:    }
       12:  218:    *request = sreq;
        -:  219:
       12:  220:  fn_exit:    
        -:  221:    MPIDI_FUNC_EXIT(MPID_STATE_MPID_SSEND_INIT);
       12:  222:    return mpi_errno;
        -:  223:}
        -:  224:
        -:  225:/*
        -:  226: * MPID_Rsend_init()
        -:  227: */
        -:  228:#undef FUNCNAME
        -:  229:#define FUNCNAME MPID_Rsend_init
        -:  230:#undef FCNAME
        -:  231:#define FCNAME MPIDI_QUOTE(FUNCNAME)
        -:  232:int MPID_Rsend_init(const void * buf, int count, MPI_Datatype datatype, int rank, int tag, MPID_Comm * comm, int context_offset,
        -:  233:		    MPID_Request ** request)
      284:  234:{
        -:  235:    MPID_Request * sreq;
      284:  236:    int mpi_errno = MPI_SUCCESS;
        -:  237:    MPIDI_STATE_DECL(MPID_STATE_MPID_RSEND_INIT);
        -:  238:
        -:  239:    MPIDI_FUNC_ENTER(MPID_STATE_MPID_RSEND_INIT);
        -:  240:
      284:  241:    MPIDI_Request_create_psreq(sreq, mpi_errno, goto fn_exit);
      284:  242:    MPIDI_Request_set_type(sreq, MPIDI_REQUEST_TYPE_RSEND);
      284:  243:    if (HANDLE_GET_KIND(datatype) != HANDLE_KIND_BUILTIN)
        -:  244:    {
      224:  245:	MPID_Datatype_get_ptr(datatype, sreq->dev.datatype_ptr);
      224:  246:	MPID_Datatype_add_ref(sreq->dev.datatype_ptr);
        -:  247:    }
      284:  248:    *request = sreq;
        -:  249:
      284:  250:  fn_exit:    
        -:  251:    MPIDI_FUNC_EXIT(MPID_STATE_MPID_RSEND_INIT);
      284:  252:    return mpi_errno;
        -:  253:}
        -:  254:
        -:  255:/*
        -:  256: * MPID_Bsend_init()
        -:  257: */
        -:  258:#undef FUNCNAME
        -:  259:#define FUNCNAME MPID_Bsend_init
        -:  260:#undef FCNAME
        -:  261:#define FCNAME MPIDI_QUOTE(FUNCNAME)
        -:  262:int MPID_Bsend_init(const void * buf, int count, MPI_Datatype datatype, int rank, int tag, MPID_Comm * comm, int context_offset,
        -:  263:		    MPID_Request ** request)
       38:  264:{
        -:  265:    MPID_Request * sreq;
       38:  266:    int mpi_errno = MPI_SUCCESS;
        -:  267:    MPIDI_STATE_DECL(MPID_STATE_MPID_BSEND_INIT);
        -:  268:
        -:  269:    MPIDI_FUNC_ENTER(MPID_STATE_MPID_BSEND_INIT);
        -:  270:
       38:  271:    MPIDI_Request_create_psreq(sreq, mpi_errno, goto fn_exit);
       38:  272:    MPIDI_Request_set_type(sreq, MPIDI_REQUEST_TYPE_BSEND);
       38:  273:    if (HANDLE_GET_KIND(datatype) != HANDLE_KIND_BUILTIN)
        -:  274:    {
    #####:  275:	MPID_Datatype_get_ptr(datatype, sreq->dev.datatype_ptr);
    #####:  276:	MPID_Datatype_add_ref(sreq->dev.datatype_ptr);
        -:  277:    }
       38:  278:    *request = sreq;
        -:  279:
       38:  280:  fn_exit:    
        -:  281:    MPIDI_FUNC_EXIT(MPID_STATE_MPID_BSEND_INIT);
       38:  282:    return mpi_errno;
        -:  283:}
        -:  284:
        -:  285:/* 
        -:  286: * FIXME: The ch3 implmentation of the persistent routines should
        -:  287: * be very simple and use common code as much as possible.  All
        -:  288: * persistent routine should be in the same file, along with 
        -:  289: * startall.  Consider using function pointers to specify the 
        -:  290: * start functions, as if these were generalized requests, 
        -:  291: * rather than having MPID_Startall look at the request type.
        -:  292: */
        -:  293:/*
        -:  294: * MPID_Recv_init()
        -:  295: */
        -:  296:#undef FUNCNAME
        -:  297:#define FUNCNAME MPID_Recv_init
        -:  298:#undef FCNAME
        -:  299:#define FCNAME MPIDI_QUOTE(FUNCNAME)
        -:  300:int MPID_Recv_init(void * buf, int count, MPI_Datatype datatype, int rank, int tag, MPID_Comm * comm, int context_offset,
        -:  301:		   MPID_Request ** request)
      325:  302:{
        -:  303:    MPID_Request * rreq;
      325:  304:    int mpi_errno = MPI_SUCCESS;
        -:  305:    MPIDI_STATE_DECL(MPID_STATE_MPID_RECV_INIT);
        -:  306:
        -:  307:    MPIDI_FUNC_ENTER(MPID_STATE_MPID_RECV_INIT);
        -:  308:    
      325:  309:    rreq = MPID_Request_create();
      325:  310:    if (rreq == NULL)
        -:  311:    {
        -:  312:	/* --BEGIN ERROR HANDLING-- */
    #####:  313:	mpi_errno = MPIR_Err_create_code(MPI_SUCCESS, MPIR_ERR_FATAL, FCNAME, __LINE__, MPI_ERR_OTHER, "**nomem", 0);
        -:  314:	/* --END ERROR HANDLING-- */
    #####:  315:	goto fn_exit;
        -:  316:    }
        -:  317:    
      325:  318:    MPIU_Object_set_ref(rreq, 1);
      325:  319:    rreq->kind = MPID_PREQUEST_RECV;
      325:  320:    rreq->comm = comm;
      325:  321:    rreq->cc   = 0;
      325:  322:    MPIR_Comm_add_ref(comm);
      325:  323:    rreq->dev.match.parts.rank = rank;
      325:  324:    rreq->dev.match.parts.tag = tag;
      325:  325:    rreq->dev.match.parts.context_id = comm->recvcontext_id + context_offset;
      325:  326:    rreq->dev.user_buf = (void *) buf;
      325:  327:    rreq->dev.user_count = count;
      325:  328:    rreq->dev.datatype = datatype;
      325:  329:    rreq->partner_request = NULL;
      325:  330:    MPIDI_Request_set_type(rreq, MPIDI_REQUEST_TYPE_RECV);
      325:  331:    if (HANDLE_GET_KIND(datatype) != HANDLE_KIND_BUILTIN)
        -:  332:    {
      224:  333:	MPID_Datatype_get_ptr(datatype, rreq->dev.datatype_ptr);
      224:  334:	MPID_Datatype_add_ref(rreq->dev.datatype_ptr);
        -:  335:    }
      325:  336:    *request = rreq;
        -:  337:
      325:  338:  fn_exit:
        -:  339:    MPIDI_FUNC_EXIT(MPID_STATE_MPID_RECV_INIT);
      325:  340:    return mpi_errno;
        -:  341:}