-:    0:Source:/home/MPI/testing/mpich2/mpich2/src/mpid/common/datatype/mpid_datatype_contents.c
        -:    0:Graph:mpid_datatype_contents.gcno
        -:    0:Data:mpid_datatype_contents.gcda
        -:    0:Runs:3459
        -:    0:Programs:899
        -:    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:/*@
        -:   14:  MPID_Datatype_set_contents - store contents information for use in
        -:   15:                               MPI_Type_get_contents.
        -:   16:
        -:   17:  Returns MPI_SUCCESS on success, MPI error code on error.
        -:   18:@*/
        -:   19:int MPID_Datatype_set_contents(MPID_Datatype *new_dtp,
        -:   20:			       int combiner,
        -:   21:			       int nr_ints,
        -:   22:			       int nr_aints,
        -:   23:			       int nr_types,
        -:   24:			       int array_of_ints[],
        -:   25:			       MPI_Aint array_of_aints[],
        -:   26:			       MPI_Datatype array_of_types[])
    69056:   27:{
    69056:   28:    int i, contents_size, align_sz = 8, epsilon, mpi_errno;
        -:   29:    int struct_sz, ints_sz, aints_sz, types_sz;
        -:   30:    MPID_Datatype_contents *cp;
        -:   31:    MPID_Datatype *old_dtp;
        -:   32:    char *ptr;
        -:   33:
        -:   34:#ifdef HAVE_MAX_STRUCT_ALIGNMENT
    69056:   35:    if (align_sz > HAVE_MAX_STRUCT_ALIGNMENT) {
    69056:   36:	align_sz = HAVE_MAX_STRUCT_ALIGNMENT;
        -:   37:    }
        -:   38:#endif
        -:   39:
    69056:   40:    struct_sz = sizeof(MPID_Datatype_contents);
    69056:   41:    types_sz  = nr_types * sizeof(MPI_Datatype);
    69056:   42:    ints_sz   = nr_ints * sizeof(int);
    69056:   43:    aints_sz  = nr_aints * sizeof(MPI_Aint);
        -:   44:
        -:   45:    /* pad the struct, types, and ints before we allocate.
        -:   46:     *
        -:   47:     * note: it's not necessary that we pad the aints,
        -:   48:     *       because they are last in the region.
        -:   49:     */
    69056:   50:    if ((epsilon = struct_sz % align_sz)) {
    #####:   51:	struct_sz += align_sz - epsilon;
        -:   52:    }
    69056:   53:    if ((epsilon = types_sz % align_sz)) {
    #####:   54:	types_sz += align_sz - epsilon;
        -:   55:    }
    69056:   56:    if ((epsilon = ints_sz % align_sz)) {
    #####:   57:	ints_sz += align_sz - epsilon;
        -:   58:    }
        -:   59:
    69056:   60:    contents_size = struct_sz + types_sz + ints_sz + aints_sz;
        -:   61:
    69056:   62:    cp = (MPID_Datatype_contents *) MPIU_Malloc(contents_size);
        -:   63:    /* --BEGIN ERROR HANDLING-- */
    69056:   64:    if (cp == NULL) {
    #####:   65:	mpi_errno = MPIR_Err_create_code(MPI_SUCCESS,
        -:   66:					 MPIR_ERR_RECOVERABLE,
        -:   67:					 "MPID_Datatype_set_contents",
        -:   68:					 __LINE__,
        -:   69:					 MPI_ERR_OTHER,
        -:   70:					 "**nomem",
        -:   71:					 0);
    #####:   72:	return mpi_errno;
        -:   73:    }
        -:   74:    /* --END ERROR HANDLING-- */
        -:   75:
    69056:   76:    cp->combiner = combiner;
    69056:   77:    cp->nr_ints  = nr_ints;
    69056:   78:    cp->nr_aints = nr_aints;
    69056:   79:    cp->nr_types = nr_types;
        -:   80:
        -:   81:    /* arrays are stored in the following order: types, ints, aints,
        -:   82:     * following the structure itself.
        -:   83:     */
    69056:   84:    ptr = ((char *) cp) + struct_sz;
        -:   85:    /* Fortran90 combiner types do not have a "base" type */
    69056:   86:    if (nr_types > 0) {
    69031:   87:	MPIU_Memcpy(ptr, array_of_types, nr_types * sizeof(MPI_Datatype));
        -:   88:    }
        -:   89:    
    69056:   90:    ptr = ((char *) cp) + struct_sz + types_sz;
    69056:   91:    if (nr_ints > 0) {
    62601:   92:	MPIU_Memcpy(ptr, array_of_ints, nr_ints * sizeof(int));
        -:   93:    }
        -:   94:
    69056:   95:    ptr = ((char *) cp) + struct_sz + types_sz + ints_sz;
    69056:   96:    if (nr_aints > 0) {
    30496:   97:	MPIU_Memcpy(ptr, array_of_aints, nr_aints * sizeof(MPI_Aint));
        -:   98:    }
    69056:   99:    new_dtp->contents = cp;
        -:  100:
        -:  101:    /* increment reference counts on all the derived types used here */
  2833917:  102:    for (i=0; i < nr_types; i++) {
  2764861:  103:	if (HANDLE_GET_KIND(array_of_types[i]) != HANDLE_KIND_BUILTIN) {
    12257:  104:	    MPID_Datatype_get_ptr(array_of_types[i], old_dtp);
    12257:  105:	    MPID_Datatype_add_ref(old_dtp);
        -:  106:	}
        -:  107:    }
        -:  108:
    69056:  109:    return MPI_SUCCESS;
        -:  110:}
        -:  111:
        -:  112:void MPID_Datatype_free_contents(MPID_Datatype *dtp)
    66242:  113:{
    66242:  114:    int i, struct_sz = sizeof(MPID_Datatype_contents);
    66242:  115:    int align_sz = 8, epsilon;
        -:  116:    MPID_Datatype *old_dtp;
        -:  117:    MPI_Datatype *array_of_types;
        -:  118:
    66242:  119:    if ((epsilon = struct_sz % align_sz)) {
    #####:  120:	struct_sz += align_sz - epsilon;
        -:  121:    }
        -:  122:
        -:  123:    /* note: relies on types being first after structure */
    66242:  124:    array_of_types = (MPI_Datatype *) ((char *)dtp->contents + struct_sz);
        -:  125:
  2809257:  126:    for (i=0; i < dtp->contents->nr_types; i++) {
  2743015:  127:	if (HANDLE_GET_KIND(array_of_types[i]) != HANDLE_KIND_BUILTIN) {
    12257:  128:	    MPID_Datatype_get_ptr(array_of_types[i], old_dtp);
    12257:  129:	    MPID_Datatype_release(old_dtp);
        -:  130:	}
        -:  131:    }
        -:  132:
    66242:  133:    MPIU_Free(dtp->contents);
    66242:  134:    dtp->contents = NULL;
    66242:  135:}
        -:  136:
        -:  137:void MPIDI_Datatype_get_contents_ints(MPID_Datatype_contents *cp,
        -:  138:				      int *user_ints)
    72796:  139:{
        -:  140:    char *ptr;
    72796:  141:    int align_sz = 8, epsilon;
        -:  142:    int struct_sz, types_sz;
        -:  143:
        -:  144:#ifdef HAVE_MAX_STRUCT_ALIGNMENT
    72796:  145:    if (align_sz > HAVE_MAX_STRUCT_ALIGNMENT) {
    72796:  146:	align_sz = HAVE_MAX_STRUCT_ALIGNMENT;
        -:  147:    }
        -:  148:#endif
        -:  149:
    72796:  150:    struct_sz = sizeof(MPID_Datatype_contents);
    72796:  151:    types_sz  = cp->nr_types * sizeof(MPI_Datatype);
        -:  152:
        -:  153:    /* pad the struct, types, and ints before we allocate.
        -:  154:     *
        -:  155:     * note: it's not necessary that we pad the aints,
        -:  156:     *       because they are last in the region.
        -:  157:     */
    72796:  158:    if ((epsilon = struct_sz % align_sz)) {
    #####:  159:	struct_sz += align_sz - epsilon;
        -:  160:    }
    72796:  161:    if ((epsilon = types_sz % align_sz)) {
    #####:  162:	types_sz += align_sz - epsilon;
        -:  163:    }
        -:  164:
    72796:  165:    ptr = ((char *) cp) + struct_sz + types_sz;
    72796:  166:    MPIU_Memcpy(user_ints, ptr, cp->nr_ints * sizeof(int));
        -:  167:
        -:  168:    return;
        -:  169:}
        -:  170:
        -:  171:void MPIDI_Datatype_get_contents_aints(MPID_Datatype_contents *cp,
        -:  172:				       MPI_Aint *user_aints)
      404:  173:{
        -:  174:    char *ptr;
      404:  175:    int align_sz = 8, epsilon;
        -:  176:    int struct_sz, ints_sz, aints_sz, types_sz;
        -:  177:
        -:  178:#ifdef HAVE_MAX_STRUCT_ALIGNMENT
      404:  179:    if (align_sz > HAVE_MAX_STRUCT_ALIGNMENT) {
      404:  180:	align_sz = HAVE_MAX_STRUCT_ALIGNMENT;
        -:  181:    }
        -:  182:#endif
        -:  183:
      404:  184:    struct_sz = sizeof(MPID_Datatype_contents);
      404:  185:    types_sz  = cp->nr_types * sizeof(MPI_Datatype);
      404:  186:    ints_sz   = cp->nr_ints * sizeof(int);
        -:  187:    /* FIXME: Why is this here?  The value is never used.  Should it be? */
      404:  188:    aints_sz  = cp->nr_aints * sizeof(MPI_Aint);
        -:  189:
        -:  190:    /* pad the struct, types, and ints before we allocate.
        -:  191:     *
        -:  192:     * note: it's not necessary that we pad the aints,
        -:  193:     *       because they are last in the region.
        -:  194:     */
      404:  195:    if ((epsilon = struct_sz % align_sz)) {
    #####:  196:	struct_sz += align_sz - epsilon;
        -:  197:    }
      404:  198:    if ((epsilon = types_sz % align_sz)) {
    #####:  199:	types_sz += align_sz - epsilon;
        -:  200:    }
      404:  201:    if ((epsilon = ints_sz % align_sz)) {
    #####:  202:	ints_sz += align_sz - epsilon;
        -:  203:    }
        -:  204:
      404:  205:    ptr = ((char *) cp) + struct_sz + types_sz + ints_sz;
      404:  206:    MPIU_Memcpy(user_aints, ptr, cp->nr_aints * sizeof(MPI_Aint));
        -:  207:
        -:  208:    return;
        -:  209:}
        -:  210:
        -:  211:void MPIDI_Datatype_get_contents_types(MPID_Datatype_contents *cp,
        -:  212:				       MPI_Datatype *user_types)
     2794:  213:{
        -:  214:    char *ptr;
     2794:  215:    int align_sz = 8, epsilon;
        -:  216:    int struct_sz;
        -:  217:
        -:  218:#ifdef HAVE_MAX_STRUCT_ALIGNMENT
     2794:  219:    if (align_sz > HAVE_MAX_STRUCT_ALIGNMENT) {
     2794:  220:	align_sz = HAVE_MAX_STRUCT_ALIGNMENT;
        -:  221:    }
        -:  222:#endif
        -:  223:
     2794:  224:    struct_sz = sizeof(MPID_Datatype_contents);
        -:  225:
        -:  226:    /* pad the struct, types, and ints before we allocate.
        -:  227:     *
        -:  228:     * note: it's not necessary that we pad the aints,
        -:  229:     *       because they are last in the region.
        -:  230:     */
     2794:  231:    if ((epsilon = struct_sz % align_sz)) {
    #####:  232:	struct_sz += align_sz - epsilon;
        -:  233:    }
        -:  234:
     2794:  235:    ptr = ((char *) cp) + struct_sz;
     2794:  236:    MPIU_Memcpy(user_types, ptr, cp->nr_types * sizeof(MPI_Datatype));
        -:  237:
        -:  238:    return;
        -:  239:}