I am new to MPI and I want to create a new datatype for Residence
struct
. I just want to see if I can create the new type right way.
struct Residence
{
double x;
double y;
};
My new MPI Type
MPI_Datatype createRecType()
{
// Set-up the arguments for the type constructor
MPI_Datatype new_type;
int count = 2;
int blocklens[] = { 1,1 };
MPI_Aint indices[2];
//indices[0]=0;
MPI_Type_extent( MPI_DOUBLE, &indices[0] );
MPI_Type_extent( MPI_DOUBLE, &indices[1] );
MPI_Datatype old_types[] = {MPI_DOUBLE,MPI_DOUBLE};
MPI_Type_struct(count,blocklens,indices,old_types,&new_type);
MPI_Type_commit(&new_type);
}
You've almost got it right except that
indices
is supposed to give the offset of each structure field in bytes from the beginning of the structure. The correct way to construct such a type would be to use theoffsetof
operator, defined instddef.h
:While this would suffice for that particular structure, in general one has to adjust the structured type length in order to account for any trailing padding that the compiler might insert at the end of the structure. This is only necessary if one wants to send multiple items of that structured type, i.e. an array of structure elements. The old way to do that was to add a third member to the structure of type
MPI_UB
(UB comes from Upper Bound) and set the offset of that member to be equal tosizeof(struct Residence)
(padding is accounted in the structure size as returned bysizeof
). The modern way is to useMPI_Type_create_resized
, which creates a new MPI type with the same type signature as the original one but with a different extent:Only the relevant code lines are shown. The code above assumes that
indices[0]
gives the offset of the first structure element. One could instead useMPI_Type_get_extent
to get the true lower bound and that would work for structure types with negative offsets. It is not necessary to commitnew_type
as it is only used to construct the resized type. It is also not necessary to keep it around and that's why it is freed afterresized_new_type
has been created.