CMS 3D CMS Logo

ScopedContext.cc
Go to the documentation of this file.
2 
8 
9 #include "chooseDevice.h"
10 
11 namespace {
12  struct CallbackData {
14  int device;
15  };
16 
17  void CUDART_CB cudaScopedContextCallback(cudaStream_t streamId, cudaError_t status, void* data) {
18  std::unique_ptr<CallbackData> guard{reinterpret_cast<CallbackData*>(data)};
19  edm::WaitingTaskWithArenaHolder& waitingTaskHolder = guard->holder;
20  int device = guard->device;
21  if (status == cudaSuccess) {
22  LogTrace("ScopedContext") << " GPU kernel finished (in callback) device " << device << " CUDA stream "
23  << streamId;
24  waitingTaskHolder.doneWaiting(nullptr);
25  } else {
26  // wrap the exception in a try-catch block to let GDB "catch throw" break on it
27  try {
28  auto error = cudaGetErrorName(status);
29  auto message = cudaGetErrorString(status);
30  throw cms::Exception("CUDAError") << "Callback of CUDA stream " << streamId << " in device " << device
31  << " error " << error << ": " << message;
32  } catch (cms::Exception&) {
33  waitingTaskHolder.doneWaiting(std::current_exception());
34  }
35  }
36  }
37 } // namespace
38 
39 namespace cms::cuda {
40  namespace impl {
41  ScopedContextBase::ScopedContextBase(edm::StreamID streamID) : currentDevice_(chooseDevice(streamID)) {
42  cudaCheck(cudaSetDevice(currentDevice_));
44  }
45 
46  ScopedContextBase::ScopedContextBase(const ProductBase& data) : currentDevice_(data.device()) {
47  cudaCheck(cudaSetDevice(currentDevice_));
48  if (data.mayReuseStream()) {
49  stream_ = data.streamPtr();
50  } else {
52  }
53  }
54 
56  : currentDevice_(device), stream_(std::move(stream)) {
57  cudaCheck(cudaSetDevice(currentDevice_));
58  }
59 
61 
63  cudaStream_t dataStream,
64  bool available,
65  cudaEvent_t dataEvent) {
66  if (dataDevice != device()) {
67  // Eventually replace with prefetch to current device (assuming unified memory works)
68  // If we won't go to unified memory, need to figure out something else...
69  throw cms::Exception("LogicError") << "Handling data from multiple devices is not yet supported";
70  }
71 
72  if (dataStream != stream()) {
73  // Different streams, need to synchronize
74  if (not available) {
75  // Event not yet occurred, so need to add synchronization
76  // here. Sychronization is done by making the CUDA stream to
77  // wait for an event, so all subsequent work in the stream
78  // will run only after the event has "occurred" (i.e. data
79  // product became available).
80  cudaCheck(cudaStreamWaitEvent(stream(), dataEvent, 0), "Failed to make a stream to wait for an event");
81  }
82  }
83  }
84 
85  void ScopedContextHolderHelper::enqueueCallback(int device, cudaStream_t stream) {
86  cudaCheck(
87  cudaStreamAddCallback(stream, cudaScopedContextCallback, new CallbackData{waitingTaskHolder_, device}, 0));
88  }
89  } // namespace impl
90 
92 
95  if (contextState_) {
97  }
98  }
99 
101  throw cms::Exception("LogicError")
102  << "Calling ScopedContextAcquire::insertNextTask() requires ScopedContextAcquire to be constructed with "
103  "ContextState, but that was not the case";
104  }
105 
107 
109  // Intentionally not checking the return value to avoid throwing
110  // exceptions. If this call would fail, we should get failures
111  // elsewhere as well.
112  cudaEventRecord(event_.get(), stream());
113  }
114 
116 
118 } // namespace cms::cuda
cms::cuda
Definition: Product.h:14
cms::cuda::impl::ScopedContextHolderHelper::waitingTaskHolder_
edm::WaitingTaskWithArenaHolder waitingTaskHolder_
Definition: ScopedContext.h:90
edm::StreamID
Definition: StreamID.h:30
cms::cuda::ScopedContextAcquire::holderHelper_
impl::ScopedContextHolderHelper holderHelper_
Definition: ScopedContext.h:139
MessageLogger.h
cms::cuda::ScopedContextAcquire::throwNoState
void throwNoState()
Definition: ScopedContext.cc:100
cms::cuda::chooseDevice
int chooseDevice(edm::StreamID id)
Definition: chooseDevice.cc:8
chooseDevice.h
StreamCache.h
mps_update.status
status
Definition: mps_update.py:69
cms::cuda::ScopedContextTask::holderHelper_
impl::ScopedContextHolderHelper holderHelper_
Definition: ScopedContext.h:212
cms::cuda::stream
cudaStream_t stream
Definition: HistoContainer.h:57
cms::cuda::impl::ScopedContextBase::stream
cudaStream_t stream() const
Definition: ScopedContext.h:34
cms::cuda::SharedStreamPtr
std::shared_ptr< std::remove_pointer_t< cudaStream_t > > SharedStreamPtr
Definition: SharedStreamPtr.h:14
cms::cuda::impl::ScopedContextHolderHelper::enqueueCallback
void enqueueCallback(int device, cudaStream_t stream)
Definition: ScopedContext.cc:85
cms::cuda::impl::ScopedContextGetterBase::synchronizeStreams
void synchronizeStreams(int dataDevice, cudaStream_t dataStream, bool available, cudaEvent_t dataEvent)
Definition: ScopedContext.cc:62
cms::cuda::ScopedContextAcquire::contextState_
ContextState * contextState_
Definition: ScopedContext.h:140
relativeConstraints.error
error
Definition: relativeConstraints.py:53
cms::cuda::ScopedContextProduce::event_
SharedEventPtr event_
Definition: ScopedContext.h:183
edm::WaitingTaskWithArenaHolder
Definition: WaitingTaskWithArenaHolder.h:34
cms::cuda::ScopedContextTask::~ScopedContextTask
~ScopedContextTask()
Definition: ScopedContext.cc:117
Service.h
cms::cuda::impl::ScopedContextBase::streamPtr
const SharedStreamPtr & streamPtr() const
Definition: ScopedContext.h:35
cms::cuda::impl::ScopedContextBase::stream_
SharedStreamPtr stream_
Definition: ScopedContext.h:52
cms::cuda::impl::ScopedContextBase::currentDevice_
int currentDevice_
Definition: ScopedContext.h:51
cms::cuda::getStreamCache
StreamCache & getStreamCache()
Definition: StreamCache.cc:39
cms::cuda::ProductBase
Definition: ProductBase.h:20
cms::cuda::ContextState::set
void set(int device, SharedStreamPtr stream)
Definition: ContextState.h:30
cms::cuda::StreamCache::get
SharedStreamPtr get()
Definition: StreamCache.cc:20
cms::cuda::ScopedContextProduce::~ScopedContextProduce
~ScopedContextProduce()
Record the CUDA event, all asynchronous work must have been queued before the destructor.
Definition: ScopedContext.cc:108
cudaCheck.h
cms::cuda::impl::ScopedContextBase::ScopedContextBase
ScopedContextBase(edm::StreamID streamID)
Definition: ScopedContext.cc:41
impl
Definition: trackAlgoPriorityOrder.h:18
eostools.move
def move(src, dest)
Definition: eostools.py:511
std
Definition: JetResolutionObject.h:76
cudaCheck
#define cudaCheck(ARG,...)
Definition: cudaCheck.h:62
cms::cuda::ScopedContextAcquire::~ScopedContextAcquire
~ScopedContextAcquire()
Definition: ScopedContext.cc:93
Exception
Definition: hltDiff.cc:245
ScopedContext.h
Exception.h
data
char data[epos_bytes_allocation]
Definition: EPOS_Wrapper.h:79
cms::Exception
Definition: Exception.h:70
LogTrace
#define LogTrace(id)
Definition: MessageLogger.h:234
cms::cuda::impl::ScopedContextBase::device
int device() const
Definition: ScopedContext.h:28
edm::WaitingTaskWithArenaHolder::doneWaiting
void doneWaiting(std::exception_ptr iExcept)
Definition: WaitingTaskWithArenaHolder.cc:69