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

📄 typesize_support.c

📁 fortran并行计算包
💻 C
📖 第 1 页 / 共 2 页
字号:
	if (combiner == MPI_COMBINER_NAMED) {	    /* NOTE: This is a special case. If a user creates a struct	     *       with a named type at a non-zero displacement, the	     *       alignment may be different than expected due to 	     *       special compiler rules for this case. Thus we must	     *       over-ride the value that we obtained from	     *       Type_calc_footprint() above.	     */	    alignsz = DLOOP_Named_type_alignsize(types[i], aints[i]);	}	if (max_alignsz < alignsz) max_alignsz = alignsz;  	/* We save this LB if:	 * (1) this is our first iteration where we saw a nonzero blklen,	 * (2) we haven't found a sticky LB and this LB is lower than	 *     any we have previously seen,	 * (3) we haven't found a sticky LB and this one is sticky, or	 * (4) this sticky LB is lower than any we have previously seen.	 */	if ((first_iter) ||	    (!found_sticky_lb && min_lb > tmp_lb) ||	    (!found_sticky_lb && sticky_lb) ||	    (sticky_lb && min_lb > tmp_lb))	{	    min_lb = tmp_lb;	    if (sticky_lb) found_sticky_lb = 1;	}	if ((first_iter) ||	    (!found_sticky_ub && max_ub < tmp_ub) ||	    (!found_sticky_ub && sticky_ub) ||	    (sticky_ub && max_ub < tmp_ub))	{	    max_ub = tmp_ub;	    if (sticky_ub) found_sticky_ub = 1;	}	if ((first_iter) ||	    (tmp_true_lb > min_true_lb))	{	    min_true_lb = tmp_true_lb;	}	if ((first_iter) ||	    (tmp_true_ub < max_true_ub))	{	    max_true_ub = tmp_true_ub;	}	first_iter = 0;    }    /* calculate extent, not including potential padding */    tmp_extent = max_ub - min_lb;    /* account for padding if no sticky LB/UB is found */    if ((!found_sticky_lb) && (!found_sticky_ub)) {	DLOOP_Offset epsilon;	epsilon = (max_alignsz > 0) ? tmp_extent % max_alignsz : 0;	if (epsilon) {	    max_ub += (max_alignsz - epsilon);	    tmp_extent = max_ub - min_lb;	}    }#if 0    printf("size = %d, extent = %d\n", (int) tmp_size, (int) tmp_extent);#endif    tfp->size    = tmp_size;    tfp->lb      = min_lb;    tfp->ub      = max_ub;    tfp->true_lb = min_true_lb;    tfp->true_ub = max_true_ub;    tfp->extent  = tmp_extent;    tfp->alignsz = max_alignsz;    tfp->has_sticky_lb = found_sticky_lb;    tfp->has_sticky_ub = found_sticky_ub;    return;}/* DLOOP_Named_type_alignsize - calculate alignment in bytes for a struct                              based on constituent elements. Returns alignment in bytes.*/static int DLOOP_Named_type_alignsize(MPI_Datatype type, MPI_Aint disp){    int alignsize = 0;    static int havent_tested_align_rules = 1;    static int max_intalign = 0, max_fpalign = 0;    static int have_double_pos_align = 0, have_llint_pos_align = 0;    static int max_doublealign = 0, max_longdoublealign = 0;    if (havent_tested_align_rules) {	max_intalign          = DLOOP_Structalign_integer_max();	max_fpalign           = DLOOP_Structalign_float_max();	max_doublealign       = DLOOP_Structalign_double_max();	max_longdoublealign   = DLOOP_Structalign_long_double_max();	have_double_pos_align = DLOOP_Structalign_double_position();	have_llint_pos_align  = DLOOP_Structalign_llint_position();	havent_tested_align_rules = 0;    }    /* skip LBs, UBs, and elements with zero block length */    if (type == MPI_LB || type == MPI_UB)	return 0;    PMPI_Type_size(type, &alignsize);    switch(type)    {	case MPI_FLOAT:	    if (alignsize > max_fpalign)		alignsize = max_fpalign;	    break;	case MPI_DOUBLE:	    if (alignsize > max_doublealign)		alignsize = max_doublealign;	    	    if (have_double_pos_align && disp != (MPI_Aint) 0)		alignsize = 4; /* would be better to test */	    break;	case MPI_LONG_DOUBLE:	    if (alignsize > max_longdoublealign)		alignsize = max_longdoublealign;	    break;	default:	    if (alignsize > max_intalign) 		alignsize = max_intalign;	    	    if (have_llint_pos_align &&		type == MPI_LONG_LONG_INT &&		disp != (MPI_Aint) 0)	    {		alignsize = 4; /* would be better to test */	    }	    break;    }    return alignsize;}/* INTERNAL STRUCT ALIGNMENT TESTS BELOW *//* from MPICH2 PAC_C_MAX_INTEGER_ALIGN test: * * Tests for max C struct integer alignment. Note that this is for *all* * integer types. * * Return value is 1, 2, 4, or 8. */static int DLOOP_Structalign_integer_max(){    int is_packed  = 1;    int is_two     = 1;    int is_four    = 1;    int is_eight   = 1;    int size, extent;    struct { char a; int b; } char_int;    struct { char a; short b; } char_short;    struct { char a; long b; } char_long;    struct { char a; int b; char c; } char_int_char;    struct { char a; short b; char c; } char_short_char;#ifdef HAVE_LONG_LONG_INT    struct { long long int a; char b; } lli_c;    struct { char a; long long int b; } c_lli;    int extent2;#endif    /* assume max integer alignment isn't 8 if we don't have     * an eight-byte value.     */#ifdef HAVE_LONG_LONG_INT    if (sizeof(int) < 8 && sizeof(long) < 8 && sizeof(long long int) < 8)	is_eight = 0;#else    if (sizeof(int) < 8 && sizeof(long) < 8) is_eight = 0;#endif    size = sizeof(char) + sizeof(int);    extent = sizeof(char_int);    if (size != extent) is_packed = 0;    if ( (extent % 2) != 0) is_two = 0;    if ( (extent % 4) != 0) is_four = 0;    if (sizeof(int) == 8 && (extent % 8) != 0) is_eight = 0;    size = sizeof(char) + sizeof(short);    extent = sizeof(char_short);    if (size != extent) is_packed = 0;    if ( (extent % 2) != 0) is_two = 0;    if (sizeof(short) == 4 && (extent % 4) != 0) is_four = 0;    if (sizeof(short) == 8 && (extent % 8) != 0) is_eight = 0;    size = sizeof(char) + sizeof(long);    extent = sizeof(char_long);    if (size != extent) is_packed = 0;    if ( (extent % 2) != 0) is_two = 0;    if ( (extent % 4) != 0) is_four = 0;    if (sizeof(long) == 8 && (extent % 8) != 0) is_eight = 0;#ifdef HAVE_LONG_LONG_INT    size = sizeof(char) + sizeof(long long int);    extent = sizeof(lli_c);    extent2 = sizeof(c_lli);    if (size != extent) is_packed = 0;    if ( (extent % 2) != 0 && (extent2 % 2) != 0) is_two = 0;    if ( (extent % 4) != 0 && (extent2 % 4) != 0) is_four = 0;    if (sizeof(long long int) >= 8 && (extent % 8) != 0 && (extent2 % 8) != 0)	is_eight = 0;#endif    size = sizeof(char) + sizeof(int) + sizeof(char);    extent = sizeof(char_int_char);    if (size != extent) is_packed = 0;    if ( (extent % 2) != 0) is_two = 0;    if ( (extent % 4) != 0) is_four = 0;    if (sizeof(int) == 8 && (extent % 8) != 0) is_eight = 0;    size = sizeof(char) + sizeof(short) + sizeof(char);    extent = sizeof(char_short_char);    if (size != extent) is_packed = 0;    if ( (extent % 2) != 0) is_two = 0;    if (sizeof(short) == 4 && (extent % 4) != 0) is_four = 0;    if (sizeof(short) == 8 && (extent % 8) != 0) is_eight = 0;    if (is_eight) { is_four = 0; is_two = 0; }    if (is_four) is_two = 0;    DLOOP_Assert(is_packed + is_two + is_four + is_eight == 1);    if (is_packed) return 1;    if (is_two)    return 2;    if (is_four)   return 4;    return 8;}/* from MPICH2 PAC_C_MAX_FP_ALIGN test: * * Checks for max C struct floating point alignment. Note that * in this test we are *only* testing float types, whereas in * the original test we were testing double and long double also. * * Return value is 1, 2, 4, 8, or 16. */static int DLOOP_Structalign_float_max(){    int is_packed  = 1;    int is_two     = 1;    int is_four    = 1;    int is_eight   = 1;    int is_sixteen = 1;    struct { char a; float b; } char_float;    struct { float b; char a; } float_char;    int size, extent1, extent2;    size = sizeof(char) + sizeof(float);    extent1 = sizeof(char_float);    extent2 = sizeof(float_char);    if (size != extent1) is_packed = 0;    if ( (extent1 % 2) != 0 && (extent2 % 2) != 0) is_two = 0;    if ( (extent1 % 4) != 0 && (extent2 % 4) != 0) is_four = 0;    if (sizeof(float) == 8 && (extent1 % 8) != 0 && (extent2 % 8) != 0)	is_eight = 0;    if (is_sixteen) { is_eight = 0; is_four = 0; is_two = 0; }    if (is_eight) { is_four = 0; is_two = 0; }    if (is_four) is_two = 0;    DLOOP_Assert(is_packed + is_two + is_four + is_eight + is_sixteen == 1);    if (is_packed)  return 1;    if (is_two)     return 2;    if (is_four)    return 4;    if (is_eight)   return 8;    return 16;}/* from MPICH2 PAC_C_MAX_DOUBLE_FP_ALIGN test: * * Determines maximum struct alignment with floats and doubles. * * Return value is 1, 2, 4, or 8. */static int DLOOP_Structalign_double_max(){    int is_packed  = 1;    int is_two     = 1;    int is_four    = 1;    int is_eight   = 1;    struct { char a; double b; } char_double;    struct { double b; char a; } double_char;    int size, extent1, extent2;    size = sizeof(char) + sizeof(double);    extent1 = sizeof(char_double);    extent2 = sizeof(double_char);    if (size != extent1) is_packed = 0;    if ( (extent1 % 2) != 0 && (extent2 % 2) != 0) is_two = 0;    if ( (extent1 % 4) != 0 && (extent2 % 4) != 0) is_four = 0;    if (sizeof(double) == 8 && (extent1 % 8) != 0 && (extent2 % 8) != 0)	is_eight = 0;    if (is_eight) { is_four = 0; is_two = 0; }    if (is_four) is_two = 0;    DLOOP_Assert(is_packed + is_two + is_four + is_eight == 1);    if (is_packed) return 1;    if (is_two)    return 2;    if (is_four)   return 4;    return 8;}/* from MPICH2 PAC_C_MAX_LONGDOUBLE_FP_ALIGN test: * * Determines maximum alignment of structs with long doubles. * * Return value is 1, 2, 4, 8, or 16. */static int DLOOP_Structalign_long_double_max(){    int is_packed  = 1;    int is_two     = 1;    int is_four    = 1;    int is_eight   = 1;    int is_sixteen = 1;    struct { char a; long double b; } char_long_double;    struct { long double b; char a; } long_double_char;    struct { long double a; int b; char c; } long_double_int_char;    int size, extent1, extent2;    size = sizeof(char) + sizeof(long double);    extent1 = sizeof(char_long_double);    extent2 = sizeof(long_double_char);    if (size != extent1) is_packed = 0;    if ( (extent1 % 2) != 0 && (extent2 % 2) != 0) is_two = 0;    if ( (extent1 % 4) != 0 && (extent2 % 4) != 0) is_four = 0;    if (sizeof(long double) >= 8 && (extent1 % 8) != 0 && (extent2 % 8) != 0)	is_eight = 0;    if (sizeof(long double) > 8 && (extent1 % 16) != 0	&& (extent2 % 16) != 0) is_sixteen = 0;    extent1 = sizeof(long_double_int_char);    if ( (extent1 % 2) != 0) is_two = 0;    if ( (extent1 % 4) != 0) is_four = 0;    if (sizeof(long double) >= 8 && (extent1 % 8) != 0)	is_eight = 0;    if (sizeof(long double) > 8 && (extent1 % 16) != 0) is_sixteen = 0;    if (is_sixteen) { is_eight = 0; is_four = 0; is_two = 0; }    if (is_eight) { is_four = 0; is_two = 0; }    if (is_four) is_two = 0;    DLOOP_Assert(is_packed + is_two + is_four + is_eight + is_sixteen == 1);    if (is_packed)  return 1;    if (is_two)     return 2;    if (is_four)    return 4;    if (is_eight)   return 8;    return 16;}/* from MPICH2 PAC_C_DOUBLE_POS_ALIGN test: * * Test for odd struct alignment rule that only applies max. padding when * double value is at front of type. * * Search for "Power alignment mode" for more details. *  * Return value is 1 or 0. */static int DLOOP_Structalign_double_position(){    int padding_varies_by_pos = 0;    struct { char a; double b; } char_double;    struct { double b; char a; } double_char;    int extent1, extent2;    extent1 = sizeof(char_double);    extent2 = sizeof(double_char);    if (extent1 != extent2) padding_varies_by_pos = 1;    if (padding_varies_by_pos) return 1;    else                       return 0;}/* from MPICH2 PAC_C_LLINT_POS_ALIGN test: * Test for odd struct alignment rule that only applies max. * padding when long long int value is at front of type. * * Search for "Power alignment mode" for more details. *  * Return value is 1 or 0. */static int DLOOP_Structalign_llint_position(){    int padding_varies_by_pos = 0;#ifdef HAVE_LONG_LONG_INT    struct { char a; long long int b; } char_llint;    struct { long long int b; char a; } llint_char;    int extent1, extent2;    extent1 = sizeof(char_llint);    extent2 = sizeof(llint_char);    if (extent1 != extent2) padding_varies_by_pos = 1;#endif    if (padding_varies_by_pos) return 1;    else                       return 0;}#if 0/* from MPICH2 PAC_C_DOUBLE_ALIGNMENT_EXCEPTION test: * * Other tests assume that there is potentially a maximum alignment * and that if there is no maximum alignment, or a type is smaller than * that value, then we align on the size of the value, with the exception * of the "position-based alignment" rules we test for separately. *  * It turns out that these assumptions have fallen short in at least one * case, on MacBook Pros, where doubles are aligned on 4-byte boundaries * even when long doubles are aligned on 16-byte boundaries. So this test * is here specifically to handle this case. *  * Return value is 4 or 0.*/static int double_align_exception(){    struct { char a; double b; } char_double;    struct { double b; char a; } double_char;    int extent1, extent2, align_4 = 0;    extent1 = sizeof(char_double);    extent2 = sizeof(double_char);    /* we're interested in the largest value, will let separate test     * deal with position-based issues.     */    if (extent1 < extent2) extent1 = extent2;    if ((sizeof(double) == 8) && (extent1 % 8) != 0) {       if (extent1 % 4 == 0) {#ifdef HAVE_MAX_FP_ALIGNMENT          if (HAVE_MAX_FP_ALIGNMENT >= 8) align_4 = 1;#else          align_4 = 1;#endif       }    }    if (align_4) return 4;    else         return 0;}#endif

⌨️ 快捷键说明

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