CMS 3D CMS Logo

List of all members | Public Member Functions | Private Member Functions | Private Attributes
ALPAKA_ACCELERATOR_NAMESPACE::EDMetadata Class Reference

#include <EDMetadata.h>

Public Member Functions

Device device () const
 
 EDMetadata (std::shared_ptr< Queue > queue, std::shared_ptr< Event > event)
 
void enqueueCallback (edm::WaitingTaskWithArenaHolder holder)
 
Queue & queue () const
 
void recordEvent ()
 
void synchronize (EDMetadata &consumer, bool tryReuseQueue) const
 
 ~EDMetadata ()
 

Private Member Functions

std::shared_ptr< Queue > tryReuseQueue_ () const
 

Private Attributes

std::shared_ptr< Eventevent_
 
std::atomic< bool > mayReuseQueue_ = true
 
std::shared_ptr< Queue > queue_
 

Detailed Description

The EDMetadata class provides the exact synchronization mechanisms for Event data products for backends with asynchronous Queue. These include

For synchronous backends the EDMetadata acts as an owner of the Queue object, as no further synchronization is needed.

EDMetadata is used as the Metadata class for edm::DeviceProduct<T>, and is an implementation detail (not visible to user code).

TODO: What to do with device-synchronous backends? The data product needs to be wrapped into the edm::DeviceProduct, but the EDMetadata class used there does not need anything except "dummy" implementation of synchronize(). The question is clearly solvable, so maybe leave it to the time we would actually need one?

Definition at line 61 of file EDMetadata.h.

Constructor & Destructor Documentation

◆ EDMetadata()

ALPAKA_ACCELERATOR_NAMESPACE::EDMetadata::EDMetadata ( std::shared_ptr< Queue >  queue,
std::shared_ptr< Event event 
)
inline

Definition at line 63 of file EDMetadata.h.

std::shared_ptr< Event > event_
Definition: EDMetadata.h:90
std::shared_ptr< Queue > queue_
Definition: EDMetadata.h:89
def move(src, dest)
Definition: eostools.py:511
Definition: event.py:1

◆ ~EDMetadata()

ALPAKA_ACCELERATOR_NAMESPACE::EDMetadata::~EDMetadata ( )

Definition at line 8 of file EDMetadata.cc.

References CMS_SA_ALLOW, event_, and SequenceTypes::wait().

8  {
9  // Make sure that the production of the product in the GPU is
10  // complete before destructing the product. This is to make sure
11  // that the EDM stream does not move to the next event before all
12  // asynchronous processing of the current is complete.
13 
14  // TODO: a callback notifying a WaitingTaskHolder (or similar)
15  // would avoid blocking the CPU, but would also require more work.
16 
17  if (event_) {
18  // Must not throw in a destructor, and if there were an
19  // exception could not really propagate it anyway.
20  CMS_SA_ALLOW try { alpaka::wait(*event_); } catch (...) {
21  }
22  }
23  }
#define CMS_SA_ALLOW
std::shared_ptr< Event > event_
Definition: EDMetadata.h:90

Member Function Documentation

◆ device()

Device ALPAKA_ACCELERATOR_NAMESPACE::EDMetadata::device ( ) const
inline

Definition at line 67 of file EDMetadata.h.

References queue_.

67 { return alpaka::getDev(*queue_); }
std::shared_ptr< Queue > queue_
Definition: EDMetadata.h:89

◆ enqueueCallback()

void ALPAKA_ACCELERATOR_NAMESPACE::EDMetadata::enqueueCallback ( edm::WaitingTaskWithArenaHolder  holder)

Definition at line 25 of file EDMetadata.cc.

References eostools::move(), and queue_.

25  {
26  alpaka::enqueue(*queue_, alpaka::HostOnlyTask([holder = std::move(holder)]() {
27  // The functor is required to be const, but the original waitingTaskHolder_
28  // needs to be notified...
29  const_cast<edm::WaitingTaskWithArenaHolder&>(holder).doneWaiting(nullptr);
30  }));
31  }
std::shared_ptr< Queue > queue_
Definition: EDMetadata.h:89
def move(src, dest)
Definition: eostools.py:511

