-:    0:Source:/home/MPI/testing/mpich2/mpich2/src/mpid/ch3/src/mpid_isend.c
        -:    0:Graph:mpid_isend.gcno
        -:    0:Data:mpid_isend.gcda
        -:    0:Runs:4382
        -:    0:Programs:1376
        -:    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:
        -:    9:/* FIXME: HOMOGENEOUS SYSTEMS ONLY -- no data conversion is performed */
        -:   10:
        -:   11:/* FIXME: The routines MPID_Isend, MPID_Issend, MPID_Irsend are nearly 
        -:   12:   identical. It would be better if these did roughly:
        -:   13:
        -:   14:   MPID_Irsend -> always eager send (with ready mode for error detection)
        -:   15:   MPID_Issend -> always rendezvous send
        -:   16:   MPID_Isend  -> chose eager/rendezvous based on a threshold (and consider
        -:   17:   making the threshold configurable at either compile time (for best 
        -:   18:   low-latency performance) or run-time (for application tuning).
        -:   19:
        -:   20:   Then the 3 routines share little code, particularly if the eager/rendezvous 
        -:   21:   implementations are in their own routine
        -:   22:   */
        -:   23:/*
        -:   24: * MPID_Isend()
        -:   25: */
        -:   26:#undef FUNCNAME
        -:   27:#define FUNCNAME MPID_Isend
        -:   28:#undef FCNAME
        -:   29:#define FCNAME MPIDI_QUOTE(FUNCNAME)
        -:   30:int MPID_Isend(const void * buf, int count, MPI_Datatype datatype, int rank, 
        -:   31:	       int tag, MPID_Comm * comm, int context_offset,
        -:   32:               MPID_Request ** request)
  8803772:   33:{
        -:   34:    MPIDI_msg_sz_t data_sz;
        -:   35:    int dt_contig;
        -:   36:    MPI_Aint dt_true_lb;
        -:   37:    MPID_Datatype * dt_ptr;
        -:   38:    MPID_Request * sreq;
  8803772:   39:    MPIDI_VC_t * vc=0;
        -:   40:#if defined(MPID_USE_SEQUENCE_NUMBERS)
        -:   41:    MPID_Seqnum_t seqnum;
        -:   42:#endif    
  8803772:   43:    int mpi_errno = MPI_SUCCESS;
        -:   44:    MPIDI_STATE_DECL(MPID_STATE_MPID_ISEND);
        -:   45:
        -:   46:    MPIDI_FUNC_ENTER(MPID_STATE_MPID_ISEND);
        -:   47:
        -:   48:    MPIU_DBG_MSG_FMT(CH3_OTHER,VERBOSE,(MPIU_DBG_FDEST,
        -:   49:                  "rank=%d, tag=%d, context=%d", 
        -:   50:                  rank, tag, comm->context_id + context_offset));
        -:   51:    
  8803772:   52:    if (rank == comm->rank && comm->comm_kind != MPID_INTERCOMM)
        -:   53:    {
    61023:   54:	mpi_errno = MPIDI_Isend_self(buf, count, datatype, rank, tag, comm, 
        -:   55:			    context_offset, MPIDI_REQUEST_TYPE_SEND, &sreq);
    61023:   56:	goto fn_exit;
        -:   57:    }
        -:   58:
  8742749:   59:    if (rank != MPI_PROC_NULL) {
  8719409:   60:        MPIDI_Comm_get_vc_set_active(comm, rank, &vc);
        -:   61:#ifdef ENABLE_COMM_OVERRIDES
        -:   62:        /* this needs to come before the sreq is created, since the override
        -:   63:         * function is responsible for creating its own request */
        -:   64:        if (vc->comm_ops && vc->comm_ops->isend)
        -:   65:        {
        -:   66:            mpi_errno = vc->comm_ops->isend( vc, buf, count, datatype, rank, tag, comm, context_offset, &sreq);
        -:   67:            goto fn_exit;
        -:   68:        }
        -:   69:#endif
        -:   70:    }
        -:   71:
  8742749:   72:    MPIDI_Request_create_sreq(sreq, mpi_errno, goto fn_exit);
  8742749:   73:    MPIDI_Request_set_type(sreq, MPIDI_REQUEST_TYPE_SEND);
        -:   74:
  8742749:   75:    if (rank == MPI_PROC_NULL)
        -:   76:    {
    23340:   77:	MPIU_Object_set_ref(sreq, 1);
    23340:   78:	sreq->cc = 0;
    23340:   79:	goto fn_exit;
        -:   80:    }
        -:   81:
  8719409:   82:    MPIDI_Datatype_get_info(count, datatype, dt_contig, data_sz, dt_ptr, 
        -:   83:			    dt_true_lb);
        -:   84:    
  8719409:   85:    if (data_sz == 0)
        -:   86:    {
        -:   87:	MPIDI_CH3_Pkt_t upkt;
  1892880:   88:	MPIDI_CH3_Pkt_eager_send_t * const eager_pkt = &upkt.eager_send;
        -:   89:
  1892880:   90:	MPIDI_Request_set_msg_type(sreq, MPIDI_REQUEST_EAGER_MSG);
  1892880:   91:	sreq->dev.OnDataAvail = 0;
        -:   92:	    
        -:   93:	MPIU_DBG_MSG(CH3_OTHER,VERBOSE,"sending zero length message");
  1892880:   94:	MPIDI_Pkt_init(eager_pkt, MPIDI_CH3_PKT_EAGER_SEND);
  1892880:   95:	eager_pkt->match.parts.rank = comm->rank;
  1892880:   96:	eager_pkt->match.parts.tag = tag;
  1892880:   97:	eager_pkt->match.parts.context_id = comm->context_id + context_offset;
  1892880:   98:	eager_pkt->sender_req_id = sreq->handle;
  1892880:   99:	eager_pkt->data_sz = 0;
        -:  100:	
        -:  101:	MPIDI_VC_FAI_send_seqnum(vc, seqnum);
        -:  102:	MPIDI_Pkt_set_seqnum(eager_pkt, seqnum);
        -:  103:	MPIDI_Request_set_seqnum(sreq, seqnum);
        -:  104:	
        -:  105:	MPIU_THREAD_CS_ENTER(CH3COMM,vc);
  1892880:  106:	mpi_errno = MPIU_CALL(MPIDI_CH3,iSend(vc, sreq, eager_pkt, 
        -:  107:					      sizeof(*eager_pkt)));
        -:  108:	MPIU_THREAD_CS_EXIT(CH3COMM,vc);
        -:  109:	/* --BEGIN ERROR HANDLING-- */
  1892880:  110:	if (mpi_errno != MPI_SUCCESS)
        -:  111:	{
    #####:  112:	    MPIU_Object_set_ref(sreq, 0);
    #####:  113:	    MPIDI_CH3_Request_destroy(sreq);
    #####:  114:	    sreq = NULL;
    #####:  115:	    mpi_errno = MPIR_Err_create_code(mpi_errno, MPIR_ERR_FATAL, FCNAME,
        -:  116:			 __LINE__, MPI_ERR_OTHER, "**ch3|eagermsg", 0);
    #####:  117:	    goto fn_exit;
        -:  118:	}
        -:  119:	/* --END ERROR HANDLING-- */
        -:  120:
        -:  121:	goto fn_exit;
        -:  122:    }
        -:  123:    
        -:  124:    /* FIXME: flow control: limit number of outstanding eager messsages 
        -:  125:       containing data and need to be buffered by the receiver */
        -:  126:
  6826529:  127:    if (data_sz + sizeof(MPIDI_CH3_Pkt_eager_send_t) <=	vc->eager_max_msg_sz)
        -:  128:    {
  6824594:  129:	if (dt_contig)
        -:  130:	{
  6801933:  131:	    mpi_errno = MPIDI_CH3_EagerContigIsend( &sreq, 
        -:  132:						    MPIDI_CH3_PKT_EAGER_SEND,
        -:  133:						    (char*)buf + dt_true_lb, 
        -:  134:						    data_sz, rank, tag, 
        -:  135:						    comm, context_offset );
        -:  136:	}
        -:  137:	else
        -:  138:	{
    22661:  139:	    mpi_errno = MPIDI_CH3_EagerNoncontigSend( &sreq, 
        -:  140:                                                      MPIDI_CH3_PKT_EAGER_SEND,
        -:  141:                                                      buf, count, datatype,
        -:  142:                                                      data_sz, rank, tag, 
        -:  143:                                                      comm, context_offset );
        -:  144:	    /* If we're not complete, then add a reference to the datatype */
    22661:  145:	    if (sreq && sreq->dev.OnDataAvail) {
    #####:  146:		sreq->dev.datatype_ptr = dt_ptr;
    #####:  147:		MPID_Datatype_add_ref(dt_ptr);
        -:  148:	    }
        -:  149:	}
        -:  150:    }
        -:  151:    else
        -:  152:    {
        -:  153:	/* Note that the sreq was created above */
     1935:  154:	MPIDI_Request_set_msg_type( sreq, MPIDI_REQUEST_RNDV_MSG );
     1935:  155:	mpi_errno = vc->rndvSend_fn( &sreq, buf, count, datatype, dt_contig,
        -:  156:                                     data_sz, dt_true_lb, rank, tag, comm, 
        -:  157:                                     context_offset );
        -:  158:	/* FIXME: fill temporary IOV or pack temporary buffer after send to 
        -:  159:	   hide some latency.  This requires synchronization
        -:  160:           because the CTS packet could arrive and be processed before the 
        -:  161:	   above iStartmsg completes (depending on the progress
        -:  162:           engine, threads, etc.). */
        -:  163:	
     1935:  164:	if (sreq && dt_ptr != NULL)
        -:  165:	{
    #####:  166:	    sreq->dev.datatype_ptr = dt_ptr;
    #####:  167:	    MPID_Datatype_add_ref(dt_ptr);
        -:  168:	}
        -:  169:    }
        -:  170:
  8803772:  171:  fn_exit:
  8803772:  172:    *request = sreq;
        -:  173:
        -:  174:    MPIU_DBG_STMT(CH3_OTHER,VERBOSE,
        -:  175:    {
        -:  176:	if (sreq != NULL)
        -:  177:	{
        -:  178:	    MPIU_DBG_MSG_P(CH3_OTHER,VERBOSE,"request allocated, handle=0x%08x", sreq->handle);
        -:  179:	}
        -:  180:    }
        -:  181:		  );
        -:  182:    
        -:  183:    MPIDI_FUNC_EXIT(MPID_STATE_MPID_ISEND);
  8803772:  184:    return mpi_errno;
        -:  185:}