vendor.hh
Go to the documentation of this file.
1#pragma once
2
3/// @file
4/// @brief Link facts for `if constexpr` gates: is an op's vendor library compiled in for a
5/// backend, and is the native level-3 tile kernel linked. @ingroup api_selection
6
8
9#include <batchlas/backend_config.h>
11#include <batchlas/no_route.hh>
12
13#include <cstdint>
14#include <string>
15#include <type_traits>
16
17namespace batchlas::select {
18/// @addtogroup api_selection
19/// @{
20
21inline constexpr bool kHasNetlib = BATCHLAS_HAS_LAPACKE && BATCHLAS_HAS_CBLAS;
22inline constexpr bool kHasCudaVendor = // all three; configure rejects a partial set
23 BATCHLAS_HAS_CUBLAS && BATCHLAS_HAS_CUSOLVER && BATCHLAS_HAS_CUSPARSE;
24
25/// Backends with wired native GPU kernels; ROCm and the host keep their vendor routes.
26template <Backend B>
27inline constexpr bool native_gpu_backend = B == Backend::CUDA || B == Backend::SYCL;
28
29template <Backend B> // gemm gemv trsm trmm symm syrk syr2k hemm herk her2k (ROCm: not the last three, level3.cc)
30inline constexpr bool level3_vendor_available =
32 B == Backend::ROCM ? bool(BATCHLAS_HAS_ROCBLAS) :
33 B == Backend::NETLIB ? kHasNetlib : false;
34
35/// geqrf/orgqr/getrf/getrs/getri/ormqr. On NVIDIA the group spans cuBLAS (getrf, getri)
36/// and cuSOLVER (geqrf, orgqr, ormqr, getrs).
37template <Backend B>
38inline constexpr bool factorization_vendor_available =
40 B == Backend::ROCM ? bool(BATCHLAS_HAS_ROCSOLVER) :
41 B == Backend::NETLIB ? kHasNetlib : false;
42
43template <Backend B> // potrf syev gesvd: cuSOLVER on NVIDIA
44inline constexpr bool solver_vendor_available =
46 B == Backend::ROCM ? bool(BATCHLAS_HAS_ROCSOLVER) :
47 B == Backend::NETLIB ? kHasNetlib : false;
48
49template <Backend B> // spmm
50inline constexpr bool sparse_vendor_available =
52 B == Backend::ROCM ? bool(BATCHLAS_HAS_ROCSPARSE) :
53 B == Backend::NETLIB ? kHasNetlib : false;
54
55/// The library name a diagnostic quotes when the answer is no.
56template <Backend B>
57inline constexpr const char* kLevel3Library =
58 B == Backend::CUDA ? "cuBLAS" : B == Backend::ROCM ? "rocBLAS"
59 : B == Backend::SYCL ? "a vendor GPU library" : "netlib CBLAS/LAPACKE";
60template <Backend B>
61inline constexpr const char* kFactorizationLibrary =
62 B == Backend::CUDA ? "cuBLAS and cuSOLVER" : B == Backend::ROCM ? "rocSOLVER"
63 : B == Backend::SYCL ? "a vendor GPU library" : "netlib CBLAS/LAPACKE";
64template <Backend B>
65inline constexpr const char* kSolverLibrary =
66 B == Backend::CUDA ? "cuSOLVER" : B == Backend::ROCM ? "rocSOLVER"
67 : B == Backend::SYCL ? "a vendor GPU library" : "netlib CBLAS/LAPACKE";
68template <Backend B>
69inline constexpr const char* kSparseLibrary =
70 B == Backend::CUDA ? "cuSPARSE" : B == Backend::ROCM ? "rocSPARSE"
71 : B == Backend::SYCL ? "a vendor GPU library" : "netlib CBLAS/LAPACKE";
72
73/// The library group an op's Vendor family calls; an op names exactly one (OpSpec::vendor).
74enum class Lib : std::uint8_t { none, level3, factorization, solver, sparse };
75
76/// Is library group @p l compiled in for backend B? Always false for Lib::none.
77template <Backend B>
78constexpr bool has_library(Lib l) {
79 switch (l) {
84 case Lib::none: return false;
85 }
86 return false;
87}
88
89template <Backend B>
90constexpr const char* library_name(Lib l) {
91 switch (l) {
93 case Lib::solver: return kSolverLibrary<B>;
94 case Lib::sparse: return kSparseLibrary<B>;
95 default: return kLevel3Library<B>;
96 }
97}
98
99// Where sytrd_blocked, ortho and ormqr_blocked swap a gemm for a level-3 tile kernel, and
100// coverage's float native rows: a native GPU backend and (float, or CUDA with cuBLAS). Narrower than where those
101// kernels now run vendor-free; widening it changes ortho's and ormqr's choices, which are unmeasured.
102// evidence: docs/design/vendor-independence.md#the-vendor-gate-why-the-tile-route-predicate-is-per-backend-and-scalar
103template <Backend B, typename T>
104inline constexpr bool level3_tile_substitution_enabled =
105 native_gpu_backend<B> && (std::is_same_v<T, float> || (B == Backend::CUDA && bool(BATCHLAS_HAS_CUBLAS)));
106
107/// The single funnel for "nothing can serve this call": records the miss, then throws NoRouteError.
108template <typename T>
109[[noreturn]] inline void throw_no_vendor_route(Op op, Backend backend, const char* library) {
111 throw NoRouteError(op, backend, scalar_kind_of<T>, std::string("built without ") + library);
112}
113
114/// @}
115} // namespace batchlas::select
NoRouteError(Op op, Backend backend, ScalarKind scalar, std::string detail)
Definition no_route.hh:70
What this build links and what a run reached, as CSV in BATCHLAS_COVERAGE_OUT.pid; the columns are a ...
Enumerations, scalar traits and scalar concepts shared by every public header.
Backend
Library family an entry point dispatches to, used as a template argument.
Definition enums.hh:111
@ NETLIB
Host CBLAS / LAPACKE; the fallback for any device.
Definition enums.hh:119
@ SYCL
Native SYCL kernels on a GPU with no vendor library (AdaptiveCpp Metal); float and complex<float> onl...
Definition enums.hh:117
@ ROCM
AMD GPU: rocBLAS / rocSOLVER / rocSPARSE and the native SYCL kernels.
Definition enums.hh:114
@ CUDA
NVIDIA GPU: cuBLAS / cuSOLVER / cuSPARSE and the native SYCL kernels.
Definition enums.hh:113
void record_miss(Op op, ScalarKind scalar, Backend backend, const char *library)
constexpr bool solver_vendor_available
Definition vendor.hh:44
constexpr bool level3_vendor_available
Definition vendor.hh:30
constexpr const char * kLevel3Library
The library name a diagnostic quotes when the answer is no.
Definition vendor.hh:57
constexpr bool native_gpu_backend
Backends with wired native GPU kernels; ROCm and the host keep their vendor routes.
Definition vendor.hh:27
constexpr bool factorization_vendor_available
geqrf/orgqr/getrf/getrs/getri/ormqr.
Definition vendor.hh:38
Lib
The library group an op's Vendor family calls; an op names exactly one (OpSpec::vendor).
Definition vendor.hh:74
constexpr bool kHasNetlib
Definition vendor.hh:21
constexpr bool has_library(Lib l)
Is library group l compiled in for backend B? Always false for Lib::none.
Definition vendor.hh:78
constexpr const char * library_name(Lib l)
Definition vendor.hh:90
constexpr bool level3_tile_substitution_enabled
Definition vendor.hh:104
constexpr bool sparse_vendor_available
Definition vendor.hh:50
constexpr const char * kSolverLibrary
Definition vendor.hh:65
constexpr bool kHasCudaVendor
Definition vendor.hh:22
void throw_no_vendor_route(Op op, Backend backend, const char *library)
The single funnel for "nothing can serve this call": records the miss, then throws NoRouteError.
Definition vendor.hh:109
constexpr const char * kSparseLibrary
Definition vendor.hh:69
constexpr const char * kFactorizationLibrary
Definition vendor.hh:61
constexpr ScalarKind scalar_kind_of
Definition no_route.hh:31