ompi_datatype_t* create_strange_dt( void ) { sdata_intern v[2]; MPI_Aint displ[3]; ompi_datatype_t* types[3] = { &ompi_mpi_int.dt }; sstrange t[2]; int pBlock[3] = {1, 10, 1}, dispi[3]; ompi_datatype_t *pdt, *pdt1, *pdt2, *pdtTemp; dispi[0] = (int)((char*)&(v[0].i1) - (char*)&(v[0])); /* 0 */ dispi[1] = (int)(((char*)(&(v[0].i2)) - (char*)&(v[0])) / sizeof(int)); /* 2 */ ompi_datatype_create_indexed_block( 2, 1, dispi, &ompi_mpi_int.dt, &pdtTemp ); #ifdef USE_RESIZED /* optional */ displ[0] = 0; displ[1] = (char*)&(v[1]) - (char*)&(v[0]); ompi_datatype_create_resized( pdtTemp, displ[0], displ[1], &pdt1 ); OBJ_RELEASE( pdtTemp ); assert( pdtTemp == NULL ); #else pdt1 = pdtTemp; #endif /* USE_RESIZED */ types[1] = pdt1; types[2] = &ompi_mpi_int.dt; displ[0] = 0; displ[1] = (long)((char*)&(t[0].v[0]) - (char*)&(t[0])); displ[2] = (long)((char*)&(t[0].last) - (char*)&(t[0])); ompi_datatype_create_struct( 3, pBlock, displ, types, &pdtTemp ); #ifdef USE_RESIZED /* optional */ displ[1] = (char*)&(t[1]) - (char*)&(t[0]); ompi_datatype_create_resized( pdtTemp, displ[0], displ[1], &pdt2 ); OBJ_RELEASE( pdtTemp ); assert( pdtTemp == NULL ); #else pdt2 = pdtTemp; #endif /* USE_RESIZED */ ompi_datatype_create_contiguous( SSTRANGE_CNT, pdt2, &pdt ); OBJ_RELEASE( pdt1 ); OBJ_RELEASE( pdt2 ); printf( "\nStrange datatype BEFORE COMMIT\n" ); if( outputFlags & DUMP_DATA_AFTER_COMMIT ) { ompi_datatype_dump( pdt ); } ompi_datatype_commit( &pdt ); printf( "\nStrange datatype AFTER COMMIT\n" ); if( outputFlags & DUMP_DATA_AFTER_COMMIT ) { ompi_datatype_dump( pdt ); } return pdt; }
ompi_datatype_t* create_struct_constant_gap_resized_ddt( ompi_datatype_t* type ) { struct structure data[1]; ompi_datatype_t *struct_type, *temp_type; ompi_datatype_t *types[2] = {type, type}; int blocklens[2] = {1, 1}; MPI_Aint disps[3]; MPI_Get_address(&data[0].transfered_1, &disps[0]); MPI_Get_address(&data[0].transfered_2, &disps[1]); MPI_Get_address(&data[0], &disps[2]); disps[1] -= disps[2]; /* 8 */ disps[0] -= disps[2]; /* 16 */ ompi_datatype_create_struct(2, blocklens, disps, types, &temp_type); ompi_datatype_create_resized(temp_type, 0, sizeof(data[0]), &struct_type); ompi_datatype_commit(&struct_type); OBJ_RELEASE(temp_type); assert( temp_type == NULL ); if( outputFlags & DUMP_DATA_AFTER_COMMIT ) { ompi_datatype_dump( struct_type ); } return struct_type; }
static ompi_datatype_t* __ompi_datatype_create_from_args( int32_t* i, MPI_Aint* a, ompi_datatype_t** d, int32_t type ) { ompi_datatype_t* datatype = NULL; switch(type){ /******************************************************************/ case MPI_COMBINER_DUP: /* should we duplicate d[0]? */ /* ompi_datatype_set_args( datatype, 0, NULL, 0, NULL, 1, d[0], MPI_COMBINER_DUP ); */ assert(0); /* shouldn't happen */ break; /******************************************************************/ case MPI_COMBINER_CONTIGUOUS: ompi_datatype_create_contiguous( i[0], d[0], &datatype ); ompi_datatype_set_args( datatype, 1, (const int **) &i, 0, NULL, 1, d, MPI_COMBINER_CONTIGUOUS ); break; /******************************************************************/ case MPI_COMBINER_VECTOR: ompi_datatype_create_vector( i[0], i[1], i[2], d[0], &datatype ); { const int* a_i[3] = {&i[0], &i[1], &i[2]}; ompi_datatype_set_args( datatype, 3, a_i, 0, NULL, 1, d, MPI_COMBINER_VECTOR ); } break; /******************************************************************/ case MPI_COMBINER_HVECTOR_INTEGER: case MPI_COMBINER_HVECTOR: ompi_datatype_create_hvector( i[0], i[1], a[0], d[0], &datatype ); { const int* a_i[2] = {&i[0], &i[1]}; ompi_datatype_set_args( datatype, 2, a_i, 1, a, 1, d, MPI_COMBINER_HVECTOR ); } break; /******************************************************************/ case MPI_COMBINER_INDEXED: /* TO CHECK */ ompi_datatype_create_indexed( i[0], &(i[1]), &(i[1+i[0]]), d[0], &datatype ); { const int* a_i[3] = {&i[0], &i[1], &(i[1+i[0]])}; ompi_datatype_set_args( datatype, 2 * i[0] + 1, a_i, 0, NULL, 1, d, MPI_COMBINER_INDEXED ); } break; /******************************************************************/ case MPI_COMBINER_HINDEXED_INTEGER: case MPI_COMBINER_HINDEXED: ompi_datatype_create_hindexed( i[0], &(i[1]), a, d[0], &datatype ); { const int* a_i[2] = {&i[0], &i[1]}; ompi_datatype_set_args( datatype, i[0] + 1, a_i, i[0], a, 1, d, MPI_COMBINER_HINDEXED ); } break; /******************************************************************/ case MPI_COMBINER_INDEXED_BLOCK: ompi_datatype_create_indexed_block( i[0], i[1], &(i[2]), d[0], &datatype ); { const int* a_i[3] = {&i[0], &i[1], &i[2]}; ompi_datatype_set_args( datatype, i[0] + 2, a_i, 0, NULL, 1, d, MPI_COMBINER_INDEXED_BLOCK ); } break; /******************************************************************/ case MPI_COMBINER_STRUCT_INTEGER: case MPI_COMBINER_STRUCT: ompi_datatype_create_struct( i[0], &(i[1]), a, d, &datatype ); { const int* a_i[2] = {&i[0], &i[1]}; ompi_datatype_set_args( datatype, i[0] + 1, a_i, i[0], a, i[0], d, MPI_COMBINER_STRUCT ); } break; /******************************************************************/ case MPI_COMBINER_SUBARRAY: ompi_datatype_create_subarray( i[0], &i[1 + 0 * i[0]], &i[1 + 1 * i[0]], &i[1 + 2 * i[0]], i[1 + 3 * i[0]], d[0], &datatype ); { const int* a_i[5] = {&i[0], &i[1 + 0 * i[0]], &i[1 + 1 * i[0]], &i[1 + 2 * i[0]], &i[1 + 3 * i[0]]}; ompi_datatype_set_args( datatype, 3 * i[0] + 2, a_i, 0, NULL, 1, d, MPI_COMBINER_SUBARRAY); } break; /******************************************************************/ case MPI_COMBINER_DARRAY: ompi_datatype_create_darray( i[0] /* size */, i[1] /* rank */, i[2] /* ndims */, &i[3 + 0 * i[0]], &i[3 + 1 * i[0]], &i[3 + 2 * i[0]], &i[3 + 3 * i[0]], i[3 + 4 * i[0]], d[0], &datatype ); { const int* a_i[8] = {&i[0], &i[1], &i[2], &i[3 + 0 * i[0]], &i[3 + 1 * i[0]], &i[3 + 2 * i[0]], &i[3 + 3 * i[0]], &i[3 + 4 * i[0]]}; ompi_datatype_set_args( datatype, 4 * i[0] + 4,a_i, 0, NULL, 1, d, MPI_COMBINER_DARRAY); } break; /******************************************************************/ case MPI_COMBINER_F90_REAL: case MPI_COMBINER_F90_COMPLEX: /*pArgs->i[0] = i[0][0]; pArgs->i[1] = i[1][0]; */ break; /******************************************************************/ case MPI_COMBINER_F90_INTEGER: /*pArgs->i[0] = i[0][0];*/ break; /******************************************************************/ case MPI_COMBINER_RESIZED: ompi_datatype_create_resized(d[0], a[0], a[1], &datatype); ompi_datatype_set_args( datatype, 0, NULL, 2, a, 1, d, MPI_COMBINER_RESIZED ); break; /******************************************************************/ case MPI_COMBINER_HINDEXED_BLOCK: ompi_datatype_create_hindexed_block( i[0], i[1], a, d[0], &datatype ); { const int* a_i[2] = {&i[0], &i[1]}; ompi_datatype_set_args( datatype, 2 + i[0], a_i, i[0], a, 1, d, MPI_COMBINER_HINDEXED_BLOCK ); } break; /******************************************************************/ default: break; } return datatype; }
int32_t ompi_datatype_create_subarray(int ndims, int const* size_array, int const* subsize_array, int const* start_array, int order, const ompi_datatype_t* oldtype, ompi_datatype_t** newtype) { MPI_Datatype last_type; int32_t i, step, end_loop; MPI_Aint size, displ, extent; /** * If the oldtype contains the original MPI_LB and MPI_UB markers then we * are forced to follow the MPI standard suggestion and reset these 2 * markers (MPI 3.0 page 96 line 37). Otherwise we can simply resize the * datatype. */ ompi_datatype_type_extent( oldtype, &extent ); /* If the ndims is zero then return the NULL datatype */ if( ndims < 2 ) { if( 0 == ndims ) { *newtype = &ompi_mpi_datatype_null.dt; return MPI_SUCCESS; } ompi_datatype_create_contiguous( subsize_array[0], oldtype, &last_type ); size = size_array[0]; displ = start_array[0]; goto replace_subarray_type; } if( MPI_ORDER_C == order ) { i = ndims - 1; step = -1; end_loop = -1; } else { i = 0; step = 1; end_loop = ndims; } /* As we know that the ndims is at least 1 we can start by creating the * first dimension data outside the loop, such that we dont have to create * a duplicate of the oldtype just to be able to free it. */ ompi_datatype_create_vector( subsize_array[i+step], subsize_array[i], size_array[i], oldtype, newtype ); last_type = *newtype; size = (MPI_Aint)size_array[i] * (MPI_Aint)size_array[i+step]; displ = (MPI_Aint)start_array[i] + (MPI_Aint)start_array[i+step] * (MPI_Aint)size_array[i]; for( i += 2 * step; i != end_loop; i += step ) { ompi_datatype_create_hvector( subsize_array[i], 1, size * extent, last_type, newtype ); ompi_datatype_destroy( &last_type ); displ += size * start_array[i]; size *= size_array[i]; last_type = *newtype; } replace_subarray_type: /* * Resized will only set the soft lb and ub markers without moving the real * data inside. Thus, in case the original data contains the hard markers * (MPI_LB or MPI_UB) we must force the displacement of the data upward to * the right position AND set the hard markers LB and UB. * * NTH: ompi_datatype_create_resized() does not do enough for the general * pack/unpack functions to work correctly. Until this is fixed always use * ompi_datatype_create_struct(). Once this is fixed remove 1 || below. To * verify that the regression is fixed run the subarray test in the Open MPI * ibm testsuite. */ if(1 || oldtype->super.flags & (OPAL_DATATYPE_FLAG_USER_LB | OPAL_DATATYPE_FLAG_USER_UB) ) { MPI_Aint displs[3]; MPI_Datatype types[3]; int blength[3] = { 1, 1, 1 }; displs[0] = 0; displs[1] = displ * extent; displs[2] = size * extent; types[0] = MPI_LB; types[1] = last_type; types[2] = MPI_UB; ompi_datatype_create_struct( 3, blength, displs, types, newtype ); } else { ompi_datatype_create_resized(last_type, displ * extent, size * extent, newtype); } ompi_datatype_destroy( &last_type ); return OMPI_SUCCESS; }