1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89
|
/* -*- Mode: C; c-basic-offset:4 ; -*- */
/*
* Copyright (c) 2004-2006 The Trustees of Indiana University and Indiana
* University Research and Technology
* Corporation. All rights reserved.
* Copyright (c) 2004-2006 The University of Tennessee and The University
* of Tennessee Research Foundation. All rights
* reserved.
* Copyright (c) 2004-2006 High Performance Computing Center Stuttgart,
* University of Stuttgart. All rights reserved.
* Copyright (c) 2004-2006 The Regents of the University of California.
* All rights reserved.
* $COPYRIGHT$
*
* Additional copyrights may follow
*
* $HEADER$
*/
#include "ompi_config.h"
#include "ompi/datatype/datatype.h"
int32_t ompi_ddt_create_struct( int count, const int* pBlockLength, const MPI_Aint* pDisp,
ompi_datatype_t* const * pTypes, ompi_datatype_t** newType )
{
int i;
ptrdiff_t disp = 0, endto, lastExtent, lastDisp;
int lastBlock;
ompi_datatype_t *pdt, *lastType;
if( 0 == count ) {
*newType = ompi_ddt_create( 0 );
ompi_ddt_add( *newType, &ompi_mpi_datatype_null, 0, 0, 0);
return OMPI_SUCCESS;
}
/* if we compute the total number of elements before we can
* avoid increasing the size of the desc array often.
*/
lastType = (ompi_datatype_t*)pTypes[0];
lastBlock = pBlockLength[0];
lastExtent = lastType->ub - lastType->lb;
lastDisp = pDisp[0];
endto = pDisp[0] + lastExtent * lastBlock;
for( i = 1; i < count; i++ ) {
if( (pTypes[i] == lastType) && (pDisp[i] == endto) ) {
lastBlock += pBlockLength[i];
endto = lastDisp + lastBlock * lastExtent;
} else {
disp += lastType->desc.used;
if( lastBlock > 1 ) disp += 2;
lastType = (ompi_datatype_t*)pTypes[i];
lastExtent = lastType->ub - lastType->lb;
lastBlock = pBlockLength[i];
lastDisp = pDisp[i];
endto = lastDisp + lastExtent * lastBlock;
}
}
disp += lastType->desc.used;
if( lastBlock != 1 ) disp += 2;
lastType = (ompi_datatype_t*)pTypes[0];
lastBlock = pBlockLength[0];
lastExtent = lastType->ub - lastType->lb;
lastDisp = pDisp[0];
endto = pDisp[0] + lastExtent * lastBlock;
pdt = ompi_ddt_create( (int32_t)disp );
/* Do again the same loop but now add the elements */
for( i = 1; i < count; i++ ) {
if( (pTypes[i] == lastType) && (pDisp[i] == endto) ) {
lastBlock += pBlockLength[i];
endto = lastDisp + lastBlock * lastExtent;
} else {
ompi_ddt_add( pdt, lastType, lastBlock, lastDisp, lastExtent );
lastType = (ompi_datatype_t*)pTypes[i];
lastExtent = lastType->ub - lastType->lb;
lastBlock = pBlockLength[i];
lastDisp = pDisp[i];
endto = lastDisp + lastExtent * lastBlock;
}
}
ompi_ddt_add( pdt, lastType, lastBlock, lastDisp, lastExtent );
*newType = pdt;
return OMPI_SUCCESS;
}
|