⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ch3u_eager.c

📁 fortran并行计算包
💻 C
📖 第 1 页 / 共 2 页
字号:
/* -*- Mode: C; c-basic-offset:4 ; -*- *//* *  (C) 2001 by Argonne National Laboratory. *      See COPYRIGHT in top-level directory. */#include "mpidimpl.h"/* * Send an eager message.  To optimize for the important, short contiguous * message case, there are separate routines for the contig and non-contig * datatype cases. */#undef FUNCNAME#define FUNCNAME MPIDI_CH3_SendNoncontig#undef FCNAME#define FCNAME MPIDI_QUOTE(FUNCNAME)/* MPIDI_CH3_SendNoncontig - Sends a message by loading an   IOV and calling iSendv.  The caller must initialize   sreq->dev.segment as well as segment_first and segment_size. */int MPIDI_CH3_SendNoncontig( MPIDI_VC_t *vc, MPID_Request *sreq,			     void *header, MPIDI_msg_sz_t hdr_sz ){    int mpi_errno = MPI_SUCCESS;    int iov_n;    MPID_IOV iov[MPID_IOV_LIMIT];    iov[0].MPID_IOV_BUF = header;    iov[0].MPID_IOV_LEN = hdr_sz;    iov_n = MPID_IOV_LIMIT - 1;    /* One the initial load of a send iov req, set the OnFinal action (null       for point-to-point) */    sreq->dev.OnFinal = 0;    mpi_errno = MPIDI_CH3U_Request_load_send_iov(sreq, &iov[1], &iov_n);    if (mpi_errno == MPI_SUCCESS)    {	iov_n += 1;		mpi_errno = MPIU_CALL(MPIDI_CH3,iSendv(vc, sreq, iov, iov_n));	/* --BEGIN ERROR HANDLING-- */	if (mpi_errno != MPI_SUCCESS)	{	    MPIU_Object_set_ref(sreq, 0);	    MPIDI_CH3_Request_destroy(sreq);	    mpi_errno = MPIR_Err_create_code(mpi_errno, MPIR_ERR_FATAL, 		         FCNAME, __LINE__, MPI_ERR_OTHER, "**ch3|eagermsg", 0);	    goto fn_fail;	}	/* --END ERROR HANDLING-- */	/* Note that in the non-blocking case, we need to add a ref to the	   datatypes */    }    else    {	/* --BEGIN ERROR HANDLING-- */	MPIU_Object_set_ref(sreq, 0);	MPIDI_CH3_Request_destroy(sreq);	mpi_errno = MPIR_Err_create_code(mpi_errno, MPIR_ERR_RECOVERABLE, 		    FCNAME, __LINE__, MPI_ERR_OTHER, "**ch3|loadsendiov", 0);	goto fn_fail;	/* --END ERROR HANDLING-- */    } fn_exit:    return mpi_errno; fn_fail:    goto fn_exit;}/* This function will allocate a segment.  That segment must be freed when   it is no longer needed */#undef FUNCNAME#define FUNCNAME MPIDI_EagerNoncontigSend#undef FCNAME#define FCNAME MPIDI_QUOTE(FUNCNAME)/* MPIDI_CH3_EagerNoncontigSend - Eagerly send noncontiguous data */int MPIDI_CH3_EagerNoncontigSend( MPID_Request **sreq_p, 				  MPIDI_CH3_Pkt_type_t reqtype, 				  const void * buf, int count, 				  MPI_Datatype datatype, MPIDI_msg_sz_t data_sz,				  int rank, 				  int tag, MPID_Comm * comm, 				  int context_offset ){    int mpi_errno = MPI_SUCCESS;    MPIDI_VC_t * vc;    MPID_Request *sreq = *sreq_p;    MPIDI_CH3_Pkt_t upkt;    MPIDI_CH3_Pkt_eager_send_t * const eager_pkt = &upkt.eager_send;        MPIU_DBG_MSG_FMT(CH3_OTHER,VERBOSE,(MPIU_DBG_FDEST,                     "sending non-contiguous eager message, data_sz=" MPIDI_MSG_SZ_FMT,					data_sz));    MPIDI_Pkt_init(eager_pkt, reqtype);    eager_pkt->match.rank	= comm->rank;    eager_pkt->match.tag	= tag;    eager_pkt->match.context_id	= comm->context_id + context_offset;    eager_pkt->sender_req_id	= MPI_REQUEST_NULL;    eager_pkt->data_sz		= data_sz;        MPIDI_Comm_get_vc(comm, rank, &vc);    MPIDI_VC_FAI_send_seqnum(vc, seqnum);    MPIDI_Pkt_set_seqnum(eager_pkt, seqnum);    MPIDI_Request_set_seqnum(sreq, seqnum);    MPIU_DBG_MSGPKT(vc,tag,eager_pkt->match.context_id,rank,data_sz,                    "Eager");	        sreq->dev.segment_ptr = MPID_Segment_alloc( );    /* if (!sreq->dev.segment_ptr) { MPIU_ERR_POP(); } */    MPID_Segment_init(buf, count, datatype, sreq->dev.segment_ptr, 0);    sreq->dev.segment_first = 0;    sreq->dev.segment_size = data_sz;	        mpi_errno = vc->sendNoncontig_fn(vc, sreq, eager_pkt, 					  sizeof(MPIDI_CH3_Pkt_eager_send_t));    if (mpi_errno) MPIU_ERR_POP(mpi_errno); fn_exit:    return mpi_errno; fn_fail:    *sreq_p = NULL;    goto fn_exit;}/* Send a contiguous eager message.  We'll want to optimize (and possibly   inline) this.   Make sure that buf is at the beginning of the data to send;    adjust by adding dt_true_lb if necessary */#undef FUNCNAME#define FUNCNAME MPIDI_EagerContigSend#undef FCNAME#define FCNAME MPIDI_QUOTE(FUNCNAME)int MPIDI_CH3_EagerContigSend( MPID_Request **sreq_p, 			       MPIDI_CH3_Pkt_type_t reqtype, 			       const void * buf, MPIDI_msg_sz_t data_sz, int rank, 			       int tag, MPID_Comm * comm, int context_offset ){    int mpi_errno = MPI_SUCCESS;    MPIDI_VC_t * vc;    MPIDI_CH3_Pkt_t upkt;    MPIDI_CH3_Pkt_eager_send_t * const eager_pkt = &upkt.eager_send;    MPID_Request *sreq = *sreq_p;    MPID_IOV iov[2];        MPIDI_Pkt_init(eager_pkt, reqtype);    eager_pkt->match.rank	= comm->rank;    eager_pkt->match.tag	= tag;    eager_pkt->match.context_id	= comm->context_id + context_offset;    eager_pkt->sender_req_id	= MPI_REQUEST_NULL;    eager_pkt->data_sz		= data_sz;        iov[0].MPID_IOV_BUF = (MPID_IOV_BUF_CAST)eager_pkt;    iov[0].MPID_IOV_LEN = sizeof(*eager_pkt);        MPIU_DBG_MSG_FMT(CH3_OTHER,VERBOSE,(MPIU_DBG_FDEST,	       "sending contiguous eager message, data_sz=" MPIDI_MSG_SZ_FMT,					data_sz));	        iov[1].MPID_IOV_BUF = (MPID_IOV_BUF_CAST) buf;    iov[1].MPID_IOV_LEN = data_sz;        MPIDI_Comm_get_vc(comm, rank, &vc);    MPIDI_VC_FAI_send_seqnum(vc, seqnum);    MPIDI_Pkt_set_seqnum(eager_pkt, seqnum);        MPIU_DBG_MSGPKT(vc,tag,eager_pkt->match.context_id,rank,data_sz,"EagerContig");    mpi_errno = MPIU_CALL(MPIDI_CH3,iStartMsgv(vc, iov, 2, sreq_p));    if (mpi_errno != MPI_SUCCESS) {	MPIU_ERR_SETFATALANDJUMP(mpi_errno,MPI_ERR_OTHER,"**ch3|eagermsg");    }    sreq = *sreq_p;    if (sreq != NULL)    {	MPIDI_Request_set_seqnum(sreq, seqnum);	MPIDI_Request_set_type(sreq, MPIDI_REQUEST_TYPE_SEND);    } fn_fail:    return mpi_errno;}#ifdef USE_EAGER_SHORT/* Send a short contiguous eager message.  We'll want to optimize (and possibly   inline) this    Make sure that buf is at the beginning of the data to send;    adjust by adding dt_true_lb if necessary    We may need a nonblocking (cancellable) version of this, which will    have a smaller payload.*/#undef FUNCNAME#define FUNCNAME MPIDI_EagerContigShortSend#undef FCNAME#define FCNAME MPIDI_QUOTE(FUNCNAME)int MPIDI_CH3_EagerContigShortSend( MPID_Request **sreq_p, 				    MPIDI_CH3_Pkt_type_t reqtype, 				    const void * buf, MPIDI_msg_sz_t data_sz, int rank, 				    int tag, MPID_Comm * comm, 				    int context_offset ){    int mpi_errno = MPI_SUCCESS;    MPIDI_VC_t * vc;    MPIDI_CH3_Pkt_t upkt;    MPIDI_CH3_Pkt_eagershort_send_t * const eagershort_pkt = 	&upkt.eagershort_send;    MPID_Request *sreq = *sreq_p;        /*    printf( "Sending short eager\n"); fflush(stdout); */    MPIDI_Pkt_init(eagershort_pkt, reqtype);    eagershort_pkt->match.rank	     = comm->rank;    eagershort_pkt->match.tag	     = tag;    eagershort_pkt->match.context_id = comm->context_id + context_offset;    eagershort_pkt->data_sz	     = data_sz;        MPIU_DBG_MSG_FMT(CH3_OTHER,VERBOSE,(MPIU_DBG_FDEST,       "sending contiguous short eager message, data_sz=" MPIDI_MSG_SZ_FMT,					data_sz));	        MPIDI_Comm_get_vc(comm, rank, &vc);    MPIDI_VC_FAI_send_seqnum(vc, seqnum);    MPIDI_Pkt_set_seqnum(eagershort_pkt, seqnum);    /* Copy the payload. We could optimize this if data_sz & 0x3 == 0        (copy (data_sz >> 2) ints, inline that since data size is        currently limited to 4 ints */    {	unsigned char * restrict p = 	    (unsigned char *)eagershort_pkt->data;	unsigned char const * restrict bufp = (unsigned char *)buf;	int i;	for (i=0; i<data_sz; i++) {	    *p++ = *bufp++;	}    }    MPIU_DBG_MSGPKT(vc,tag,eagershort_pkt->match.context_id,rank,data_sz,		    "EagerShort");    mpi_errno = MPIU_CALL(MPIDI_CH3,iStartMsg(vc, eagershort_pkt, 				      sizeof(*eagershort_pkt), sreq_p ));    if (mpi_errno != MPI_SUCCESS) {	MPIU_ERR_SETFATALANDJUMP(mpi_errno,MPI_ERR_OTHER,"**ch3|eagermsg");    }    sreq = *sreq_p;    if (sreq != NULL) {	/*printf( "Surprise, did not complete send of eagershort (starting connection?)\n" ); 	  fflush(stdout); */	MPIDI_Request_set_seqnum(sreq, seqnum);	MPIDI_Request_set_type(sreq, MPIDI_REQUEST_TYPE_SEND);    } fn_fail:        return mpi_errno;}/* This is the matching handler for the EagerShort message defined above */#undef FUNCNAME#define FUNCNAME MPIDI_CH3_PktHandler_EagerShortSend#undef FCNAME#define FCNAME MPIDI_QUOTE(FUNCNAME)int MPIDI_CH3_PktHandler_EagerShortSend( MPIDI_VC_t *vc, MPIDI_CH3_Pkt_t *pkt, 					 MPIDI_msg_sz_t *buflen, MPID_Request **rreqp ){    MPIDI_CH3_Pkt_eagershort_send_t * eagershort_pkt = &pkt->eagershort_send;    MPID_Request * rreq;    int found;    int mpi_errno = MPI_SUCCESS;    /* printf( "Receiving short eager!\n" ); fflush(stdout); */    MPIU_DBG_MSG_FMT(CH3_OTHER,VERBOSE,(MPIU_DBG_FDEST,	"received eagershort send pkt, rank=%d, tag=%d, context=%d",	eagershort_pkt->match.rank, 	eagershort_pkt->match.tag, eagershort_pkt->match.context_id));	        MPIU_DBG_MSGPKT(vc,eagershort_pkt->match.tag,		    eagershort_pkt->match.context_id,		    eagershort_pkt->match.rank,eagershort_pkt->data_sz,		    "ReceivedEagerShort");    rreq = MPIDI_CH3U_Recvq_FDP_or_AEU(&eagershort_pkt->match, &found);    if (rreq == NULL) {	MPIU_ERR_SETANDJUMP(mpi_errno,MPI_ERR_OTHER, "**nomemreq");    }    (rreq)->status.MPI_SOURCE = (eagershort_pkt)->match.rank;    (rreq)->status.MPI_TAG    = (eagershort_pkt)->match.tag;    (rreq)->status.count      = (eagershort_pkt)->data_sz;    (rreq)->dev.recv_data_sz  = (eagershort_pkt)->data_sz;    MPIDI_Request_set_seqnum((rreq), (eagershort_pkt)->seqnum);    /* FIXME: Why do we set the message type? */    MPIDI_Request_set_msg_type((rreq), MPIDI_REQUEST_EAGER_MSG);    /* The request is still complete (in the sense of        having all data) */    MPIDI_CH3U_Request_complete(rreq);    /* This packed completes the reception of the indicated data.       The packet handler returns null for a request that requires       no further communication */    *rreqp = NULL;    *buflen = sizeof(MPIDI_CH3_Pkt_t);    /* Extract the data from the packet */    /* Note that if the data size if zero, we're already done */    if (rreq->dev.recv_data_sz > 0) {	if (found) {	    int            dt_contig;	    MPI_Aint       dt_true_lb;	    MPIDI_msg_sz_t userbuf_sz;	    MPID_Datatype *dt_ptr;	    MPIDI_msg_sz_t data_sz;	    /* Make sure that we handle the general (non-contiguous)	       datatypes correctly while optimizing for the 	       special case */	    MPIDI_Datatype_get_info(rreq->dev.user_count, rreq->dev.datatype, 				    dt_contig, userbuf_sz, dt_ptr, dt_true_lb);			    if (rreq->dev.recv_data_sz <= userbuf_sz) {		data_sz = rreq->dev.recv_data_sz;	    }	    else {		MPIU_DBG_MSG_FMT(CH3_OTHER,VERBOSE,(MPIU_DBG_FDEST,		    "receive buffer too small; message truncated, msg_sz=" 					  MPIDI_MSG_SZ_FMT ", userbuf_sz="				          MPIDI_MSG_SZ_FMT,				 rreq->dev.recv_data_sz, userbuf_sz));		rreq->status.MPI_ERROR = MPIR_Err_create_code(MPI_SUCCESS,                      MPIR_ERR_RECOVERABLE, FCNAME, __LINE__, MPI_ERR_TRUNCATE,		     "**truncate", "**truncate %d %d %d %d", 		     rreq->status.MPI_SOURCE, rreq->status.MPI_TAG, 		     rreq->dev.recv_data_sz, userbuf_sz );		rreq->status.count = userbuf_sz;		data_sz = userbuf_sz;	    }	    if (dt_contig && data_sz == rreq->dev.recv_data_sz) {		/* user buffer is contiguous and large enough to store the		   entire message.  We can just copy the code */		/* Copy the payload. We could optimize this 		   if data_sz & 0x3 == 0 		   (copy (data_sz >> 2) ints, inline that since data size is 		   currently limited to 4 ints */		{		    unsigned char const * restrict p = 			(unsigned char *)eagershort_pkt->data;		    unsigned char * restrict bufp = 			(unsigned char *)(char*)(rreq->dev.user_buf) + 			dt_true_lb;		    int i;		    for (i=0; i<data_sz; i++) {			*bufp++ = *p++;		    }		}		/* FIXME: We want to set the OnDataAvail to the appropriate 		   function, which depends on whether this is an RMA 		   request or a pt-to-pt request. */		rreq->dev.OnDataAvail = 0;		/* The recv_pending_count must be one here (!) because of		   the way the pending count is queried.  We may want 		   to fix this, but it will require a sweep of the code */	    }	    else {		MPIDI_msg_sz_t data_sz, last;		/* user buffer is not contiguous.  Use the segment		   code to unpack it, handling various errors and 		   exceptional cases */		/* FIXME: The MPICH2 tests do not exercise this branch */		/* printf( "Surprise!\n" ); fflush(stdout);*/		rreq->dev.segment_ptr = MPID_Segment_alloc( );		/* if (!rreq->dev.segment_ptr) { MPIU_ERR_POP(); } */		MPID_Segment_init(rreq->dev.user_buf, rreq->dev.user_count, 				  rreq->dev.datatype, rreq->dev.segment_ptr, 0);		data_sz = rreq->dev.recv_data_sz;		last    = data_sz;		MPID_Segment_unpack( rreq->dev.segment_ptr, 0, 				     &last, eagershort_pkt->data );		if (last != data_sz) {		    /* --BEGIN ERROR HANDLING-- */		    /* There are two cases:  a datatype mismatch (could

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -