2

I have a structure of type:

typedef struct{
    double x;
    double y;
    double z;
}bodyType;

and I want to use allgatherv to exchange only the the x and y members of the structure. Is this possible using the MPI_Type_vector or it doesn't apply for structures?

I tried the following:

MPI_Datatype MPI_Position_type;
MPI_Datatype pos_types= {MPI_DOUBLE,MPI_DOUBLE};
int blocklen[2] = {1,1};
MPI_Aint dis[2];
size_t offset_x_1 = offsetof(bodyType,x);
size_t offset_y_1 = offsetof(bodyType,y);

dis[0] = offset_x_1;
dis[1] = offset_y_1;

MPI_Type_create_struct(2,blocklen,dis,&pos_types,&MPI_Position_type);
MPI_Type_commit(&MPI_Position_type);
...
MPI_Allgatherv(MPI_IN_PLACE,0,MPI_Position_type,bodies,counts,displacements,MPI_Position_type,MPI_COMM_WORLD);

but I get a SEGFAULT.

Actually, I cannot see how AllgatherV will use counts and displacements in this case. My intention is to exchange only some members of the struct in order to reduce the communication overhead.

NickSar68
  • 55
  • 5
  • Do you have a vector of structs? Then create a strider vector type. Also look up AoS-to-SoA transformation to see if you really want to use structs like this. – Jeff Hammond Dec 14 '15 at 21:08
  • Yes, it is possible. But it is better done using the structure type constructor `MPI_Type_create_struct` since structure members are in general subject to alignment and padding. – Hristo Iliev Dec 14 '15 at 21:24

1 Answers1

0

Your code is almost right. What's missing is the resizing of your struct, to align the full extend of your MPI type with the one of your structure. This can be achieved using the MPI_Type_create_resized() function the following way:

MPI_Datatype myHollowStruct;
MPI_Type_create_resized( MPI_Position_type, 0, sizeof( bodyType ), &myHollowStruct );
MPI_Type_commit( &myHollowStruct );
MPI_Type_free( &MPI_Position_type );

Now, myHollowStruct should represent exactly what you wanted, namely a mask on your bodytype struct tacking only the x and y fields, but avoiding z while keeping the correct extend to correctly align with an array of these structures.

If from there you still experience segfaults, then that would be for another reason, possibly some mistake in calling MPI_Allgatherv().

NB: Naming your own MPI_Datatype MPI_Position_type is a bad idea since the use of MPI_ or PMPI_ as prefixes is by standard reserved for the MPI library (API and internals), and therefore prohibited for users.

Gilles
  • 9,269
  • 4
  • 34
  • 53
  • Thank you Gilles... Do you think that MPI_IN_PLACE would cause a problem? – NickSar68 Dec 15 '15 at 10:48
  • If the other parameters are right, there's no reason why `MPI_IN_PLACE` would cause a problem. – Gilles Dec 15 '15 at 11:07
  • Yeah I had a typo in definition of pos_types instead of pos_types[2] array. Is there a way to set displacements dynamically, so as in consequent calls different members of the structure are chosed ? – NickSar68 Dec 15 '15 at 12:42
  • No, you can't have a dynamic type. However, you can create several types corresponding to all the ones you could want to use, select dynamically the actual one you need and use a pointer to it in the communication call. – Gilles Dec 15 '15 at 13:13