-: 0:Source:/home/MPI/testing/mpich2/mpich2/src/mpid/common/datatype/mpid_type_struct.c
-: 0:Graph:mpid_type_struct.gcno
-: 0:Data:mpid_type_struct.gcda
-: 0:Runs:4382
-: 0:Programs:1376
-: 1:/* -*- Mode: C; c-basic-offset:4 ; -*- */
-: 2:
-: 3:/*
-: 4: * (C) 2001 by Argonne National Laboratory.
-: 5: * See COPYRIGHT in top-level directory.
-: 6: */
-: 7:
-: 8:#include <mpiimpl.h>
-: 9:#include <mpid_dataloop.h>
-: 10:#include <stdlib.h>
-: 11:#include <limits.h>
-: 12:
-: 13:#undef MPID_STRUCT_FLATTEN_DEBUG
-: 14:#undef MPID_STRUCT_DEBUG
-: 15:
-: 16:static int MPID_Type_struct_alignsize(int count,
-: 17: MPI_Datatype *oldtype_array,
-: 18: MPI_Aint *displacement_array);
-: 19:
-: 20:/* MPID_Type_struct_alignsize
-: 21: *
-: 22: * This function guesses at how the C compiler would align a structure
-: 23: * with the given components.
-: 24: *
-: 25: * It uses these configure-time defines to do its magic:
-: 26: * - HAVE_MAX_INTEGER_ALIGNMENT - maximum byte alignment of integers
-: 27: * - HAVE_MAX_FP_ALIGNMENT - maximum byte alignment of floating points
-: 28: * - HAVE_MAX_LONG_DOUBLE_FP_ALIGNMENT - maximum byte alignment with long
-: 29: * doubles (if different from FP_ALIGNMENT)
-: 30: * - HAVE_MAX_DOUBLE_FP_ALIGNMENT - maximum byte alignment with doubles (if
-: 31: * long double is different from FP_ALIGNMENT)
-: 32: * - HAVE_DOUBLE_POS_ALIGNMENT - indicates that structures with doubles
-: 33: * are aligned differently if double isn't
-: 34: * at displacement 0 (e.g. PPC32/64).
-: 35: * - HAVE_LLINT_POS_ALIGNMENT - same as above, for MPI_LONG_LONG_INT
-: 36: *
-: 37: * The different FP, DOUBLE, LONG_DOUBLE alignment case are necessary for
-: 38: * Cygwin on X86 (because long_double is 12 bytes, so double and long double
-: 39: * have different natural alignments). Linux on X86, however, does not have
-: 40: * different rules for this case.
-: 41: */
-: 42:static int MPID_Type_struct_alignsize(int count,
-: 43: MPI_Datatype *oldtype_array,
-: 44: MPI_Aint *displacement_array)
29483: 45:{
29483: 46: int i, max_alignsize = 0, tmp_alignsize, derived_alignsize = 0;
-: 47:
5400627: 48: for (i=0; i < count; i++)
-: 49: {
-: 50: /* shouldn't be called with an LB or UB, but we'll handle it nicely */
5371144: 51: if (oldtype_array[i] == MPI_LB || oldtype_array[i] == MPI_UB) continue;
5348067: 52: else if (HANDLE_GET_KIND(oldtype_array[i]) == HANDLE_KIND_BUILTIN)
-: 53: {
5338788: 54: tmp_alignsize = MPID_Datatype_get_basic_size(oldtype_array[i]);
-: 55:
-: 56:#ifdef HAVE_DOUBLE_ALIGNMENT_EXCEPTION
-: 57: if (oldtype_array[i] == MPI_DOUBLE) {
-: 58: tmp_alignsize = HAVE_DOUBLE_ALIGNMENT_EXCEPTION;
-: 59: }
-: 60:#endif
-: 61:
5338788: 62: switch(oldtype_array[i])
-: 63: {
-: 64: case MPI_FLOAT:
-: 65: case MPI_DOUBLE:
-: 66: case MPI_LONG_DOUBLE:
-: 67:#if defined(HAVE_MAX_LONG_DOUBLE_FP_ALIGNMENT) && \
-: 68: defined(HAVE_MAX_DOUBLE_FP_ALIGNMENT)
-: 69: if (oldtype_array[i] == MPI_LONG_DOUBLE) {
-: 70: if (tmp_alignsize > HAVE_MAX_LONG_DOUBLE_FP_ALIGNMENT)
-: 71: tmp_alignsize = HAVE_MAX_LONG_DOUBLE_FP_ALIGNMENT;
-: 72: }
-: 73: else if (oldtype_array[i] == MPI_DOUBLE) {
-: 74: if (tmp_alignsize > HAVE_MAX_DOUBLE_FP_ALIGNMENT)
-: 75: tmp_alignsize = HAVE_MAX_DOUBLE_FP_ALIGNMENT;
-: 76: }
-: 77: else {
-: 78: /* HAVE_MAX_FP_ALIGNMENT may not be defined, hence commented */
-: 79: /*
-: 80: if (tmp_alignsize > HAVE_MAX_FP_ALIGNMENT)
-: 81: tmp_alignsize = HAVE_MAX_FP_ALIGNMENT;
-: 82: */
-: 83: }
-: 84:#elif defined(HAVE_MAX_FP_ALIGNMENT)
463245: 85: if (tmp_alignsize > HAVE_MAX_FP_ALIGNMENT)
216033: 86: tmp_alignsize = HAVE_MAX_FP_ALIGNMENT;
-: 87:#endif
-: 88:#ifdef HAVE_DOUBLE_POS_ALIGNMENT
-: 89: /* sort of a hack, but so is this rule */
-: 90: if (oldtype_array[i] == MPI_DOUBLE &&
-: 91: displacement_array[i] != (MPI_Aint) 0)
-: 92: {
-: 93: tmp_alignsize = 4;
-: 94: }
-: 95:#endif
-: 96: break;
-: 97: default:
-: 98:#ifdef HAVE_MAX_INTEGER_ALIGNMENT
4875543: 99: if (tmp_alignsize > HAVE_MAX_INTEGER_ALIGNMENT)
6: 100: tmp_alignsize = HAVE_MAX_INTEGER_ALIGNMENT;
-: 101:#endif
-: 102: break;
-: 103:#ifdef HAVE_LLINT_POS_ALIGNMENT
-: 104: if (oldtype_array[i] == MPI_LONG_LONG_INT &&
-: 105: displacement_array[i] != (MPI_Aint) 0)
-: 106: {
-: 107: tmp_alignsize = 4;
-: 108: }
-: 109:#endif
-: 110: }
-: 111: }
-: 112: else
-: 113: {
-: 114: MPID_Datatype *dtp;
-: 115:
9279: 116: MPID_Datatype_get_ptr(oldtype_array[i], dtp);
9279: 117: tmp_alignsize = dtp->alignsize;
9279: 118: if (derived_alignsize < tmp_alignsize)
6391: 119: derived_alignsize = tmp_alignsize;
-: 120: }
5348067: 121: if (max_alignsize < tmp_alignsize) max_alignsize = tmp_alignsize;
-: 122:
-: 123: }
-: 124:
29483: 125: return max_alignsize;
-: 126:}
-: 127:
-: 128:
-: 129:/*@
-: 130: MPID_Type_struct - create a struct datatype
-: 131:
-: 132: Input Parameters:
-: 133:+ count - number of blocks in vector
-: 134:. blocklength_array - number of elements in each block
-: 135:. displacement_array - offsets of blocks from start of type in bytes
-: 136:- oldtype_array - types (using handle) of datatypes on which vector is based
-: 137:
-: 138: Output Parameters:
-: 139:. newtype - handle of new struct datatype
-: 140:
-: 141: Return Value:
-: 142: MPI_SUCCESS on success, MPI errno on failure.
-: 143:@*/
-: 144:int MPID_Type_struct(int count,
-: 145: int *blocklength_array,
-: 146: MPI_Aint *displacement_array,
-: 147: MPI_Datatype *oldtype_array,
-: 148: MPI_Datatype *newtype)
29484: 149:{
29484: 150: int mpi_errno = MPI_SUCCESS;
29484: 151: int i, old_are_contig = 1, definitely_not_contig = 0;
29484: 152: int found_sticky_lb = 0, found_sticky_ub = 0, found_true_lb = 0,
29484: 153: found_true_ub = 0, found_el_type = 0;
29484: 154: MPI_Aint el_sz = 0;
29484: 155: int size = 0;
29484: 156: MPI_Datatype el_type = MPI_DATATYPE_NULL;
29484: 157: MPI_Aint true_lb_disp = 0, true_ub_disp = 0, sticky_lb_disp = 0,
29484: 158: sticky_ub_disp = 0;
-: 159:
-: 160: MPID_Datatype *new_dtp;
-: 161:
29484: 162: if (count == 0) return MPID_Type_zerolen(newtype);
-: 163:
-: 164:#ifdef MPID_STRUCT_DEBUG
-: 165: MPIDI_Datatype_printf(oldtype_array[0], 1, displacement_array[0],
-: 166: blocklength_array[0], 1);
-: 167: for (i=1; i < count; i++)
-: 168: {
-: 169: MPIDI_Datatype_printf(oldtype_array[i], 1, displacement_array[i],
-: 170: blocklength_array[i], 0);
-: 171: }
-: 172:#endif
-: 173:
-: 174: /* allocate new datatype object and handle */
29483: 175: new_dtp = (MPID_Datatype *) MPIU_Handle_obj_alloc(&MPID_Datatype_mem);
|
-: 176: /* --BEGIN ERROR HANDLING-- */
29483: 177: if (!new_dtp)
-: 178: {
#####: 179: mpi_errno = MPIR_Err_create_code(MPI_SUCCESS, MPIR_ERR_RECOVERABLE,
-: 180: "MPID_Type_struct",
-: 181: __LINE__, MPI_ERR_OTHER,
-: 182: "**nomem", 0);
#####: 183: return mpi_errno;
-: 184: }
-: 185: /* --END ERROR HANDLING-- */
-: 186:
-: 187: /* handle is filled in by MPIU_Handle_obj_alloc() */
|
29483: 212: new_dtp->max_contig_blocks = 0;
5400627: 213: for (i=0; i < count; i++)
-: 214: {
-: 215: int is_builtin =
5371144: 216: (HANDLE_GET_KIND(oldtype_array[i]) == HANDLE_KIND_BUILTIN);
-: 217: MPI_Aint tmp_lb, tmp_ub, tmp_true_lb, tmp_true_ub;
-: 218: MPI_Aint tmp_el_sz;
-: 219: MPI_Datatype tmp_el_type;
5371144: 220: MPID_Datatype *old_dtp = NULL;
-: 221:
-: 222: /* Interpreting typemap to not include 0 blklen things, including
-: 223: * MPI_LB and MPI_UB. -- Rob Ross, 10/31/2005
-: 224: */
5371144: 225: if (blocklength_array[i] == 0) continue;
-: 226:
5371143: 227: if (is_builtin)
-: 228: {
5361864: 229: tmp_el_sz = MPID_Datatype_get_basic_size(oldtype_array[i]);
5361864: 230: tmp_el_type = oldtype_array[i];
-: 231:
5361864: 232: MPID_DATATYPE_BLOCK_LB_UB((MPI_Aint)(blocklength_array[i]),
-: 233: displacement_array[i],
-: 234: 0,
-: 235: tmp_el_sz,
-: 236: tmp_el_sz,
-: 237: tmp_lb,
-: 238: tmp_ub);
5361864: 239: tmp_true_lb = tmp_lb;
5361864: 240: tmp_true_ub = tmp_ub;
-: 241:
5361864: 242: size += tmp_el_sz * blocklength_array[i];
-: 243:
5361864: 244: new_dtp->max_contig_blocks++;
-: 245: }
-: 246: else
-: 247: {
9279: 248: MPID_Datatype_get_ptr(oldtype_array[i], old_dtp);
-: 249:
-: 250: /* Ensure that "element_size" fits into an int datatype. */
-: 251: MPID_Ensure_Aint_fits_in_int(old_dtp->element_size);
-: 252:
9279: 253: tmp_el_sz = old_dtp->element_size;
9279: 254: tmp_el_type = old_dtp->eltype;
-: 255:
9279: 256: MPID_DATATYPE_BLOCK_LB_UB((MPI_Aint) blocklength_array[i],
-: 257: displacement_array[i],
-: 258: old_dtp->lb,
-: 259: old_dtp->ub,
-: 260: old_dtp->extent,
-: 261: tmp_lb,
-: 262: tmp_ub);
9279: 263: tmp_true_lb = tmp_lb + (old_dtp->true_lb - old_dtp->lb);
9279: 264: tmp_true_ub = tmp_ub + (old_dtp->true_ub - old_dtp->ub);
-: 265:
9279: 266: size += old_dtp->size * blocklength_array[i];
-: 267:
9279: 268: new_dtp->max_contig_blocks += old_dtp->max_contig_blocks;
-: 269: }
-: 270:
-: 271: /* element size and type */
5371143: 272: if (oldtype_array[i] != MPI_LB && oldtype_array[i] != MPI_UB)
-: 273: {
5348066: 274: if (found_el_type == 0)
-: 275: {
29482: 276: el_sz = tmp_el_sz;
29482: 277: el_type = tmp_el_type;
29482: 278: found_el_type = 1;
-: 279: }
5318584: 280: else if (el_sz != tmp_el_sz)
-: 281: {
65918: 282: el_sz = -1;
65918: 283: el_type = MPI_DATATYPE_NULL;
-: 284: }
5252666: 285: else if (el_type != tmp_el_type)
-: 286: {
-: 287: /* Q: should we set el_sz = -1 even though the same? */
34: 288: el_type = MPI_DATATYPE_NULL;
-: 289: }
-: 290: }
-: 291:
-: 292: /* keep lowest sticky lb */
5371143: 293: if ((oldtype_array[i] == MPI_LB) ||
-: 294: (!is_builtin && old_dtp->has_sticky_lb))
-: 295: {
23776: 296: if (!found_sticky_lb)
-: 297: {
19066: 298: found_sticky_lb = 1;
19066: 299: sticky_lb_disp = tmp_lb;
-: 300: }
4710: 301: else if (sticky_lb_disp > tmp_lb)
-: 302: {
2310: 303: sticky_lb_disp = tmp_lb;
-: 304: }
-: 305: }
-: 306:
-: 307: /* keep highest sticky ub */
5371143: 308: if ((oldtype_array[i] == MPI_UB) ||
-: 309: (!is_builtin && old_dtp->has_sticky_ub))
-: 310: {
11356: 311: if (!found_sticky_ub)
-: 312: {
8624: 313: found_sticky_ub = 1;
8624: 314: sticky_ub_disp = tmp_ub;
-: 315: }
2732: 316: else if (sticky_ub_disp < tmp_ub)
-: 317: {
2534: 318: sticky_ub_disp = tmp_ub;
-: 319: }
-: 320: }
-: 321:
-: 322: /* keep lowest true lb and highest true ub
-: 323: *
-: 324: * note: checking for contiguity at the same time, to avoid
-: 325: * yet another pass over the arrays
-: 326: */
5371143: 327: if (oldtype_array[i] != MPI_UB && oldtype_array[i] != MPI_LB)
-: 328: {
5348066: 329: if (!found_true_lb)
-: 330: {
29482: 331: found_true_lb = 1;
29482: 332: true_lb_disp = tmp_true_lb;
-: 333: }
5318584: 334: else if (true_lb_disp > tmp_true_lb)
-: 335: {
-: 336: /* element starts before previous */
955: 337: true_lb_disp = tmp_true_lb;
955: 338: definitely_not_contig = 1;
-: 339: }
-: 340:
5348066: 341: if (!found_true_ub)
-: 342: {
29482: 343: found_true_ub = 1;
29482: 344: true_ub_disp = tmp_true_ub;
-: 345: }
5318584: 346: else if (true_ub_disp < tmp_true_ub)
-: 347: {
5317361: 348: true_ub_disp = tmp_true_ub;
-: 349: }
-: 350: else {
-: 351: /* element ends before previous ended */
1223: 352: definitely_not_contig = 1;
-: 353: }
-: 354: }
-: 355:
5371143: 356: if (!is_builtin && !old_dtp->is_contig)
-: 357: {
8382: 358: old_are_contig = 0;
-: 359: }
-: 360: }
-: 361:
29483: 362: new_dtp->n_elements = -1; /* TODO */
29483: 363: new_dtp->element_size = el_sz;
29483: 364: new_dtp->eltype = el_type;
-: 365:
29483: 366: new_dtp->has_sticky_lb = found_sticky_lb;
29483: 367: new_dtp->true_lb = true_lb_disp;
29483: 368: new_dtp->lb = (found_sticky_lb) ? sticky_lb_disp : true_lb_disp;
-: 369:
29483: 370: new_dtp->has_sticky_ub = found_sticky_ub;
29483: 371: new_dtp->true_ub = true_ub_disp;
29483: 372: new_dtp->ub = (found_sticky_ub) ? sticky_ub_disp : true_ub_disp;
-: 373:
29483: 374: new_dtp->alignsize = MPID_Type_struct_alignsize(count,
-: 375: oldtype_array,
-: 376: displacement_array);
-: 377:
29483: 378: new_dtp->extent = new_dtp->ub - new_dtp->lb;
29483: 379: if ((!found_sticky_lb) && (!found_sticky_ub))
-: 380: {
-: 381: /* account for padding */
-: 382: MPI_Aint epsilon = (new_dtp->alignsize > 0) ?
10058: 383: new_dtp->extent % ((MPI_Aint)(new_dtp->alignsize)) : 0;
-: 384:
10058: 385: if (epsilon)
-: 386: {
1360: 387: new_dtp->ub += ((MPI_Aint)(new_dtp->alignsize) - epsilon);
1360: 388: new_dtp->extent = new_dtp->ub - new_dtp->lb;
-: 389: }
-: 390: }
-: 391:
29483: 392: new_dtp->size = size;
-: 393:
-: 394: /* new type is contig for N types if its size and extent are the
-: 395: * same, and the old type was also contiguous, and we didn't see
-: 396: * something noncontiguous based on true ub/ub.
-: 397: */
32337: 398: if (((MPI_Aint)(new_dtp->size) == new_dtp->extent) &&
-: 399: old_are_contig && (! definitely_not_contig))
-: 400: {
2854: 401: new_dtp->is_contig = 1;
-: 402: }
-: 403: else
-: 404: {
26629: 405: new_dtp->is_contig = 0;
-: 406: }
-: 407:
29483: 408: *newtype = new_dtp->handle;
29483: 409: return mpi_errno;
-: 410:}
-: 411:
-: 412:
|