-: 0:Source:/home/MPI/testing/mpich2/mpich2/src/mpi/datatype/get_elements.c
-: 0:Graph:get_elements.gcno
-: 0:Data:get_elements.gcda
-: 0:Runs:528
-: 0:Programs:148
-: 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:
-: 10:/* -- Begin Profiling Symbol Block for routine MPI_Get_elements */
-: 11:#if defined(HAVE_PRAGMA_WEAK)
-: 12:#pragma weak MPI_Get_elements = PMPI_Get_elements
-: 13:#elif defined(HAVE_PRAGMA_HP_SEC_DEF)
-: 14:#pragma _HP_SECONDARY_DEF PMPI_Get_elements MPI_Get_elements
-: 15:#elif defined(HAVE_PRAGMA_CRI_DUP)
-: 16:#pragma _CRI duplicate MPI_Get_elements as PMPI_Get_elements
-: 17:#endif
-: 18:/* -- End Profiling Symbol Block */
-: 19:
-: 20:#ifndef MIN
-: 21:#define MIN(__a, __b) (((__a) < (__b)) ? (__a) : (__b))
-: 22:#endif
-: 23:
-: 24:PMPI_LOCAL int MPIR_Type_get_basic_type_elements(int *bytes_p,
-: 25: int count,
-: 26: MPI_Datatype datatype);
-: 27:PMPI_LOCAL int MPIR_Type_get_elements(int *bytes_p,
-: 28: int count,
-: 29: MPI_Datatype datatype);
-: 30:
-: 31:/* Define MPICH_MPI_FROM_PMPI if weak symbols are not supported to build
-: 32: the MPI routines */
-: 33:#ifndef MPICH_MPI_FROM_PMPI
-: 34:#undef MPI_Get_elements
-: 35:#define MPI_Get_elements PMPI_Get_elements
-: 36:
-: 37:/* Note that all helper routines must be within the
-: 38: * MPICH_MPI_FROM_PMPI ifdef so that we don't get two copies of the
-: 39: * helper routines in the case where we don't have weak symbols. */
-: 40:
-: 41:/* MPIR_Type_get_basic_type_elements()
-: 42: *
-: 43: * Arguments:
-: 44: * - bytes_p - input/output byte count
-: 45: * - count - maximum number of this type to subtract from the bytes; a count
-: 46: * of -1 indicates use as many as we like
-: 47: * - datatype - input datatype
-: 48: *
-: 49: * Returns number of elements available given the two constraints of number of
-: 50: * bytes and count of types. Also reduces the byte count by the amount taken
-: 51: * up by the types.
-: 52: *
-: 53: * Assumptions:
-: 54: * - the type passed to this function must be a basic *or* a pairtype
-: 55: * (which aren't basic types)
-: 56: * - the count is not zero (otherwise we can't tell between a "no more
-: 57: * complete types" case and a "zero count" case)
-: 58: *
-: 59: * As per section 4.9.3 of the MPI 1.1 specification, the two-part reduction
-: 60: * types are to be treated as structs of the constituent types. So we have to
-: 61: * do something special to handle them correctly in here.
-: 62: *
-: 63: * As per section 3.12.5 get_count and get_elements report the same value for
-: 64: * basic datatypes; I'm currently interpreting this to *not* include these
-: 65: * reduction types, as they are considered structs.
-: 66: */
-: 67:PMPI_LOCAL int MPIR_Type_get_basic_type_elements(int *bytes_p,
-: 68: int count,
-: 69: MPI_Datatype datatype)
2359: 70:{
-: 71: int elements, usable_bytes, used_bytes, type1_sz, type2_sz;
-: 72:
2359: 73: if (count == 0) return 0;
-: 74:
-: 75: /* determine the maximum number of bytes we should take from the
-: 76: * byte count.
-: 77: */
2359: 78: if (count < 0) {
2351: 79: usable_bytes = *bytes_p;
-: 80: }
-: 81: else {
8: 82: usable_bytes = MIN(*bytes_p,
-: 83: count * MPID_Datatype_get_basic_size(datatype));
-: 84: }
-: 85:
2359: 86: switch (datatype) {
-: 87: /* we don't get valid fortran datatype handles in all cases... */
-: 88:#ifdef HAVE_FORTRAN_BINDING
-: 89: case MPI_2REAL:
|
#####: 90: type1_sz = type2_sz = MPID_Datatype_get_basic_size(MPI_REAL);
#####: 91: break;
-: 92: case MPI_2DOUBLE_PRECISION:
#####: 93: type1_sz = type2_sz =
-: 94: MPID_Datatype_get_basic_size(MPI_DOUBLE_PRECISION);
#####: 95: break;
-: 96: case MPI_2INTEGER:
#####: 97: type1_sz = type2_sz = MPID_Datatype_get_basic_size(MPI_INTEGER);
#####: 98: break;
-: 99:#endif
-: 100: case MPI_2INT:
#####: 101: type1_sz = type2_sz = MPID_Datatype_get_basic_size(MPI_INT);
#####: 102: break;
-: 103: case MPI_FLOAT_INT:
#####: 104: type1_sz = MPID_Datatype_get_basic_size(MPI_FLOAT);
#####: 105: type2_sz = MPID_Datatype_get_basic_size(MPI_INT);
#####: 106: break;
-: 107: case MPI_DOUBLE_INT:
|
1: 108: type1_sz = MPID_Datatype_get_basic_size(MPI_DOUBLE);
1: 109: type2_sz = MPID_Datatype_get_basic_size(MPI_INT);
1: 110: break;
-: 111: case MPI_LONG_INT:
|
#####: 112: type1_sz = MPID_Datatype_get_basic_size(MPI_LONG);
#####: 113: type2_sz = MPID_Datatype_get_basic_size(MPI_INT);
#####: 114: break;
-: 115: case MPI_SHORT_INT:
#####: 116: type1_sz = MPID_Datatype_get_basic_size(MPI_SHORT);
#####: 117: type2_sz = MPID_Datatype_get_basic_size(MPI_INT);
#####: 118: break;
-: 119: case MPI_LONG_DOUBLE_INT:
#####: 120: type1_sz = MPID_Datatype_get_basic_size(MPI_LONG_DOUBLE);
#####: 121: type2_sz = MPID_Datatype_get_basic_size(MPI_INT);
#####: 122: break;
-: 123: default:
-: 124: /* all other types. this is more complicated than
-: 125: * necessary for handling these types, but it puts us in the
-: 126: * same code path for all the basics, so we stick with it.
-: 127: */
|
2358: 128: type1_sz = type2_sz = MPID_Datatype_get_basic_size(datatype);
-: 129: break;
-: 130: }
-: 131:
-: 132: /* determine the number of elements in the region */
2359: 133: elements = 2 * (usable_bytes / (type1_sz + type2_sz));
2359: 134: if (usable_bytes % (type1_sz + type2_sz) >= type1_sz) elements++;
-: 135:
-: 136: /* determine how many bytes we used up with those elements */
2359: 137: used_bytes = ((elements / 2) * (type1_sz + type2_sz));
2359: 138: if (elements % 2 == 1) used_bytes += type1_sz;
-: 139:
2359: 140: *bytes_p -= used_bytes;
-: 141:
2359: 142: return elements;
-: 143:}
-: 144:
-: 145:
-: 146:/* MPIR_Type_get_elements
-: 147: *
-: 148: * Arguments:
-: 149: * - bytes_p - input/output byte count
-: 150: * - count - maximum number of this type to subtract from the bytes; a count
-: 151: * of -1 indicates use as many as we like
-: 152: * - datatype - input datatype
-: 153: *
-: 154: * Returns number of elements available given the two constraints of number of
-: 155: * bytes and count of types. Also reduces the byte count by the amount taken
-: 156: * up by the types.
-: 157: *
-: 158: * This is called from MPI_Get_elements() when it sees a type with multiple
-: 159: * element types (datatype_ptr->element_sz = -1). This function calls itself too.
-: 160: */
-: 161:PMPI_LOCAL int MPIR_Type_get_elements(int *bytes_p,
-: 162: int count,
-: 163: MPI_Datatype datatype)
13: 164:{
13: 165: MPID_Datatype *datatype_ptr = NULL;
-: 166:
13: 167: MPID_Datatype_get_ptr(datatype, datatype_ptr); /* invalid if builtin */
-: 168:
-: 169: /* if we have gotten down to a type with only one element type,
-: 170: * call MPIR_Type_get_basic_type_elements() and return.
-: 171: */
13: 172: if (HANDLE_GET_KIND(datatype) == HANDLE_KIND_BUILTIN ||
-: 173: datatype == MPI_FLOAT_INT ||
-: 174: datatype == MPI_DOUBLE_INT ||
-: 175: datatype == MPI_LONG_INT ||
-: 176: datatype == MPI_SHORT_INT ||
-: 177: datatype == MPI_LONG_DOUBLE_INT)
-: 178: {
9: 179: return MPIR_Type_get_basic_type_elements(bytes_p, count, datatype);
-: 180: }
4: 181: else if (datatype_ptr->element_size >= 0) {
|
#####: 182: return MPIR_Type_get_basic_type_elements(bytes_p,
-: 183: count * datatype_ptr->n_elements,
-: 184: datatype_ptr->eltype);
-: 185: }
-: 186: else {
-: 187: /* we have bytes left and still don't have a single element size; must
-: 188: * recurse.
-: 189: */
|
4: 190: int i, j, typecount = 0, *ints, nr_elements = 0, last_nr_elements;
-: 191: MPI_Aint *aints;
-: 192: MPI_Datatype *types;
-: 193:
-: 194: /* Establish locations of arrays; perhaps this should be a fn. call or
-: 195: * this fn. should be an MPID one?
-: 196: */
4: 197: if (datatype_ptr->contents == NULL)
|
#####: 198: return MPI_ERR_TYPE;
|
4: 199: types = (MPI_Datatype *) (((char *) datatype_ptr->contents) +
-: 200: sizeof(MPID_Datatype_contents));
4: 201: if (types == NULL)
|
#####: 202: return MPI_ERR_TYPE;
|
4: 203: ints = (int *) (((char *) types) +
-: 204: datatype_ptr->contents->nr_types * sizeof(MPI_Datatype));
4: 205: if (ints == NULL)
|
#####: 206: return MPI_ERR_TYPE;
|
4: 207: aints = (MPI_Aint *) (((char *) ints) +
-: 208: datatype_ptr->contents->nr_ints * sizeof(int));
4: 209: if (aints == NULL)
|
#####: 210: return MPI_ERR_TYPE;
-: 211:
|
4: 212: switch (datatype_ptr->contents->combiner) {
-: 213: case MPI_COMBINER_NAMED:
-: 214: case MPI_COMBINER_DUP:
-: 215: case MPI_COMBINER_RESIZED:
|
#####: 216: return MPIR_Type_get_elements(bytes_p, count, *types);
-: 217: break;
-: 218: case MPI_COMBINER_CONTIGUOUS:
-: 219: case MPI_COMBINER_VECTOR:
-: 220: case MPI_COMBINER_HVECTOR_INTEGER:
-: 221: case MPI_COMBINER_HVECTOR:
-: 222: /* count is first in ints array */
#####: 223: return MPIR_Type_get_elements(bytes_p, count * (*ints), *types);
-: 224: break;
-: 225: case MPI_COMBINER_INDEXED_BLOCK:
-: 226: /* count is first in ints array, blocklength is second */
#####: 227: return MPIR_Type_get_elements(bytes_p,
-: 228: count * ints[0] * ints[1],
-: 229: *types);
-: 230: break;
-: 231: case MPI_COMBINER_INDEXED:
-: 232: case MPI_COMBINER_HINDEXED_INTEGER:
-: 233: case MPI_COMBINER_HINDEXED:
#####: 234: for (i=0; i < (*ints); i++) {
-: 235: /* add up the blocklengths to get a max. # of the next type */
#####: 236: typecount += ints[i+1];
-: 237: }
#####: 238: return MPIR_Type_get_elements(bytes_p, count * typecount, *types);
-: 239: break;
-: 240: case MPI_COMBINER_STRUCT_INTEGER:
-: 241: case MPI_COMBINER_STRUCT:
-: 242: /* In this case we can't simply multiply the count of the next
-: 243: * type by the count of the current type, because we need to
-: 244: * cycle through the types just as the struct would. thus the
-: 245: * nested loops.
-: 246: *
-: 247: * We need to keep going until we see a "0" elements returned
-: 248: * or we run out of bytes.
-: 249: */
-: 250:
-: 251:
|
4: 252: last_nr_elements = 1; /* seed value */
4: 253: for (j=0;
12: 254: (count == -1 || j < count) &&
-: 255: *bytes_p > 0 && last_nr_elements > 0;
4: 256: j++)
-: 257: {
-: 258: /* recurse on each type; bytes are reduced in calls */
12: 259: for (i=0; i < (*ints); i++) {
-: 260: /* skip zero-count elements of the struct */
8: 261: if (ints[i+1] == 0) continue;
-: 262:
8: 263: last_nr_elements = MPIR_Type_get_elements(bytes_p,
-: 264: ints[i+1],
-: 265: types[i]);
8: 266: nr_elements += last_nr_elements;
-: 267:
8: 268: MPIU_Assert(last_nr_elements >= 0);
-: 269:
8: 270: if (last_nr_elements == 0) break;
-: 271: }
-: 272: }
4: 273: return nr_elements;
-: 274: break;
-: 275: case MPI_COMBINER_SUBARRAY:
-: 276: case MPI_COMBINER_DARRAY:
-: 277: case MPI_COMBINER_F90_REAL:
-: 278: case MPI_COMBINER_F90_COMPLEX:
-: 279: case MPI_COMBINER_F90_INTEGER:
-: 280: default:
|
-: 281: /* --BEGIN ERROR HANDLING-- */
#####: 282: MPIU_Assert(0);
#####: 283: return -1;
-: 284: break;
-: 285: /* --END ERROR HANDLING-- */
-: 286: }
-: 287: }
-: 288:}
-: 289:#endif
-: 290:
-: 291:#undef FUNCNAME
-: 292:#define FUNCNAME MPI_Get_elements
-: 293:#undef FCNAME
-: 294:#define FCNAME "MPI_Get_elements"
-: 295:
-: 296:/*@
-: 297: MPI_Get_elements - Returns the number of basic elements
-: 298: in a datatype
-: 299:
-: 300:Input Parameters:
-: 301:+ status - return status of receive operation (Status)
-: 302:- datatype - datatype used by receive operation (handle)
-: 303:
-: 304:Output Parameter:
-: 305:. count - number of received basic elements (integer)
-: 306:
-: 307: Notes:
-: 308:
-: 309: If the size of the datatype is zero and the amount of data returned as
-: 310: determined by 'status' is also zero, this routine will return a count of
-: 311: zero. This is consistent with a clarification made by the MPI Forum.
-: 312:
-: 313:.N Fortran
-: 314:
-: 315:.N Errors
-: 316:.N MPI_SUCCESS
-: 317:@*/
-: 318:int MPI_Get_elements(MPI_Status *status, MPI_Datatype datatype, int *elements)
|
2359: 319:{
2359: 320: int mpi_errno = MPI_SUCCESS, byte_count;
2359: 321: MPID_Datatype *datatype_ptr = NULL;
-: 322:
-: 323: MPID_MPI_STATE_DECL(MPID_STATE_MPI_GET_ELEMENTS);
-: 324:
2359: 325: MPIR_ERRTEST_INITIALIZED_ORDIE();
-: 326:
-: 327: MPID_MPI_FUNC_ENTER(MPID_STATE_MPI_GET_ELEMENTS);
-: 328:
-: 329: /* Validate parameters, especially handles needing to be converted */
|
-: 330:# ifdef HAVE_ERROR_CHECKING
-: 331: {
-: 332: MPID_BEGIN_ERROR_CHECKS;
-: 333: {
2359: 334: MPIR_ERRTEST_DATATYPE(datatype, "datatype", mpi_errno);
2359: 335: if (mpi_errno != MPI_SUCCESS) goto fn_fail;
-: 336: }
-: 337: MPID_END_ERROR_CHECKS;
-: 338: }
-: 339:# endif
-: 340:
-: 341: /* Convert MPI object handles to object pointers */
|
2358: 342: MPID_Datatype_get_ptr(datatype, datatype_ptr);
-: 343:
-: 344: /* Validate parameters and objects (post conversion) */
|
-: 345:# ifdef HAVE_ERROR_CHECKING
-: 346: {
-: 347: MPID_BEGIN_ERROR_CHECKS;
-: 348: {
2358: 349: MPIR_ERRTEST_ARGNULL(status, "status", mpi_errno);
2358: 350: MPIR_ERRTEST_ARGNULL(elements, "elements", mpi_errno);
-: 351: /* Validate datatype_ptr */
2358: 352: if (HANDLE_GET_KIND(datatype) != HANDLE_KIND_BUILTIN) {
1035: 353: MPID_Datatype_get_ptr(datatype, datatype_ptr);
1035: 354: MPID_Datatype_valid_ptr(datatype_ptr, mpi_errno);
1035: 355: if (mpi_errno == MPI_SUCCESS) {
1035: 356: MPID_Datatype_committed_ptr(datatype_ptr, mpi_errno);
-: 357: }
-: 358: }
2358: 359: if (mpi_errno != MPI_SUCCESS) goto fn_fail;
-: 360: }
-: 361: MPID_END_ERROR_CHECKS;
-: 362: }
-: 363:# endif
-: 364:
-: 365: /* ... body of routine ... */
-: 366:
-: 367: /* three cases:
-: 368: * - nice, simple, single element type
-: 369: * - derived type with a zero size
-: 370: * - type with multiple element types (nastiest)
-: 371: */
|
2357: 372: if (HANDLE_GET_KIND(datatype) == HANDLE_KIND_BUILTIN ||
-: 373: (datatype_ptr->element_size != -1 && datatype_ptr->size > 0))
-: 374: {
2350: 375: byte_count = status->count;
-: 376:
-: 377: /* QUESTION: WHAT IF SOMEONE GAVE US AN MPI_UB OR MPI_LB???
-: 378: */
-: 379:
-: 380: /* in both cases we do not limit the number of types that might
-: 381: * be in bytes
-: 382: */
2350: 383: if (HANDLE_GET_KIND(datatype) != HANDLE_KIND_BUILTIN) {
1027: 384: *elements = MPIR_Type_get_basic_type_elements(&byte_count,
-: 385: -1,
-: 386: datatype_ptr->eltype);
-: 387: }
-: 388: else {
-: 389: /* Behaves just like MPI_Get_Count in the predefined case */
-: 390: int size;
1323: 391: MPID_Datatype_get_size_macro(datatype, size);
1323: 392: if ((byte_count % size) != 0)
|
#####: 393: *elements = MPI_UNDEFINED;
-: 394: else
|
1323: 395: *elements = MPIR_Type_get_basic_type_elements(&byte_count,
-: 396: -1,
-: 397: datatype);
-: 398: }
2350: 399: MPIU_Assert(byte_count >= 0);
-: 400: }
7: 401: else if (datatype_ptr->size == 0) {
2: 402: if (status->count > 0) {
|
-: 403: /* --BEGIN ERROR HANDLING-- */
-: 404:
-: 405: /* datatype size of zero and count > 0 should never happen. */
-: 406:
#####: 407: (*elements) = MPI_UNDEFINED;
-: 408: /* --END ERROR HANDLING-- */
-: 409: }
-: 410: else {
-: 411: /* This is ambiguous. However, discussions on MPI Forum
-: 412: * reached a consensus that this is the correct return
-: 413: * value
-: 414: */
|
2: 415: (*elements) = 0;
-: 416: }
-: 417: }
-: 418: else /* derived type with weird element type or weird size */ {
5: 419: MPIU_Assert(datatype_ptr->element_size == -1);
-: 420:
5: 421: byte_count = status->count;
5: 422: *elements = MPIR_Type_get_elements(&byte_count, -1, datatype);
-: 423: }
-: 424:
-: 425: /* ... end of body of routine ... */
-: 426:
|
-: 427:#ifdef HAVE_ERROR_CHECKING
2359: 428: fn_exit:
-: 429:#endif
-: 430: MPID_MPI_FUNC_EXIT(MPID_STATE_MPI_GET_ELEMENTS);
|
2359: 431: return mpi_errno;
-: 432:
|
-: 433: /* --BEGIN ERROR HANDLING-- */
-: 434:# ifdef HAVE_ERROR_CHECKING
2: 435: fn_fail:
-: 436: {
2: 437: mpi_errno = MPIR_Err_create_code(
-: 438: mpi_errno, MPIR_ERR_RECOVERABLE, FCNAME, __LINE__, MPI_ERR_OTHER,
-: 439: "**mpi_get_elements",
-: 440: "**mpi_get_elements %p %D %p", status, datatype, elements);
-: 441: }
2: 442: mpi_errno = MPIR_Err_return_comm(0, FCNAME, mpi_errno);
2: 443: goto fn_exit;
-: 444:# endif
-: 445: /* --END ERROR HANDLING-- */
-: 446:}
|