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

📄 segment_ops.c

📁 fortran并行计算包
💻 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 <string.h>#include <sys/types.h>#include "./dataloop.h"#ifdef HAVE_ANY_INT64_T_ALIGNEMENT#define MPIR_ALIGN8_TEST(p1,p2)#else#define MPIR_ALIGN8_TEST(p1,p2) && ((((MPI_Aint)p1 | (MPI_Aint)p2) & 0x7) == 0)#endif#ifdef HAVE_ANY_INT32_T_ALIGNEMENT#define MPIR_ALIGN4_TEST(p1,p2)#else#define MPIR_ALIGN4_TEST(p1,p2) && ((((MPI_Aint)p1 | (MPI_Aint)p2) & 0x3) == 0)#endif#define MPIDI_COPY_FROM_VEC(src,dest,stride,type,nelms,count)	\{								\    type * l_src = (type *)src, * l_dest = (type *)dest;	\    int i, j;							\    const int l_stride = stride;				\    if (nelms == 1) {						\        for (i=count;i!=0;i--) {				\            *l_dest++ = *l_src;					\            l_src = (type *) ((char *) l_src + l_stride);	\        }							\    }								\    else {							\        for (i=count; i!=0; i--) {				\            for (j=0; j<nelms; j++) {				\                *l_dest++ = l_src[j];				\	    }							\            l_src = (type *) ((char *) l_src + l_stride);	\        }							\    }								\    dest = (char *) l_dest;					\    src  = (char *) l_src;                                      \}#define MPIDI_COPY_TO_VEC(src,dest,stride,type,nelms,count)	\{								\    type * l_src = (type *)src, * l_dest = (type *)dest;	\    int i, j;							\    const int l_stride = stride;				\    if (nelms == 1) {						\        for (i=count;i!=0;i--) {				\            *l_dest = *l_src++;					\            l_dest = (type *) ((char *) l_dest + l_stride);	\        }							\    }								\    else {							\        for (i=count; i!=0; i--) {				\            for (j=0; j<nelms; j++) {				\                l_dest[j] = *l_src++;				\	    }							\            l_dest = (type *) ((char *) l_dest + l_stride);	\        }							\    }								\    dest = (char *) l_dest;					\    src  = (char *) l_src;                                      \}/* m2m_params defined in dataloop_parts.h */int PREPEND_PREFIX(Segment_contig_m2m)(DLOOP_Offset *blocks_p,				       DLOOP_Type    el_type,				       DLOOP_Offset  rel_off,				       DLOOP_Buffer  unused,				       void         *v_paramp){    DLOOP_Offset el_size; /* DLOOP_Count? */    DLOOP_Offset size;    struct PREPEND_PREFIX(m2m_params) *paramp = v_paramp;    DLOOP_Handle_get_size_macro(el_type, el_size);    size = *blocks_p * el_size;#ifdef MPID_SU_VERBOSE    dbg_printf("\t[contig unpack: do=%d, dp=%x, bp=%x, sz=%d, blksz=%d]\n",	       rel_off, 	       (unsigned) bufp,	       (unsigned) paramp->u.unpack.unpack_buffer,	       el_size,	       (int) *blocks_p);#endif    if (paramp->direction == DLOOP_M2M_TO_USERBUF) {	memcpy((char *) (paramp->userbuf + rel_off), paramp->streambuf, size);    }    else {	memcpy(paramp->streambuf, (char *) (paramp->userbuf + rel_off), size);    }    paramp->streambuf += size;    return 0;}/* Segment_vector_m2m * * Note: this combines both packing and unpacking functionality. * * Note: this is only called when the starting position is at the beginning * of a whole block in a vector type. */int PREPEND_PREFIX(Segment_vector_m2m)(DLOOP_Offset *blocks_p,				       DLOOP_Count   unused,				       DLOOP_Count   blksz,				       DLOOP_Offset  stride,				       DLOOP_Type    el_type,				       DLOOP_Offset  rel_off, /* into buffer */				       DLOOP_Buffer  unused2,				       void         *v_paramp){    DLOOP_Count i, blocks_left, whole_count;    DLOOP_Offset el_size;    struct PREPEND_PREFIX(m2m_params) *paramp = v_paramp;    char *cbufp;    cbufp = paramp->userbuf + rel_off;    DLOOP_Handle_get_size_macro(el_type, el_size);    whole_count = (blksz > 0) ? (*blocks_p / blksz) : 0;    blocks_left = (blksz > 0) ? (*blocks_p % blksz) : 0;    if (paramp->direction == DLOOP_M2M_TO_USERBUF) {	if (el_size == 8 	    MPIR_ALIGN8_TEST(paramp->streambuf,cbufp))	{	    MPIDI_COPY_TO_VEC(paramp->streambuf, cbufp, stride,			      int64_t, blksz, whole_count);	    MPIDI_COPY_TO_VEC(paramp->streambuf, cbufp, 0,			      int64_t, blocks_left, 1);	}	else if (el_size == 4		 MPIR_ALIGN4_TEST(paramp->streambuf,cbufp))	{	    MPIDI_COPY_TO_VEC((paramp->streambuf), cbufp, stride,			      int32_t, blksz, whole_count);	    MPIDI_COPY_TO_VEC(paramp->streambuf, cbufp, 0,			      int32_t, blocks_left, 1);	}	else if (el_size == 2) {	    MPIDI_COPY_TO_VEC(paramp->streambuf, cbufp, stride,			      int16_t, blksz, whole_count);	    MPIDI_COPY_TO_VEC(paramp->streambuf, cbufp, 0,			      int16_t, blocks_left, 1);	}	else {	    for (i=0; i < whole_count; i++) {		memcpy(cbufp, paramp->streambuf, blksz * el_size);		paramp->streambuf += blksz * el_size;		cbufp += stride;	    }	    if (blocks_left) {		memcpy(cbufp, paramp->streambuf, blocks_left * el_size);		paramp->streambuf += blocks_left * el_size;	    }	}    }    else /* M2M_FROM_USERBUF */ {	if (el_size == 8 	    MPIR_ALIGN8_TEST(cbufp,paramp->streambuf))	{	    MPIDI_COPY_FROM_VEC(cbufp, paramp->streambuf, stride,				int64_t, blksz, whole_count);	    MPIDI_COPY_FROM_VEC(cbufp, paramp->streambuf, 0,				int64_t, blocks_left, 1);	}	else if (el_size == 4		 MPIR_ALIGN4_TEST(cbufp,paramp->streambuf))	{	    MPIDI_COPY_FROM_VEC(cbufp, paramp->streambuf, stride,				int32_t, blksz, whole_count);	    MPIDI_COPY_FROM_VEC(cbufp, paramp->streambuf, 0,				int32_t, blocks_left, 1);	}	else if (el_size == 2) {	    MPIDI_COPY_FROM_VEC(cbufp, paramp->streambuf, stride,				int16_t, blksz, whole_count);	    MPIDI_COPY_FROM_VEC(cbufp, paramp->streambuf, 0,				int16_t, blocks_left, 1);	}	else {	    for (i=0; i < whole_count; i++) {		memcpy(paramp->streambuf, cbufp, blksz * el_size);		paramp->streambuf += blksz * el_size;		cbufp += stride;	    }	    if (blocks_left) {		memcpy(paramp->streambuf, cbufp, blocks_left * el_size);		paramp->streambuf += blocks_left * el_size;	    }	}    }    return 0;}/* MPID_Segment_blkidx_m2m */int PREPEND_PREFIX(Segment_blkidx_m2m)(DLOOP_Offset *blocks_p,				       DLOOP_Count   count,				       DLOOP_Count   blocklen,				       DLOOP_Offset *offsetarray,				       DLOOP_Type    el_type,				       DLOOP_Offset  rel_off,				       DLOOP_Buffer  unused,				       void         *v_paramp){    DLOOP_Count curblock = 0;    DLOOP_Offset el_size;    DLOOP_Offset blocks_left = *blocks_p;    char *cbufp;    struct PREPEND_PREFIX(m2m_params) *paramp = v_paramp;    DLOOP_Handle_get_size_macro(el_type, el_size);    while (blocks_left) {	char *src, *dest;	DLOOP_Assert(curblock < count);	cbufp = paramp->userbuf + rel_off + offsetarray[curblock];	if (blocklen > blocks_left) blocklen = blocks_left;	if (paramp->direction == DLOOP_M2M_TO_USERBUF) {	    src  = paramp->streambuf;	    dest = cbufp;	}	else {	    src  = cbufp;	    dest = paramp->streambuf;	}	/* note: macro modifies dest buffer ptr, so we must reset */	if (el_size == 8	    MPIR_ALIGN8_TEST(src, dest))	{	    MPIDI_COPY_FROM_VEC(src, dest, 0, int64_t, blocklen, 1);	}	else if (el_size == 4		 MPIR_ALIGN4_TEST(src,dest))	{	    MPIDI_COPY_FROM_VEC(src, dest, 0, int32_t, blocklen, 1);	}	else if (el_size == 2) {	    MPIDI_COPY_FROM_VEC(src, dest, 0, int16_t, blocklen, 1);	}	else {	    memcpy(dest, src, blocklen * el_size);	}	paramp->streambuf += blocklen * el_size;	blocks_left -= blocklen;	curblock++;    }    return 0;}/* MPID_Segment_index_m2m */int PREPEND_PREFIX(Segment_index_m2m)(DLOOP_Offset *blocks_p,				      DLOOP_Count   count,				      DLOOP_Count  *blockarray,				      DLOOP_Offset *offsetarray,				      DLOOP_Type    el_type,				      DLOOP_Offset  rel_off,				      DLOOP_Buffer  unused,				      void         *v_paramp){    int curblock = 0;    DLOOP_Offset el_size;    DLOOP_Offset cur_block_sz, blocks_left = *blocks_p;    char *cbufp;    struct PREPEND_PREFIX(m2m_params) *paramp = v_paramp;    DLOOP_Handle_get_size_macro(el_type, el_size);    while (blocks_left) {	char *src, *dest;	DLOOP_Assert(curblock < count);	cur_block_sz = blockarray[curblock];	cbufp = paramp->userbuf + rel_off + offsetarray[curblock];	if (cur_block_sz > blocks_left) cur_block_sz = blocks_left;	if (paramp->direction == DLOOP_M2M_TO_USERBUF) {	    src  = paramp->streambuf;	    dest = cbufp;	}	else {	    src  = cbufp;	    dest = paramp->streambuf;	}	/* note: macro modifies dest buffer ptr, so we must reset */	if (el_size == 8	    MPIR_ALIGN8_TEST(src, dest))	{	    MPIDI_COPY_FROM_VEC(src, dest, 0, int64_t, cur_block_sz, 1);	}	else if (el_size == 4		 MPIR_ALIGN4_TEST(src,dest))	{	    MPIDI_COPY_FROM_VEC(src, dest, 0, int32_t, cur_block_sz, 1);	}	else if (el_size == 2) {	    MPIDI_COPY_FROM_VEC(src, dest, 0, int16_t, cur_block_sz, 1);	}	else {	    memcpy(dest, src, cur_block_sz * el_size);	}	paramp->streambuf += cur_block_sz * el_size;	blocks_left -= cur_block_sz;	curblock++;    }    return 0;}void PREPEND_PREFIX(Segment_pack)(DLOOP_Segment *segp,				  DLOOP_Offset   first,				  DLOOP_Offset  *lastp,				  void          *streambuf){    struct PREPEND_PREFIX(m2m_params) params;    /* experimenting with discarding buf value in the segment, keeping in     * per-use structure instead. would require moving the parameters around a     * bit. same applies to Segment_unpack below.     */    params.userbuf   = segp->ptr;    params.streambuf = streambuf;    params.direction = DLOOP_M2M_FROM_USERBUF;    PREPEND_PREFIX(Segment_manipulate)(segp, first, lastp,				       PREPEND_PREFIX(Segment_contig_m2m),				       PREPEND_PREFIX(Segment_vector_m2m),				       PREPEND_PREFIX(Segment_blkidx_m2m),				       PREPEND_PREFIX(Segment_index_m2m),				       NULL, /* size fn */				       &params);    return;}void PREPEND_PREFIX(Segment_unpack)(DLOOP_Segment *segp,				    DLOOP_Offset   first,				    DLOOP_Offset  *lastp,				    void *streambuf){    struct PREPEND_PREFIX(m2m_params) params;    params.userbuf   = segp->ptr;    params.streambuf = streambuf;    params.direction = DLOOP_M2M_TO_USERBUF;    PREPEND_PREFIX(Segment_manipulate)(segp, first, lastp,				       PREPEND_PREFIX(Segment_contig_m2m),				       PREPEND_PREFIX(Segment_vector_m2m),				       PREPEND_PREFIX(Segment_blkidx_m2m),				       PREPEND_PREFIX(Segment_index_m2m),				       NULL, /* size fn */				       &params);    return;}struct PREPEND_PREFIX(contig_blocks_params) {    DLOOP_Count  count;    DLOOP_Offset last_loc;};/* MPID_Segment_contig_count_block * * Note: because bufp is just an offset, we can ignore it in our *       calculations of # of contig regions. */static int DLOOP_Segment_contig_count_block(DLOOP_Offset *blocks_p,					    DLOOP_Type    el_type,					    DLOOP_Offset  rel_off,					    DLOOP_Buffer  unused,					    void         *v_paramp){    DLOOP_Offset size, el_size;    struct PREPEND_PREFIX(contig_blocks_params) *paramp = v_paramp;    DLOOP_Assert(*blocks_p > 0);    DLOOP_Handle_get_size_macro(el_type, el_size);    size = *blocks_p * el_size;#ifdef MPID_SP_VERBOSE    MPIU_dbg_printf("contig count block: count = %d, buf+off = %d, lastloc = %d\n",		    (int) paramp->count,

⌨️ 快捷键说明

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