12#include <uni20/config.hpp>
14#if !UNI20_BACKEND_CUDA
15#error "CUDA task awaiters require the CUDA backend"
20#include <cuda_runtime_api.h>
28template <
class Resource>
32 : cuda::detail::ResourceWaiter<Resource>(&CudaResourceAcquireAwaiter::resource_available), pool_(&pool)
42 lease_ = pool_->try_acquire();
43 return lease_.has_value();
49 state_.store(registration_state::registering, std::memory_order_relaxed);
50 task_ =
handle.promise().take_ownership();
53 auto lease = pool_->acquire_or_enqueue(*
this);
56 lease_ = std::move(*lease);
57 this->publish_ready();
60 auto const prior = state_.exchange(registration_state::suspended, std::memory_order_acq_rel);
67 CHECK(lease_.has_value());
68 return std::move(*lease_);
72 static void resource_available(cuda::detail::ResourceWaiter<Resource>& waiter,
76 self.lease_ = std::move(lease);
80 enum class registration_state
87 void publish_ready() noexcept
89 auto const prior = state_.exchange(registration_state::ready, std::memory_order_acq_rel);
93 cuda::ResourcePool<Resource>* pool_;
94 std::optional<cuda::ResourceLease<Resource>> lease_;
96 std::atomic<registration_state> state_{registration_state::registering};
103 : cuda::detail::StreamWaiter(&CudaStreamAcquireAwaiter::stream_available), pool_(&pool)
114 return stream_.has_value();
120 state_.store(registration_state::registering, std::memory_order_relaxed);
121 task_ =
handle.promise().take_ownership();
127 stream_ = std::move(*stream);
128 this->publish_ready();
131 auto const prior = state_.exchange(registration_state::suspended, std::memory_order_acq_rel);
138 CHECK(stream_.has_value());
139 int current_device = -1;
140 cuda::check(cudaGetDevice(¤t_device),
"cudaGetDevice after stream acquisition");
141 CHECK_EQUAL(current_device, stream_->device(),
"CUDA task resumed outside the acquired stream's device");
142 return std::move(*stream_);
146 static void stream_available(cuda::detail::StreamWaiter& waiter,
cuda::Stream stream)
noexcept
149 self.stream_ = std::move(stream);
150 self.publish_ready();
153 enum class registration_state
160 void publish_ready() noexcept
162 auto const prior = state_.exchange(registration_state::ready, std::memory_order_acq_rel);
166 cuda::StreamPool* pool_;
167 std::optional<cuda::Stream> stream_;
169 std::atomic<registration_state> state_{registration_state::registering};
181 [[nodiscard]]
constexpr bool await_ready() const noexcept {
return false; }
185 int current_device = -1;
186 cuda::check(cudaGetDevice(¤t_device),
"cudaGetDevice for CUDA task device selection");
189 auto& promise =
handle.promise();
190 promise.select_device(device_);
191 if (current_device == device_)
return false;
210template <
class Resource>
237template <
typename DeviceLike>
238 requires requires(DeviceLike
const& device) {
239 { device.ordinal() } -> std::convertible_to<int>;
243 return set_device(
static_cast<int>(device.ordinal()));
static void reschedule(BasicTask task)
Reschedule a task when it becomes the sole ownership claimant.
Definition async_task_impl.hpp:11
Awaiter that establishes or changes a CUDA task's device affinity.
Definition cuda/task_awaiters.hpp:177
constexpr void await_resume() const noexcept
Definition cuda/task_awaiters.hpp:198
constexpr bool await_ready() const noexcept
Definition cuda/task_awaiters.hpp:181
bool await_suspend(std::coroutine_handle< CudaTaskPromise > handle) const
Definition cuda/task_awaiters.hpp:183
constexpr CudaDeviceAwaiter(int device) noexcept
Definition cuda/task_awaiters.hpp:179
CUDA-task awaiter for one provider resource from a fixed-capacity pool.
Definition cuda/task_awaiters.hpp:29
cuda::ResourceLease< Resource > await_resume()
Definition cuda/task_awaiters.hpp:65
bool await_ready()
Definition cuda/task_awaiters.hpp:40
CudaResourceAcquireAwaiter & operator=(CudaResourceAcquireAwaiter &&)=delete
CudaResourceAcquireAwaiter(CudaResourceAcquireAwaiter const &)=delete
bool await_suspend(std::coroutine_handle< CudaTaskPromise > handle) noexcept
Definition cuda/task_awaiters.hpp:46
CudaResourceAcquireAwaiter(CudaResourceAcquireAwaiter &&)=delete
CudaResourceAcquireAwaiter(cuda::ResourcePool< Resource > &pool) noexcept
Definition cuda/task_awaiters.hpp:31
CudaResourceAcquireAwaiter & operator=(CudaResourceAcquireAwaiter const &)=delete
CUDA-task awaiter for an actually-idle stream-pool lease.
Definition cuda/task_awaiters.hpp:100
cuda::Stream await_resume()
Definition cuda/task_awaiters.hpp:136
CudaStreamAcquireAwaiter(CudaStreamAcquireAwaiter &&)=delete
CudaStreamAcquireAwaiter(CudaStreamAcquireAwaiter const &)=delete
CudaStreamAcquireAwaiter & operator=(CudaStreamAcquireAwaiter &&)=delete
bool await_suspend(std::coroutine_handle< CudaTaskPromise > handle) noexcept
Definition cuda/task_awaiters.hpp:117
bool await_ready()
Definition cuda/task_awaiters.hpp:111
CudaStreamAcquireAwaiter & operator=(CudaStreamAcquireAwaiter const &)=delete
CudaStreamAcquireAwaiter(cuda::StreamPool &pool) noexcept
Definition cuda/task_awaiters.hpp:102
static TaskHandle from(std::coroutine_handle< Promise > handle) noexcept
Definition async_task_promise.hpp:991
static void note_suspended(TaskHandle handle) noexcept
Record that a coroutine has suspended and is waiting for resumption.
Definition async_task_promise.hpp:370
Move-only exclusive lease of one provider-resource pool slot.
Definition resource_pool.hpp:51
Fixed-capacity pool of preconstructed provider resources.
Definition resource_pool.hpp:96
Device-local pool whose streams become available only after their queued work completes.
Definition runtime.hpp:163
std::optional< Stream > acquire_or_enqueue(detail::StreamWaiter &waiter) noexcept
Register an internal awaiter unless a stream is immediately available.
Definition runtime.cpp:608
std::optional< Stream > try_acquire()
Try to lease one actually idle stream without waiting.
Definition runtime.cpp:576
Reference-counted lease of one CUDA stream-pool slot.
Definition runtime.hpp:65
cuda::ResourceLease< HandleSlot > handle
Definition cublas/execution.cpp:33
Structured CUDA runtime failures and checked-call helpers.
Defines the CUDA task admission type and scheduler interface.
This represents the reverse-mode adjoint for functions of complex variables, assuming a real-valued s...
Definition async/async.hpp:26
Definition cublas/execution.hpp:18
void check(cudaError_t status, std::string_view operation, std::optional< int > device, std::source_location where)
Raise when a CUDA runtime operation did not return cudaSuccess.
Definition cuda_error.cpp:44
Fixed-capacity pools and move-only leases for CUDA provider resources.
CUDA device, stream, resource, and scoped runtime primitives.
Marker base for awaiters that require a CudaTaskPromise handle.
Definition async_task_promise.hpp:29
#define CHECK(cond,...)
Definition trace.hpp:299
#define CHECK_EQUAL(a, b,...)
Definition trace.hpp:309