25template <
class Backend,
class Op,
class... Args>
consteval bool backend_has_kernel_task_factory()
27 if constexpr (
requires {
29 std::declval<kernel_type_probe_arg_t<Args>>()...);
32 using result_type =
decltype(
try_make_kernel_task(std::declval<Backend const&>(), std::declval<Op const&>(),
33 std::declval<kernel_type_probe_arg_t<Args>>()...));
34 static_assert(is_kernel_task_attempt<result_type>,
35 "try_make_kernel_task must return KernelTaskAttempt<ConcreteTask>");
41template <std::size_t Index,
class... Backends,
class Op, std::size_t ResultCount,
class... Args>
42async::AsyncTask co_dispatch_kernel_at(backend_list<Backends...>
const& backends, Op
const& op,
43 std::array<std::optional<KernelAttempt>, ResultCount>& runtime_results,
44 bool& succeeded, Args&... args)
46 static_assert(ResultCount ==
sizeof...(Backends));
47 if constexpr (Index ==
sizeof...(Backends))
53 using backend_type = std::tuple_element_t<Index, std::tuple<Backends...>>;
54 constexpr auto acceptance = backend_type_acceptance<backend_type, Op, Args&...>();
59 if constexpr (backend_has_kernel_task_factory<backend_type, Op, Args&...>())
62 attempt = task_attempt.attempt();
63 runtime_results[Index] = attempt;
66 co_await std::move(task_attempt).take_task();
71 attempt =
try_kernel(std::get<Index>(backends.entries), op, args...);
72 runtime_results[Index] = attempt;
87 co_await co_dispatch_kernel_at<Index + 1>(backends, op, runtime_results, succeeded, args...);
104template <
class BackendSelector,
class Op,
class... Args>
105 requires detail::KernelDispatchTypesAccepted<detail::normalized_backend_selector_t<BackendSelector>, Op, Args&...>
109 constexpr auto backend_count = std::tuple_size_v<
decltype(backends.entries)>;
110 std::array<std::optional<KernelAttempt>, backend_count> runtime_results{};
111 bool succeeded =
false;
113 co_await detail::co_dispatch_kernel_at<0>(backends, op, runtime_results, succeeded, args...);
115 auto const results = std::span<std::optional<KernelAttempt>
const>(runtime_results);
120 auto diagnostic = detail::make_kernel_dispatch_diagnostic(backends, results, op, args...);
121 dispatch_diagnostics::detail::emit(diagnostic);
128 auto diagnostic = detail::make_kernel_dispatch_diagnostic(backends, results, op, args...);
129 dispatch_diagnostics::detail::emit(diagnostic);
131 std::move(diagnostic.backend_attempts)));
134 trace::raise(detail::make_kernel_dispatch_error<KernelDispatchFailure::all_candidates_declined>(backends, results, op,
Promise-neutral coroutine task ownership and the public AsyncTask type.
Canonical host-oriented coroutine task type.
Definition async_task.hpp:196
Exception carrying structured information about a failed backend walk.
Definition dispatch_error.hpp:93
Operation-tag backend dispatch over tensor-view operands.
Deferred task result for an optional coroutine kernel implementation.
void raise(Exception &&exception, std::source_location where=std::source_location::current())
Raise a concrete exception through Uni20's configured error boundary.
Definition trace_impl.hpp:2184
bool enabled() noexcept
Return whether runtime kernel-dispatch diagnostics are enabled.
Definition dispatch_diagnostics.hpp:60
Definition linalg/async.hpp:28
constexpr bool kernel_attempt_succeeded(KernelAttempt attempt) noexcept
Return whether a backend performed the operation.
Definition kernel_attempt.hpp:40
KernelAttempt try_kernel(BlasBackend, gemm_op const &, C &c, S const &alpha, A &a, B &b, S const &beta)
Pack logical host values and execute GEMM through value-preserving provider conversion.
Definition linalg/backends/blas/binary80.hpp:30
KernelAttempt
Result of one runtime kernel backend attempt.
Definition kernel_attempt.hpp:27
@ all_candidates_declined
constexpr auto normalize_backend_selector(backend_list< Backends... > selector) -> backend_list< Backends... >
Return an explicit backend list unchanged.
Definition backend_selector.hpp:259
async::AsyncTask co_dispatch_kernel(BackendSelector selector, Op op, Args &... args)
Dispatch a kernel from a coroutine without requiring coroutine wrappers for blocking backends.
Definition async/dispatch.hpp:106
auto try_make_kernel_task(CublasBackend, gemm_op const &, OutputMdspan &output, Scalar const &alpha, LhsMdspan &lhs, RhsMdspan &rhs, Scalar const &beta) -> KernelTaskAttempt< async::CudaTask >
Prepare asynchronous cuBLAS work from normalized mdspecs.
Definition gemm_task.hpp:59
#define CHECK(cond,...)
Definition trace.hpp:299