23inline void service_task_registry_debug_requests()
25#if UNI20_DEBUG_ASYNC_TASKS
30inline void dump_deadlock_graphviz_snapshot()
32#if UNI20_DEBUG_ASYNC_TASKS
36 display::info(
"Async Graphviz DAG snapshot written to {}", path);
73 TRACE_MODULE(ASYNC,
"Scheduling a task", &task, task.coroutine_handle());
75 if (task.set_scheduler(
this))
86 if (std::uncaught_exceptions() > 0)
88 while (!Handles_.empty())
90 Handles_.back().abandon_leak();
98 [[nodiscard]]
bool can_run() const noexcept {
return !Blocked_ && !Handles_.empty(); }
108 void pause()
override { Blocked_ =
true; }
111 void resume()
override { Blocked_ =
false; }
122 if (Blocked_ || Handles_.empty())
124 detail::dump_deadlock_graphviz_snapshot();
126 PANIC(
"**DEADLOCK** get_wait object is not available but there are no runnable tasks!");
133 [[nodiscard]]
bool done() const noexcept {
return Handles_.empty(); }
141 std::vector<std::size_t> indices(batch.
size());
142 std::iota(indices.begin(), indices.end(), std::size_t{0});
143 this->order_batch(indices);
144 for (std::size_t
const index : indices)
148 bool accepts_route(TaskRoute route)
const noexcept override
153 bool can_direct_transfer(TaskHandle, TaskHandle)
const noexcept override {
return true; }
156 void reschedule(BasicTask&& task)
override
158 TRACE_MODULE(ASYNC,
"Rescheduling a task", &task, task.coroutine_handle());
163 bool Blocked_ =
false;
165 std::vector<BasicTask> Handles_;
166 DebugSchedulerOptions options_;
167 std::mt19937_64 random_engine_;
169 template <
class T>
void order_batch(std::vector<T>& batch)
171 switch (options_.order)
176 std::reverse(batch.begin(), batch.end());
180 for (std::size_t remaining = batch.size(); remaining > 1; --remaining)
182 auto const selected =
static_cast<std::size_t
>(random_engine_() % remaining);
183 std::swap(batch[remaining - 1], batch[selected]);
187 PANIC(
"invalid DebugScheduler ordering policy",
static_cast<int>(options_.order));
201inline DebugScheduler DefaultScheduler;
203inline IAsyncScheduler* global_scheduler = &DefaultScheduler;
243template <
class Function>
244 requires std::invocable<Function&, std::size_t>
256 CHECK(scheduler !=
nullptr,
"the global scheduler does not accept CUDA tasks");
257 scheduler->schedule(std::move(task));
268 CHECK(scheduler !=
nullptr,
"the global scheduler does not accept CUDA tasks");
269 scheduler->schedule(std::move(task), device);
282 .
is_ready = [epoch] {
return epoch->reader_ready(); },
298 .
is_ready = [epoch] {
return epoch->reader_ready(); },
333 auto epoch = this->epoch_context_shared();
335 .
is_ready = [
this] {
return this->ready(); },
340 return std::move(this->data());
350 detail::service_task_registry_debug_requests();
356 TRACE_MODULE(ASYNC,
"Got some coroutines to resume", Handles_.size());
358 std::vector<BasicTask> H;
359 std::swap(H, Handles_);
360 this->order_batch(H);
363 TRACE_MODULE(ASYNC,
"resuming coroutine...", &h, h.coroutine_handle());
368 detail::service_task_registry_debug_requests();
374 detail::service_task_registry_debug_requests();
384 detail::service_task_registry_debug_requests();
static bool service_debug_requests()
Processes pending dump requests on the calling thread.
static bool dump_graphviz_file_best_effort(std::string const &path)
Writes a best-effort Graphviz DOT snapshot to a file.
static void dump()
Prints global task-registry diagnostics.
static std::string default_graphviz_dump_path()
Creates a default DOT output path for the current process.
static void record_task_scheduled(std::coroutine_handle<> h)
Records the call stack where a coroutine was submitted to a scheduler.
Canonical host-oriented coroutine task type.
Definition async_task.hpp:196
Move-only promise-neutral ownership claim for a Uni20 coroutine.
Definition async_task.hpp:103
void resume()
Resume the coroutine and transfer this ownership claim.
Definition async_task_impl.hpp:77
CUDA-constrained public task type used for typed initial admission.
Definition cuda_task.hpp:14
Single-threaded scheduler with configurable runnable-batch ordering.
Definition debug_scheduler.hpp:63
~DebugScheduler()
Destructor.
Definition debug_scheduler.hpp:82
void enqueue_task(BasicTask &&task)
Add one already-bound task to the runnable queue.
Definition debug_scheduler.hpp:192
void resume() override
Unblock the scheduler.
Definition debug_scheduler.hpp:111
bool done() const noexcept
Check whether the runnable queue is empty.
Definition debug_scheduler.hpp:133
void run_all()
Run until no runnable tasks remain.
Definition debug_scheduler.hpp:371
bool can_run() const noexcept
Reports whether at least one runnable task exists.
Definition debug_scheduler.hpp:98
void pause() override
Block the scheduler from running.
Definition debug_scheduler.hpp:108
void run()
Run one batch of scheduled coroutines in the configured order.
Definition debug_scheduler.hpp:347
DebugSchedulerOptions const & options() const noexcept
Return the scheduler's immutable ordering configuration.
Definition debug_scheduler.hpp:136
void schedule(AsyncTask &&task) override
Enqueue a task for later run.
Definition debug_scheduler.hpp:71
virtual void resume_task(BasicTask &task)
Resume one queued task in the execution context selected by this scheduler.
Definition debug_scheduler.hpp:195
void help_while_waiting(const WaitPredicate &is_ready) override
Drives one runnable task while waiting for readiness.
Definition debug_scheduler.hpp:115
DebugScheduler(DebugSchedulerOptions options={})
Default-construct an empty scheduler.
Definition debug_scheduler.hpp:66
void wait() const
Wait for the epoch to become available on the global scheduler.
Definition debug_scheduler.hpp:274
T const & get_wait() const
Wait for the epoch to become available on the global scheduler and return a reference to the value.
Definition debug_scheduler.hpp:308
T && move_from_wait()
Wait for the epoch to become available, and then return a prvalue-reference to the value.
Definition debug_scheduler.hpp:327
Scheduler interface for initial AsyncTask submission and host-side progress.
Definition scheduler.hpp:89
std::function< void()> WaitWakeup
Definition scheduler.hpp:128
std::function< bool()> WaitPredicate
Definition scheduler.hpp:127
virtual void schedule(AsyncTask &&task)=0
Schedule a coroutine for its initial execution.
virtual void wait_for(const WaitPredicate &is_ready)
Block the calling thread until is_ready returns true.
Definition scheduler.hpp:166
void execute_batch(std::size_t size, Function &&function)
Execute a synchronous batch of independent lightweight work items.
Definition scheduler.hpp:113
Scheduler interface for initial CudaTask admission.
Definition cuda_task.hpp:49
Borrowed type-erased description of a synchronous lightweight task batch.
Definition scheduler.hpp:28
auto size() const noexcept -> std::size_t
Return the number of independent work items.
Definition scheduler.hpp:45
RAII helper that temporarily overrides the global scheduler.
Definition debug_scheduler.hpp:219
ScopedScheduler(IAsyncScheduler *sched)
Install a temporary global scheduler until destruction.
Definition debug_scheduler.hpp:223
~ScopedScheduler()
Restore the previous global scheduler.
Definition debug_scheduler.hpp:229
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
void schedule(AsyncTask &&task)
Schedule a task on the currently configured global scheduler.
Definition debug_scheduler.hpp:237
void set_global_scheduler(IAsyncScheduler *sched)
Sets the process-wide scheduler used by async helpers.
Definition debug_scheduler.hpp:208
IAsyncScheduler * get_global_scheduler()
Returns the currently-installed process-wide scheduler.
Definition debug_scheduler.hpp:212
void reset_global_scheduler()
Restores the process-wide scheduler to the default debug scheduler.
Definition debug_scheduler.hpp:215
void execute_batch(std::size_t size, Function &&function)
Execute a synchronous lightweight batch on the global scheduler.
Definition debug_scheduler.hpp:245
DebugSchedulerOrder
Runnable-batch ordering policy for DebugScheduler.
Definition debug_scheduler.hpp:44
@ reverse
Execute each runnable batch in reverse submission order.
@ random
Execute each runnable batch in seeded pseudo-random order.
@ fifo
Execute each runnable batch in submission order.
void info(checked_format_string< Args... > format, Args &&... args)
Emit an informational display message.
Definition display.hpp:393
Defines internal task routing and the host-oriented scheduler interface.
Configuration for deterministic debug scheduling.
Definition debug_scheduler.hpp:55
std::uint64_t random_seed
Initial state for the reproducible random policy.
Definition debug_scheduler.hpp:59
DebugSchedulerOrder order
Runnable-batch ordering policy.
Definition debug_scheduler.hpp:57
Readiness predicate and optional targeted wakeup registration for a blocking wait.
Definition scheduler.hpp:133
WaitPredicate is_ready
Predicate that reports whether the requested value is available.
Definition scheduler.hpp:135
Selects the task-registry implementation for the current build mode.
Async aliases for lazy tensor-level views.
#define CHECK(cond,...)
Definition trace.hpp:299
#define TRACE_MODULE(m,...)
Definition trace.hpp:149
#define DEBUG_TRACE_MODULE(m,...)
Definition trace.hpp:511
#define PANIC(...)
Definition trace.hpp:382