24namespace detail::cublas_backend
27template <
class Output,
class Scalar>
29 requires(Output& output, Scalar
value) { output =
value; };
31template <
class Mdspec,
class Scalar>
32concept RawReadableCudaReductionMdspec =
35 std::same_as<typename std::remove_cvref_t<Mdspec>::element_type, Scalar
const> &&
38template <
class Mdspec> [[nodiscard]] std::size_t reduction_element_count(Mdspec
const&
span)
40 if (!
span.mapping().is_unique() || !
span.mapping().is_exhaustive())
return 0;
41 auto const required =
span.mapping().required_span_size();
42 CHECK(std::cmp_greater_equal(required, 0), required);
43 return static_cast<std::size_t
>(required);
46template <
class Mdspec>
void require_reduction_descriptor_range(Mdspec
const&
span, std::size_t size)
48 auto const& descriptor =
span.data_descriptor();
49 auto const offset = descriptor.element_offset();
50 auto const buffer_size = descriptor.buffer().size();
51 CHECK(offset <= buffer_size && size <= buffer_size - offset, offset, size, buffer_size);
54template <
class Scalar,
class LhsMdspec,
class RhsMdspec>
55KernelAttempt try_inner_product(Scalar& output, LhsMdspec
const& lhs, RhsMdspec
const& rhs)
57 static_assert(RawReadableCudaReductionMdspec<LhsMdspec, Scalar>);
58 static_assert(RawReadableCudaReductionMdspec<RhsMdspec, Scalar>);
59 static_assert(std::remove_cvref_t<LhsMdspec>::rank() == std::remove_cvref_t<RhsMdspec>::rank());
60 for (std::size_t axis = 0; axis < std::remove_cvref_t<LhsMdspec>::rank(); ++axis)
63 if (!lhs.mapping().is_unique() || !lhs.mapping().is_exhaustive() || !rhs.mapping().is_unique() ||
64 !rhs.mapping().is_exhaustive())
66 for (std::size_t axis = 0; axis < std::remove_cvref_t<LhsMdspec>::rank(); ++axis)
71 auto const size = reduction_element_count(lhs);
80 auto const& lhs_descriptor = lhs.data_descriptor();
81 auto const& rhs_descriptor = rhs.data_descriptor();
83 require_reduction_descriptor_range(lhs, size);
84 require_reduction_descriptor_range(rhs, size);
87 auto lhs_access = lhs_descriptor.buffer().read_synchronized_with(execution.stream());
88 auto rhs_access = rhs_descriptor.buffer().read_synchronized_with(execution.stream());
89 output =
uni20::cublas::dotc(execution,
static_cast<int>(size), lhs_access.data() + lhs_descriptor.element_offset(),
90 rhs_access.data() + rhs_descriptor.element_offset());
91 lhs_access.release_after_synchronization();
92 rhs_access.release_after_synchronization();
96template <
class Scalar,
class InputMdspec>
99 static_assert(RawReadableCudaReductionMdspec<InputMdspec, Scalar>);
102 auto const size = reduction_element_count(input);
110 auto const& descriptor = input.data_descriptor();
111 require_reduction_descriptor_range(input, size);
113 auto access = descriptor.buffer().read_synchronized_with(execution.stream());
114 output =
uni20::cublas::nrm2(execution,
static_cast<int>(size), access.data() + descriptor.element_offset());
115 access.release_after_synchronization();
122template <
class Output, uni20::MdspecLike LhsMdspec, uni20::MdspecLike RhsMdspec>
125 using lhs_type = std::remove_cvref_t<LhsMdspec>;
126 using rhs_type = std::remove_cvref_t<RhsMdspec>;
127 if constexpr (lhs_type::rank() == rhs_type::rank() &&
128 std::same_as<typename lhs_type::value_type, typename rhs_type::value_type> &&
129 detail::cublas_backend::HostScalarOutput<Output, typename lhs_type::value_type> &&
130 detail::cublas_backend::RawReadableCudaReductionMdspec<LhsMdspec, typename lhs_type::value_type> &&
131 detail::cublas_backend::RawReadableCudaReductionMdspec<RhsMdspec, typename lhs_type::value_type>)
138template <
class Output, uni20::MdspecLike LhsMdspec, uni20::MdspecLike RhsMdspec>
139 requires detail::cublas_backend::HostScalarOutput<Output, typename std::remove_cvref_t<LhsMdspec>::value_type> &&
140 detail::cublas_backend::RawReadableCudaReductionMdspec<
141 LhsMdspec,
typename std::remove_cvref_t<LhsMdspec>::value_type> &&
142 detail::cublas_backend::RawReadableCudaReductionMdspec<RhsMdspec,
143 typename std::remove_cvref_t<LhsMdspec>::value_type>
146 return detail::cublas_backend::try_inner_product(output, lhs, rhs);
150template <
class Output, uni20::MdspecLike InputMdspec>
153 using scalar_type =
typename std::remove_cvref_t<InputMdspec>::value_type;
154 if constexpr (detail::cublas_backend::HostScalarOutput<Output, uni20::make_real_t<scalar_type>> &&
155 detail::cublas_backend::RawReadableCudaReductionMdspec<InputMdspec, scalar_type>)
162template <
class Output, uni20::MdspecLike InputMdspec>
163 requires detail::cublas_backend::HostScalarOutput<
165 detail::cublas_backend::RawReadableCudaReductionMdspec<InputMdspec,
166 typename std::remove_cvref_t<InputMdspec>::value_type>
169 using scalar_type =
typename std::remove_cvref_t<InputMdspec>::value_type;
170 return detail::cublas_backend::try_norm<scalar_type>(output, input);
Typed CUDA device buffers and scoped stream access guards.
ExecutionLease acquire()
Block until a handle and then an idle stream are available.
Definition cublas/execution.cpp:203
Mdspan metadata whose data handle is immediate or available through a data descriptor.
Definition mdspan/concepts.hpp:304
An mdspec-like type whose mapping exposes multidimensional strides.
Definition mdspan/concepts.hpp:427
Scalar types supported by the cuBLAS level-one wrappers.
Definition level1.hpp:27
CUDA-accessible mdspec backed by a CudaBufferView descriptor.
Definition cuda_storage.hpp:118
cuBLAS handle slots and dynamically paired stream execution leases.
CUDA-device-callable accessors for leased Tensor storage.
CUDA Tensor storage with deferred device-memory data descriptors.
locale_t value
Definition data_table.cpp:49
Operation-tag backend dispatch over tensor-view operands.
typename make_real< T >::type make_real_t
Alias for the underlying real-valued type of T.
Definition scalar_traits.hpp:168
Checked cuBLAS dot-product and Euclidean-norm wrappers.
std::pair< int, int > size(std::FILE *stream)
Return the terminal size associated with a C stream.
Definition terminal.cpp:504
auto nrm2(ExecutionLease &execution, int size, Scalar const *input) -> uni20::make_real_t< Scalar >
Compute a Euclidean norm and return a host real scalar.
Definition level1.hpp:117
auto dotc(ExecutionLease &execution, int size, Scalar const *lhs, Scalar const *rhs) -> Scalar
Compute the conjugate-linear dot product and return a host scalar.
Definition level1.hpp:62
ExecutionPool & execution_pool(cuda::DeviceResources &resources)
Return the lazily constructed cuBLAS execution pool for one CUDA device.
Definition cublas/execution.cpp:215
Definition linalg/async.hpp:28
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
constexpr KernelAcceptance< KernelTypeAcceptance::no > kernel_types_no
Report that a backend rejects the argument types.
Definition dispatch_error.hpp:34
consteval auto kernel_accepts_types(BlasBackend, gemm_op const &, C &, S const &, A &, B &, S const &)
Accept host-readable native binary80 operands, including transforming accessors.
Definition linalg/backends/blas/binary80.hpp:19
constexpr KernelAcceptance< KernelTypeAcceptance::maybe > kernel_types_maybe
Report that runtime operand values determine backend acceptance.
Definition dispatch_error.hpp:37
std::size_t span
Definition presentation.cpp:2017
Accessor for a CUDA mdspan whose device pointer has been leased.
Definition cuda_accessor.hpp:80
Backend value for cuBLAS dense linalg kernels.
Definition backend_selector.hpp:34
Conjugate-linear-left tensor inner-product operation tag.
Definition operation_tags.hpp:105
Euclidean tensor norm operation tag.
Definition operation_tags.hpp:111
Trait to extract the scalar type from a type T.
Definition scalar_traits.hpp:93
#define CHECK(cond,...)
Definition trace.hpp:299
#define CHECK_EQUAL(a, b,...)
Definition trace.hpp:309