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

📄 mpid_onesided.h

📁 fortran并行计算包
💻 H
📖 第 1 页 / 共 3 页
字号:
/*  (C)Copyright IBM Corp.  2007, 2008  *//** * \file src/onesided/mpid_onesided.h * \brief MPI-DCMF Common declarations and definitions for RMA */#include "mpidimpl.h"/* redefine these for debugging purposes *//** * \brief Macro for allocating memory * * \param[out] p variable to receive new pointer * \param[in] t type of "p", excluding "*" * \param[in] z size in bytes to allocate * \param[in] e variable to receive error code * \param[in] n string to identify where/what allocation is * \return nothing, per ce. fills in "p" with address or NULL */#define MPIDU_MALLOC(p, t, z, e, n)	p = (t *)MPIU_Malloc(z)/** * \brief Macro for allocating memory * * \param[in] p variable containing address to be freed * \param[in] e variable to receive error code * \param[in] n string to identify where/what allocation/free is */#define MPIDU_FREE(p, e, n)		MPIU_Free((void *)p)/** * \brief structure of DCMF_Control_t as used by RMA ops * * DCMF_Control_t is assumed to be one quad. */typedef union {        DCMF_Control_t ctl;	/**< access to underlying type */        struct {                unsigned _0w0;	/**< word 0 */                unsigned _0w1;	/**< word 1 */                unsigned _0w2;	/**< word 2 */                unsigned _0w3;	/**< word 3 */        } _c_u;	/**< overlay of DCMF_Control_t */} MPIDU_Onesided_ctl_t __attribute__ ((__aligned__ (16)));#define mpid_ctl_w0	_c_u._0w0	/**< ctl word 0 */#define mpid_ctl_w1	_c_u._0w1	/**< ctl word 1 */#define mpid_ctl_w2	_c_u._0w2	/**< ctl word 2 */#define mpid_ctl_w3	_c_u._0w3	/**< ctl word 3 *//** * \brief structure of "msginfo" as used by RMA ops * * We always use 2 quads, just for consistency. */typedef union {        DCQuad info[2];		/**< access to underlying type */        struct {                unsigned _0w0;	/**< word 0 */                unsigned _0w1;	/**< word 1 */                unsigned _0w2;	/**< word 2 */                unsigned _0w3;	/**< word 3 */                unsigned _1w0;	/**< word 4 */                unsigned _1w1;	/**< word 5 */                unsigned _1w2;	/**< word 6 */                unsigned _1w3;	/**< word 7 */        } _i_u;	/**< overlay of DCQuads */} MPIDU_Onesided_info_t __attribute__ ((__aligned__ (16)));#define mpid_info_w0	_i_u._0w0	/**< info word 0 */#define mpid_info_w1	_i_u._0w1	/**< info word 1 */#define mpid_info_w2	_i_u._0w2	/**< info word 2 */#define mpid_info_w3	_i_u._0w3	/**< info word 3 */#define mpid_info_w4	_i_u._1w0	/**< info word 4 */#define mpid_info_w5	_i_u._1w1	/**< info word 5 */#define mpid_info_w6	_i_u._1w2	/**< info word 6 */#define mpid_info_w7	_i_u._1w3	/**< info word 7 */#if 0/** * \brief Translate message type into string */extern char *msgtypes[];#endif/** \brief DCMF Protocol object for DCMF_Send() calls */extern DCMF_Protocol_t bg1s_sn_proto;/** \brief DCMF Protocol object for DCMF_Get() calls */extern DCMF_Protocol_t bg1s_gt_proto;/** \brief DCMF Protocol object for DCMF_Control() calls */extern DCMF_Protocol_t bg1s_ct_proto;/** \brief global for our lpid */extern unsigned mpid_my_lpid;/** * \brief struct used by MPID_Get to delay unpacking of datatype * * Active only when the origin datatype is non-contiguous. * Reference count is used to determine when the last chunk of * data is received, rest of struct is used to unpack data. */struct mpid_get_cb_data {	int ref;		/**< reference counter */        MPID_Datatype *dtp;	/**< datatype object */	void *addr;		/**< origin address of get */	int count;		/**< origin count */	int len;		/**< computed length of get */	char *buf;		/**< temp buffer of packed data */};/** \brief datatype map entry - adjacent fields with same datatype are combined * * map[x].len = map[x].num * MPID_Datatype_get_basic_size(map[x].dt); * map[x+1].off = map[x].off + map[x].len + <stride>; * */typedef struct MPID_Type_map {        unsigned off;		/**< offset in datatype */        unsigned len;		/**< length of map segment */        unsigned num;		/**< number of fields */        MPI_Datatype dt;	/**< datatype of fields */} MPID_Type_map;/*******************************************************//** * \brief Structure to house info on cached datatypes * * Used to store info in the actual cache, and also to pass * info back and forth. * * Only derived datatypes ever use this. eltype and elsize are * zero if the dtp->eltype is not builtin. MPID_Accumulate() * uses this for error checking. */typedef struct {        MPID_Datatype *dtp;	/**< datatype object */        int _pad;		/**< padding to power of 2 length */        MPID_Type_map *map;	/**< datatype map */        int map_len;		/**< datatype map length */} mpid_dt_info;/** * \brief Build datatype map and iovec * * \param[in] dt	Datatype to build map/iov for * \param[out] dti	Pointer to datatype info struct */void make_dt_map_vec(MPI_Datatype dt, mpid_dt_info *dti);/** \brief Hi-order bit of integer type \note should be taken from standard include */#define INT_MSB	(1UL << (sizeof(int) * 8 - 1))/** * \brief Datatype created to represent the rma_sends element * of the coll_info array of the window structure */extern MPI_Datatype Coll_info_rma_dt;/** * \brief User defined function created to process the rma_sends * elements of the coll_info array of the window structure */extern MPI_Op Coll_info_rma_op;/** * \brief Dummy, global, MPID_Progress_state since its not used. */extern MPID_Progress_state dummy_state;/** * \brief Progress (advance) wait - how to spin and make progress * * 'expr' is true if must wait, i.e. *	while(expr) { make_progress; } * * Guaranteed to call DCMF_Messager_advance() _at least_ once * (via MPID_Progress_wait()) * * In DCMF, MPID_Progress_wait() never returns an error... * Also, MPID_Progress_state is never used. * * \param[in] expr	Conditional expression to be evaluated on each loop, *			FALSE will terminate loop. * \return nothing */#define MPIDU_Progress_spin(expr) {	\        MPID_Progress_start(&dummy_state);\        do {				\                (void)MPID_Progress_test();\                MPID_CS_EXIT();		\                MPID_CS_ENTER();	\        } while (expr);			\        MPID_Progress_end(&dummy_state);\}/* * * * * * Generic resource pool management * * * * * *//** * \page rsrc_design Basic resource element design * * Generic resources are managed through a \e mpid_qhead structure * which defines the basic geometry of the allocation blocks and * references the first allocated block. * * Generic resources are allocated in blocks. Each block begins * with a header of \e mpid_resource and is followed by a number * of elements whose size and count are defined for each resource * type. Also, the header size is defined, which may be larger * than the natural size of \e mpid_resource in order to optimize * memory layout (i.e. cache usage). * * Resource blocks are never freed (exception: lock wait queue * resources are freed when the window is freed). * * Specific resources are defined by their elements. Every resource * element must have as its first field the \e next pointer, as * defined by \e mpid_element. Following this is * defined by the needs of the specific resource. * * A newly allocated block is initialized with all elements \e next * chained together and the block's \e next_free pointer set to the * first (free) element. Except for the first allocated block * (the one directly referenced by \e mpid_qhead), the \e next_free * is not used again.  This also applies to the \e next_used and * \e last_used pointers. * * A newly allocated secondary block is linked into the \e mpid_qhead * \e next_block chain and \e next_free chain. * * When an element is taken from the free list, it is always taken * from the top of the list, i.e. directly from \e next_free. * When an element is returned to the free list, it is placed * (pushed) on the top. So an element to be allocated is always the * one most-recently freed, i.e. a LIFO queue. * * When an element is added to the used list, it is always added * to the end of the list, i.e. using the \e last_used pointer. * If an arbitrary element is taken from the used list, it is * taken from the top of the list, i.e. using \e next_used.  This * effectively forms a FIFO queue. * * Other routines exist that permit the used list to be searched, * and the found element may be removed from the used list * "out of turn". A specific resource implementation decides * how it will use this list. *//** * \brief Basic resource element structure. * * This implements the basic linked-list pointer(s) * needed to manage generic elements. * An actual element implementation will have additional * fields. * * \ref rsrc_design */struct mpid_element {        struct mpid_element *next;	/**< next used or next free */};/** * \brief Resource block header structure. * * This structure exists at the beginning of each * allocated block of elements. * * \ref rsrc_design */struct mpid_resource {        struct mpid_element *next_used;	/**< Pointer to top of queue */        struct mpid_element *last_used;	/**< Pointer to bottom of queue */        struct mpid_element *next_free;	/**< Pointer to top of free list */        struct mpid_resource *next_block;	/**< Pointer to next allocated block */};/** * \brief Resource "queue head" structure. * * This structure is required to exist and be initialized * before any resource or element management functions are call. * * \ref rsrc_design */struct mpid_qhead {        int num;	/**< number of elements per block */        short len;	/**< length of each element */        short hdl;	/**< length of header in block */        struct mpid_resource *blocks; /**< Allocated block(s) chain */        struct mpid_resource *lastblock; /**< last block in chain */};/** * \brief Queue-head static initializer. * * This is used to initialize a mpid_qhead structure at * compile-time. * * \param[in] n	number of elements per block * \param[in] l	length (bytes) of each element * \param[in] p	padding for header: added to sizeof(mpid_resource) * \return static initializer * * \ref rsrc_design */#define MPIDU_INIT_QHEAD_DECL(n, l, p) \        { (n), (l), sizeof(struct mpid_resource) + p, NULL }/** * \brief Queue-head dynamic initializer. * * This is used to initialize a mpid_qhead structure at * runtime. * * \param[in] qp	pointer to mpid_qhead structure * \param[in] n	number of elements per block * \param[in] l	length (bytes) of each element * \param[in] p	padding for header: added to sizeof(mpid_resource) * \return n/a * * \ref rsrc_design */#define MPIDU_INIT_QHEAD(qp, n, l, p) {	\        (qp)->num = n;			\        (qp)->len = l;			\        (qp)->hdl = sizeof(struct mpid_resource) + p;	\        (qp)->blocks = NULL;		\}/** * \brief Allocate a new block of elements. * * Unconditionally allocates a block of resources as described by * 'qhead' and link the block into 'qhead'. The new elements * are added to the 'qhead' free list. The new elements are * uninitialized except for the mpid_element field(s). * * \param[in] qhead	Queue Head * \return nothing * * \ref rsrc_design */void MPIDU_alloc_resource(struct mpid_qhead *qhead);/** * \brief Unconditionally free all resource blocks * referenced by 'qhead'. * * NOTE: elements such as datatype cache require addition freeing * and so won't work with this. We could add a "free func ptr" to * qhead and call it here - so each element type can free any other * buffers it may have allocated. * * Right now, this is only called by Win_free() on the lock and unlock * wait queues, which do no additional allocation. * * \param[in] qhead	Queue Head * \return nothing * * \ref rsrc_design */void MPIDU_free_resource(struct mpid_qhead *qhead);/** * \brief Get a new (unused) resource element. * * Take a resource element off the free list and put it on the * end of used list (bottom of queue). Element is uninitialized * except for mpid_element structure fields. * * \param[in] qhead	Queue Head * \return pointer to element. * * \ref rsrc_design */void *MPIDU_get_element(struct mpid_qhead *qhead);/** * \brief Initialize a new (unused) element. * * Get a new element from free list and initialize its contents * from 'el'. Element is placed at bottom of queue. * 'el' is assumed to be of qhead->len size. * * \param[in] qhead	Queue Head * \param[in] el	Pointer to new element data * \return pointer to element. * * \ref rsrc_design */void *MPIDU_add_element(struct mpid_qhead *qhead, void *el);/** * \brief Peek at top element in queue (used list). * * Copy contents of first element in used list (top of queue) * into 'el'. Does not alter qhead (used or free lists). * 'el' is assumed to be of qhead->len size. * * \param[in] qhead	Queue Head * \param[out] el	Pointer to destination for element data * \return 1 if no elements on queue or *	0 on success with 'el' filled-in. * * \ref rsrc_design */int MPIDU_peek_element(struct mpid_qhead *qhead, void *el);/** * \brief Free an element. * * Remove element 'el' (parent element 'pe') from used list * and place on free list. Typically, this is only called * after calling MPIDU_find_element() to obtain 'el' and 'pe'. * * (See MPIDU_free_resource()) This does not take into account * any additional allocations done by the element type. Whether * any such buffers need to be freed depends on how the element- * type re-uses elements (when taken off the free list). * * \param[in] qhead	Queue Head * \param[in] el	Element object * \param[in] pe	Parent element object, or NULL if 'el' *		is at top of queue. * \return nothing * * \ref rsrc_design */void MPIDU_free_element(struct mpid_qhead *qhead, void *el, void *pe);/** * \brief Pop first element off used list (top of queue). * * Element contents is copied into 'el', if not NULL. * Popped element is placed on free list. * Returns 0 (success) if element was popped, or 1 if list empty. * * \param[in] qhead	Queue Head * \param[out] el	Element contents buffer * \return 1 if no elements on queue or *	0 on success with 'el' filled-in. * * \ref rsrc_design */int MPIDU_pop_element(struct mpid_qhead *qhead, void *el);/** * \brief Find specific element in queue. *

⌨️ 快捷键说明

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