CMS 3D CMS Logo

HostOnlyTask.h
Go to the documentation of this file.
1 #ifndef HeterogeneousCore_AlpakaInterface_interface_HostOnlyTask_h
2 #define HeterogeneousCore_AlpakaInterface_interface_HostOnlyTask_h
3 
4 #include <functional>
5 #include <memory>
6 
7 #include <fmt/format.h>
8 
9 #include <alpaka/alpaka.hpp>
10 
11 namespace alpaka {
12 
17  class HostOnlyTask {
18  public:
19  HostOnlyTask(std::function<void(std::exception_ptr)> task) : task_(std::move(task)) {}
20 
21  void operator()(std::exception_ptr eptr) const { task_(eptr); }
22 
23  private:
24  std::function<void(std::exception_ptr)> task_;
25  };
26 
27  namespace trait {
28 
29 #ifdef ALPAKA_ACC_GPU_CUDA_ENABLED
30  template <>
32  struct Enqueue<QueueCudaRtNonBlocking, HostOnlyTask> {
33  using TApi = ApiCudaRt;
34 
35  static void CUDART_CB callback(cudaStream_t queue, cudaError_t status, void* arg) {
36  std::unique_ptr<HostOnlyTask> pTask(static_cast<HostOnlyTask*>(arg));
37  if (status == cudaSuccess) {
38  (*pTask)(nullptr);
39  } else {
40  // wrap the exception in a try-catch block to let GDB "catch throw" break on it
41  try {
42  throw std::runtime_error(fmt::format("CUDA error: callback of stream {} received error {}: {}.",
43  fmt::ptr(queue),
44  cudaGetErrorName(status),
45  cudaGetErrorString(status)));
46  } catch (std::exception&) {
47  // pass the exception to the task
48  (*pTask)(std::current_exception());
49  }
50  }
51  }
52 
53  ALPAKA_FN_HOST static auto enqueue(QueueCudaRtNonBlocking& queue, HostOnlyTask task) -> void {
54  auto pTask = std::make_unique<HostOnlyTask>(std::move(task));
55  ALPAKA_UNIFORM_CUDA_HIP_RT_CHECK(
56  cudaStreamAddCallback(alpaka::getNativeHandle(queue), callback, static_cast<void*>(pTask.release()), 0u));
57  }
58  };
59 #endif // ALPAKA_ACC_GPU_CUDA_ENABLED
60 
61 #ifdef ALPAKA_ACC_GPU_HIP_ENABLED
62  template <>
64  struct Enqueue<QueueHipRtNonBlocking, HostOnlyTask> {
65  using TApi = ApiHipRt;
66 
67  static void callback(hipStream_t queue, hipError_t status, void* arg) {
68  std::unique_ptr<HostOnlyTask> pTask(static_cast<HostOnlyTask*>(arg));
69  if (status == hipSuccess) {
70  (*pTask)(nullptr);
71  } else {
72  // wrap the exception in a try-catch block to let GDB "catch throw" break on it
73  try {
74  throw std::runtime_error(fmt::format("HIP error: callback of stream {} received error {}: {}.",
75  fmt::ptr(queue),
76  hipGetErrorName(status),
77  hipGetErrorString(status)));
78  } catch (std::exception&) {
79  // pass the exception to the task
80  (*pTask)(std::current_exception());
81  }
82  }
83  }
84 
85  ALPAKA_FN_HOST static auto enqueue(QueueHipRtNonBlocking& queue, HostOnlyTask task) -> void {
86  auto pTask = std::make_unique<HostOnlyTask>(std::move(task));
87  ALPAKA_UNIFORM_CUDA_HIP_RT_CHECK(
88  hipStreamAddCallback(alpaka::getNativeHandle(queue), callback, static_cast<void*>(pTask.release()), 0u));
89  }
90  };
91 #endif // ALPAKA_ACC_GPU_HIP_ENABLED
92 
93  } // namespace trait
94 
95 } // namespace alpaka
96 
97 #endif // HeterogeneousCore_AlpakaInterface_interface_HostOnlyTask_h
HostOnlyTask(std::function< void(std::exception_ptr)> task)
Definition: HostOnlyTask.h:19
std::function< void(std::exception_ptr)> task_
Definition: HostOnlyTask.h:24
void operator()(std::exception_ptr eptr) const
Definition: HostOnlyTask.h:21
A arg
Definition: Factorize.h:31
def move(src, dest)
Definition: eostools.py:511