Kambrian
Kambrian

Reputation: 337

using boost serialization with C MPI functions

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

Answers (1)

Kambrian
Kambrian

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

Related Questions