36 #ifndef _OBJECTCOMMUNICATOR_HPP_
37 #define _OBJECTCOMMUNICATOR_HPP_
40 #include <boost/archive/binary_oarchive.hpp>
41 #include <boost/archive/binary_iarchive.hpp>
43 #include <boost/scoped_array.hpp>
44 #include <boost/shared_ptr.hpp>
45 #include <boost/serialization/shared_ptr.hpp>
49 const unsigned MAX_BUFFER_SIZE = 1000000;
56 template<
typename CLASS>
100 void SendObject(boost::shared_ptr<CLASS>
const pObject,
unsigned destinationProcess,
unsigned tag);
109 void ISendObject(boost::shared_ptr<CLASS>
const pObject,
unsigned destinationProcess,
unsigned tag);
120 boost::shared_ptr<CLASS>
RecvObject(
unsigned sourceProcess,
unsigned tag, MPI_Status& status);
128 void IRecvObject(
unsigned sourceProcess,
unsigned tag);
149 boost::shared_ptr<CLASS>
SendRecvObject(boost::shared_ptr<CLASS>
const pSendObject,
unsigned destinationProcess,
unsigned sendTag,
unsigned sourceProcess,
unsigned sourceTag, MPI_Status& status);
157 template<
typename CLASS>
165 template<
typename CLASS>
169 std::ostringstream ss(std::ios::binary);
170 boost::archive::binary_oarchive output_arch(ss);
172 output_arch << pObject;
174 const std::string send_msg = ss.str();
177 unsigned string_length = send_msg.size();
182 char* send_buf =
const_cast<char*
>(send_msg.data());
186 template<
typename CLASS>
192 std::ostringstream ss(std::ios::binary);
193 boost::archive::binary_oarchive output_arch(ss);
195 output_arch << pObject;
197 mSendString[destinationProcess] = ss.str();
198 mSendBufferLength = mSendString[destinationProcess].size();
201 assert(mSendBufferLength < MAX_BUFFER_SIZE);
205 mSendBuffer[destinationProcess] =
const_cast<char*
>(mSendString[destinationProcess].data());
206 MPI_Isend(mSendBuffer[destinationProcess], mSendBufferLength, MPI_BYTE, destinationProcess, tag,
PetscTools::GetWorld(), &request);
207 MPI_Request_free(&request);
210 template<
typename CLASS>
213 unsigned string_length = 0;
216 char* recv_array =
new char[string_length];
217 MPI_Recv(recv_array, string_length, MPI_BYTE, sourceProcess , tag,
PetscTools::GetWorld(), &status);
220 std::string recv_string(recv_array, string_length);
222 std::istringstream ss(recv_string, std::ios::binary);
224 boost::shared_ptr<CLASS> p_recv_object(
new CLASS);
225 boost::archive::binary_iarchive input_arch(ss);
227 input_arch >> p_recv_object;
229 return p_recv_object;
232 template<
typename CLASS>
239 mRecvBuffer =
new char[MAX_BUFFER_SIZE];
240 MPI_Irecv(mRecvBuffer, MAX_BUFFER_SIZE, MPI_BYTE, sourceProcess, tag,
PetscTools::GetWorld(), &mMpiRequest);
243 template<
typename CLASS>
248 EXCEPTION(
"No object to receive in ObjectCommunicator::GetRecvObject");
251 MPI_Status return_status;
253 MPI_Wait(&mMpiRequest, &return_status);
256 MPI_Get_count(&return_status, MPI_BYTE, &recv_size);
259 std::string recv_string(mRecvBuffer, recv_size);
260 std::istringstream ss(recv_string, std::ios::binary);
262 boost::shared_ptr<CLASS> p_recv_object(
new CLASS);
263 boost::archive::binary_iarchive input_arch(ss);
265 input_arch >> p_recv_object;
268 delete[] mRecvBuffer;
272 return p_recv_object;
275 template<
typename CLASS>
276 boost::shared_ptr<CLASS>
ObjectCommunicator<CLASS>::SendRecvObject(boost::shared_ptr<CLASS>
const pSendObject,
unsigned destinationProcess,
unsigned sendTag,
unsigned sourceProcess,
unsigned sourceTag, MPI_Status& status)
279 std::ostringstream oss(std::ios::binary);
280 boost::archive::binary_oarchive output_arch(oss);
282 output_arch << pSendObject;
284 std::string send_msg = oss.str();
287 unsigned send_string_length = send_msg.size();
288 unsigned recv_string_length;
290 MPI_Sendrecv(&send_string_length, 1, MPI_UNSIGNED, destinationProcess, sendTag, &recv_string_length, 1, MPI_UNSIGNED, sourceProcess, sourceTag,
PetscTools::GetWorld(), &status);
292 boost::scoped_array<char> recv_array(
new char[recv_string_length]);
295 char* send_buf =
const_cast<char*
>(send_msg.data());
296 MPI_Sendrecv(send_buf, send_string_length, MPI_BYTE, destinationProcess, sendTag, recv_array.get(), recv_string_length, MPI_BYTE, sourceProcess, sourceTag,
PetscTools::GetWorld(), &status);
299 std::string recv_string(recv_array.get(), recv_string_length);
300 std::istringstream iss(recv_string, std::ios::binary);
302 boost::shared_ptr<CLASS> p_recv_object(
new CLASS);
303 boost::archive::binary_iarchive input_arch(iss);
305 input_arch >> p_recv_object;
307 return p_recv_object;
310 #endif // _OBJECTCOMMUNICATOR_HPP_
unsigned mSendBufferLength
boost::shared_ptr< CLASS > SendRecvObject(boost::shared_ptr< CLASS > const pSendObject, unsigned destinationProcess, unsigned sendTag, unsigned sourceProcess, unsigned sourceTag, MPI_Status &status)
#define EXCEPTION(message)
void IRecvObject(unsigned sourceProcess, unsigned tag)
std::vector< std::string > mSendString
void SendObject(boost::shared_ptr< CLASS > const pObject, unsigned destinationProcess, unsigned tag)
unsigned mRecvBufferLength
boost::shared_ptr< CLASS > GetRecvObject()
std::vector< char * > mSendBuffer
void ISendObject(boost::shared_ptr< CLASS > const pObject, unsigned destinationProcess, unsigned tag)
boost::shared_ptr< CLASS > RecvObject(unsigned sourceProcess, unsigned tag, MPI_Status &status)