c - Trouble Understanding MPI_Type_create_struct -
i'm having trouble understanding mpi_type_create_struct method. have struct:
struct foo(){ float value; char rank; } and want send struct process. conside code sample below:
int count = 2; //number of elements in struct mpi_aint offsets[count] = {0, 8}; int blocklengths[count] = {1, 1}; mpi_datatype types[count] = {mpi_float, mpi_char}; mpi_datatype my_mpi_type; mpi_type_create_struct(count, blocklengths, offsets, types, &my_mpi_type); i'm not sure offsets , blocklengths in example. can explain these 2 parts above?
the purpose of mpi_type_create_struct() is, know, provide way create user's mpi_datatypes mapping structured types. these new types subsequently usable mpi communications , other calls default types, allowing example transfer arrays of structures same way transfer arrays of ints or floats.
now let's see function in more details.
here synopsis returned man command:
name mpi_type_create_struct - create mpi datatype general set of datatypes, displacements, , block sizes synopsis int mpi_type_create_struct(int count, const int array_of_blocklengths[], const mpi_aint array_of_displacements[], const mpi_datatype array_of_types[], mpi_datatype *newtype) input parameters count - number of blocks (integer) --- number of entries in arrays array_of_types, array_of_displacements , array_of_blocklengths array_of_blocklengths - number of elements in each block (array of integer) array_of_displacements - byte displacement of each block (array of address integer) array_of_types - type of elements in each block (array of handles datatype objects) output parameters newtype - new datatype (handle) let's see input parameters if meaning calls further explanation:
count: quite clear, , in case,2array_of_types: well, that'd{ mpi_float, mpi_char }examplearray_of_blocklengths: again, not say.{ 1, 1 }need herearray_of_displacements: 1 have bit more careful. corresponds memory address offsets start of structure, address of each element listed inarray_of_types. in case,{ &f.value - &f, &f.rank - &f },fbeing of typefoo. tricky part here that, because of potential alignment constraints, cannot sure equal{ 0, sizeof( float ) }(although here i'm pretty sure be). therefore, using addresses offsets shown makes method portable. (thx hristo iliev pointing me) can (and should) useoffsetof()macrostddef.hpointer arithmetic your, simplifying code{ offsetof( foo, value ), offsetof( foo, rank ) }looks nicer.
with arguments initialised way, call mpi_type_create_struct() return new mpi_datatype, suitable sending or receiving one foo @ time. reason new type doesn't take account actual extent of structure, including alignment constraints fields. , example perfect in regards since (very likely) hollow.
the reason floats have in general alignment constraint of 32b, while chars have none. therefore, starting address of second structure foo of array of theme not right @ end of first one. @ next 32b-aligned memory address. leave hole of 3 bytes between end of element of structure start of next in array.
to handle issue, you'll have resize type extending mpi_type_create_resized(), synopsis follow:
name mpi_type_create_resized - create datatype new lower bound , extent existing datatype synopsis int mpi_type_create_resized(mpi_datatype oldtype, mpi_aint lb, mpi_aint extent, mpi_datatype *newtype) input parameters oldtype - input datatype (handle) lb - new lower bound of datatype (address integer) extent - new extent of datatype (address integer) output parameters newtype - output datatype (handle) using quite easy both lb , extend can retrieved directly calling function meant purpose, namely mpi_type_get_extent() (but actually, directly use 0 , sizeof( foo )). in addition, since intermediary type used calling mpi_type_get_extent() , mpi_type_create_resized() isn't used in actual mpi communication, doesn't need committed mpi_type_commit(), sparing calls , time.
now, that, code becomes:
int count = 2; int array_of_blocklengths[] = { 1, 1 }; mpi_aint array_of_displacements[] = { offsetof( foo, value ), offsetof( foo, rank ) }; mpi_datatype array_of_types[] = { mpi_float, mpi_char }; mpi_datatype tmp_type, my_mpi_type; mpi_aint lb, extent; mpi_type_create_struct( count, array_of_blocklengths, array_of_displacements, array_of_types, &tmp_type ); mpi_type_get_extent( tmp_type, &lb, &extent ); mpi_type_create_resized( tmp_type, lb, extent, &my_mpi_type ); mpi_type_commit( &my_mpi_type );
Comments
Post a Comment