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