-:    0:Source:/home/MPI/testing/mpich2/mpich2/src/mpid/common/datatype/dataloop/dataloop_create.c
        -:    0:Graph:dataloop_create.gcno
        -:    0:Data:dataloop_create.gcda
        -:    0:Runs:4381
        -:    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 <stdlib.h>
        -:    9:#include <limits.h>
        -:   10:
        -:   11:#include "./dataloop.h"
        -:   12:
        -:   13:static void DLOOP_Dataloop_create_named(MPI_Datatype type,
        -:   14:					DLOOP_Dataloop **dlp_p,
        -:   15:					int *dlsz_p,
        -:   16:					int *dldepth_p,
        -:   17:					int flag);
        -:   18:
        -:   19:void PREPEND_PREFIX(Dataloop_create)(MPI_Datatype type,
        -:   20:				     DLOOP_Dataloop **dlp_p,
        -:   21:				     int *dlsz_p,
        -:   22:				     int *dldepth_p,
        -:   23:				     int flag)
   124080:   24:{
        -:   25:    int i;
        -:   26:    int err;
        -:   27:
        -:   28:    int nr_ints, nr_aints, nr_types, combiner;
        -:   29:    MPI_Datatype *types;
        -:   30:    int *ints;
        -:   31:    MPI_Aint *aints;
        -:   32:
        -:   33:    DLOOP_Dataloop *old_dlp;
        -:   34:    int old_dlsz, old_dldepth;
        -:   35:
        -:   36:    int dummy1, dummy2, dummy3, type0_combiner, ndims;
        -:   37:    MPI_Datatype tmptype;
        -:   38:
        -:   39:    MPI_Aint stride;
        -:   40:    MPI_Aint *disps;
        -:   41:
   124080:   42:    NMPI_Type_get_envelope(type, &nr_ints, &nr_aints, &nr_types, &combiner);
        -:   43:
        -:   44:    /* some named types do need dataloops; handle separately. */
   124080:   45:    if (combiner == MPI_COMBINER_NAMED) {
    #####:   46:	DLOOP_Dataloop_create_named(type, dlp_p, dlsz_p, dldepth_p, flag);
    #####:   47:	return;
        -:   48:    }
        -:   49:
        -:   50:    /* Q: should we also check for "hasloop", or is the COMBINER
        -:   51:     *    check above enough to weed out everything that wouldn't
        -:   52:     *    have a loop?
        -:   53:     */
   124080:   54:    DLOOP_Handle_get_loopptr_macro(type, old_dlp, flag);
   124080:   55:    if (old_dlp != NULL) {
        -:   56:	/* dataloop already created; just return it. */
    #####:   57:	*dlp_p = old_dlp;
    #####:   58:	DLOOP_Handle_get_loopsize_macro(type, *dlsz_p, flag);
    #####:   59:	DLOOP_Handle_get_loopdepth_macro(type, *dldepth_p, flag);
        -:   60:	return;
        -:   61:    }
        -:   62:
   124080:   63:    PREPEND_PREFIX(Type_access_contents)(type, &ints, &aints, &types);
        -:   64:
        -:   65:    /* first check for zero count on types where that makes sense */
   124080:   66:    switch(combiner) {
        -:   67:	case MPI_COMBINER_CONTIGUOUS:
        -:   68:	case MPI_COMBINER_VECTOR:
        -:   69:	case MPI_COMBINER_HVECTOR_INTEGER:
        -:   70:	case MPI_COMBINER_HVECTOR:
        -:   71:	case MPI_COMBINER_INDEXED_BLOCK:
        -:   72:	case MPI_COMBINER_INDEXED:
        -:   73:	case MPI_COMBINER_HINDEXED_INTEGER:
        -:   74:	case MPI_COMBINER_HINDEXED:
        -:   75:	case MPI_COMBINER_STRUCT_INTEGER:
        -:   76:	case MPI_COMBINER_STRUCT:
   110582:   77:	    if (ints[0] == 0) {
       46:   78:		PREPEND_PREFIX(Dataloop_create_contiguous)(0,
        -:   79:							   MPI_INT,
        -:   80:							   dlp_p,
        -:   81:							   dlsz_p,
        -:   82:							   dldepth_p,
        -:   83:							   flag);
       46:   84:		goto clean_exit;
        -:   85:	    }
        -:   86:	    break;
        -:   87:	default:
        -:   88:	    break;
        -:   89:    }
        -:   90:
        -:   91:    /* recurse, processing types "below" this one before processing
        -:   92:     * this one, if those type don't already have dataloops.
        -:   93:     *
        -:   94:     * note: in the struct case below we'll handle any additional
        -:   95:     *       types "below" the current one.
        -:   96:     */
   124034:   97:    NMPI_Type_get_envelope(types[0], &dummy1, &dummy2, &dummy3,
        -:   98:			   &type0_combiner);
   124034:   99:    if (type0_combiner != MPI_COMBINER_NAMED)
        -:  100:    {
    10324:  101:	DLOOP_Handle_get_loopptr_macro(types[0], old_dlp, flag);
    10324:  102:	if (old_dlp == NULL)
        -:  103:	{
        -:  104:	    /* no dataloop already present; create and store one */
     2426:  105:	    PREPEND_PREFIX(Dataloop_create)(types[0],
        -:  106:					    &old_dlp,
        -:  107:					    &old_dlsz,
        -:  108:					    &old_dldepth,
        -:  109:					    flag);
        -:  110:
     2426:  111:	    DLOOP_Handle_set_loopptr_macro(types[0], old_dlp, flag);
     2426:  112:	    DLOOP_Handle_set_loopsize_macro(types[0], old_dlsz, flag);
     2426:  113:	    DLOOP_Handle_set_loopdepth_macro(types[0], old_dldepth, flag);
        -:  114:	}
        -:  115:	else {
     7898:  116:	    DLOOP_Handle_get_loopsize_macro(types[0], old_dlsz, flag);
     7898:  117:	    DLOOP_Handle_get_loopdepth_macro(types[0], old_dldepth, flag);
        -:  118:	}
        -:  119:    }
        -:  120:       
   124034:  121:    switch(combiner)
        -:  122:    {
        -:  123:	case MPI_COMBINER_DUP:
    12798:  124:	    if (type0_combiner != MPI_COMBINER_NAMED) {
        8:  125:		PREPEND_PREFIX(Dataloop_dup)(old_dlp, old_dlsz, dlp_p);
        8:  126:		*dlsz_p    = old_dlsz;
        8:  127:		*dldepth_p = old_dldepth;
        -:  128:	    }
        -:  129:	    else {
    12790:  130:		PREPEND_PREFIX(Dataloop_create_contiguous)(1,
        -:  131:							   types[0], 
        -:  132:							   dlp_p, dlsz_p,
        -:  133:							   dldepth_p,
        -:  134:							   flag);
        -:  135:	    }
        -:  136:	    break;
        -:  137:	case MPI_COMBINER_RESIZED:
       92:  138:	    if (type0_combiner != MPI_COMBINER_NAMED) {
       80:  139:		PREPEND_PREFIX(Dataloop_dup)(old_dlp, old_dlsz, dlp_p);
       80:  140:		*dlsz_p    = old_dlsz;
       80:  141:		*dldepth_p = old_dldepth;
        -:  142:	    }
        -:  143:	    else {
       12:  144:		PREPEND_PREFIX(Dataloop_create_contiguous)(1,
        -:  145:							   types[0], 
        -:  146:							   dlp_p, dlsz_p,
        -:  147:							   dldepth_p,
        -:  148:							   flag);
        -:  149:
       12:  150:		(*dlp_p)->el_extent = aints[1]; /* extent */
        -:  151:	    }
        -:  152:	    break;
        -:  153:	case MPI_COMBINER_CONTIGUOUS:
     6572:  154:	    PREPEND_PREFIX(Dataloop_create_contiguous)(ints[0] /* count */,
        -:  155:						       types[0] /* oldtype */,
        -:  156:						       dlp_p, dlsz_p,
        -:  157:						       dldepth_p,
        -:  158:						       flag);
     6572:  159:	    break;
        -:  160:	case MPI_COMBINER_VECTOR:
    17610:  161:	    PREPEND_PREFIX(Dataloop_create_vector)(ints[0] /* count */,
        -:  162:						   ints[1] /* blklen */,
        -:  163:						   ints[2] /* stride */,
        -:  164:						   0 /* stride not bytes */,
        -:  165:						   types[0] /* oldtype */,
        -:  166:						   dlp_p, dlsz_p, dldepth_p,
        -:  167:						   flag);
    17610:  168:	    break;
        -:  169:	case MPI_COMBINER_HVECTOR_INTEGER:
        -:  170:	case MPI_COMBINER_HVECTOR:
        -:  171:	    /* fortran hvector has integer stride in bytes */
     7830:  172:	    if (combiner == MPI_COMBINER_HVECTOR_INTEGER) {
    #####:  173:		stride = (MPI_Aint) ints[2];
        -:  174:	    }
        -:  175:	    else {
     7830:  176:		stride = aints[0];
        -:  177:	    }
        -:  178:
     7830:  179:	    PREPEND_PREFIX(Dataloop_create_vector)(ints[0] /* count */,
        -:  180:						   ints[1] /* blklen */,
        -:  181:						   stride,
        -:  182:						   1 /* stride in bytes */,
        -:  183:						   types[0] /* oldtype */,
        -:  184:						   dlp_p, dlsz_p, dldepth_p,
        -:  185:						   flag);
     7830:  186:	    break;
        -:  187:	case MPI_COMBINER_INDEXED_BLOCK:
     1070:  188:	    PREPEND_PREFIX(Dataloop_create_blockindexed)(ints[0] /* count */,
        -:  189:							 ints[1] /* blklen */,
        -:  190:							 &ints[2] /* disps */,
        -:  191:							 0 /* disp not bytes */,
        -:  192:							 types[0] /* oldtype */,
        -:  193:							 dlp_p, dlsz_p,
        -:  194:							 dldepth_p,
        -:  195:							 flag);
     1070:  196:	    break;
        -:  197:	case MPI_COMBINER_INDEXED:
    37930:  198:	    PREPEND_PREFIX(Dataloop_create_indexed)(ints[0] /* count */,
        -:  199:						    &ints[1] /* blklens */,
        -:  200:						    &ints[ints[0]+1] /* disp */,
        -:  201:						    0 /* disp not in bytes */,
        -:  202:						    types[0] /* oldtype */,
        -:  203:						    dlp_p, dlsz_p, dldepth_p,
        -:  204:						    flag);
    37930:  205:	    break;
        -:  206:	case MPI_COMBINER_HINDEXED_INTEGER:
        -:  207:	case MPI_COMBINER_HINDEXED:
     6778:  208:	    if (combiner == MPI_COMBINER_HINDEXED_INTEGER) {
    #####:  209:		disps = (MPI_Aint *) DLOOP_Malloc(ints[0] * sizeof(MPI_Aint));
        -:  210:
    #####:  211:		for (i=0; i < ints[0]; i++) {
    #####:  212:		    disps[i] = (MPI_Aint) ints[ints[0] + 1 + i];
        -:  213:		}
        -:  214:	    }
        -:  215:	    else {
     6778:  216:		disps = aints;
        -:  217:	    }
        -:  218:
     6778:  219:	    PREPEND_PREFIX(Dataloop_create_indexed)(ints[0] /* count */,
        -:  220:						    &ints[1] /* blklens */,
        -:  221:						    disps,
        -:  222:						    1 /* disp in bytes */,
        -:  223:						    types[0] /* oldtype */,
        -:  224:						    dlp_p, dlsz_p, dldepth_p,
        -:  225:						    flag);
        -:  226:
     6778:  227:	    if (combiner == MPI_COMBINER_HINDEXED_INTEGER) {
    #####:  228:		DLOOP_Free(disps);
        -:  229:	    }
        -:  230:
        -:  231:	    break;
        -:  232:	case MPI_COMBINER_STRUCT_INTEGER:
        -:  233:	case MPI_COMBINER_STRUCT:
 10688442:  234:	    for (i = 1; i < ints[0]; i++) {
        -:  235:		int type_combiner;
 10655696:  236:		NMPI_Type_get_envelope(types[i], &dummy1, &dummy2, &dummy3,
        -:  237:				       &type_combiner);
        -:  238:
 10655696:  239:		if (type_combiner != MPI_COMBINER_NAMED) {
    11462:  240:		    DLOOP_Handle_get_loopptr_macro(types[i], old_dlp, flag);
    11462:  241:		    if (old_dlp == NULL)
        -:  242:		    {
      688:  243:			PREPEND_PREFIX(Dataloop_create)(types[i],
        -:  244:							&old_dlp,
        -:  245:							&old_dlsz,
        -:  246:							&old_dldepth,
        -:  247:							flag);
        -:  248:			
      688:  249:			DLOOP_Handle_set_loopptr_macro(types[i], old_dlp,
        -:  250:						       flag);
      688:  251:			DLOOP_Handle_set_loopsize_macro(types[i], old_dlsz,
        -:  252:							flag);
      688:  253:			DLOOP_Handle_set_loopdepth_macro(types[i], old_dldepth,
        -:  254:							 flag);
        -:  255:		    }
        -:  256:		}
        -:  257:	    }
    32746:  258:	    if (combiner == MPI_COMBINER_STRUCT_INTEGER) {
    #####:  259:		disps = (MPI_Aint *) DLOOP_Malloc(ints[0] * sizeof(MPI_Aint));
        -:  260:
    #####:  261:		for (i=0; i < ints[0]; i++) {
    #####:  262:		    disps[i] = (MPI_Aint) ints[ints[0] + 1 + i];
        -:  263:		}
        -:  264:	    }
        -:  265:	    else {
    32746:  266:		disps = aints;
        -:  267:	    }
        -:  268:
    32746:  269:            err = PREPEND_PREFIX(Dataloop_create_struct)(ints[0] /* count */,
        -:  270:                                                         &ints[1] /* blklens */,
        -:  271:                                                         disps,
        -:  272:                                                         types /* oldtype array */,
        -:  273:                                                         dlp_p, dlsz_p, dldepth_p,
        -:  274:                                                         flag);
        -:  275:            /* TODO if/when this function returns error codes, propagate this failure instead */
    32746:  276:            DLOOP_Assert(0 == err);
        -:  277:            /* if (err) return err; */
        -:  278:
    32746:  279:	    if (combiner == MPI_COMBINER_STRUCT_INTEGER) {
    #####:  280:		DLOOP_Free(disps);
        -:  281:	    }
        -:  282:	    break;
        -:  283:	case MPI_COMBINER_SUBARRAY:
       20:  284:	    ndims = ints[0];
       20:  285:	    PREPEND_PREFIX(Type_convert_subarray)(ndims,
        -:  286:						  &ints[1] /* sizes */,
        -:  287:						  &ints[1+ndims] /* subsizes */,
        -:  288:						  &ints[1+2*ndims] /* starts */,
        -:  289:						  ints[1+3*ndims] /* order */,
        -:  290:						  types[0],
        -:  291:						  &tmptype);
        -:  292:
       20:  293:	    PREPEND_PREFIX(Dataloop_create)(tmptype,
        -:  294:					    dlp_p,
        -:  295:					    dlsz_p,
        -:  296:					    dldepth_p,
        -:  297:					    flag);
        -:  298:	    
       20:  299:	    NMPI_Type_free(&tmptype);
       20:  300:	    break;
        -:  301:	case MPI_COMBINER_DARRAY:
      588:  302:	    ndims = ints[2];
      588:  303:	    PREPEND_PREFIX(Type_convert_darray)(ints[0] /* size */,
        -:  304:						ints[1] /* rank */,
        -:  305:						ndims,
        -:  306:						&ints[3] /* gsizes */,
        -:  307:						&ints[3+ndims] /*distribs */,
        -:  308:						&ints[3+2*ndims] /* dargs */,
        -:  309:						&ints[3+3*ndims] /* psizes */,
        -:  310:						ints[3+4*ndims] /* order */,
        -:  311:						types[0],
        -:  312:						&tmptype);
        -:  313:
      588:  314:	    PREPEND_PREFIX(Dataloop_create)(tmptype,
        -:  315:					    dlp_p,
        -:  316:					    dlsz_p,
        -:  317:					    dldepth_p,
        -:  318:					    flag);
        -:  319:
      588:  320:	    NMPI_Type_free(&tmptype);
      588:  321:	    break;
        -:  322:	case MPI_COMBINER_F90_REAL:
        -:  323:	case MPI_COMBINER_F90_COMPLEX:
        -:  324:	case MPI_COMBINER_F90_INTEGER:
        -:  325:	    /* TODO: WHAT DO I DO HERE? */
        -:  326:	default:
    #####:  327:	    DLOOP_Assert(0);
        -:  328:	    break;
        -:  329:    }
        -:  330:
   124080:  331: clean_exit:
        -:  332:
   124080:  333:    PREPEND_PREFIX(Type_release_contents)(type, &ints, &aints, &types);
        -:  334:
        -:  335:    /* for now we just leave the intermediate dataloops in place.
        -:  336:     * could remove them to save space if we wanted.
        -:  337:     */
        -:  338:
   124080:  339:    return;
        -:  340:}
        -:  341:
        -:  342:/*@
        -:  343:  DLOOP_Dataloop_create_named - create a dataloop for a "named" type
        -:  344:  if necessary.
        -:  345:
        -:  346:  "named" types are ones for which MPI_Type_get_envelope() returns a
        -:  347:  combiner of MPI_COMBINER_NAMED. some types that fit this category,
        -:  348:  such as MPI_SHORT_INT, have multiple elements with potential gaps
        -:  349:  and padding. these types need dataloops for correct processing.
        -:  350:@*/
        -:  351:static void DLOOP_Dataloop_create_named(MPI_Datatype type,
        -:  352:					DLOOP_Dataloop **dlp_p,
        -:  353:					int *dlsz_p,
        -:  354:					int *dldepth_p,
        -:  355:					int flag)
    #####:  356:{
        -:  357:    DLOOP_Dataloop *dlp;
        -:  358:
        -:  359:    /* special case: pairtypes need dataloops too.
        -:  360:     *
        -:  361:     * note: not dealing with MPI_2INT because size == extent
        -:  362:     *       in all cases for that type.
        -:  363:     *
        -:  364:     * note: MPICH2 always precreates these, so we will never call
        -:  365:     *       Dataloop_create_pairtype() from here in the MPICH2
        -:  366:     *       case.
        -:  367:     */
    #####:  368:    if (type == MPI_FLOAT_INT || type == MPI_DOUBLE_INT ||
        -:  369:	type == MPI_LONG_INT || type == MPI_SHORT_INT ||
        -:  370:	type == MPI_LONG_DOUBLE_INT)
        -:  371:    {
    #####:  372:	DLOOP_Handle_get_loopptr_macro(type, dlp, flag);
    #####:  373:	if (dlp != NULL) {
        -:  374:	    /* dataloop already created; just return it. */
    #####:  375:	    *dlp_p = dlp;
    #####:  376:	    DLOOP_Handle_get_loopsize_macro(type, *dlsz_p, flag);
    #####:  377:	    DLOOP_Handle_get_loopdepth_macro(type, *dldepth_p, flag);
        -:  378:	}
        -:  379:	else {
    #####:  380:	    PREPEND_PREFIX(Dataloop_create_pairtype)(type,
        -:  381:						     dlp_p,
        -:  382:						     dlsz_p,
        -:  383:						     dldepth_p,
        -:  384:						     flag);
        -:  385:	}
        -:  386:	return;
        -:  387:    }
        -:  388:    /* no other combiners need dataloops; exit. */
        -:  389:    else {
    #####:  390:	*dlp_p = NULL;
    #####:  391:	*dlsz_p = 0;
    #####:  392:	*dldepth_p = 0;
    #####:  393:	return;
        -:  394:    }
        -:  395:}