Discussion:
MPI_Type_struct
(too old to reply)
Nico
2010-01-08 09:14:12 UTC
Permalink
Hi,

I have an array of the following C structure :

typedef struct
{
int nb;
int nb2[100];
float nb3[340];
float fnb[2][2];
} MyType;


I would like to reduce to all processors some of the members of that
structure, namely 'nb' and 'fnb'.

is the following ok :


// first member to reduce

offsets[0] = 0;
MyTypeMembTypes[0] = MPI_INT;
blockcounts[0] = 1;


// second member to reduce

MPI_Type_extent(MPI_INT, &extent);
offsets[1] = 101 * extent;
MPI_Type_extent(MPI_FLOAT, &extent);
offsets[1] += 340 * extent;
MyTypeMembTypes[1] = MPI_FLOAT;
blockcounts[1] = 2*2;




MPI_Type_struct(2, blockcounts, offsets, MyTypeMembTypes, &MyTypeMPI);
MPI_Type_commit(&MyTypeMPI);


MPI_Op_create((MPI_User_function *)MyTypeSum, 1, &MyOp);


MPI_Allreduce(MPI_IN_PLACE, MyTypeObj, NELEM, MyTypeMPI, MyOp,
MPI_COMM_WORLD);





Thanks
Nico
Michael Hofmann
2010-01-08 16:01:51 UTC
Permalink
Post by Nico
Hi,
typedef struct
{
int nb;
int nb2[100];
float nb3[340];
float fnb[2][2];
} MyType;
I would like to reduce to all processors some of the members of that
structure, namely 'nb' and 'fnb'.
// first member to reduce
offsets[0] = 0;
MyTypeMembTypes[0] = MPI_INT;
blockcounts[0] = 1;
// second member to reduce
MPI_Type_extent(MPI_INT, &extent);
offsets[1] = 101 * extent;
MPI_Type_extent(MPI_FLOAT, &extent);
offsets[1] += 340 * extent;
MyTypeMembTypes[1] = MPI_FLOAT;
blockcounts[1] = 2*2;
This construction looks a bit odd (even though it might not be wrong). One
can use MPI_Get_address to easily determine the offsets of structure
members.

MyType my_type;
MPI_Aint base;

MPI_Get_address(&my_type, &base);
MPI_Get_address(&my_type.fnb, &offset[1]);
offset[1] -= base;

To be completely correct, you also have to take the extent of MyType into
account. Since the compiler can insert padding bytes at the end of the
structure, you have to tell MPI the exact size of the structure. You can
either add an MPI_UB marker or use MPI_Type_create_resized.

MyTypeMembTypes[2] = MPI_UB;
offsets[2] = sizeof(MyType);
blockcounts[2] = 1;

/* or */

...
MPI_Type_create_resized(&MyTypeMPI, 0, sizeof(MyType),
&ResizedMyTypeMPI);
MPI_Type_commit(&ResizedMyTypeMPI);
Post by Nico
MPI_Op_create((MPI_User_function *)MyTypeSum, 1, &MyOp);
MPI_Allreduce(MPI_IN_PLACE, MyTypeObj, NELEM, MyTypeMPI, MyOp,
MPI_COMM_WORLD);
Looks OK.


Michael

Loading...