📄 mpidimpl.h
字号:
/* -*- Mode: C; c-basic-offset:4 ; -*- *//* * (C) 2001 by Argonne National Laboratory. * See COPYRIGHT in top-level directory. *//* * WARNING: Functions and macros in this file are for internal use only. * As such, they are only visible to the device and * channel. Do not include them in the MPID macros. */#if !defined(MPICH_MPIDIMPL_H_INCLUDED)#define MPICH_MPIDIMPL_H_INCLUDED#include "mpichconf.h"#if defined(HAVE_ASSERT_H)#include <assert.h>#endif#include "mpiimpl.h"#if !defined(MPICH_MPIDPRE_H_INCLUDED)#include "mpidpre.h"#endif/* Add the ch3 packet definitions */#include "mpidpkt.h"/* We need to match the size of MPI_Aint to the relevant Format control */#ifdef MPI_AINT_IS_LONG_INT#define MPIDI_MSG_SZ_FMT "%ld"#elif defined(MPI_AINT_IS_LONG_LONG_INT)#define MPIDI_MSG_SZ_FMT "%lld"#else#define MPIDI_MSG_SZ_FMT "%d"#endif#if !defined(MPIDI_IOV_DENSITY_MIN)# define MPIDI_IOV_DENSITY_MIN (16 * 1024)#endif#if defined(HAVE_GETHOSTNAME) && defined(NEEDS_GETHOSTNAME_DECL) && \ !defined(gethostname)int gethostname(char *name, size_t len);# endif/*S MPIDI_PG_t - Process group description Notes: Every 'MPI_COMM_WORLD' known to this process has an associated process group. S*/typedef struct MPIDI_PG{ /* MPIU_Object field. MPIDI_PG_t objects are not allocated using the MPIU_Object system, but we do use the associated reference counting routines. Therefore, handle must be present, but is not used except by debugging routines */ int handle; volatile int ref_count; /* Next pointer used to maintain a list of all process groups known to this process */ struct MPIDI_PG * next; /* Number of processes in the process group */ int size; /* VC table. At present this is a pointer to an array of VC structures. Someday we may want make this a pointer to an array of VC references. Thus, it is important to use MPIDI_PG_Get_vc() instead of directly referencing this field. */ struct MPIDI_VC * vct; /* Pointer to the process group ID. The actual ID is defined and allocated by the process group. The pointer is kept in the device space because it is necessary for the device to be able to find a particular process group. */ void * id; /* Replacement abstraction for connection information */ /* Connection information needed to access processes in this process group and to share the data with other processes. The items are connData - pointer for data used to implement these functions (e.g., a pointer to an array of process group info) getConnInfo( rank, buf, bufsize, self ) - function to store into buf the connection information for rank in this process group connInfoToString( buf_p, size, self ) - return in buf_p a string that can be sent to another process to recreate the connection information (the info needed to support getConnInfo) connInfoFromString( buf, self ) - setup the information needed to implement getConnInfo freeConnInfo( self ) - free any storage or resources associated with the connection information. See ch3/src/mpidi_pg.c */ void *connData; int (*getConnInfo)( int, char *, int, struct MPIDI_PG * ); int (*connInfoToString)( char **, int *, struct MPIDI_PG * ); int (*connInfoFromString)( const char *, struct MPIDI_PG * ); int (*freeConnInfo)( struct MPIDI_PG * ); /* Rather than have each channel define its own fields for the channel-specific data, we provide a fixed-sized scratchpad. Currently, this has a very generous size, though this may shrink later (a channel can always allocate storage and hang it off of the end). This is necessary to allow dynamic loading of channels at MPI_Init time. */#define MPIDI_CH3_PG_SIZE 48 int32_t channel_private[MPIDI_CH3_PG_SIZE];#if defined(MPIDI_CH3_PG_DECL) MPIDI_CH3_PG_DECL#endif }MPIDI_PG_t;/*S MPIDI_Process_t - The information required about this process by the CH3 device. S*/typedef struct MPIDI_Process{ MPIDI_PG_t * my_pg; int my_pg_rank;}MPIDI_Process_t;extern MPIDI_Process_t MPIDI_Process;/*---------------------- BEGIN DATATYPE SECTION ----------------------*//* FIXME: We want to avoid even storing information about the builtins if we can */#define MPIDI_Datatype_get_info(count_, datatype_, dt_contig_out_, data_sz_out_, dt_ptr_, dt_true_lb_)\{ \ if (HANDLE_GET_KIND(datatype_) == HANDLE_KIND_BUILTIN) \ { \ (dt_ptr_) = NULL; \ (dt_contig_out_) = TRUE; \ (dt_true_lb_) = 0; \ (data_sz_out_) = (count_) * MPID_Datatype_get_basic_size(datatype_);\ MPIDI_DBG_PRINTF((15, FCNAME, "basic datatype: dt_contig=%d, dt_sz=%d, data_sz=" MPIDI_MSG_SZ_FMT,\ (dt_contig_out_), MPID_Datatype_get_basic_size(datatype_), (data_sz_out_)));\ } \ else \ { \ MPID_Datatype_get_ptr((datatype_), (dt_ptr_)); \ (dt_contig_out_) = (dt_ptr_)->is_contig; \ (data_sz_out_) = (count_) * (dt_ptr_)->size; \ (dt_true_lb_) = (dt_ptr_)->true_lb; \ MPIDI_DBG_PRINTF((15, FCNAME, "user defined datatype: dt_contig=%d, dt_sz=%d, data_sz=" MPIDI_MSG_SZ_FMT,\ (dt_contig_out_), (dt_ptr_)->size, (data_sz_out_)));\ } \}/*-------------------- END DATATYPE SECTION --------------------*//*--------------------- BEGIN REQUEST SECTION ---------------------*//* * MPID_Requests * * MPI Requests are handles to MPID_Request structures. These are used * for most communication operations to provide a uniform way in which to * define pending operations. As such, they contain many fields that are * only used by some operations (logically, an MPID_Request is a union type). * * There are several kinds of requests. They are * Send, Receive, RMA, User, Persistent * In addition, send and RMA requests may be "incomplete"; this means that * they have not sent their initial packet, and they may store additional * data about the operation that will be used when the initial packet * can be sent. * * Also, requests that are used internally within blocking MPI routines * (only Send and Receive requests) do not require references to * (or increments of the reference counts) communicators or datatypes. * Thus, freeing these requests also does not require testing or * decrementing these fields. * * Finally, we want to avoid multiple tests for a failure to allocate * a request. Thus, the request allocation macros will jump to fn_fail * if there is an error. This is akin to using a "throw" in C++. * * For example, a posted (unmatched) receive queue entry needs only: * match info * buffer info (address, count, datatype) * if nonblocking, communicator (used for finding error handler) * if nonblocking, cancelled state * Once matched, a receive queue entry also needs * actual match info * message type (eager, rndv, eager-sync) * completion state (is all data available) * If destination datatype is non-contiguous, it also needs * current unpack state. * An unexpected message (in the unexpected receive queue) needs only: * match info * message type (eager, rndv, eager-sync) * if (eager, eager-sync), data * completion state (is all data available?) * A send request requires only * message type (eager, rndv, eager-sync) * completion state (has all data been sent?) * canceled state * if nonblocking, communicator (used for finding error handler) * if the initial envelope is still pending (e.g., could not write yet) * match info * if the data is still pending (rndv or would not send eager) * buffer info (address, count, datatype) * RMA requests require (what)? * User (generalized) requests require * function pointers for operations * completion state * cancelled state */#define MPIDI_CH3U_Request_complete(req_) \{ \ int incomplete__; \ \ MPIDI_CH3U_Request_decrement_cc((req_), &incomplete__); \ if (!incomplete__) \ { \ MPID_Request_release(req_); \ MPIDI_CH3_Progress_signal_completion(); \ } \}/* If the channel doesn't initialize anything in the request, provide a dummy */#ifndef MPIDI_CH3_REQUEST_INIT#define MPIDI_CH3_REQUEST_INIT(a_)#endif/* FIXME: Why does a send request need the match information? Is that for debugging information? In case the initial envelope cannot be sent? Ditto for the dev.user_buf, count, and datatype fields when the data is sent eagerly. The following fields needed to be set: datatype_ptr status.MPI_ERROR Note that this macro requires that rank, tag, context_offset, comm, buf, datatype, and count all be available with those names (they are not arguments to the routine)*/#define MPIDI_Request_create_sreq(sreq_, mpi_errno_, FAIL_) \{ \ (sreq_) = MPIU_Handle_obj_alloc(&MPID_Request_mem); \ if ((sreq_) == NULL) \ { \ MPIU_DBG_MSG(CH3_CHANNEL,TYPICAL,"unable to allocate a request");\ (mpi_errno_) = MPIR_ERR_MEMALLOCFAILED; \ FAIL_; \ } \ MPIU_DBG_MSG_P(CH3_CHANNEL,VERBOSE, \ "allocated request, handle=0x%08x", (sreq_)->handle);\ \ MPIU_Object_set_ref((sreq_), 2); \ (sreq_)->kind = MPID_REQUEST_SEND; \ (sreq_)->comm = comm; \ (sreq_)->cc = 1; \ (sreq_)->cc_ptr = &(sreq_)->cc; \ MPIR_Comm_add_ref(comm); \ (sreq_)->status.MPI_ERROR = MPI_SUCCESS; \ (sreq_)->status.cancelled = FALSE; \ (sreq_)->dev.state = 0; \ (sreq_)->dev.cancel_pending = FALSE; \ (sreq_)->dev.match.rank = rank; \ (sreq_)->dev.match.tag = tag; \ (sreq_)->dev.match.context_id = comm->context_id + context_offset; \ (sreq_)->dev.user_buf = (void *) buf; \ (sreq_)->dev.user_count = count; \ (sreq_)->dev.datatype = datatype; \ (sreq_)->dev.datatype_ptr = NULL; \ (sreq_)->dev.segment_ptr = NULL; \}/* This is the receive request version of MPIDI_Request_create_sreq */#define MPIDI_Request_create_rreq(rreq_, mpi_errno_, FAIL_) \{ \ (rreq_) = MPIU_Handle_obj_alloc(&MPID_Request_mem); \ if ((rreq_) == NULL) \ { \ MPIU_DBG_MSG(CH3_CHANNEL,TYPICAL,"unable to allocate a request");\ (mpi_errno_) = MPIR_ERR_MEMALLOCFAILED; \ FAIL_; \ } \ MPIU_DBG_MSG_P(CH3_CHANNEL,VERBOSE, \ "allocated request, handle=0x%08x", (rreq_)->handle);\ \ MPIU_Object_set_ref((rreq_), 2); \ (rreq_)->kind = MPID_REQUEST_RECV; \ (rreq_)->comm = NULL; \ (rreq_)->cc = 1; \ (rreq_)->cc_ptr = &(rreq_)->cc; \ (rreq_)->status.MPI_ERROR = MPI_SUCCESS; \ (rreq_)->status.cancelled = FALSE; \ (rreq_)->dev.state = 0; \ (rreq_)->dev.cancel_pending = FALSE; \ (rreq_)->dev.datatype_ptr = NULL; \ (rreq_)->dev.segment_ptr = NULL; \ (rreq_)->dev.iov_offset = 0; \ MPIDI_CH3_REQUEST_INIT(rreq_);\}#define MPIDI_REQUEST_MSG_MASK (0x3 << MPIDI_REQUEST_MSG_SHIFT)#define MPIDI_REQUEST_MSG_SHIFT 0#define MPIDI_REQUEST_NO_MSG 0#define MPIDI_REQUEST_EAGER_MSG 1#define MPIDI_REQUEST_RNDV_MSG 2#define MPIDI_REQUEST_SELF_MSG 3#define MPIDI_Request_get_msg_type(req_) \(((req_)->dev.state & MPIDI_REQUEST_MSG_MASK) >> MPIDI_REQUEST_MSG_SHIFT)#define MPIDI_Request_set_msg_type(req_, msgtype_) \{ \ (req_)->dev.state &= ~MPIDI_REQUEST_MSG_MASK; \ (req_)->dev.state |= ((msgtype_) << MPIDI_REQUEST_MSG_SHIFT) & MPIDI_REQUEST_MSG_MASK;\}#define MPIDI_REQUEST_SRBUF_MASK (0x1 << MPIDI_REQUEST_SRBUF_SHIFT)#define MPIDI_REQUEST_SRBUF_SHIFT 2#define MPIDI_Request_get_srbuf_flag(req_) \
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -