How to pass user-defined structures using boost mpi

I am trying to send a user-defined structure called ABC using the boost :: mpi :: send () call.

This structure contains vector "data" whose size is determined at runtime. Struct ABC objects are sent by the master to the subordinates. But the slaves must know the size of the vector "data" so that a sufficient buffer is available on the slave server to receive this data. I can get around it by first sending the size and initializing a sufficient buffer on the slave before receiving struct ABC objects. But this is detrimental to the entire purpose of using STL containers.

Does anyone know how best to deal with this? Any suggestions are welcome.

Here is a sample code that describes the intent of my program. This code fails due to the above reason.

struct ABC { double cur_stock_price; double strike_price; double risk_free_rate; double option_price; std::vector <char> data; }; namespace boost { namespace serialization { template<class Archive> void serialize (Archive &ar, struct ABC &abc, unsigned int version) { ar & abc.cur_stock_price; ar & abc.strike_price; ar & abc.risk_free_rate; ar & abc.option_price; ar & bopr.data; } } } BOOST_IS_MPI_DATATYPE (ABC); int main(int argc, char* argv[]) { mpi::environment env (argc, argv); mpi::communicator world; if (world.rank () == 0) { ABC abc_obj; abc.cur_stock_price = 1.0; abc.strike_price = 5.0; abc.risk_free_rate = 2.5; abc.option_price = 3.0; abc_obj.data.push_back ('a'); abc_obj.data.push_back ('b'); world.send ( 1, ANY_TAG, abc_obj;); std::cout << "Rank 0 OK!" << std::endl; } else if (world.rank () == 1) { ABC abc_obj; // Fails here because abc_obj is not big enough world.recv (0,ANY_TAG, abc_obj;); std::cout << "Rank 1 OK!" << std::endl; for (int i = 0; i < abc_obj;.data.size(); i++) std::cout << i << "=" << abc_obj.data[i] << std::endl; } MPI_Finalize(); return 0; } 
+4
source share
2 answers

You should not send the vector object itself to the message, since the recipient only needs its contents, and the internal state of vector will probably be corrupted after receiving it anyway (memory addresses that were valid on the sending end will probably not be valid on host party).

Instead, here is what you need to do:

  • Define a separate structure with four doubles and a simple char array.
  • Whenever you need to send, create a temporary variable for this new structure and fill the char array with the contents of the vector you want to send.
  • Define a temporary MPI data type that matches the size of this particular structure object.
  • Send the temporary structure as an instance of this temporary data type.
  • Receive it in a sufficiently large receive buffer (or send the size in advance)
  • Restore the ABC structure based on the contents of the char array.

At the very least, this is what you need to do with vanilla C ++ and MPI. I am not familiar with the promotion, so I do not know if this makes any of these steps easier.

+3
source

BOOST_IS_MPI_DATATYPE is for fixed-length data only. Your array is not a fixed length, and therefore it fails.

0
source

Source: https://habr.com/ru/post/1307577/


All Articles