Reputation: 337
Could anyone give me an example of mixing boost serialization with C MPI functions?
I guess I need to use boost::mpi::oarchive
. But how should I initialize the buffer parameter, and what should I pass to MPI_Send
after that?
More specifically, I am trying to do something like the following:
mpi::environment env;
mpi::communicator world;
typedef vector <int> ParticleList_t;
#define MSG_LEN 100000
ParticleList_t sendbuf(MSG_LEN, 1), recvbuf(MSG_LEN);
mpi::packed_oarchive::buffer_type buffer(sizeof(sendbuf[0])*sendbuf.size());
mpi::packed_oarchive oa(world, buffer, boost::archive::no_header);
oa & sendbuf;
if(world.rank()==0)
MPI_Send(oa, 1, MPI_PACKED, 1, 0, MPI_COMM_WORLD);
Do I have to make sure buffer is big enough or the oarchive
will handle the memory automatically? If the former, what is the correct memory size to hold a vector? I guess it should hold not just vec.data()
, but also vec.size()
.
And lastly, oa
does not appear to be the correct variable to pass to MPI_Send
. Then what should I pass to MPI_Send
after creating the archive?
I am asking because the boost mpi installation on our server appears to have a limitation on the message size.
Upvotes: 1
Views: 431
Reputation: 337
With help from the boost.MPI mailing list, I have put together the following example:
using namespace std;
#include <iostream>
#include <string>
#include <boost/mpi.hpp>
namespace mpi = boost::mpi;
int main(int argc, char **argv)
{
mpi::environment env;
mpi::communicator world;
#define MSG_LEN 100000
vector <int> sendbuf(MSG_LEN, 1), recvbuf(MSG_LEN);
MPI_Comm comm=world;
if(world.rank()==0)
{
mpi::packed_oarchive oa(comm);
oa << sendbuf;
auto sendptr = const_cast<void*>(oa.address());
// cast to int because MPI uses ints for sizes like it's still 1990
int sendsize = static_cast<int>(oa.size());
MPI_Send(&sendsize, 1, MPI_INT, 1, 0, comm);
MPI_Send(sendptr, sendsize, MPI_PACKED, 1, 0, comm);
}
else if (world.rank()==1)
{
mpi::packed_iarchive ia(comm);
int recvsize;
MPI_Recv(&recvsize, 1, MPI_INT, 0, 0, comm, MPI_STATUS_IGNORE);
ia.resize(recvsize);
auto recvptr = ia.address();
MPI_Recv(recvptr, recvsize, MPI_PACKED, 0, 0, comm, MPI_STATUS_IGNORE);
ia >> recvbuf;
cout<<"Data received: "<<recvbuf[0]<<","<<recvbuf[1]<<"...\n";
}
return 0;
}
Upvotes: 2