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
 
void discardEvent ()
 
 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 > eventComplete_ = false
 
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 62 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 64 of file EDMetadata.h.

std::shared_ptr< Event > event_
Definition: EDMetadata.h:92
std::shared_ptr< Queue > queue_
Definition: EDMetadata.h:91
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_, eventComplete_, mayReuseQueue_, 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_ is null, the EDMetadata was either
18  // default-constructed, or fully synchronized before leaving the
19  // produce() call, so no synchronization is needed.
20  // If the queue was re-used, then some other EDMetadata object in
21  // the same edm::Event records the event_ (in the same queue) and
22  // calls alpaka::wait(), and therefore this wait() call can be
23  // skipped).
24  if (event_ and not eventComplete_ and mayReuseQueue_) {
25  // Must not throw in a destructor, and if there were an
26  // exception could not really propagate it anyway.
27  CMS_SA_ALLOW try { alpaka::wait(*event_); } catch (...) {
28  }
29  }
30  }
#define CMS_SA_ALLOW
std::shared_ptr< Event > event_
Definition: EDMetadata.h:92

Member Function Documentation

◆ device()

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

Definition at line 68 of file EDMetadata.h.

References queue_.

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

◆ discardEvent()

void ALPAKA_ACCELERATOR_NAMESPACE::EDMetadata::discardEvent ( )
inline

Definition at line 77 of file EDMetadata.h.

References event_.

77 { event_.reset(); }
std::shared_ptr< Event > event_
Definition: EDMetadata.h:92

◆ enqueueCallback()

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

Definition at line 32 of file EDMetadata.cc.

References eostools::move(), and queue_.

32  {
33  alpaka::enqueue(*queue_, alpaka::HostOnlyTask([holder = std::move(holder)](std::exception_ptr eptr) {
34  // The functor is required to be const, but the original waitingTaskHolder_
35  // needs to be notified...
36  const_cast<edm::WaitingTaskWithArenaHolder&>(holder).doneWaiting(eptr);
37  }));
38  }
std::shared_ptr< Queue > queue_
Definition: EDMetadata.h:91
def move(src, dest)
Definition: eostools.py:511

◆ queue()

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

Definition at line 72 of file EDMetadata.h.

References queue_.

Referenced by synchronize().

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

◆ recordEvent()

void ALPAKA_ACCELERATOR_NAMESPACE::EDMetadata::recordEvent ( )
inline

Definition at line 76 of file EDMetadata.h.

References event_, and queue_.

76 { alpaka::enqueue(*queue_, *event_); }
std::shared_ptr< Event > event_
Definition: EDMetadata.h:92
std::shared_ptr< Queue > queue_
Definition: EDMetadata.h:91

◆ synchronize()

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

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

Definition at line 40 of file EDMetadata.cc.

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

40  {
41  if (*queue_ == *consumer.queue_) {
42  return;
43  }
44 
45  if (tryReuseQueue) {
46  if (auto queue = tryReuseQueue_()) {
47  consumer.queue_ = queue_;
48  return;
49  }
50  }
51 
52  if (eventComplete_) {
53  return;
54  }
55 
56  // TODO: how necessary this check is?
57  if (alpaka::getDev(*queue_) != alpaka::getDev(*consumer.queue_)) {
58  throw edm::Exception(edm::errors::LogicError) << "Handling data from multiple devices is not yet supported";
59  }
60 
61  // If the event has been discarded, the produce() function that
62  // constructed this EDMetadata object did not launch any
63  // asynchronous work.
64  if (not event_) {
65  return;
66  }
67 
68  if (alpaka::isComplete(*event_)) {
69  eventComplete_ = true;
70  } else {
71  // Event not yet occurred, so need to add synchronization
72  // here. Sychronization is done by making the queue to wait
73  // for an event, so all subsequent work in the queue will run
74  // only after the event has "occurred" (i.e. data product
75  // became available).
76  alpaka::wait(*consumer.queue_, *event_);
77  }
78  }
std::shared_ptr< Event > event_
Definition: EDMetadata.h:92
std::shared_ptr< Queue > queue_
Definition: EDMetadata.h:91
std::shared_ptr< Queue > tryReuseQueue_() const
Definition: EDMetadata.cc:80

◆ 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 80 of file EDMetadata.cc.

References mayReuseQueue_, and queue_.

Referenced by synchronize().

80  {
81  bool expected = true;
82  if (mayReuseQueue_.compare_exchange_strong(expected, false)) {
83  // If the current thread is the one flipping the flag, it may
84  // reuse the queue.
85  return queue_;
86  }
87  return nullptr;
88  }
std::shared_ptr< Queue > queue_
Definition: EDMetadata.h:91

Member Data Documentation

◆ event_

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

Definition at line 92 of file EDMetadata.h.

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

◆ eventComplete_

std::atomic<bool> ALPAKA_ACCELERATOR_NAMESPACE::EDMetadata::eventComplete_ = false
mutableprivate

Definition at line 98 of file EDMetadata.h.

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

◆ mayReuseQueue_

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

Definition at line 96 of file EDMetadata.h.

Referenced by tryReuseQueue_(), and ~EDMetadata().

◆ queue_

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

Definition at line 91 of file EDMetadata.h.

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