There is a dynamically allocated struct:
TYPE Struct
INTEGER :: N
REAL*8 :: A
REAL*8,ALLOCATABLE :: B(:)
END TYPE Struct
and it has a dynamically allocated memeber : B(:)
When I try to use MPI_TYPE_CREATE_STRUCT to create a derived datatype for such Struct, it happens that differen CPUs create inconsistent derived datatypes. This is because Struct%B(:) might be located in different memory locations relative to the first memeber Struct%N, on different CPUs.
Then MPI_SEND( Struct,...) won't succeed...
So, how could such problem be solved if I really want to send this Struct using MPI derived datatype?
Or such kind of derived datatype is forbidden?
To send one element of that struct, simply proceed as usual by creating a structured datatype using
MPI_TYPE_CREATE_STRUCT
. Depending on how the heap and the stack of the program are located in respect to each other, the offset ofB(1)
relative toN
could end up being a a huge positive or negative number, but that is of no issue on most Unix platforms and the number should fit in the range ofINTEGER(KIND=MPI_ADDRESS_KIND)
.Important: Separate instances of the structure will most likely have different offsets of
B
relative toN
, therefore the MPI datatype can only be used for sending the specific record that was used for obtaining the offsets during the construction of the datatype.This is a non-issue. The MPI datatypes on both sides of the communication operation must only be congruent, which means that they should consist of the same basic datatypes in the same sequence. The offset of each element is irrelevant. In other words, as long as both the sender and the receiver specify the same types and number of data elements in the
MPI_TYPE_CREATE_STRUCT
call, the program will function correctly.To send more than one element, things get a bit complicated. There are two solutions:
Use
MPI_PACK
to serialise the data on the sender side andMPI_UNPACK
to deserialise it on the receiver side. As packing and unpacking require additional buffer space, this doubles the memory requirements of the program.or
Create a separate MPI structure datatype for each record and then create a structure datatype that combines all records. Here is an example of how to send an array of two such structures, one with 10 elements in
B
and one with 20:Note that though constructing MPI datatypes is a relatively cheap operation, you should not use the procedure described above to send e.g. 1000000 instances of the structured type. Also, MPI datatype descriptors live in memory managed by the library and the timely deallocation of datatypes that are no longer needed is important.