0
votes

I am writing an object-oriented program that has abstract structs. Each struct has member variables depending on the inheritor's implementation.

struct abstract
{};

struct concrete: abstract
{
    int data[5][10];
};

struct concrete2: abstract
{
    int data[20];
    std::string s;
};

I need a way to serialize and send these structs between MPI processes using MPI_Send.

Is there a way to programmatically define MPI_Datatypes for each individual struct implementation? Ideally, I can use a function to define a type regardless of what is inside the struct. Is something like this possible?

MPI_Datatype myType;
concrete2 myStruct;
figureOutMPIType(&myStruct, &myType);

MPI_Send(&myStruct, 1, myType, 1, 0, MCW);
1
You definitely can't do it for std::string. For struct of primitive types, see MPI_Type_create_struct.Evg
you might want to consider C++-ish abstractions such as Boost.MPI or ElementalsGilles Gouaillardet

1 Answers

0
votes

When the data was sent, a pointer to that data was sent. We want to send a pointer to indicate which data is to be sent, but as the data can be discontinuous and/or of different types, we need to create a list of the data types and sizes to be sent together with the offset of that data’s memory location from the pointer.

To do this, you need to do these steps:

  • Building a temporary object of the data we are trying to make the MPI datatype for.

  • Then store information about the individual variables that will make up the MPI datatype

  • Then get the pointer to that variable (stored in an MPI friendly format)

  • This data have been gathered for all the member variables that wish to send using this MPI datatype we can calculate the offsets in the memory location:

    Obtain the memory location of the beginning of the object MPI_Get_address (&temp, add_start);

    Then subtract this from all the addresses to get their offsets

    offsets[i] = addresses[i];
    add_start;
    
  • Once we have all this information we can use it to create the structure for the MPI_datatype

MPI_Type_create_struct (4, block_lengths , offsets, typelist , & my_class MPI_type);
  • Once the structure for the datatype has been created it must be committed before it can be used in any communications (Send and recv)
MPI_Type_commit (&my_class::MPI_type);
  • You can send them using this MPI datatype like we would any other MPI variable E.g.
MPI_Bcast (&data, 1, my_class::MPI_type , 0, MPI_COMM_WORLD);

or

MPI_Send (&data, 1, my_class::MPI_type , i, tag_num , MPI_COMM_WORLD);
  • You need to free types once they are no longer needed
MPI_Type_free(&my _class::MPI_type);