How can I transmit instances of my class or a std::vector using MPI_Send() or MPI_Bcast() in C++?
-
have you tried anything?Sleepyhead– Sleepyhead2014-05-05 20:47:29 +00:00Commented May 5, 2014 at 20:47
-
LMGTFY stackoverflow.com/questions/18746553/…Sleepyhead– Sleepyhead2014-05-05 20:48:41 +00:00Commented May 5, 2014 at 20:48
4 Answers
You cannot simply transmit instances of random classes since being C calls neither MPI_Send() nor MPI_Bcast() understand the structure of those classes. You can send instances of std::vector (since it uses contiguous memory storage) by providing &vector[0] to MPI_Send() but the receive operation should then be implemented in several steps: MPI_Probe() -> get the number of elements in the message -> resize the vector instance -> MPI_Recv() into the resized instance. For all other cases, you should use something like Boost.MPI or you should use MPI_Pack() and MPI_Unpack() to serialise and deserialise your class instances to and from MPI messages.
Comments
MPI doesn't operate on objects, it operates on memory locations. So to send an object from your own class, you will need to know the memory layout from your class. You can then use this to build an MPI datatype. There is an entire chapter of the MPI specification (chapter 4) devoted to how to do this. The basic premise is that you build a datatype based on the standard MPI types, arranged in a specified memory layout. Once this type is built and committed, you can then use it in MPI operations.
Comments
Ok, I've already found a solution:
http://www.mpi-forum.org/docs/mpi-2.2/mpi22-report/node83.htm#Node83
in 5th Example
Comments
You could try sending it as a byte array like this:
MPI_Send(vec.data(), vec.size() * sizeof(VectorElement), MPI_CHAR, 0, 0, MPI_COMM_WORLD);
And recieve it like this:
MPI_Recv(&vec.front(), vec.size() * sizeof(VectorElement), MPI_CHAR, 0, MPI_ANY_TAG, MPI_COMM_WORLD, &status);
Where vec is an instanse of std::vector<VectorElement>
If you think that the receiving vector size could change, you can simply send it before the vector.
I can't guarantee that this method is safe but i believe it should be since both padding and the order of fields of a certain class should be the same on every subprocess.
3 Comments
C struct (though not as elegant as using derived datatypes) that do not contain pointers, but generally do not work with C++ classes. better use a higher level library such as Boost::MPI that automagically (de)serialize C++ objects.std::vector<int> (use different vector sizes to make it fun)?