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

📄 gen_segment.c

📁 刚才是说明 现在是安装程序在 LINUX环境下进行编程的MPICH安装文件
💻 C
📖 第 1 页 / 共 2 页
字号:
/* -*- Mode: C; c-basic-offset:4 ; -*- *//* *  (C) 2001 by Argonne National Laboratory. *      See COPYRIGHT in top-level directory. */#include <stdio.h>#include <stdlib.h>#include <assert.h>/* NOTE: This is kind-of a hack; it would be better to somehow get this * included on the compile line. */#include <mpid_dataloop.h>#include <mpiimpl.h>#undef DLOOP_M_VERBOSE#ifndef GEN_DATALOOP_H#error "You must explicitly include a header that sets the PREPEND_PREFIX and includes gen_dataloop.h"#endif/* Notes on functions: * * There are a few different sets of functions here: * - DLOOP_Segment_manipulate() - uses a "piece" function to perform operations *   using segments (piece functions defined elsewhere) * - PREPEND_PREFIX functions - these define the externally visible interface *   to segment functionality */static inline int DLOOP_Stackelm_blocksize(struct DLOOP_Dataloop_stackelm *elmp);static inline int DLOOP_Stackelm_offset(struct DLOOP_Dataloop_stackelm *elmp);/* Segment_init * * buf    - datatype buffer location * count  - number of instances of the datatype in the buffer * handle - handle for datatype (could be derived or not) * segp   - pointer to previously allocated segment structure * * Assumes that the segment has been allocated. * * NOTE: THIS IMPLEMENTATION DOES NOT HANDLE STRUCT DATALOOPS. */int PREPEND_PREFIX(Segment_init)(const DLOOP_Buffer buf,				 DLOOP_Count count,				 DLOOP_Handle handle, 				 struct DLOOP_Segment *segp){    int i, elmsize, depth = 0;    struct DLOOP_Dataloop_stackelm *elmp;    struct DLOOP_Dataloop *dlp = 0;        /* first figure out what to do with the datatype/count.     * there are three cases:     * - predefined datatype, any count; use the builtin loop only     * - derived type, count == 1; don't use builtin at all     * - derived type, count > 1; use builtin for contig of derived type     */#ifdef DLOOP_M_VERBOSE    DLOOP_dbg_printf("DLOOP_Segment_init: count = %d, buf = %x\n",		    count,		    buf);#endif    if (!DLOOP_Handle_hasloop_macro(handle)) {	/* simplest case; datatype has no loop (basic) */	DLOOP_Handle_get_size_macro(handle, elmsize);	/* NOTE: ELMSIZE IS WRONG */	segp->builtin_loop.kind = DLOOP_KIND_CONTIG | DLOOP_FINAL_MASK 	    | (elmsize << DLOOP_ELMSIZE_SHIFT);	segp->builtin_loop.handle = handle;	segp->builtin_loop.loop_params.c_t.count = count;	segp->builtin_loop.loop_params.c_t.dataloop = 0;	segp->builtin_loop.el_size = elmsize;	DLOOP_Handle_get_extent_macro(handle, segp->builtin_loop.el_extent);	dlp = &segp->builtin_loop;	depth = 1;    }    else if (count == 1) {	/* don't use the builtin */	DLOOP_Handle_get_loopptr_macro(handle, dlp);	DLOOP_Handle_get_loopdepth_macro(handle, depth);    }    else {	/* need to use builtin to handle contig; must check loop depth first */		DLOOP_Handle_get_loopdepth_macro(handle, depth);	if (depth >= DLOOP_MAX_DATATYPE_DEPTH) return -1;	depth++; /* we're adding to the depth with the builtin */	DLOOP_Handle_get_size_macro(handle, elmsize);	/* NOTE: ELMSIZE IS WRONG */	segp->builtin_loop.kind = DLOOP_KIND_CONTIG 	    | (elmsize << DLOOP_ELMSIZE_SHIFT);	segp->builtin_loop.loop_params.c_t.count = count;	DLOOP_Handle_get_loopptr_macro(handle, segp->builtin_loop.loop_params.c_t.dataloop);	segp->builtin_loop.el_size = elmsize;	DLOOP_Handle_get_extent_macro(handle, segp->builtin_loop.el_extent);	dlp = &segp->builtin_loop;    }    /* initialize the rest of the segment values */    segp->handle = handle;    segp->ptr = (DLOOP_Buffer) buf;    segp->stream_off = 0;    segp->cur_sp = 0;    segp->valid_sp = 0;    /* initialize the first stackelm in its entirety */    /* Note that we start counts (and blocks) at the maximum value and then decrement;     * that way when we're testing for completion we don't have to look back at the     * maximum value.     */    elmp = &(segp->stackelm[0]);    elmp->loop_p      = dlp;    elmp->orig_count  = dlp->loop_params.count;    elmp->curcount    = elmp->orig_count;    elmp->orig_offset = 0;    /* NOTE: orig_count, curcount, and loop_p MUST be correct in elm before calling     * DLOOP_Stackelm_blocksize().     */    elmp->orig_block  = DLOOP_Stackelm_blocksize(elmp);    elmp->curblock    = elmp->orig_block;    /* NOTE: orig_count, curcount, and loop_p MUST be correct in elm before calling     * DLOOP_Stackelm_offset().     */    elmp->curoffset   = /* elmp->orig_offset + */ DLOOP_Stackelm_offset(elmp);        dlp = dlp->loop_params.cm_t.dataloop;    for (i=1; i < depth; i++) {	/* for the rest of the elements, we only fill in loop_p, orig_count, and	 * orig_block.  the rest are filled in as we process the type (and for	 * indexed case orig_block will be overwritten as well).	 */	elmp = &(segp->stackelm[i]);	elmp->curcount   = dlp->loop_params.count;	elmp->loop_p     = dlp; /* DO NOT MOVE THIS BELOW THE Stackelm CALLS! */	elmp->orig_count = elmp->curcount;	elmp->orig_block = DLOOP_Stackelm_blocksize(elmp);	if (i < depth-1) {	    /* not at last point in the stack */	    if (dlp->kind & DLOOP_FINAL_MASK) assert(0);	    dlp = dlp->loop_params.cm_t.dataloop;	}	else if (!(dlp->kind & DLOOP_FINAL_MASK)) assert(0); /* sanity check */    }    segp->valid_sp = depth-1;    return 0;}/* Segment_alloc * */struct DLOOP_Segment * PREPEND_PREFIX(Segment_alloc)(void){    return (struct DLOOP_Segment *) DLOOP_Malloc(sizeof(struct DLOOP_Segment));}/* Segment_free * * Input Parameters: * segp - pointer to segment */void PREPEND_PREFIX(Segment_free)(struct DLOOP_Segment *segp){    DLOOP_Free(segp);    return;}/* DLOOP_Segment_manipulate - do something to a segment * * If you think of all the data to be manipulated (packed, unpacked, whatever), * as a stream of bytes, it's easier to understand how first and last fit in. * * This function does all the work, calling the piecefn passed in when it  * encounters a datatype element which falls into the range of first..(last-1). * * piecefn can be NULL, in which case this function doesn't do anything when it * hits a region.  This is used internally for repositioning within this stream. * * last is a byte offset to the byte just past the last byte in the stream  * to operate on.  this makes the calculations all over MUCH cleaner. * * This is a horribly long function.  Too bad; it's complicated :)! -- Rob * * NOTE: THIS IMPLEMENTATION CANNOT HANDLE STRUCT DATALOOPS. */#define DLOOP_SEGMENT_SAVE_LOCAL_VALUES		\do {						\    segp->cur_sp     = cur_sp;			\    segp->valid_sp   = valid_sp;		\    segp->stream_off = stream_off;		\    *lastp           = stream_off;		\} while (0)#define DLOOP_SEGMENT_LOAD_LOCAL_VALUES		\do {						\    last       = *lastp;			\    cur_sp     = segp->cur_sp;			\    valid_sp   = segp->valid_sp;		\    stream_off = segp->stream_off;		\    cur_elmp   = &(segp->stackelm[cur_sp]);	\} while (0)#define DLOOP_SEGMENT_RESET_VALUES							\do {											\    segp->stream_off     = 0;								\    segp->cur_sp         = 0; 								\    cur_elmp             = &(segp->stackelm[0]);					\    cur_elmp->curcount   = cur_elmp->orig_count;					\    cur_elmp->orig_block = DLOOP_Stackelm_blocksize(cur_elmp);				\    cur_elmp->curblock   = cur_elmp->orig_block;					\    cur_elmp->curoffset  = cur_elmp->orig_offset + DLOOP_Stackelm_offset(cur_elmp);	\} while (0)#define DLOOP_SEGMENT_POP_AND_MAYBE_EXIT			\do {								\    cur_sp--;							\    if (cur_sp >= 0) cur_elmp = &segp->stackelm[cur_sp];	\    else {							\	DLOOP_SEGMENT_SAVE_LOCAL_VALUES;			\	return;							\    }								\} while (0)#define DLOOP_SEGMENT_PUSH			\do {						\    cur_sp++;					\    cur_elmp = &segp->stackelm[cur_sp];		\} while (0)#define DLOOP_STACKELM_BLOCKINDEXED_OFFSET(__elmp, __curcount) \(__elmp)->loop_p->loop_params.bi_t.offset_array[(__curcount)]#define DLOOP_STACKELM_INDEXED_OFFSET(__elmp, __curcount) \(__elmp)->loop_p->loop_params.i_t.offset_array[(__curcount)]#define DLOOP_STACKELM_INDEXED_BLOCKSIZE(__elmp, __curcount) \(__elmp)->loop_p->loop_params.i_t.blocksize_array[(__curcount)]void PREPEND_PREFIX(Segment_manipulate)(struct DLOOP_Segment *segp,					DLOOP_Offset first, 					DLOOP_Offset *lastp, 					int (*piecefn)(DLOOP_Handle,						       int,						       int,						       void *,						       void *), 					void *pieceparams){    int cur_sp, valid_sp;    DLOOP_Offset last;    DLOOP_Offset stream_off;    struct DLOOP_Dataloop_stackelm *cur_elmp;    DLOOP_SEGMENT_LOAD_LOCAL_VALUES;    /* first we ensure that stream_off and first are in the same spot */    if (first != stream_off) {	DLOOP_Offset tmp_last;#ifdef DLOOP_M_VERBOSE	DLOOP_dbg_printf("first=%d; stream_off=%ld; resetting.\n", first, stream_off);#endif	/* TODO: BE SMARTER AND DON'T RESET IF STREAM_OFF IS BEFORE FIRST */	/* reset to beginning of stream */	DLOOP_SEGMENT_RESET_VALUES;	/* TODO: AVOID CALLING MANIP. IF FIRST == 0 */	/* Note: we're simply using the manipulate function with a NULL piecefn	 * to handle this case.  It's one more function call, but it dramatically	 * simplifies this code.	 */	tmp_last = first;	PREPEND_PREFIX(Segment_manipulate)(segp, 0, &tmp_last, NULL, NULL);		/* verify that we're in the right location */	if (tmp_last != first) assert(0);	DLOOP_SEGMENT_LOAD_LOCAL_VALUES;	/* continue processing... */#ifdef DLOOP_M_VERBOSE	DLOOP_dbg_printf("done repositioning stream_off; first=%d, stream_off=%ld, last=%d\n",		   first, stream_off, last);#endif    }    for (;;) {	if ((cur_elmp->loop_p->kind & DLOOP_KIND_MASK) == DLOOP_KIND_STRUCT) assert(0);#ifdef DLOOP_M_VERBOSE        DLOOP_dbg_printf("looptop; cur_sp=%d, cur_elmp=%x\n", cur_sp, (unsigned) cur_elmp);#endif	if (cur_elmp->loop_p->kind & DLOOP_FINAL_MASK) {	    int partial_flag, piecefn_indicated_exit;	    DLOOP_Offset piece_size, basic_size, dtype_size;	    /* process data region */	    /* First discover how large a region we *could* process, if it	     * could all be handled by the processing function.	     */	    dtype_size = cur_elmp->loop_p->el_size;	    /* this is the fundamental size at which we should work.	     * this could theoretically be smaller than the 	     * dtype size; dunno yet.  if so, it will be a big mess	     * to keep up with...	     *	     * TODO: GET THIS FROM THE TYPE MORE CORRECTLY	     */	    basic_size = cur_elmp->loop_p->el_size;	    switch (cur_elmp->loop_p->kind & DLOOP_KIND_MASK) {		case DLOOP_KIND_CONTIG:		    piece_size = cur_elmp->curcount * dtype_size;		    break;         	case DLOOP_KIND_BLOCKINDEXED:		case DLOOP_KIND_INDEXED:

⌨️ 快捷键说明

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