@@ -192,4 +192,63 @@ void MPIChannel::receiveTrivialProduct_(int instance, edm::ObjectWithDict& produ
192192 MPI_Get_count (&status, MPI_BYTE, &size);
193193 assert (static_cast <int >(product.typeOf ().size ()) == size);
194194 MPI_Mrecv (product.address (), size, MPI_BYTE, &message, MPI_STATUS_IGNORE);
195- }
195+ }
196+
197+ // transfer a wrapped object using its TrivialCopyTraits
198+ void MPIChannel::sendTrivialCopyProduct_ (int instance, edm::WrapperBase const * wrapper) {
199+ int tag = EDM_MPI_SendTrivialCopyProduct | instance * EDM_MPI_MessageTagWidth_;
200+
201+ // if the wrapped type requires it, send the properties required toinitialise the remote copy
202+ if (wrapper->hasTrivialCopyProperties ()) {
203+ edm::AnyBuffer buffer = wrapper->trivialCopyParameters ();
204+ MPI_Send (buffer.data (), buffer.size_bytes (), MPI_BYTE, dest_, tag, comm_);
205+ }
206+
207+ // transfer the memory regions
208+ auto regions = wrapper->trivialCopyRegions ();
209+ // TODO send the number of regions ?
210+ for (size_t i = 0 ; i < regions.size (); ++i) {
211+ assert (regions[i].data () != nullptr );
212+ MPI_Send (regions[i].data (), regions[i].size_bytes (), MPI_BYTE, dest_, tag, comm_);
213+ }
214+ }
215+
216+ // receive a wrapped object using its TrivialCopyTraits
217+ void MPIChannel::receiveTrivialCopyProduct_ (int instance, edm::WrapperBase* wrapper) {
218+ int tag = EDM_MPI_SendTrivialCopyProduct | instance * EDM_MPI_MessageTagWidth_;
219+
220+ MPI_Message message;
221+ MPI_Status status;
222+ int size;
223+
224+ // mark the wrapped object as present
225+ wrapper->markAsPresent ();
226+
227+ // if the wrapped type requires it, send the properties required toinitialise the remote copy
228+ if (wrapper->hasTrivialCopyProperties ()) {
229+ edm::AnyBuffer buffer = wrapper->trivialCopyParameters ();
230+ MPI_Mprobe (dest_, tag, comm_, &message, &status);
231+ // check that the message size matches the expected buffer size
232+ MPI_Get_count (&status, MPI_BYTE, &size);
233+ assert (static_cast <int >(buffer.size_bytes ()) == size);
234+ // receive the properties
235+ MPI_Mrecv (buffer.data (), buffer.size_bytes (), MPI_BYTE, &message, &status);
236+ wrapper->trivialCopyInitialize (buffer);
237+ }
238+
239+ // receive the memory regions
240+ auto regions = wrapper->trivialCopyRegions ();
241+ // TODO receive and validate the number of regions ?
242+ for (size_t i = 0 ; i < regions.size (); ++i) {
243+ assert (regions[i].data () != nullptr );
244+ MPI_Mprobe (dest_, tag, comm_, &message, &status);
245+ // check that the message size matches the expected region size
246+ MPI_Get_count (&status, MPI_BYTE, &size);
247+ assert (static_cast <int >(regions[i].size_bytes ()) == size);
248+ // receive the data region
249+ MPI_Mrecv (regions[i].data (), regions[i].size_bytes (), MPI_BYTE, &message, &status);
250+ }
251+
252+ // finalize the clone after the trivialCopy, if the type requires it
253+ wrapper->trivialCopyFinalize ();
254+ }
0 commit comments