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

📄 segment_ops.c

📁 fortran并行计算包
💻 C
📖 第 1 页 / 共 2 页
字号:
    return 0;}/* DLOOP_Segment_index_count_block * * Note: this is only called when the starting position is at the * beginning of a whole block in an indexed type. */static int DLOOP_Segment_index_count_block(DLOOP_Offset *blocks_p,					   DLOOP_Count count,					   DLOOP_Count *blockarray,					   DLOOP_Offset *offsetarray,					   DLOOP_Type el_type,					   DLOOP_Offset rel_off,					   void *bufp, /* unused */					   void *v_paramp){    DLOOP_Count new_blk_count;    DLOOP_Offset el_size, last_loc;    struct PREPEND_PREFIX(contig_blocks_params) *paramp = v_paramp;    DLOOP_Assert(count > 0 && *blocks_p > 0);    DLOOP_Handle_get_size_macro(el_type, el_size);    new_blk_count = count;    if (paramp->count > 0 && ((rel_off + offsetarray[0]) == paramp->last_loc))    {	/* first block sits at end of last block */	new_blk_count--;    }    /* Note: when we build an indexed type we combine adjacent regions,     *       so we're not going to go through and check every piece     *       separately here. if someone else were building indexed     *       dataloops by hand, then the loop here might be necessary.     *       DLOOP_Count i and DLOOP_Offset size would need to be     *       declared above.     */#if 0    last_loc = rel_off * offsetarray[0] + blockarray[0] * el_size;    for (i=1; i < count; i++) {	if (last_loc == rel_off + offsetarray[i]) new_blk_count--;	last_loc = rel_off + offsetarray[i] + blockarray[i] * el_size;    }#else    last_loc = rel_off + offsetarray[count-1] + blockarray[count-1] * el_size;#endif    paramp->last_loc = last_loc;    paramp->count += new_blk_count;    return 0;}/* DLOOP_Segment_count_contig_blocks() * * Count number of contiguous regions in segment between first and last. */void PREPEND_PREFIX(Segment_count_contig_blocks)(DLOOP_Segment *segp,						 DLOOP_Offset first,						 DLOOP_Offset *lastp,						 DLOOP_Count *countp){    struct PREPEND_PREFIX(contig_blocks_params) params;    params.count    = 0;    params.last_loc = 0;    /* FIXME: The blkidx and index functions are not used since they     * optimize the count by coalescing contiguous segments, while     * functions using the count do not optimize in the same way     * (e.g., flatten code) */    PREPEND_PREFIX(Segment_manipulate)(segp,				       first,				       lastp,				       DLOOP_Segment_contig_count_block,				       DLOOP_Segment_vector_count_block,				       DLOOP_Segment_blkidx_count_block,				       DLOOP_Segment_index_count_block,				       NULL, /* size fn */				       (void *) &params);    *countp = params.count;    return;}/********** FUNCTIONS FOR FLATTENING INTO MPI OFFSETS AND BLKLENS  **********//* Segment_mpi_flatten * * Flattens into a set of blocklengths and displacements, as in an * MPI hindexed type. Note that we use appropriately-sized variables * in the associated params structure for this reason. * * NOTE: blocks will be in units of bytes when returned. * * WARNING: there's potential for overflow here as we convert from *          various types into an index of bytes. */struct PREPEND_PREFIX(mpi_flatten_params) {    int       index, length;    MPI_Aint  last_end;    int      *blklens;    MPI_Aint *disps;};/* DLOOP_Segment_contig_mpi_flatten * */static int DLOOP_Segment_contig_mpi_flatten(DLOOP_Offset *blocks_p,					    DLOOP_Type el_type,					    DLOOP_Offset rel_off,					    void *bufp,					    void *v_paramp){    int last_idx, size;    DLOOP_Offset el_size;    char *last_end = NULL;    struct PREPEND_PREFIX(mpi_flatten_params) *paramp = v_paramp;    DLOOP_Handle_get_size_macro(el_type, el_size);    size = *blocks_p * (int) el_size;        last_idx = paramp->index - 1;    if (last_idx >= 0) {	last_end = ((char *) paramp->disps[last_idx]) +	    paramp->blklens[last_idx];    }    if ((last_idx == paramp->length-1) &&	(last_end != ((char *) bufp + rel_off)))    {	/* we have used up all our entries, and this region doesn't fit on	 * the end of the last one.  setting blocks to 0 tells manipulation	 * function that we are done (and that we didn't process any blocks).	 */	*blocks_p = 0;	return 1;    }    else if (last_idx >= 0 && (last_end == ((char *) bufp + rel_off)))    {	/* add this size to the last vector rather than using up another one */	paramp->blklens[last_idx] += size;    }    else {	paramp->disps[last_idx+1]   = (MPI_Aint) ((char *) bufp + rel_off);	paramp->blklens[last_idx+1] = size;	paramp->index++;    }    return 0;}/* DLOOP_Segment_vector_mpi_flatten * * Input Parameters: * blocks_p - [inout] pointer to a count of blocks (total, for all noncontiguous pieces) * count    - # of noncontiguous regions * blksz    - size of each noncontiguous region * stride   - distance in bytes from start of one region to start of next * el_type - elemental type (e.g. MPI_INT) * ... * * Note: this is only called when the starting position is at the beginning * of a whole block in a vector type. * * TODO: MAKE THIS CODE SMARTER, USING THE SAME GENERAL APPROACH AS IN THE *       COUNT BLOCK CODE ABOVE. */static int DLOOP_Segment_vector_mpi_flatten(DLOOP_Offset *blocks_p,					    DLOOP_Count count,					    DLOOP_Count blksz,					    DLOOP_Offset stride,					    DLOOP_Type el_type,					    DLOOP_Offset rel_off, /* offset into buffer */					    void *bufp, /* start of buffer */					    void *v_paramp){    int i, size, blocks_left;    DLOOP_Offset el_size;    struct PREPEND_PREFIX(mpi_flatten_params) *paramp = v_paramp;    DLOOP_Handle_get_size_macro(el_type, el_size);    blocks_left = *blocks_p;    for (i=0; i < count && blocks_left > 0; i++) {	int last_idx;	char *last_end = NULL;	if (blocks_left > blksz) {	    size = blksz * (int) el_size;	    blocks_left -= blksz;	}	else {	    /* last pass */	    size = blocks_left * (int) el_size;	    blocks_left = 0;	}	last_idx = paramp->index - 1;	if (last_idx >= 0) {	    last_end = ((char *) paramp->disps[last_idx]) +		paramp->blklens[last_idx];	}	if ((last_idx == paramp->length-1) &&	    (last_end != ((char *) bufp + rel_off)))	{	    /* we have used up all our entries, and this one doesn't fit on	     * the end of the last one.	     */	    *blocks_p -= (blocks_left + (size / (int) el_size));#ifdef MPID_SP_VERBOSE	    MPIU_dbg_printf("\t[vector to vec exiting (1): next ind = %d, %d blocks processed.\n",			    paramp->u.pack_vector.index,			    (int) *blocks_p);#endif	    return 1;	}	else if (last_idx >= 0 && (last_end == ((char *) bufp + rel_off)))	{	    /* add this size to the last vector rather than using up new one */	    paramp->blklens[last_idx] += size;	}	else {	    paramp->disps[last_idx+1]   = (MPI_Aint) ((char *) bufp + rel_off);	    paramp->blklens[last_idx+1] = size;	    paramp->index++;	}	rel_off += stride;    }#ifdef MPID_SP_VERBOSE    MPIU_dbg_printf("\t[vector to vec exiting (2): next ind = %d, %d blocks processed.\n",		    paramp->u.pack_vector.index,		    (int) *blocks_p);#endif    /* if we get here then we processed ALL the blocks; don't need to update     * blocks_p     */    DLOOP_Assert(blocks_left == 0);    return 0;}static int DLOOP_Segment_blkidx_mpi_flatten(DLOOP_Offset *blocks_p,                                            DLOOP_Count count,                                            DLOOP_Count blksz,                                            DLOOP_Offset *offsetarray,                                            DLOOP_Type el_type,                                            DLOOP_Offset rel_off,                                            void *bufp, /* unused */                                            void *v_paramp){    int i, size, blocks_left;    DLOOP_Offset el_size;    struct PREPEND_PREFIX(mpi_flatten_params) *paramp = v_paramp;    DLOOP_Handle_get_size_macro(el_type, el_size);    blocks_left = *blocks_p;    for (i=0; i < count && blocks_left > 0; i++) {	int last_idx;	char *last_end = NULL;	if (blocks_left > blksz) {	    size = blksz * (int) el_size;	    blocks_left -= blksz;	}	else {	    /* last pass */	    size = blocks_left * (int) el_size;	    blocks_left = 0;	}	last_idx = paramp->index - 1;	if (last_idx >= 0) {	    last_end = ((char *) paramp->disps[last_idx]) +		paramp->blklens[last_idx];	}	if ((last_idx == paramp->length-1) &&	    (last_end != ((char *) bufp + rel_off)))	{	    /* we have used up all our entries, and this one doesn't fit on	     * the end of the last one.	     */	    *blocks_p -= (blocks_left + (size / (int) el_size));#ifdef MPID_SP_VERBOSE	    MPIU_dbg_printf("\t[vector to vec exiting (1): next ind = %d, %d blocks processed.\n",			    paramp->u.pack_vector.index,			    (int) *blocks_p);#endif	    return 1;	}	else if (last_idx >= 0 && (last_end == ((char *) bufp + rel_off)))	{	    /* add this size to the last vector rather than using up new one */	    paramp->blklens[last_idx] += size;	}	else {	    paramp->disps[last_idx+1]   = (MPI_Aint) ((char *) bufp + rel_off + offsetarray[last_idx+1]);	    paramp->blklens[last_idx+1] = size;	    paramp->index++;	}	rel_off += offsetarray[i];    }#ifdef MPID_SP_VERBOSE    MPIU_dbg_printf("\t[vector to vec exiting (2): next ind = %d, %d blocks processed.\n",		    paramp->u.pack_vector.index,		    (int) *blocks_p);#endif    /* if we get here then we processed ALL the blocks; don't need to update     * blocks_p     */    DLOOP_Assert(blocks_left == 0);    return 0;}static int DLOOP_Segment_index_mpi_flatten(DLOOP_Offset *blocks_p,					   DLOOP_Count count,					   DLOOP_Count *blockarray,					   DLOOP_Offset *offsetarray,					   DLOOP_Type el_type,					   DLOOP_Offset rel_off,					   void *bufp, /* unused */					   void *v_paramp){    int i, size, blocks_left;    DLOOP_Offset el_size;    struct PREPEND_PREFIX(mpi_flatten_params) *paramp = v_paramp;    DLOOP_Handle_get_size_macro(el_type, el_size);    blocks_left = *blocks_p;    for (i=0; i < count && blocks_left > 0; i++) {	int last_idx;	char *last_end = NULL;	if (blocks_left > blockarray[i]) {	    size = blockarray[i] * (int) el_size;	    blocks_left -= blockarray[i];	}	else {	    /* last pass */	    size = blocks_left * (int) el_size;	    blocks_left = 0;	}	last_idx = paramp->index - 1;	if (last_idx >= 0) {	    last_end = ((char *) paramp->disps[last_idx]) +		paramp->blklens[last_idx];	}	if ((last_idx == paramp->length-1) &&	    (last_end != ((char *) bufp + rel_off)))	{	    /* we have used up all our entries, and this one doesn't fit on	     * the end of the last one.	     */	    *blocks_p -= (blocks_left + (size / (int) el_size));#ifdef MPID_SP_VERBOSE	    MPIU_dbg_printf("\t[vector to vec exiting (1): next ind = %d, %d blocks processed.\n",			    paramp->u.pack_vector.index,			    (int) *blocks_p);#endif	    return 1;	}	else if (last_idx >= 0 && (last_end == ((char *) bufp + rel_off)))	{	    /* add this size to the last vector rather than using up new one */	    paramp->blklens[last_idx] += size;	}	else {	    paramp->disps[last_idx+1]   = (MPI_Aint) ((char *) bufp + rel_off + offsetarray[last_idx+1]);	    paramp->blklens[last_idx+1] = size;	    paramp->index++;	}	rel_off += offsetarray[i];    }#ifdef MPID_SP_VERBOSE    MPIU_dbg_printf("\t[vector to vec exiting (2): next ind = %d, %d blocks processed.\n",		    paramp->u.pack_vector.index,		    (int) *blocks_p);#endif    /* if we get here then we processed ALL the blocks; don't need to update     * blocks_p     */    DLOOP_Assert(blocks_left == 0);    return 0;}/* MPID_Segment_mpi_flatten - flatten a type into a representation *                            appropriate for passing to hindexed create. * * Parameters: * segp    - pointer to segment structure * first   - first byte in segment to pack * lastp   - in/out parameter describing last byte to pack (and afterwards *           the last byte _actually_ packed) *           NOTE: actually returns index of byte _after_ last one packed * blklens, disps - the usual blocklength and displacement arrays for MPI * lengthp - in/out parameter describing length of array (and afterwards *           the amount of the array that has actual data) */void PREPEND_PREFIX(Segment_mpi_flatten)(DLOOP_Segment *segp,					 DLOOP_Offset first,					 DLOOP_Offset *lastp,					 int *blklens,					 MPI_Aint *disps,					 int *lengthp){    struct PREPEND_PREFIX(mpi_flatten_params) params;    DLOOP_Assert(*lengthp > 0);    params.index   = 0;    params.length  = *lengthp;    params.blklens = blklens;    params.disps   = disps;    PREPEND_PREFIX(Segment_manipulate)(segp,				       first,				       lastp, 				       DLOOP_Segment_contig_mpi_flatten, 				       DLOOP_Segment_vector_mpi_flatten,				       NULL, /* DLOOP_Segment_blkidx_mpi_flatten, */				       NULL, /* DLOOP_Segment_index_mpi_flatten, */				       NULL,				       &params);    /* last value already handled by MPID_Segment_manipulate */    *lengthp = params.index;    return;}/*  * Local variables: * c-indent-tabs-mode: nil * End: */

⌨️ 快捷键说明

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