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

📄 ch3u_request.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"/* This file contains two types of routines associated with requests:  * Routines to allocate and free requests * Routines to manage iovs on requests  * * Note that there are a number of macros that also manage requests defined * in mpidimpl.h ; these are intended to optimize request creation for * specific types of requests.  See the comments in mpidimpl.h for more * details. *//* Routines and data structures for request allocation and deallocation */#ifndef MPID_REQUEST_PREALLOC#define MPID_REQUEST_PREALLOC 8#endifMPID_Request MPID_Request_direct[MPID_REQUEST_PREALLOC] = {{0}};MPIU_Object_alloc_t MPID_Request_mem = {    0, 0, 0, 0, MPID_REQUEST, sizeof(MPID_Request), MPID_Request_direct,    MPID_REQUEST_PREALLOC };/* See the comments above about request creation.  Some routines will   use macros in mpidimpl.h *instead* of this routine */#undef FUNCNAME#define FUNCNAME MPID_Request_create#undef FCNAME#define FCNAME MPIDI_QUOTE(FUNCNAME)MPID_Request * MPID_Request_create(void){    MPID_Request * req;    MPIDI_STATE_DECL(MPID_STATE_MPID_REQUEST_CREATE);    MPIDI_FUNC_ENTER(MPID_STATE_MPID_REQUEST_CREATE);        req = MPIU_Handle_obj_alloc(&MPID_Request_mem);    if (req != NULL)    {	MPIU_DBG_MSG_P(CH3_CHANNEL,VERBOSE,		       "allocated request, handle=0x%08x", req->handle);#ifdef MPICH_DBG_OUTPUT	/*MPIU_Assert(HANDLE_GET_MPI_KIND(req->handle) == MPID_REQUEST);*/	if (HANDLE_GET_MPI_KIND(req->handle) != MPID_REQUEST)	{	    int mpi_errno;	    mpi_errno = MPIR_Err_create_code(MPI_SUCCESS, MPIR_ERR_FATAL, 		       FCNAME, __LINE__, MPI_ERR_OTHER, 		       "**invalid_handle", "**invalid_handle %d", req->handle);	    MPID_Abort(MPIR_Process.comm_world, mpi_errno, -1, NULL);	}#endif	/* FIXME: This makes request creation expensive.  We need to trim	   this to the basics, with additional setup for special-purpose 	   requests (think base class and inheritance).  For example, do we 	   *really* want to set the kind to UNDEFINED? And should the RMA 	   values be set only for RMA requests? */	MPIU_Object_set_ref(req, 1);	req->kind		   = MPID_REQUEST_UNDEFINED;	req->cc			   = 1;	req->cc_ptr		   = &req->cc;	/* FIXME: status fields meaningful only for receive, and even then	   should not need to be set. */	req->status.MPI_SOURCE	   = MPI_UNDEFINED;	req->status.MPI_TAG	   = MPI_UNDEFINED;	req->status.MPI_ERROR	   = MPI_SUCCESS;	req->status.count	   = 0;	req->status.cancelled	   = FALSE;	req->comm		   = NULL;	req->dev.datatype_ptr	   = NULL;	req->dev.segment_ptr	   = NULL;	/* Masks and flags for channel device state in an MPID_Request */	req->dev.state		   = 0;	req->dev.cancel_pending	   = FALSE;	/* FIXME: RMA ops shouldn't need to be set except when creating a	   request for RMA operations */	req->dev.target_win_handle = MPI_WIN_NULL;	req->dev.source_win_handle = MPI_WIN_NULL;	req->dev.single_op_opt	   = 0;	req->dev.lock_queue_entry  = NULL;	req->dev.dtype_info	   = NULL;	req->dev.dataloop	   = NULL;	req->dev.iov_offset        = 0;#if 0	req->dev.rdma_iov_count	   = 0;	req->dev.rdma_iov_offset   = 0;#endif#ifdef MPIDI_CH3_REQUEST_INIT	MPIDI_CH3_REQUEST_INIT(req);#endif    }    else    {	/* FIXME: This fails to fail if debugging is turned off */	MPIU_DBG_MSG(CH3_CHANNEL,TYPICAL,"unable to allocate a request");    }        MPIDI_FUNC_EXIT(MPID_STATE_MPID_REQUEST_CREATE);    return req;}/* FIXME: We need a lighter-weight version of this to avoid all of the   extra checks.  One posibility would be a single, no special case (no    comm, datatype, or srbuf to check) and a more general (check everything)   version.  */#undef FUNCNAME#define FUNCNAME MPIDI_CH3_Request_destroy#undef FCNAME#define FCNAME MPIDI_QUOTE(FUNCNAME)void MPIDI_CH3_Request_destroy(MPID_Request * req){    MPIDI_STATE_DECL(MPID_STATE_MPIDI_CH3_REQUEST_DESTROY);        MPIDI_FUNC_ENTER(MPID_STATE_MPIDI_CH3_REQUEST_DESTROY);    MPIU_DBG_MSG_P(CH3_CHANNEL,VERBOSE,		   "freeing request, handle=0x%08x", req->handle);    #ifdef MPICH_DBG_OUTPUT    /*MPIU_Assert(HANDLE_GET_MPI_KIND(req->handle) == MPID_REQUEST);*/    if (HANDLE_GET_MPI_KIND(req->handle) != MPID_REQUEST)    {	int mpi_errno = MPIR_Err_create_code(MPI_SUCCESS, MPIR_ERR_FATAL,                       FCNAME, __LINE__, MPI_ERR_OTHER,                       "**invalid_handle", "**invalid_handle %d", req->handle);	MPID_Abort(MPIR_Process.comm_world, mpi_errno, -1, NULL);    }    /*MPIU_Assert(req->ref_count == 0);*/    if (req->ref_count != 0)    {	int mpi_errno = MPIR_Err_create_code(MPI_SUCCESS, MPIR_ERR_FATAL,                       FCNAME, __LINE__, MPI_ERR_OTHER,               "**invalid_refcount", "**invalid_refcount %d", req->ref_count);	MPID_Abort(MPIR_Process.comm_world, mpi_errno, -1, NULL);    }#endif    /* FIXME: We need a better way to handle these so that we       do not always need to initialize these fields and check them       when we destroy a request */    /* FIXME: We need a way to call these routines ONLY when the        related ref count has become zero. */    if (req->comm != NULL) {	MPIR_Comm_release(req->comm, 0);    }    if (req->dev.datatype_ptr != NULL) {	MPID_Datatype_release(req->dev.datatype_ptr);    }    if (req->dev.segment_ptr != NULL) {	MPID_Segment_free(req->dev.segment_ptr);    }    if (MPIDI_Request_get_srbuf_flag(req)) {	MPIDI_CH3U_SRBuf_free(req);    }    MPIU_Handle_obj_free(&MPID_Request_mem, req);        MPIDI_FUNC_EXIT(MPID_STATE_MPIDI_CH3_REQUEST_DESTROY);}/* ------------------------------------------------------------------------- *//* Here are the routines to manipulate the iovs in the requests              *//* ------------------------------------------------------------------------- *//* * MPIDI_CH3U_Request_load_send_iov() * * Fill the provided IOV with the next (or remaining) portion of data described * by the segment contained in the request structure. * If the density of IOV is not sufficient, pack the data into a send/receive  * buffer and point the IOV at the buffer. */#undef FUNCNAME#define FUNCNAME MPIDI_CH3U_Request_load_send_iov#undef FCNAME#define FCNAME MPIDI_QUOTE(FUNCNAME)int MPIDI_CH3U_Request_load_send_iov(MPID_Request * const sreq, 				     MPID_IOV * const iov, int * const iov_n){    MPIDI_msg_sz_t last;    int mpi_errno = MPI_SUCCESS;    MPIDI_STATE_DECL(MPID_STATE_MPIDI_CH3U_REQUEST_LOAD_SEND_IOV);    MPIDI_FUNC_ENTER(MPID_STATE_MPIDI_CH3U_REQUEST_LOAD_SEND_IOV);    last = sreq->dev.segment_size;    MPIU_DBG_MSG_FMT(CH3_CHANNEL,VERBOSE,(MPIU_DBG_FDEST,     "pre-pv: first=" MPIDI_MSG_SZ_FMT ", last=" MPIDI_MSG_SZ_FMT ", iov_n=%d",		      sreq->dev.segment_first, last, *iov_n));    MPIU_Assert(sreq->dev.segment_first < last);    MPIU_Assert(last > 0);    MPIU_Assert(*iov_n > 0 && *iov_n <= MPID_IOV_LIMIT);    MPID_Segment_pack_vector(sreq->dev.segment_ptr, sreq->dev.segment_first, 			     &last, iov, iov_n);    MPIU_DBG_MSG_FMT(CH3_CHANNEL,VERBOSE,(MPIU_DBG_FDEST,    "post-pv: first=" MPIDI_MSG_SZ_FMT ", last=" MPIDI_MSG_SZ_FMT ", iov_n=%d",		      sreq->dev.segment_first, last, *iov_n));    MPIU_Assert(*iov_n > 0 && *iov_n <= MPID_IOV_LIMIT);        if (last == sreq->dev.segment_size)    {	MPIU_DBG_MSG(CH3_CHANNEL,VERBOSE,"remaining data loaded into IOV");	sreq->dev.OnDataAvail = sreq->dev.OnFinal;    }    else if ((last - sreq->dev.segment_first) / *iov_n >= MPIDI_IOV_DENSITY_MIN)    {	MPIU_DBG_MSG(CH3_CHANNEL,VERBOSE,"more data loaded into IOV");	sreq->dev.segment_first = last;	sreq->dev.OnDataAvail = MPIDI_CH3_ReqHandler_SendReloadIOV;    }    else    {	MPIDI_msg_sz_t data_sz;	int i, iov_data_copied;		MPIU_DBG_MSG(CH3_CHANNEL,VERBOSE,"low density.  using SRBuf.");	    	data_sz = sreq->dev.segment_size - sreq->dev.segment_first;	if (!MPIDI_Request_get_srbuf_flag(sreq))	{	    MPIDI_CH3U_SRBuf_alloc(sreq, data_sz);	    /* --BEGIN ERROR HANDLING-- */	    if (sreq->dev.tmpbuf_sz == 0)	    {		MPIU_DBG_MSG(CH3_CHANNEL,TYPICAL,"SRBuf allocation failure");		mpi_errno = MPIR_Err_create_code(MPI_SUCCESS, MPIR_ERR_FATAL,                                 FCNAME, __LINE__, MPI_ERR_OTHER, "**nomem", 0);		sreq->status.MPI_ERROR = mpi_errno;		goto fn_exit;	    }	    /* --END ERROR HANDLING-- */	}	iov_data_copied = 0;	for (i = 0; i < *iov_n; i++) {	    memcpy((char*) sreq->dev.tmpbuf + iov_data_copied, 		   iov[i].MPID_IOV_BUF, iov[i].MPID_IOV_LEN);	    iov_data_copied += iov[i].MPID_IOV_LEN;	}	sreq->dev.segment_first = last;	last = (data_sz <= sreq->dev.tmpbuf_sz - iov_data_copied) ? 	    sreq->dev.segment_size :	    sreq->dev.segment_first + sreq->dev.tmpbuf_sz - iov_data_copied;	MPIU_DBG_MSG_FMT(CH3_CHANNEL,VERBOSE,(MPIU_DBG_FDEST,               "pre-pack: first=" MPIDI_MSG_SZ_FMT ", last=" MPIDI_MSG_SZ_FMT,			  sreq->dev.segment_first, last));	MPID_Segment_pack(sreq->dev.segment_ptr, sreq->dev.segment_first, 			  &last, (char*) sreq->dev.tmpbuf + iov_data_copied);	MPIU_DBG_MSG_FMT(CH3_CHANNEL,VERBOSE,(MPIU_DBG_FDEST,              "post-pack: first=" MPIDI_MSG_SZ_FMT ", last=" MPIDI_MSG_SZ_FMT,			   sreq->dev.segment_first, last));	iov[0].MPID_IOV_BUF = (MPID_IOV_BUF_CAST)sreq->dev.tmpbuf;	iov[0].MPID_IOV_LEN = last - sreq->dev.segment_first + iov_data_copied;	*iov_n = 1;	if (last == sreq->dev.segment_size)	{	    MPIU_DBG_MSG(CH3_CHANNEL,VERBOSE,"remaining data packed into SRBuf");	    sreq->dev.OnDataAvail = sreq->dev.OnFinal;	}	else 	{	    MPIU_DBG_MSG(CH3_CHANNEL,VERBOSE,"more data packed into SRBuf");	    sreq->dev.segment_first = last;	    sreq->dev.OnDataAvail = MPIDI_CH3_ReqHandler_SendReloadIOV;	}    }      fn_exit:    MPIDI_FUNC_EXIT(MPID_STATE_MPIDI_CH3U_REQUEST_LOAD_SEND_IOV);    return mpi_errno;}/* * MPIDI_CH3U_Request_load_recv_iov() * * Fill the request's IOV with the next (or remaining) portion of data  * described by the segment (also contained in the request * structure).  If the density of IOV is not sufficient, allocate a  * send/receive buffer and point the IOV at the buffer. */#undef FUNCNAME#define FUNCNAME MPIDI_CH3U_Request_load_recv_iov#undef FCNAME#define FCNAME MPIDI_QUOTE(FUNCNAME)int MPIDI_CH3U_Request_load_recv_iov(MPID_Request * const rreq){    MPIDI_msg_sz_t last;    int mpi_errno = MPI_SUCCESS;    MPIDI_STATE_DECL(MPID_STATE_MPIDI_CH3U_REQUEST_LOAD_RECV_IOV);    MPIDI_FUNC_ENTER(MPID_STATE_MPIDI_CH3U_REQUEST_LOAD_RECV_IOV);    if (rreq->dev.segment_first < rreq->dev.segment_size)    {	/* still reading data that needs to go into the user buffer */		if (MPIDI_Request_get_srbuf_flag(rreq))	{	    MPIDI_msg_sz_t data_sz;	    MPIDI_msg_sz_t tmpbuf_sz;	    /* Once a SRBuf is in use, we continue to use it since a small 	       amount of data may already be present at the beginning	       of the buffer.  This data is left over from the previous unpack,	       most like a result of alignment issues.  NOTE: we	       could force the use of the SRBuf only 	       when (rreq->dev.tmpbuf_off > 0)... */	    	    data_sz = rreq->dev.segment_size - rreq->dev.segment_first - 		rreq->dev.tmpbuf_off;	    MPIU_Assert(data_sz > 0);	    tmpbuf_sz = rreq->dev.tmpbuf_sz - rreq->dev.tmpbuf_off;	    if (data_sz > tmpbuf_sz)	    {

⌨️ 快捷键说明

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