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_datatype
s 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 int
s or float
s.
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,2
array_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 }
,f
being 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.h
pointer 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 float
s have in general alignment constraint of 32b, while char
s 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