◆ queue()

Queue& ALPAKA_ACCELERATOR_NAMESPACE::EDMetadata::queue ( ) const
inline

Definition at line 71 of file EDMetadata.h.

References queue_.

Referenced by synchronize().

71 { return *queue_; }
std::shared_ptr< Queue > queue_
Definition: EDMetadata.h:89

◆ recordEvent()

void ALPAKA_ACCELERATOR_NAMESPACE::EDMetadata::recordEvent ( )
inline

Definition at line 75 of file EDMetadata.h.

References event_, and queue_.

75 { alpaka::enqueue(*queue_, *event_); }
std::shared_ptr< Event > event_
Definition: EDMetadata.h:90
std::shared_ptr< Queue > queue_
Definition: EDMetadata.h:89

◆ synchronize()

void ALPAKA_ACCELERATOR_NAMESPACE::EDMetadata::synchronize ( EDMetadata consumer,
bool  tryReuseQueue 
) const

Synchronizes 'consumer' metadata wrt. 'this' in the event product

Definition at line 33 of file EDMetadata.cc.

References OfflineOutput_cfi::consumer, event_, Exception, edm::errors::LogicError, queue(), queue_, tryReuseQueue_(), and SequenceTypes::wait().

33  {
34  if (*queue_ == *consumer.queue_) {
35  return;
36  }
37 
38  if (tryReuseQueue) {
39  if (auto queue = tryReuseQueue_()) {
40  consumer.queue_ = queue_;
41  return;
42  }
43  }
44 
45  // TODO: how necessary this check is?
46  if (alpaka::getDev(*queue_) != alpaka::getDev(*consumer.queue_)) {
47  throw edm::Exception(edm::errors::LogicError) << "Handling data from multiple devices is not yet supported";
48  }
49 
50  if (not alpaka::isComplete(*event_)) {
51  // Event not yet occurred, so need to add synchronization
52  // here. Sychronization is done by making the queue to wait
53  // for an event, so all subsequent work in the queue will run
54  // only after the event has "occurred" (i.e. data product
55  // became available).
56  alpaka::wait(*consumer.queue_, *event_);
57  }
58  }
std::shared_ptr< Event > event_
Definition: EDMetadata.h:90
std::shared_ptr< Queue > queue_
Definition: EDMetadata.h:89
std::shared_ptr< Queue > tryReuseQueue_() const
Definition: EDMetadata.cc:60

◆ tryReuseQueue_()

std::shared_ptr< Queue > ALPAKA_ACCELERATOR_NAMESPACE::EDMetadata::tryReuseQueue_ ( ) const
private

Returns a shared_ptr to the Queue if it can be reused, or a null shared_ptr if not

Definition at line 60 of file EDMetadata.cc.

References mayReuseQueue_, and queue_.

Referenced by synchronize().

60  {
61  bool expected = true;
62  if (mayReuseQueue_.compare_exchange_strong(expected, false)) {
63  // If the current thread is the one flipping the flag, it may
64  // reuse the queue.
65  return queue_;
66  }
67  return nullptr;
68  }
std::shared_ptr< Queue > queue_
Definition: EDMetadata.h:89

Member Data Documentation

◆ event_

std::shared_ptr<Event> ALPAKA_ACCELERATOR_NAMESPACE::EDMetadata::event_
private

Definition at line 90 of file EDMetadata.h.

Referenced by recordEvent(), synchronize(), and ~EDMetadata().

◆ mayReuseQueue_

std::atomic<bool> ALPAKA_ACCELERATOR_NAMESPACE::EDMetadata::mayReuseQueue_ = true
mutableprivate

Definition at line 94 of file EDMetadata.h.

Referenced by tryReuseQueue_().

◆ queue_

std::shared_ptr<Queue> ALPAKA_ACCELERATOR_NAMESPACE::EDMetadata::queue_
private

Definition at line 89 of file EDMetadata.h.

Referenced by device(), enqueueCallback(), queue(), recordEvent(), synchronize(), and tryReuseQueue_().