You are almost right, except that indices should give the offset of each string field in bytes from the beginning of the structure. The correct way to build this type would be to use the offsetof operator defined in stddef.h :
#include <stddef.h> // or <cstddef> for C++ struct Residence { double x; double y; }; 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] = (MPI_Aint)offsetof(struct Residence, x); indices[1] = (MPI_Aint)offsetof(struct Residence, y); MPI_Datatype old_types[] = {MPI_DOUBLE,MPI_DOUBLE}; MPI_Type_struct(count,blocklens,indices,old_types,&new_type); MPI_Type_commit(&new_type); return new_type; }
While this was enough for this particular structure, it is generally necessary to adjust the length of the structured type to allow for any final addition that the compiler could insert at the end of the structure. This is only necessary if you want to send several elements of this structured type, i.e. Array of structure elements. The old way to do this is to add a third element to the structure of type MPI_UB (UB comes from the Upper Bound) and set the offset of this member to sizeof(struct Residence) (filling is taken into account in the size of the structure as sizeof returns). The modern way is to use MPI_Type_create_resized , which creates a new MPI type with the same type signature as the original, but with different degrees:
MPI_Type_struct(count,blocklens,indices,old_types,&new_type); // Create a resized type MPI_Type resized_new_type; MPI_Type_create_resized(new_type, // lower bound == min(indices) == indices[0] indices[0], (MPI_Aint)sizeof(struct Residence), &resized_new_type); MPI_Type_commit(&resized_new_type); // Free new_type as it is no longer needed MPI_Type_free(&new_type); return resized_new_type;
Only the relevant lines of code are displayed. The code above assumes that indices[0] gives the offset of the first element of the structure. Instead, you can use MPI_Type_get_extent to get the true bottom border, and this will work for structure types with negative offsets. It is not necessary to make new_type , as it is used only to create a modified type. There is also no need to store it and release it after resized_new_type .
source share