@@ -64,6 +64,8 @@ class MPIReceiver : public edm::stream::EDProducer<edm::ExternalWork> {
6464
6565 products_.emplace_back (std::move (entry));
6666 }
67+
68+ received_wrappers_.resize (products_.size ());
6769 }
6870
6971 void acquire (edm::Event const & event, edm::EventSetup const &, edm::WaitingTaskWithArenaHolder holder) final {
@@ -75,17 +77,87 @@ class MPIReceiver : public edm::stream::EDProducer<edm::ExternalWork> {
7577 edm::Service<edm::Async> as;
7678 as->runAsync (
7779 std::move (holder),
78- [this , token]() { token.channel ()->receiveMetadata (instance_, received_meta_); },
80+ [this , token]() {
81+ token.channel ()->receiveMetadata (instance_, received_meta_);
82+ #ifdef EDM_ML_DEBUG
83+ // dump the summary of metadata
84+ received_meta_->debugPrintMetadataSummary ();
85+ #endif
86+
87+ // if filter was false before the sender, receive nothing
88+ if (received_meta_->productCount () == -1 ) {
89+ return ;
90+ }
91+
92+ std::unique_ptr<TBufferFile> serialized_buffer;
93+ if (received_meta_->hasSerialized ()) {
94+ serialized_buffer =
95+ token.channel ()->receiveSerializedBuffer (instance_, received_meta_->serializedBufferSize ());
96+ #ifdef EDM_ML_DEBUG
97+ {
98+ edm::LogSystem msg (" MPIReceiver" );
99+ msg << " Received serialised product:\n " ;
100+ for (int i = 0 ; i < received_meta_->serializedBufferSize (); ++i) {
101+ msg << " 0x" << std::hex << std::setw (2 ) << std::setfill (' 0' )
102+ << (unsigned int )(unsigned char )serialized_buffer->Buffer ()[i] << (i % 16 == 15 ? ' \n ' : ' ' );
103+ }
104+ }
105+ #endif
106+ }
107+
108+ for (size_t i = 0 ; i < products_.size (); ++i) {
109+ auto product_meta = received_meta_->getNext ();
110+ if (product_meta.kind == ProductMetadata::Kind::Missing) {
111+ continue ;
112+ }
113+
114+ auto const & entry = products_[i];
115+
116+ if (product_meta.kind == ProductMetadata::Kind::Serialized) {
117+ std::unique_ptr<edm::WrapperBase> wrapper (
118+ reinterpret_cast <edm::WrapperBase*>(entry.wrappedType .getClass ()->New ()));
119+ assert (static_cast <int32_t >(serialized_buffer->Length () + product_meta.sizeMeta ) <=
120+ received_meta_->serializedBufferSize () &&
121+ " serialized data buffer is shorter than expected" );
122+ entry.wrappedType .getClass ()->Streamer (wrapper.get (), *serialized_buffer);
123+ received_wrappers_[i] = std::move (wrapper);
124+ }
125+
126+ else if (product_meta.kind == ProductMetadata::Kind::TrivialCopy) {
127+ if (not enableTrivialSerialisation_) {
128+ edm::LogError (" MPIReceiver" )
129+ << " Received a trivially-serialised product, but enableTrivialSerialisation is set to false in "
130+ " this MPIReceiver. Please check that the MPISender and MPIReceiver have consistent settings." ;
131+ MPI_Abort (MPI_COMM_WORLD , EXIT_FAILURE );
132+ }
133+ std::unique_ptr<ngt::SerialiserBase> serialiser =
134+ ngt::SerialiserFactory::get ()->tryToCreate (entry.type .typeInfo ().name ());
135+ if (not serialiser) {
136+ throw cms::Exception (" SerializerError" )
137+ << " Receiver could not retrieve its serializer when it was expected" ;
138+ }
139+ auto writer = serialiser->writer ();
140+ ngt::AnyBuffer buffer = writer->uninitialized_parameters (); // constructs buffer with typeid
141+ assert (buffer.size_bytes () == product_meta.sizeMeta );
142+ std::memcpy (buffer.data (), product_meta.trivialCopyOffset , product_meta.sizeMeta );
143+ writer->initialize (buffer);
144+ token.channel ()->receiveInitializedTrivialCopy (instance_, *writer);
145+ writer->finalize ();
146+ received_wrappers_[i] = writer->get ();
147+ }
148+ }
149+
150+ if (received_meta_->hasSerialized ()) {
151+ assert (serialized_buffer->Length () == received_meta_->serializedBufferSize () &&
152+ " serialized data buffer is not equal to the expected length" );
153+ }
154+ },
79155 []() { return " Calling MPIReceiver::acquire()" ; });
80156 }
81157
82158 void produce (edm::Event& event, edm::EventSetup const &) final {
83159 // read the MPIToken used to establish the communication channel
84160 MPIToken token = event.get (upstream_);
85- #ifdef EDM_ML_DEBUG
86- // dump the summary of metadata
87- received_meta_->debugPrintMetadataSummary ();
88- #endif
89161
90162 // if filter was false before the sender, receive nothing
91163 if (received_meta_->productCount () == -1 ) {
@@ -96,68 +168,14 @@ class MPIReceiver : public edm::stream::EDProducer<edm::ExternalWork> {
96168 event.emplace (pathStateToken_);
97169 }
98170
99- std::unique_ptr<TBufferFile> serialized_buffer;
100- if (received_meta_->hasSerialized ()) {
101- serialized_buffer = token.channel ()->receiveSerializedBuffer (instance_, received_meta_->serializedBufferSize ());
102- #ifdef EDM_ML_DEBUG
103- {
104- edm::LogSystem msg (" MPISender" );
105- msg << " Received serialised product:\n " ;
106- for (int i = 0 ; i < received_meta_->serializedBufferSize (); ++i) {
107- msg << " 0x" << std::hex << std::setw (2 ) << std::setfill (' 0' )
108- << (unsigned int )(unsigned char )serialized_buffer->Buffer ()[i] << (i % 16 == 15 ? ' \n ' : ' ' );
109- }
110- }
111- #endif
112- }
113-
114- for (auto const & entry : products_) {
115- auto product_meta = received_meta_->getNext ();
116- if (product_meta.kind == ProductMetadata::Kind::Missing) {
117- edm::LogWarning (" MPIReceiver" ) << " Product " << entry.type .name () << " was not received." ;
118- continue ; // Skip products that weren't sent
119- }
120-
121- else if (product_meta.kind == ProductMetadata::Kind::Serialized) {
122- std::unique_ptr<edm::WrapperBase> wrapper (
123- reinterpret_cast <edm::WrapperBase*>(entry.wrappedType .getClass ()->New ()));
124- assert (static_cast <int32_t >(serialized_buffer->Length () + product_meta.sizeMeta ) <=
125- received_meta_->serializedBufferSize () &&
126- " serialized data buffer is shorter than expected" );
127- entry.wrappedType .getClass ()->Streamer (wrapper.get (), *serialized_buffer);
128- // put the data into the Event
129- event.put (entry.token , std::move (wrapper));
130- }
131-
132- else if (product_meta.kind == ProductMetadata::Kind::TrivialCopy) {
133- if (not enableTrivialSerialisation_) {
134- edm::LogError (" MPIReceiver" )
135- << " Received a trivially-serialised product, but enableTrivialSerialisation is set to false in this "
136- " MPIReceiver. Please check that the MPISender and MPIReceiver have consistent settings." ;
137- MPI_Abort (MPI_COMM_WORLD , EXIT_FAILURE );
138- }
139- std::unique_ptr<ngt::SerialiserBase> serialiser =
140- ngt::SerialiserFactory::get ()->tryToCreate (entry.type .typeInfo ().name ());
141- if (not serialiser) {
142- throw cms::Exception (" SerializerError" ) << " Receiver could not retrieve its serializer when it was expected" ;
143- }
144- auto writer = serialiser->writer ();
145- ngt::AnyBuffer buffer = writer->uninitialized_parameters (); // constructs buffer with typeid
146- assert (buffer.size_bytes () == product_meta.sizeMeta );
147- std::memcpy (buffer.data (), product_meta.trivialCopyOffset , product_meta.sizeMeta );
148- writer->initialize (buffer);
149- token.channel ()->receiveInitializedTrivialCopy (instance_, *writer);
150- writer->finalize ();
151- // put the data into the Event
152- event.put (entry.token , writer->get ());
171+ for (size_t i = 0 ; i < products_.size (); ++i) {
172+ if (received_wrappers_[i]) {
173+ event.put (products_[i].token , std::move (received_wrappers_[i]));
174+ } else {
175+ edm::LogWarning (" MPIReceiver" ) << " Product " << products_[i].type .name () << " was not received." ;
153176 }
154177 }
155178
156- if (received_meta_->hasSerialized ()) {
157- assert (serialized_buffer->Length () == received_meta_->serializedBufferSize () &&
158- " serialized data buffer is not equal to the expected length" );
159- }
160-
161179 // write a shallow copy of the channel to the output, so other modules can consume it
162180 // to indicate that they should run after this
163181 event.emplace (token_, token);
@@ -207,6 +225,7 @@ class MPIReceiver : public edm::stream::EDProducer<edm::ExternalWork> {
207225 bool activity_; // indicator whether the PathStateToken will be received by the module
208226 edm::EDPutTokenT<edm::PathStateToken> pathStateToken_;
209227 std::shared_ptr<ProductMetadataBuilder> received_meta_;
228+ std::vector<std::unique_ptr<edm::WrapperBase>> received_wrappers_;
210229 bool enableTrivialSerialisation_ = true ;
211230};
212231
0 commit comments