21 static constexpr std::string_view
name =
"lapack";
28 static constexpr std::string_view
name =
"blas";
35 static constexpr std::string_view
name =
"cublas";
42 static constexpr std::string_view
name =
"cusolver";
49 static constexpr std::string_view
name =
"cuda_reference";
56 static constexpr std::string_view
name =
"cpu_reference";
83 { std::remove_cvref_t<T>::name } -> std::convertible_to<std::string_view>;
116template <
class Tensor>
117concept HasStoragePolicy =
requires {
typename std::remove_cvref_t<Tensor>::storage_policy; } &&
118 (!std::same_as<typename std::remove_cvref_t<Tensor>::storage_policy,
void>);
120template <
class Prov
ider>
121concept HasStaticBackendSelector =
requires { std::remove_cvref_t<Provider>::backend_selector(); };
125template <
class... StoragePolicies>
struct FirstBackendBoundStorage
130template <
class StoragePolicy,
class... Rest>
struct FirstBackendBoundStorage<StoragePolicy, Rest...>
132 using type = std::conditional_t<enable_backend_neutral_storage<StoragePolicy>,
133 typename FirstBackendBoundStorage<Rest...>::type, StoragePolicy>;
136template <
class... Tensors>
137using first_backend_bound_storage_t =
typename FirstBackendBoundStorage<tensor_storage_policy_t<Tensors>...>::type;
139template <
class StoragePolicy,
class... Tensors>
140inline constexpr bool tensors_have_compatible_storage =
141 ((enable_backend_neutral_storage<tensor_storage_policy_t<Tensors>> ||
142 std::same_as<StoragePolicy, tensor_storage_policy_t<Tensors>>) &&
145template <
class StoragePolicy,
class Operation>
146[[nodiscard]]
constexpr auto select_backend_for_storage(Operation
const& operation)
148 using operation_type = std::remove_cvref_t<Operation>;
150 if constexpr (
requires { override_type::select(operation); })
152 auto selector = override_type::select(operation);
154 "backend_selector_override::select must return a backend selector");
159 auto storage_selector = StoragePolicy::backend_selector();
161 if constexpr (
requires { default_type::select(operation, std::move(storage_selector)); })
163 auto selector = default_type::select(operation, std::move(storage_selector));
165 "backend_selector_default::select must return a backend selector");
171 "storage policy backend_selector must return a backend selector");
172 return storage_selector;
186template <
class StoragePolicy,
class Operation>
189 return detail::select_backend_for_storage<StoragePolicy>(operation);
200template <
class FirstTensor,
class... RestTensors,
class Operation>
203 if constexpr (detail::HasStoragePolicy<FirstTensor> && (detail::HasStoragePolicy<RestTensors> && ...))
205 using storage_policy = detail::first_backend_bound_storage_t<FirstTensor, RestTensors...>;
206 if constexpr (std::is_void_v<storage_policy>)
208 using first_storage = detail::tensor_storage_policy_t<FirstTensor>;
209 static_assert(detail::HasStaticBackendSelector<first_storage> &&
210 (detail::HasStaticBackendSelector<detail::tensor_storage_policy_t<RestTensors>> && ...),
211 "backend-neutral storage policies must provide a static backend_selector()");
212 using selector_type = std::remove_cvref_t<
decltype(first_storage::backend_selector())>;
216 std::remove_cvref_t<
decltype(detail::tensor_storage_policy_t<RestTensors>::backend_selector())>> &&
218 "backend-neutral storage policies must provide compatible default backend selector types");
219 return detail::select_backend_for_storage<first_storage>(operation);
224 detail::tensors_have_compatible_storage<storage_policy, FirstTensor, RestTensors...>,
225 "tensor operands with different backend-bound storage policies require an explicit selector or transfer");
226 static_assert(detail::HasStaticBackendSelector<storage_policy>,
227 "tensor storage policy must provide a static backend_selector()");
229 return detail::select_backend_for_storage<storage_policy>(operation);
234 using first_tensor = std::remove_cvref_t<FirstTensor>;
235 static_assert(detail::HasStaticBackendSelector<first_tensor> &&
236 (detail::HasStaticBackendSelector<std::remove_cvref_t<RestTensors>> && ...),
237 "tensor operands without storage policies must provide a static backend_selector()");
238 using selector_type = std::remove_cvref_t<
decltype(first_tensor::backend_selector())>;
239 static_assert((std::same_as<selector_type,
240 std::remove_cvref_t<
decltype(std::remove_cvref_t<RestTensors>::backend_selector())>> &&
242 "tensor operands must provide compatible default backend selector types");
243 return first_tensor::backend_selector();
251template <
class Operation,
class FirstTensor,
class... RestTensors>
252[[nodiscard]]
constexpr auto select_backend(Operation
const& operation, FirstTensor
const&, RestTensors
const&...)
258template <
class... Backends>
265template <
class Backend>
266 requires(!is_backend_list_v<Backend>)
Single named backend or ordered backend list accepted by dispatch front ends.
Definition backend_selector.hpp:88
Named backend value accepted as one dispatch candidate.
Definition backend_selector.hpp:82
locale_t value
Definition data_table.cpp:49
Definition linalg/async.hpp:28
constexpr auto select_backend_for(Operation const &operation)
Resolve the immutable backend selector for Tensor operand types.
Definition backend_selector.hpp:201
constexpr bool enable_backend_neutral_storage
Opt-in marker for storage policies that do not constrain backend selection.
Definition backend_selector.hpp:112
constexpr bool is_backend_list_v
Definition backend_selector.hpp:78
constexpr auto normalize_backend_selector(backend_list< Backends... > selector) -> backend_list< Backends... >
Return an explicit backend list unchanged.
Definition backend_selector.hpp:259
constexpr auto select_backend_for_storage(Operation const &operation)
Resolve a backend selector directly from one storage policy.
Definition backend_selector.hpp:187
constexpr auto select_backend(Operation const &operation, FirstTensor const &, RestTensors const &...)
Select the default backend list for an operation on Tensor operands.
Definition backend_selector.hpp:252
typename detail::TensorStoragePolicy< std::remove_cvref_t< Tensor > >::type tensor_storage_policy_t
Storage-policy type exposed by a tensor-level object, or void.
Definition tensor/concepts.hpp:40
Backend family for BLAS dense linalg kernels, including MPLAPACK scalar adapters.
Definition backend_selector.hpp:27
static constexpr std::string_view name
Definition backend_selector.hpp:28
friend constexpr bool operator==(BlasBackend const &, BlasBackend const &)=default
Backend value for the reference host CPU dense linalg oracle.
Definition backend_selector.hpp:55
static constexpr std::string_view name
Definition backend_selector.hpp:56
friend constexpr bool operator==(CpuReferenceBackend const &, CpuReferenceBackend const &)=default
Backend value for cuBLAS dense linalg kernels.
Definition backend_selector.hpp:34
static constexpr std::string_view name
Definition backend_selector.hpp:35
friend constexpr bool operator==(CublasBackend const &, CublasBackend const &)=default
Backend value for generic CUDA runtime kernels and transfers.
Definition backend_selector.hpp:48
friend constexpr bool operator==(CudaReferenceBackend const &, CudaReferenceBackend const &)=default
static constexpr std::string_view name
Definition backend_selector.hpp:49
Backend value for cuSOLVER dense factorization kernels.
Definition backend_selector.hpp:41
friend constexpr bool operator==(CusolverBackend const &, CusolverBackend const &)=default
static constexpr std::string_view name
Definition backend_selector.hpp:42
Backend family for configured dense LAPACK kernels, including MPLAPACK scalar adapters.
Definition backend_selector.hpp:20
friend constexpr bool operator==(LapackBackend const &, LapackBackend const &)=default
static constexpr std::string_view name
Definition backend_selector.hpp:21
Ordered list of backend values tried by the dispatch walk.
Definition backend_selector.hpp:62
constexpr backend_list(Backends... backends)
Definition backend_selector.hpp:65
friend constexpr bool operator==(backend_list const &, backend_list const &)=default
std::tuple< Backends... > entries
Definition backend_selector.hpp:63
Uni20-owned operation-specific default for a storage policy.
Definition backend_selector.hpp:105
Optional global backend-selector override for an operation and storage policy.
Definition backend_selector.hpp:96
Definition backend_selector.hpp:73