-: 0:Source:/home/MPI/testing/mpich2/mpich2/src/mpi/datatype/typeutil.c
-: 0:Graph:typeutil.gcno
-: 0:Data:typeutil.gcda
-: 0:Runs:4383
-: 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 "datatype.h"
-: 10:
-: 11:/* This is the utility file for datatypes that contains the basic datatype
-: 12: items and storage management. It also contains a temporary routine
-: 13: that is used by ROMIO to test to see if datatypes are contiguous */
-: 14:#ifndef MPID_DATATYPE_PREALLOC
-: 15:#define MPID_DATATYPE_PREALLOC 8
-: 16:#endif
-: 17:
-: 18:/* Preallocated datatype objects */
-: 19:MPID_Datatype MPID_Datatype_builtin[MPID_DATATYPE_N_BUILTIN + 1] = { {0} };
-: 20:MPID_Datatype MPID_Datatype_direct[MPID_DATATYPE_PREALLOC] = { {0} };
-: 21:MPIU_Object_alloc_t MPID_Datatype_mem = { 0, 0, 0, 0, MPID_DATATYPE,
-: 22: sizeof(MPID_Datatype), MPID_Datatype_direct,
-: 23: MPID_DATATYPE_PREALLOC};
-: 24:
-: 25:static int MPIR_Datatype_finalize(void *dummy );
-: 26:static int MPIR_DatatypeAttrFinalizeCallback(void *dummy );
-: 27:
-: 28:/* Call this routine to associate a MPID_Datatype with each predefined
-: 29: datatype. We do this with lazy initialization because many MPI
-: 30: programs do not require anything except the predefined datatypes, and
-: 31: all of the necessary information about those is stored within the
-: 32: MPI_Datatype handle. However, if the user wants to change the name
-: 33: (character string, set with MPI_Type_set_name) associated with a
-: 34: predefined name, then the structures must be allocated.
-: 35:*/
-: 36:/* FIXME does the order of this list need to correspond to anything in
-: 37: particular? There are several lists of predefined types sprinkled throughout
-: 38: the codebase and it's unclear which (if any) of them must match exactly.
-: 39: [goodell@ 2009-03-17] */
-: 40:static MPI_Datatype mpi_dtypes[] = {
-: 41: MPI_CHAR,
-: 42: MPI_UNSIGNED_CHAR,
-: 43: MPI_SIGNED_CHAR,
-: 44: MPI_BYTE,
-: 45: MPI_WCHAR,
-: 46: MPI_SHORT,
-: 47: MPI_UNSIGNED_SHORT,
-: 48: MPI_INT,
-: 49: MPI_UNSIGNED,
-: 50: MPI_LONG,
-: 51: MPI_UNSIGNED_LONG,
-: 52: MPI_FLOAT,
-: 53: MPI_DOUBLE,
-: 54: MPI_LONG_DOUBLE,
-: 55: MPI_LONG_LONG,
-: 56: MPI_UNSIGNED_LONG_LONG,
-: 57: MPI_PACKED,
-: 58: MPI_LB,
-: 59: MPI_UB,
-: 60: MPI_2INT,
-: 61:
-: 62: /* C99 types */
-: 63: MPI_INT8_T,
-: 64: MPI_INT16_T,
-: 65: MPI_INT32_T,
-: 66: MPI_INT64_T,
-: 67: MPI_UINT8_T,
-: 68: MPI_UINT16_T,
-: 69: MPI_UINT32_T,
-: 70: MPI_UINT64_T,
-: 71: MPI_C_BOOL,
-: 72: MPI_C_FLOAT_COMPLEX,
-: 73: MPI_C_DOUBLE_COMPLEX,
-: 74: MPI_C_LONG_DOUBLE_COMPLEX,
-: 75:
-: 76: /* address/offset types */
-: 77: MPI_AINT,
-: 78: MPI_OFFSET,
-: 79:
-: 80: /* Fortran types */
-: 81: MPI_COMPLEX,
-: 82: MPI_DOUBLE_COMPLEX,
-: 83: MPI_LOGICAL,
-: 84: MPI_REAL,
-: 85: MPI_DOUBLE_PRECISION,
-: 86: MPI_INTEGER,
-: 87: MPI_2INTEGER,
-: 88: MPI_2COMPLEX,
-: 89: MPI_2DOUBLE_COMPLEX,
-: 90: MPI_2REAL,
-: 91: MPI_2DOUBLE_PRECISION,
-: 92: MPI_CHARACTER,
-: 93:#ifdef HAVE_FORTRAN_BINDING
-: 94: /* Size-specific types; these are in section 10.2.4 (Extended Fortran Support)
-: 95: as well as optional in MPI-1
-: 96: */
-: 97: MPI_REAL4,
-: 98: MPI_REAL8,
-: 99: MPI_REAL16,
-: 100: MPI_COMPLEX8,
-: 101: MPI_COMPLEX16,
-: 102: MPI_COMPLEX32,
-: 103: MPI_INTEGER1,
-: 104: MPI_INTEGER2,
-: 105: MPI_INTEGER4,
-: 106: MPI_INTEGER8,
-: 107: MPI_INTEGER16,
-: 108:#endif
-: 109: /* This entry is a guaranteed end-of-list item */
-: 110: (MPI_Datatype) -1,
-: 111:};
-: 112:
-: 113:/*
-: 114: MPIR_Datatype_init()
-: 115:
-: 116: Main purpose of this function is to set up the following pair types:
-: 117: - MPI_FLOAT_INT
-: 118: - MPI_DOUBLE_INT
-: 119: - MPI_LONG_INT
-: 120: - MPI_SHORT_INT
-: 121: - MPI_LONG_DOUBLE_INT
-: 122:
-: 123: The assertions in this code ensure that:
-: 124: - this function is called before other types are allocated
-: 125: - there are enough spaces in the direct block to hold our types
-: 126: - we actually get the values we expect (otherwise errors regarding
-: 127: these types could be terribly difficult to track down!)
-: 128:
-: 129: */
-: 130:static MPI_Datatype mpi_pairtypes[] = {
-: 131: MPI_FLOAT_INT,
-: 132: MPI_DOUBLE_INT,
-: 133: MPI_LONG_INT,
-: 134: MPI_SHORT_INT,
-: 135: MPI_LONG_DOUBLE_INT,
-: 136: (MPI_Datatype) -1
-: 137:};
-: 138:
-: 139:int MPIR_Datatype_init(void)
4383: 140:{
-: 141: int i;
-: 142: MPID_Datatype *ptr;
-: 143:
4383: 144: MPIU_Assert(MPID_Datatype_mem.initialized == 0);
-: 145: MPIU_Assert(MPID_DATATYPE_PREALLOC >= 5);
-: 146:
26298: 147: for (i=0; mpi_pairtypes[i] != (MPI_Datatype) -1; ++i) {
-: 148: /* types based on 'long long' and 'long double', may be disabled at
-: 149: configure time, and their values set to MPI_DATATYPE_NULL. skip any
-: 150: such types. */
21915: 151: if (mpi_pairtypes[i] == MPI_DATATYPE_NULL) continue;
-: 152: /* XXX: this allocation strategy isn't right if one or more of the
-: 153: pairtypes is MPI_DATATYPE_NULL. in fact, the assert below will
-: 154: fail if any type other than the las in the list is equal to
-: 155: MPI_DATATYPE_NULL. obviously, this should be fixed, but I need
-: 156: to talk to Rob R. first. -- BRT */
-: 157: /* XXX DJG it does work, but only because MPI_LONG_DOUBLE_INT is the
-: 158: * only one that is ever optional and it comes last */
-: 159:
-: 160: /* we use the _unsafe version because we are still in MPI_Init, before
-: 161: * multiple threads are permitted and possibly before support for
-: 162: * critical sections is entirely setup */
21915: 163: ptr = (MPID_Datatype *)MPIU_Handle_obj_alloc_unsafe( &MPID_Datatype_mem );
-: 164:
21915: 165: MPIU_Assert(ptr);
21915: 166: MPIU_Assert(ptr->handle == mpi_pairtypes[i]);
-: 167: /* this is a redundant alternative to the previous statement */
21915: 168: MPIU_Assert((void *) ptr == (void *) (MPID_Datatype_direct + HANDLE_INDEX(mpi_pairtypes[i])));
-: 169:
21915: 170: MPID_Type_create_pairtype(mpi_pairtypes[i], (MPID_Datatype *) ptr);
-: 171: }
-: 172:
4383: 173: MPIR_Add_finalize(MPIR_Datatype_finalize, 0,
-: 174: MPIR_FINALIZE_CALLBACK_PRIO-1);
-: 175:
4383: 176: return MPI_SUCCESS;
-: 177:}
-: 178:
-: 179:static int MPIR_Datatype_finalize(void *dummy ATTRIBUTE((unused)) )
4374: 180:{
-: 181: int i;
-: 182: MPID_Datatype *dptr;
-: 183:
26244: 184: for (i=0; mpi_pairtypes[i] != (MPI_Datatype) -1; i++) {
21870: 185: if (mpi_pairtypes[i] != MPI_DATATYPE_NULL) {
21870: 186: MPID_Datatype_get_ptr(mpi_pairtypes[i], dptr);
21870: 187: MPID_Datatype_release(dptr);
21870: 188: mpi_pairtypes[i] = MPI_DATATYPE_NULL;
-: 189: }
-: 190: }
4374: 191: return 0;
-: 192:}
-: 193:
-: 194:/* Called ONLY from MPIR_Datatype_init_names (type_get_name.c).
-: 195: That routine calls it from within a single-init section to
-: 196: ensure thread-safety. */
-: 197:
-: 198:int MPIR_Datatype_builtin_fillin(void)
58: 199:{
-: 200: static const char FCNAME[] = "MPIR_Datatype_builtin_fillin";
58: 201: int mpi_errno = MPI_SUCCESS;
-: 202: int i;
-: 203: MPID_Datatype *dptr;
58: 204: MPI_Datatype d = MPI_DATATYPE_NULL;
-: 205: static int is_init = 0;
-: 206: char error_msg[1024];
-: 207:
-: 208: /* FIXME: This is actually an error, since this routine
-: 209: should only be called once */
58: 210: if (is_init)
-: 211: {
|
#####: 212: return MPI_SUCCESS;
-: 213: }
-: 214:
|
58: 215: if (!is_init) {
3364: 216: for (i=0; i<MPID_DATATYPE_N_BUILTIN; i++) {
-: 217: /* Compute the index from the value of the handle */
3364: 218: d = mpi_dtypes[i];
3364: 219: if (d == -1) {
-: 220: /* At the end of mpi_dtypes */
58: 221: break;
-: 222: }
-: 223: /* Some of the size-specific types may be null, as might be types
-: 224: based on 'long long' and 'long double' if those types were
-: 225: disabled at configure time. skip those cases. */
3306: 226: if (d == MPI_DATATYPE_NULL) continue;
-: 227:
3132: 228: MPID_Datatype_get_ptr(d,dptr);
|
-: 229: /* --BEGIN ERROR HANDLING-- */
3132: 230: if (dptr < MPID_Datatype_builtin ||
-: 231: dptr > MPID_Datatype_builtin + MPID_DATATYPE_N_BUILTIN)
-: 232: {
#####: 233: MPIU_Snprintf(error_msg, 1024,
-: 234: "%dth builtin datatype handle references invalid memory",
-: 235: i);
#####: 236: mpi_errno = MPIR_Err_create_code(MPI_SUCCESS,
-: 237: MPIR_ERR_FATAL, FCNAME,
-: 238: __LINE__, MPI_ERR_INTERN,
-: 239: "**fail", "**fail %s",
-: 240: error_msg);
#####: 241: return mpi_errno;
-: 242: }
-: 243: /* --END ERROR HANDLING-- */
-: 244:
-: 245: /* dptr will point into MPID_Datatype_builtin */
|
3132: 246: dptr->handle = d;
3132: 247: dptr->is_permanent = 1;
3132: 248: dptr->is_contig = 1;
3132: 249: MPIU_Object_set_ref( dptr, 1 );
3132: 250: MPID_Datatype_get_size_macro(mpi_dtypes[i], dptr->size);
3132: 251: dptr->extent = dptr->size;
3132: 252: dptr->ub = dptr->size;
3132: 253: dptr->true_ub = dptr->size;
3132: 254: dptr->contents = NULL; /* should never get referenced? */
-: 255: }
|
-: 256: /* --BEGIN ERROR HANDLING-- */
58: 257: if (d != -1 && i < sizeof(mpi_dtypes)/sizeof(*mpi_dtypes) && mpi_dtypes[i] != -1) {
-: 258: /* We did not hit the end-of-list */
-: 259: /*MPIU_Internal_error_printf( "Did not initialize all of the predefined datatypes (only did first %d)\n", i-1 );*/
#####: 260: MPIU_Snprintf(error_msg, 1024,
-: 261: "Did not initialize all of the predefined datatypes (only did first %d)\n",
-: 262: i-1);
-: 263:
#####: 264: mpi_errno = MPIR_Err_create_code(MPI_SUCCESS, MPIR_ERR_FATAL,
-: 265: FCNAME, __LINE__,
-: 266: MPI_ERR_INTERN, "**fail",
-: 267: "**fail %s", error_msg);
#####: 268: return mpi_errno;
-: 269: }
-: 270: /* --END ERROR HANDLING-- */
|
58: 271: is_init = 1;
-: 272: }
58: 273: return mpi_errno;
-: 274:}
-: 275:
-: 276:/* This will eventually be removed once ROMIO knows more about MPICH2 */
-: 277:void MPIR_Datatype_iscontig(MPI_Datatype datatype, int *flag)
14790186: 278:{
-: 279: MPID_Datatype *datatype_ptr;
14790186: 280: if (HANDLE_GET_KIND(datatype) == HANDLE_KIND_BUILTIN)
13678516: 281: *flag = 1;
-: 282: else {
1111670: 283: MPID_Datatype_get_ptr(datatype, datatype_ptr);
1111670: 284: *flag = datatype_ptr->is_contig;
-: 285: }
14790186: 286:}
-: 287:
-: 288:/* If an attribute is added to a predefined type, we free the attributes
-: 289: in Finalize */
-: 290:static int MPIR_DatatypeAttrFinalizeCallback(void *dummy ATTRIBUTE((unused)) )
10: 291:{
-: 292: MPID_Datatype *dtype;
10: 293: int i, mpi_errno=MPI_SUCCESS;
-: 294:
690: 295: for (i=0; i<MPID_DATATYPE_N_BUILTIN; i++) {
680: 296: dtype = &MPID_Datatype_builtin[i];
680: 297: if (dtype && MPIR_Process.attr_free && dtype->attributes) {
3: 298: mpi_errno = MPIR_Process.attr_free( dtype->handle,
-: 299: &dtype->attributes );
-: 300: /* During finalize, we ignore error returns from the free */
-: 301: }
-: 302: }
10: 303: return mpi_errno;
-: 304:}
-: 305:
-: 306:void MPIR_DatatypeAttrFinalize( void )
506: 307:{
-: 308: static int called=0;
-: 309:
-: 310: /* FIXME: This needs to be make thread safe */
506: 311: if (!called) {
10: 312: called = 1;
10: 313: MPIR_Add_finalize(MPIR_DatatypeAttrFinalizeCallback, 0,
-: 314: MPIR_FINALIZE_CALLBACK_PRIO-1);
-: 315: }
506: 316:}
|