-:    0:Source:/home/MPI/testing/mpich2/mpich2/src/mpid/common/datatype/dataloop/dataloop_create_struct.c
        -:    0:Graph:dataloop_create_struct.gcno
        -:    0:Data:dataloop_create_struct.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 "./dataloop.h"
        -:    9:
        -:   10:#ifndef PREPEND_PREFIX
        -:   11:#error "You must explicitly include a header that sets the PREPEND_PREFIX and includes dataloop_parts.h"
        -:   12:#endif
        -:   13:
        -:   14:static int DLOOP_Dataloop_create_struct_memory_error(void);
        -:   15:static int DLOOP_Dataloop_create_unique_type_struct(int count,
        -:   16:						    int *blklens,
        -:   17:						    MPI_Aint *disps,
        -:   18:						    DLOOP_Type *oldtypes,
        -:   19:						    int type_pos,
        -:   20:						    DLOOP_Dataloop **dlp_p,
        -:   21:						    int *dlsz_p,
        -:   22:						    int *dldepth_p,
        -:   23:						    int flag);
        -:   24:static int DLOOP_Dataloop_create_basic_all_bytes_struct(
        -:   25:	       int count,
        -:   26:	       int *blklens,
        -:   27:	       MPI_Aint *disps,
        -:   28:	       DLOOP_Type *oldtypes,
        -:   29:	       DLOOP_Dataloop **dlp_p,
        -:   30:	       int *dlsz_p,
        -:   31:	       int *dldepth_p,
        -:   32:	       int flag);
        -:   33:static int DLOOP_Dataloop_create_flattened_struct(int count,
        -:   34:						  int *blklens,
        -:   35:						  MPI_Aint *disps,
        -:   36:						  DLOOP_Type *oldtypes,
        -:   37:						  DLOOP_Dataloop **dlp_p,
        -:   38:						  int *dlsz_p,
        -:   39:						  int *dldepth_p,
        -:   40:						  int flag);
        -:   41:
        -:   42:/*@
        -:   43:  Dataloop_create_struct - create the dataloop representation for a
        -:   44:  struct datatype
        -:   45:
        -:   46:  Input Parameters:
        -:   47:+ count - number of blocks in vector
        -:   48:. blklens - number of elements in each block
        -:   49:. disps - offsets of blocks from start of type in bytes
        -:   50:- oldtypes - types (using handle) of datatypes on which vector is based
        -:   51:
        -:   52:  Output Parameters:
        -:   53:+ dlp_p - pointer to address in which to place pointer to new dataloop
        -:   54:- dlsz_p - pointer to address in which to place size of new dataloop
        -:   55:
        -:   56:  Return Value:
        -:   57:  0 on success, -1 on failure.
        -:   58:
        -:   59:  Notes:
        -:   60:  This function relies on others, like Dataloop_create_indexed, to create
        -:   61:  types in some cases. This call (like all the rest) takes int blklens
        -:   62:  and MPI_Aint displacements, so it's possible to overflow when working
        -:   63:  with a particularly large struct type in some cases. This isn't detected
        -:   64:  or corrected in this code at this time.
        -:   65:
        -:   66:@*/
        -:   67:int PREPEND_PREFIX(Dataloop_create_struct)(int count,
        -:   68:					   int *blklens,
        -:   69:					   MPI_Aint *disps,
        -:   70:					   DLOOP_Type *oldtypes,
        -:   71:					   DLOOP_Dataloop **dlp_p,
        -:   72:					   int *dlsz_p,
        -:   73:					   int *dldepth_p,
        -:   74:					   int flag)
    76556:   75:{
    76556:   76:    int err, i, nr_basics = 0, nr_derived = 0, type_pos = 0;
        -:   77:
    76556:   78:    DLOOP_Type first_basic = MPI_DATATYPE_NULL,
    76556:   79:	first_derived = MPI_DATATYPE_NULL;
        -:   80:
        -:   81:    /* variables used in general case only */
        -:   82:    int loop_idx, new_loop_sz, new_loop_depth;
    76556:   83:    int old_loop_sz = 0, old_loop_depth = 0;
        -:   84:
        -:   85:    DLOOP_Dataloop *new_dlp, *curpos;
        -:   86:
        -:   87:    /* if count is zero, handle with contig code, call it a int */
    76556:   88:    if (count == 0)
        -:   89:    {
    #####:   90:	err = PREPEND_PREFIX(Dataloop_create_contiguous)(0,
        -:   91:							 MPI_INT,
        -:   92:							 dlp_p,
        -:   93:							 dlsz_p,
        -:   94:							 dldepth_p,
        -:   95:							 flag);
    #####:   96:	return err;
        -:   97:    }
        -:   98:
        -:   99:    /* browse the old types and characterize */
 10852618:  100:    for (i=0; i < count; i++)
        -:  101:    {
        -:  102:	/* ignore type elements with a zero blklen */
 10776062:  103:	if (blklens[i] == 0) continue;
        -:  104:
 10776060:  105:	if (oldtypes[i] != MPI_LB && oldtypes[i] != MPI_UB)
        -:  106:	{
        -:  107:	    int is_builtin;
        -:  108:
 10757484:  109:	    is_builtin =
        -:  110:		(DLOOP_Handle_hasloop_macro(oldtypes[i])) ? 0 : 1;
        -:  111:
 10757484:  112:	    if (is_builtin)
        -:  113:	    {
 10743510:  114:		if (nr_basics == 0)
        -:  115:		{
    73370:  116:		    first_basic = oldtypes[i];
    73370:  117:		    type_pos = i;
        -:  118:		}
 10670140:  119:		else if (oldtypes[i] != first_basic)
        -:  120:		{
   174278:  121:		    first_basic = MPI_DATATYPE_NULL;
        -:  122:		}
 10743510:  123:		nr_basics++;
        -:  124:	    }
        -:  125:	    else /* derived type */
        -:  126:	    {
    13974:  127:		if (nr_derived == 0)
        -:  128:		{
     8196:  129:		    first_derived = oldtypes[i];
     8196:  130:		    type_pos = i;
        -:  131:		}
     5778:  132:		else if (oldtypes[i] != first_derived)
        -:  133:		{
     2192:  134:		    first_derived = MPI_DATATYPE_NULL;
        -:  135:		}
    13974:  136:		nr_derived++;
        -:  137:	    }
        -:  138:	}
        -:  139:    }
        -:  140:
        -:  141:    /* note on optimizations:
        -:  142:     *
        -:  143:     * because LB, UB, and extent calculations are handled as part of
        -:  144:     * the Datatype, we can safely ignore them in all our calculations
        -:  145:     * here.
        -:  146:     */
        -:  147:
        -:  148:    /* optimization:
        -:  149:     *
        -:  150:     * if there were only MPI_LBs and MPI_UBs in the struct type,
        -:  151:     * treat it as a zero-element contiguous (just as count == 0).
        -:  152:     */
    76556:  153:    if (nr_basics == 0 && nr_derived == 0)
        -:  154:    {
    #####:  155:	err = PREPEND_PREFIX(Dataloop_create_contiguous)(0,
        -:  156:							 MPI_INT,
        -:  157:							 dlp_p,
        -:  158:							 dlsz_p,
        -:  159:							 dldepth_p,
        -:  160:							 flag);
    #####:  161:	return err;
        -:  162:    }
        -:  163:
        -:  164:    /* optimization:
        -:  165:     *
        -:  166:     * if there is only one unique instance of a type in the struct, treat it
        -:  167:     * as a blockindexed type.
        -:  168:     *
        -:  169:     * notes:
        -:  170:     *
        -:  171:     * if the displacement happens to be zero, the blockindexed code will
        -:  172:     * optimize this into a contig.
        -:  173:     */
    76556:  174:    if (nr_basics + nr_derived == 1)
        -:  175:    {
        -:  176:	/* type_pos is index to only real type in array */
     3248:  177:	err = PREPEND_PREFIX(Dataloop_create_blockindexed)
        -:  178:	    (1, /* count */
        -:  179:	     blklens[type_pos],
        -:  180:	     &disps[type_pos],
        -:  181:	     1, /* displacement in bytes */
        -:  182:	     oldtypes[type_pos],
        -:  183:	     dlp_p,
        -:  184:	     dlsz_p,
        -:  185:	     dldepth_p,
        -:  186:	     flag);
        -:  187:
     3248:  188:	return err;
        -:  189:    }
        -:  190:
        -:  191:    /* optimization:
        -:  192:     *
        -:  193:     * if there only one unique type (more than one instance) in the
        -:  194:     * struct, treat it as an indexed type.
        -:  195:     *
        -:  196:     * notes:
        -:  197:     *
        -:  198:     * this will apply to a single type with an LB/UB, as those
        -:  199:     * are handled elsewhere.
        -:  200:     *
        -:  201:     */
    73308:  202:    if (((nr_derived == 0) && (first_basic != MPI_DATATYPE_NULL)) ||
        -:  203:	((nr_basics == 0) && (first_derived != MPI_DATATYPE_NULL)))
        -:  204:    {
     8962:  205:	return DLOOP_Dataloop_create_unique_type_struct(count,
        -:  206:							blklens,
        -:  207:							disps,
        -:  208:							oldtypes,
        -:  209:							type_pos,
        -:  210:							dlp_p,
        -:  211:							dlsz_p,
        -:  212:							dldepth_p,
        -:  213:							flag);
        -:  214:    }
        -:  215:
        -:  216:    /* optimization:
        -:  217:     *
        -:  218:     * if there are no derived types and caller indicated either a
        -:  219:     * homogeneous system or the "all bytes" conversion, convert
        -:  220:     * everything to bytes and use an indexed type.
        -:  221:     */
    64346:  222:    if (nr_derived == 0 && ((flag == DLOOP_DATALOOP_HOMOGENEOUS) ||
        -:  223:			    (flag == DLOOP_DATALOOP_ALL_BYTES)))
        -:  224:    {
    29304:  225:	return DLOOP_Dataloop_create_basic_all_bytes_struct(count,
        -:  226:							    blklens,
        -:  227:							    disps,
        -:  228:							    oldtypes,
        -:  229:							    dlp_p,
        -:  230:							    dlsz_p,
        -:  231:							    dldepth_p,
        -:  232:							    flag);
        -:  233:    }
        -:  234:
        -:  235:    /* optimization:
        -:  236:     *
        -:  237:     * if caller asked for homogeneous or all bytes representation,
        -:  238:     * flatten the type and store it as an indexed type so that
        -:  239:     * there are no branches in the dataloop tree.
        -:  240:     */
    35042:  241:    if ((flag == DLOOP_DATALOOP_HOMOGENEOUS) ||
        -:  242:	     (flag == DLOOP_DATALOOP_ALL_BYTES))
        -:  243:    {
     2869:  244:	return DLOOP_Dataloop_create_flattened_struct(count,
        -:  245:						      blklens,
        -:  246:						      disps,
        -:  247:						      oldtypes,
        -:  248:						      dlp_p,
        -:  249:						      dlsz_p,
        -:  250:						      dldepth_p,
        -:  251:						      flag);
        -:  252:    }
        -:  253:
        -:  254:    /* scan through types and gather derived type info */
   166190:  255:    for (i=0; i < count; i++)
        -:  256:    {
        -:  257:	/* ignore type elements with a zero blklen */
   134017:  258:	if (blklens[i] == 0) continue;
        -:  259:
   134017:  260:	if (DLOOP_Handle_hasloop_macro(oldtypes[i]))
        -:  261:	{
        -:  262:	    int tmp_loop_depth, tmp_loop_sz;
        -:  263:
     5061:  264:	    DLOOP_Handle_get_loopdepth_macro(oldtypes[i], tmp_loop_depth, flag);
     5061:  265:	    DLOOP_Handle_get_loopsize_macro(oldtypes[i], tmp_loop_sz, flag);
        -:  266:
     5061:  267:	    if (tmp_loop_depth > old_loop_depth)
        -:  268:	    {
     2872:  269:		old_loop_depth = tmp_loop_depth;
        -:  270:	    }
     5061:  271:	    old_loop_sz += tmp_loop_sz;
        -:  272:	}
        -:  273:    }
        -:  274:
        -:  275:    /* general case below: 2 or more distinct types that are either
        -:  276:     * basics or derived, and for which we want to preserve the types
        -:  277:     * themselves.
        -:  278:     */
        -:  279:
    32173:  280:    if (nr_basics > 0)
        -:  281:    {
        -:  282:	/* basics introduce an extra level of depth, so if our new depth
        -:  283:	 * must be at least 2 if there are basics.
        -:  284:	 */
    31809:  285:	new_loop_depth = ((old_loop_depth+1) > 2) ? (old_loop_depth+1) : 2;
        -:  286:    }
        -:  287:    else
        -:  288:    {
      364:  289:	new_loop_depth = old_loop_depth + 1;
        -:  290:    }
        -:  291:
    32173:  292:    PREPEND_PREFIX(Dataloop_struct_alloc)((DLOOP_Count) nr_basics + nr_derived,
        -:  293:					  old_loop_sz,
        -:  294:					  nr_basics,
        -:  295:					  &curpos,
        -:  296:					  &new_dlp,
        -:  297:					  &new_loop_sz);
        -:  298:    /* --BEGIN ERROR HANDLING-- */
    32173:  299:    if (!new_dlp)
        -:  300:    {
    #####:  301:	return DLOOP_Dataloop_create_struct_memory_error();
        -:  302:    }
        -:  303:    /* --END ERROR HANDLING-- */
        -:  304:
        -:  305:
    32173:  306:    new_dlp->kind = DLOOP_KIND_STRUCT;
    32173:  307:    new_dlp->el_size = -1; /* not valid for struct */
    32173:  308:    new_dlp->el_extent = -1; /* not valid for struct; see el_extent_array */
    32173:  309:    new_dlp->el_type = MPI_DATATYPE_NULL; /* not valid for struct */
        -:  310:
    32173:  311:    new_dlp->loop_params.s_t.count = (DLOOP_Count) nr_basics + nr_derived;
        -:  312:
        -:  313:    /* note: curpos points to first byte in "old dataloop" region of
        -:  314:     * newly allocated space.
        -:  315:     */
        -:  316:
   166190:  317:    for (i=0, loop_idx = 0; i < count; i++)
        -:  318:    {
        -:  319:	int is_builtin;
        -:  320:
        -:  321:	/* ignore type elements with a zero blklen */
   134017:  322:	if (blklens[i] == 0) continue;
        -:  323:
   134017:  324:	is_builtin = (DLOOP_Handle_hasloop_macro(oldtypes[i])) ? 0 : 1;
        -:  325:
   134017:  326:	if (is_builtin)
        -:  327:	{
        -:  328:	    DLOOP_Dataloop *dummy_dlp;
        -:  329:	    int dummy_sz, dummy_depth;
        -:  330:
        -:  331:	    /* LBs and UBs already taken care of -- skip them */
   128956:  332:	    if (oldtypes[i] == MPI_LB || oldtypes[i] == MPI_UB)
        -:  333:	    {
     8365:  334:		continue;
        -:  335:	    }
        -:  336:
        -:  337:	    /* build a contig dataloop for this basic and point to that
        -:  338:	     *
        -:  339:	     * optimization:
        -:  340:	     *
        -:  341:	     * push the count (blklen) from the struct down into the
        -:  342:	     * contig so we can process more at the leaf.
        -:  343:	     */
   120591:  344:	    err = PREPEND_PREFIX(Dataloop_create_contiguous)(blklens[i],
        -:  345:							     oldtypes[i],
        -:  346:							     &dummy_dlp,
        -:  347:							     &dummy_sz,
        -:  348:							     &dummy_depth,
        -:  349:							     flag);
        -:  350:
        -:  351:	    /* --BEGIN ERROR HANDLING-- */
   120591:  352:	    if (err) {
        -:  353:		/* TODO: FREE ALLOCATED RESOURCES */
    #####:  354:		return -1;
        -:  355:	    }
        -:  356:	    /* --END ERROR HANDLING-- */
        -:  357:
        -:  358:	    /* copy the new contig loop into place in the struct memory
        -:  359:	     * region
        -:  360:	     */
   120591:  361:	    PREPEND_PREFIX(Dataloop_copy)(curpos, dummy_dlp, dummy_sz);
   120591:  362:	    new_dlp->loop_params.s_t.dataloop_array[loop_idx] = curpos;
   120591:  363:	    curpos = (DLOOP_Dataloop *) ((char *) curpos + dummy_sz);
        -:  364:
        -:  365:	    /* we stored the block size in the contig -- use 1 here */
   120591:  366:	    new_dlp->loop_params.s_t.blocksize_array[loop_idx] = 1;
   120591:  367:	    new_dlp->loop_params.s_t.el_extent_array[loop_idx] =
        -:  368:		((DLOOP_Offset) blklens[i]) * dummy_dlp->el_extent;
   120591:  369:	    PREPEND_PREFIX(Dataloop_free)(&dummy_dlp);
        -:  370:	}
        -:  371:	else
        -:  372:	{
        -:  373:	    DLOOP_Dataloop *old_loop_ptr;
        -:  374:	    DLOOP_Offset old_extent;
        -:  375:
     5061:  376:	    DLOOP_Handle_get_loopptr_macro(oldtypes[i], old_loop_ptr, flag);
     5061:  377:	    DLOOP_Handle_get_loopsize_macro(oldtypes[i], old_loop_sz, flag);
     5061:  378:	    DLOOP_Handle_get_extent_macro(oldtypes[i], old_extent);
        -:  379:
     5061:  380:	    PREPEND_PREFIX(Dataloop_copy)(curpos, old_loop_ptr, old_loop_sz);
     5061:  381:	    new_dlp->loop_params.s_t.dataloop_array[loop_idx] = curpos;
     5061:  382:	    curpos = (DLOOP_Dataloop *) ((char *) curpos + old_loop_sz);
        -:  383:
     5061:  384:	    new_dlp->loop_params.s_t.blocksize_array[loop_idx] =
        -:  385:		(DLOOP_Count) blklens[i];
     5061:  386:	    new_dlp->loop_params.s_t.el_extent_array[loop_idx] =
        -:  387:		old_extent;
        -:  388:	}
   125652:  389:	new_dlp->loop_params.s_t.offset_array[loop_idx] =
        -:  390:	    (DLOOP_Offset) disps[i];
   125652:  391:	loop_idx++;
        -:  392:    }
        -:  393:
    32173:  394:    *dlp_p     = new_dlp;
    32173:  395:    *dlsz_p    = new_loop_sz;
    32173:  396:    *dldepth_p = new_loop_depth;
        -:  397:
    32173:  398:    return 0;
        -:  399:}
        -:  400:
        -:  401:/* --BEGIN ERROR HANDLING-- */
        -:  402:static int DLOOP_Dataloop_create_struct_memory_error(void)
    #####:  403:{
    #####:  404:    return -1;
        -:  405:}
        -:  406:/* --END ERROR HANDLING-- */
        -:  407:
        -:  408:static int DLOOP_Dataloop_create_unique_type_struct(int count,
        -:  409:						    int *blklens,
        -:  410:						    MPI_Aint *disps,
        -:  411:						    DLOOP_Type *oldtypes,
        -:  412:						    int type_pos,
        -:  413:						    DLOOP_Dataloop **dlp_p,
        -:  414:						    int *dlsz_p,
        -:  415:						    int *dldepth_p,
        -:  416:						    int flag)
     8962:  417:{
        -:  418:    /* the same type used more than once in the array; type_pos
        -:  419:     * indexes to the first of these.
        -:  420:     */
     8962:  421:    int i, err, *tmp_blklens, cur_pos = 0;
        -:  422:    DLOOP_Offset *tmp_disps;
        -:  423:
        -:  424:    /* count is an upper bound on number of type instances */
     8962:  425:    tmp_blklens = (int *) DLOOP_Malloc(count * sizeof(int));
        -:  426:    /* --BEGIN ERROR HANDLING-- */
     8962:  427:    if (!tmp_blklens) {
        -:  428:	/* TODO: ??? */
    #####:  429:	return DLOOP_Dataloop_create_struct_memory_error();
        -:  430:    }
        -:  431:    /* --END ERROR HANDLING-- */
        -:  432:
     8962:  433:    tmp_disps = (DLOOP_Offset *)
        -:  434:	DLOOP_Malloc(count * sizeof(DLOOP_Offset));
        -:  435:    /* --BEGIN ERROR HANDLING-- */
     8962:  436:    if (!tmp_disps) {
    #####:  437:	DLOOP_Free(tmp_blklens);
        -:  438:	/* TODO: ??? */
    #####:  439:	return DLOOP_Dataloop_create_struct_memory_error();
        -:  440:    }
        -:  441:    /* --END ERROR HANDLING-- */
        -:  442:
 10511896:  443:    for (i=type_pos; i < count; i++)
        -:  444:    {
 10502934:  445:	if (oldtypes[i] == oldtypes[type_pos] && blklens != 0)
        -:  446:	{
 10502932:  447:	    tmp_blklens[cur_pos] = blklens[i];
 10502932:  448:	    tmp_disps[cur_pos]   = disps[i];
 10502932:  449:	    cur_pos++;
        -:  450:	}
        -:  451:    }
        -:  452:
     8962:  453:    err = PREPEND_PREFIX(Dataloop_create_indexed)(cur_pos,
        -:  454:						  tmp_blklens,
        -:  455:						  tmp_disps,
        -:  456:						  1, /* disp in bytes */
        -:  457:						  oldtypes[type_pos],
        -:  458:						  dlp_p,
        -:  459:						  dlsz_p,
        -:  460:						  dldepth_p,
        -:  461:						  flag);
        -:  462:
     8962:  463:    DLOOP_Free(tmp_blklens);
     8962:  464:    DLOOP_Free(tmp_disps);
        -:  465:
     8962:  466:    return err;
        -:  467:
        -:  468:}
        -:  469:
        -:  470:static int DLOOP_Dataloop_create_basic_all_bytes_struct(
        -:  471:	       int count,
        -:  472:	       int *blklens,
        -:  473:	       MPI_Aint *disps,
        -:  474:	       DLOOP_Type *oldtypes,
        -:  475:	       DLOOP_Dataloop **dlp_p,
        -:  476:	       int *dlsz_p,
        -:  477:	       int *dldepth_p,
        -:  478:	       int flag)
    29304:  479:{
    29304:  480:    int i, err, cur_pos = 0;
        -:  481:    int *tmp_blklens;
        -:  482:    MPI_Aint *tmp_disps;
        -:  483:
        -:  484:    /* count is an upper bound on number of type instances */
    29304:  485:    tmp_blklens = (int *) DLOOP_Malloc(count * sizeof(int));
        -:  486:
        -:  487:    /* --BEGIN ERROR HANDLING-- */
    29304:  488:    if (!tmp_blklens)
        -:  489:    {
    #####:  490:	return DLOOP_Dataloop_create_struct_memory_error();
        -:  491:    }
        -:  492:    /* --END ERROR HANDLING-- */
        -:  493:
    29304:  494:    tmp_disps = (MPI_Aint *) DLOOP_Malloc(count * sizeof(MPI_Aint));
        -:  495:
        -:  496:    /* --BEGIN ERROR HANDLING-- */
    29304:  497:    if (!tmp_disps)
        -:  498:    {
    #####:  499:	DLOOP_Free(tmp_blklens);
    #####:  500:	return DLOOP_Dataloop_create_struct_memory_error();
        -:  501:    }
        -:  502:    /* --END ERROR HANDLING-- */
        -:  503:
   133618:  504:    for (i=0; i < count; i++)
        -:  505:    {
   104314:  506:	if (oldtypes[i] != MPI_LB && oldtypes[i] != MPI_UB && blklens[i] != 0)
        -:  507:	{
        -:  508:	    DLOOP_Offset sz;
        -:  509:
    97390:  510:	    DLOOP_Handle_get_size_macro(oldtypes[i], sz);
    97390:  511:	    tmp_blklens[cur_pos] = (int) sz * blklens[i];
    97390:  512:	    tmp_disps[cur_pos]   = disps[i];
    97390:  513:	    cur_pos++;
        -:  514:	}
        -:  515:    }
    29304:  516:    err = PREPEND_PREFIX(Dataloop_create_indexed)(cur_pos,
        -:  517:						  tmp_blklens,
        -:  518:						  tmp_disps,
        -:  519:						  1, /* disp in bytes */
        -:  520:						  MPI_BYTE,
        -:  521:						  dlp_p,
        -:  522:						  dlsz_p,
        -:  523:						  dldepth_p,
        -:  524:						  flag);
        -:  525:
    29304:  526:    DLOOP_Free(tmp_blklens);
    29304:  527:    DLOOP_Free(tmp_disps);
        -:  528:
    29304:  529:    return err;
        -:  530:}
        -:  531:
        -:  532:static int DLOOP_Dataloop_create_flattened_struct(int count,
        -:  533:						  int *blklens,
        -:  534:						  MPI_Aint *disps,
        -:  535:						  DLOOP_Type *oldtypes,
        -:  536:						  DLOOP_Dataloop **dlp_p,
        -:  537:						  int *dlsz_p,
        -:  538:						  int *dldepth_p,
        -:  539:						  int flag)
     2869:  540:{
        -:  541:    /* arbitrary types, convert to bytes and use indexed */
     2869:  542:    int i, err, *tmp_blklens, nr_blks = 0;
        -:  543:    MPI_Aint *tmp_disps; /* since we're calling another fn that takes
        -:  544:			    this type as an input parameter */
        -:  545:    DLOOP_Offset bytes;
        -:  546:    DLOOP_Segment *segp;
        -:  547:
        -:  548:    int first_ind, last_ind;
        -:  549:
     2869:  550:    segp = PREPEND_PREFIX(Segment_alloc)();
        -:  551:    /* --BEGIN ERROR HANDLING-- */
     2869:  552:    if (!segp) {
    #####:  553:	return DLOOP_Dataloop_create_struct_memory_error();
        -:  554:    }
        -:  555:    /* --END ERROR HANDLING-- */
        -:  556:
        -:  557:    /* use segment code once to count contiguous regions */
    32572:  558:    for (i=0; i < count; i++)
        -:  559:    {
        -:  560:	int is_basic;
        -:  561:
        -:  562:	/* ignore type elements with a zero blklen */
    29703:  563:	if (blklens[i] == 0) continue;
        -:  564:
    29703:  565:	is_basic = (DLOOP_Handle_hasloop_macro(oldtypes[i])) ? 0 : 1;
        -:  566:
    52904:  567:	if (is_basic && (oldtypes[i] != MPI_LB &&
        -:  568:			 oldtypes[i] != MPI_UB))
        -:  569:	{
    23201:  570:	    nr_blks++;
        -:  571:	}
        -:  572:        else /* derived type; get a count of contig blocks */
        -:  573:        {
        -:  574:            DLOOP_Count tmp_nr_blks, sz;
        -:  575:
     6502:  576:            DLOOP_Handle_get_size_macro(oldtypes[i], sz);
        -:  577:
        -:  578:            /* if the derived type has some data to contribute,
        -:  579:             * add to flattened representation */
     6502:  580:            if (sz > 0) {
     5057:  581:                err = PREPEND_PREFIX(Segment_init)(NULL,
        -:  582:                                                   (DLOOP_Count) blklens[i],
        -:  583:                                                   oldtypes[i],
        -:  584:                                                   segp,
        -:  585:                                                   flag);
     5057:  586:                if (err) return err;
        -:  587:
     5057:  588:                bytes = SEGMENT_IGNORE_LAST;
        -:  589:
     5057:  590:                PREPEND_PREFIX(Segment_count_contig_blocks)(segp,
        -:  591:                                                            0,
        -:  592:                                                            &bytes,
        -:  593:                                                            &tmp_nr_blks);
        -:  594:
     5057:  595:                nr_blks += tmp_nr_blks;
        -:  596:            }
        -:  597:        }
        -:  598:    }
        -:  599:
        -:  600:    /* it's possible for us to get to this point only to realize that
        -:  601:     * there isn't any data in this type. in that case do what we always
        -:  602:     * do: store a simple contig of zero ints and call it done.
        -:  603:     */
     2869:  604:    if (nr_blks == 0) {
        1:  605:	PREPEND_PREFIX(Segment_free)(segp);
        1:  606:	err = PREPEND_PREFIX(Dataloop_create_contiguous)(0,
        -:  607:							 MPI_INT,
        -:  608:							 dlp_p,
        -:  609:							 dlsz_p,
        -:  610:							 dldepth_p,
        -:  611:							 flag);
        1:  612:	return err;
        -:  613:
        -:  614:    }
        -:  615:
     2868:  616:    nr_blks += 2; /* safety measure */
        -:  617:
     2868:  618:    tmp_blklens = (int *) DLOOP_Malloc(nr_blks * sizeof(int));
        -:  619:    /* --BEGIN ERROR HANDLING-- */
     2868:  620:    if (!tmp_blklens) {
    #####:  621:	PREPEND_PREFIX(Segment_free)(segp);
    #####:  622:	return DLOOP_Dataloop_create_struct_memory_error();
        -:  623:    }
        -:  624:    /* --END ERROR HANDLING-- */
        -:  625:
        -:  626:
     2868:  627:    tmp_disps = (MPI_Aint *) DLOOP_Malloc(nr_blks * sizeof(MPI_Aint));
        -:  628:    /* --BEGIN ERROR HANDLING-- */
     2868:  629:    if (!tmp_disps) {
    #####:  630:	DLOOP_Free(tmp_blklens);
    #####:  631:	PREPEND_PREFIX(Segment_free)(segp);
    #####:  632:	return DLOOP_Dataloop_create_struct_memory_error();
        -:  633:    }
        -:  634:    /* --END ERROR HANDLING-- */
        -:  635:
        -:  636:    /* use segment code again to flatten the type */
     2868:  637:    first_ind = 0;
    32568:  638:    for (i=0; i < count; i++)
        -:  639:    {
        -:  640:	int is_basic;
    29700:  641:	DLOOP_Count sz = -1;
        -:  642:
    29700:  643:	is_basic = (DLOOP_Handle_hasloop_macro(oldtypes[i])) ? 0 : 1;
    29700:  644:	if (!is_basic) DLOOP_Handle_get_size_macro(oldtypes[i], sz);
        -:  645:
        -:  646:	/* we're going to use the segment code to flatten the type.
        -:  647:	 * we put in our displacement as the buffer location, and use
        -:  648:	 * the blocklength as the count value to get N contiguous copies
        -:  649:	 * of the type.
        -:  650:	 *
        -:  651:	 * Note that we're going to get back values in bytes, so that will
        -:  652:	 * be our new element type.
        -:  653:	 */
    29700:  654:	if (oldtypes[i] != MPI_UB &&
        -:  655:	    oldtypes[i] != MPI_LB &&
        -:  656:	    blklens[i] != 0 &&
        -:  657:	    (is_basic || sz > 0))
        -:  658:	{
    28258:  659:	    err = PREPEND_PREFIX(Segment_init)((char *) MPI_AINT_CAST_TO_VOID_PTR disps[i],
        -:  660:					 (DLOOP_Count) blklens[i],
        -:  661:					 oldtypes[i],
        -:  662:					 segp,
        -:  663:					 0 /* homogeneous */);
    28258:  664:            if (err) return err;
        -:  665:
    28258:  666:	    last_ind = nr_blks - first_ind;
    28258:  667:	    bytes = SEGMENT_IGNORE_LAST;
    28258:  668:	    PREPEND_PREFIX(Segment_mpi_flatten)(segp,
        -:  669:						0,
        -:  670:						&bytes,
        -:  671:						&tmp_blklens[first_ind],
        -:  672:						&tmp_disps[first_ind],
        -:  673:						&last_ind);
    28258:  674:            if (err) return err;
    28258:  675:	    first_ind += last_ind;
        -:  676:	}
        -:  677:    }
     2868:  678:    nr_blks = first_ind;
        -:  679:
        -:  680:#if 0
        -:  681:    if (MPIU_DBG_SELECTED(DATATYPE,VERBOSE)) {
        -:  682:	MPIU_DBG_OUT(DATATYPE,"--- start of flattened type ---");
        -:  683:        for (i=0; i < nr_blks; i++) {
        -:  684:	MPIU_DBG_OUT_FMT(DATATYPE,(MPIU_DBG_FDEST,
        -:  685:				   "a[%d] = (%d, " MPI_AINT_FMT_DEC_SPEC ")\n", i,
        -:  686:				   tmp_blklens[i], tmp_disps[i]));
        -:  687:	}
        -:  688:	MPIU_DBG_OUT(DATATYPE,"--- end of flattened type ---");
        -:  689:    }
        -:  690:#endif
        -:  691:
     2868:  692:    PREPEND_PREFIX(Segment_free)(segp);
        -:  693:
     2868:  694:    err = PREPEND_PREFIX(Dataloop_create_indexed)(nr_blks,
        -:  695:						  tmp_blklens,
        -:  696:						  tmp_disps,
        -:  697:						  1, /* disp in bytes */
        -:  698:						  MPI_BYTE,
        -:  699:						  dlp_p,
        -:  700:						  dlsz_p,
        -:  701:						  dldepth_p,
        -:  702:						  flag);
        -:  703:
     2868:  704:    DLOOP_Free(tmp_blklens);
     2868:  705:    DLOOP_Free(tmp_disps);
        -:  706:
     2868:  707:    return err;
        -:  708:}