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, 2
  • array_of_types: well, that'd { mpi_float, mpi_char } example
  • array_of_blocklengths: again, not say. { 1, 1 } need here
  • array_of_displacements: 1 have bit more careful. corresponds memory address offsets start of structure, address of each element listed in array_of_types. in case, { &f.value - &f, &f.rank - &f }, f being of type foo. 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) use offsetof() macro stddef.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 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

Popular posts from this blog

c# - How Configure Devart dotConnect for SQLite Code First? -

java - Copying object fields -

c++ - Clear the memory after returning a vector in a function -