9#include <uni20/config.hpp>
10#if UNI20_HAS_MPLAPACK_MPREAL
29namespace detail::blas_backend
32template <
class OutputTensor>
33using output_mdspec_t = std::remove_cvref_t<decltype(uni20::mdspec_of(std::declval<OutputTensor&>()))>;
37template <
class OutputTensor,
class LhsMdspan,
class RhsMdspan>
41template <
class OutputMdspan,
class Scalar,
class LhsMdspan,
class RhsMdspan>
42consteval bool gemm_mdspan_types_compatible()
47 return requires(output_span& output, Scalar alpha, lhs_span& lhs, rhs_span& rhs) {
52template <
class OutputTensor,
class Scalar,
class LhsMdspan,
class RhsMdspan>
53consteval bool assign_product_types_compatible()
55 using output_span = std::remove_cvref_t<decltype(uni20::mdspec_of(std::declval<OutputTensor&>()))>;
56 return gemm_mdspan_types_compatible<output_span, Scalar, LhsMdspan, RhsMdspan>();
59template <uni20::MutableRankedMdspecLike<2> OutputMdspan,
class Scalar, uni20::RankedMdspecLike<2> LhsMdspan,
60 uni20::RankedMdspecLike<2> RhsMdspan>
63KernelAttempt try_gemm(OutputMdspan& output, Scalar alpha, LhsMdspan& lhs, RhsMdspan& rhs, Scalar
beta)
68 auto output_span = output_access.mdspan();
69 auto lhs_span = lhs_access.mdspan();
70 auto rhs_span = rhs_access.mdspan();
74template <
class OutputTensor>
75auto prepared_output_mapping(
typename output_mdspan_t<OutputTensor>::extents_type
const& extents) ->
76 typename output_mdspan_t<OutputTensor>::mapping_type
78 using output_span = output_mdspan_t<OutputTensor>;
80 if constexpr (!std::is_void_v<storage_policy>)
82 if constexpr (
requires {
typename storage_policy::default_mapping_builder; })
84 using builder_type =
typename storage_policy::default_mapping_builder;
86 typename output_span::extents_type>)
88 return builder_type{}(extents);
92 return uni20::layout::make_mapping<typename output_span::layout_type>(extents);
95template <
class OutputTensor>
96concept PreparedOutputProbeAvailable =
97 std::default_initializable<typename output_mdspan_t<OutputTensor>::data_handle_type> &&
98 std::default_initializable<typename output_mdspan_t<OutputTensor>::accessor_type> &&
99 requires(
typename output_mdspan_t<OutputTensor>::extents_type
const& extents) {
101 prepared_output_mapping<OutputTensor>(extents)
102 } -> std::same_as<typename output_mdspan_t<OutputTensor>::mapping_type>;
103 output_mdspan_t<OutputTensor>{
typename output_mdspan_t<OutputTensor>::data_handle_type{},
104 prepared_output_mapping<OutputTensor>(extents),
105 typename output_mdspan_t<OutputTensor>::accessor_type{}};
108template <
class OutputTensor>
109 requires PreparedOutputProbeAvailable<OutputTensor>
110auto prepared_output_probe(matrix_product_extents
const& shape) -> output_mdspan_t<OutputTensor>
112 using output_span = output_mdspan_t<OutputTensor>;
113 auto const extents = uni20::convert_tensor_extents<typename output_span::extents_type>(shape);
114 return output_span{
typename output_span::data_handle_type{}, prepared_output_mapping<OutputTensor>(extents),
115 typename output_span::accessor_type{}};
118template <
class OutputTensor,
class Scalar,
class LhsMdspan,
class RhsMdspan>
119KernelAttempt probe_assign_product(matrix_product_extents
const& shape, LhsMdspan& lhs, RhsMdspan& rhs)
121 if constexpr (!PreparedOutputProbeAvailable<OutputTensor>)
127 auto output_span = prepared_output_probe<OutputTensor>(shape);
128 return uni20::linalg::blas::probe_gemm<Scalar>(output_span, lhs, rhs);
135template <uni20::MutableRankedMdspecLike<2> OutputMdspan,
class Scalar, uni20::RankedMdspecLike<2> LhsMdspan,
136 uni20::RankedMdspecLike<2> RhsMdspan>
139consteval auto kernel_accepts_types(BlasBackend
const&, gemm_op
const&, OutputMdspan&, Scalar
const&, LhsMdspan&,
140 RhsMdspan&, Scalar
const&)
142 if constexpr (detail::blas_backend::gemm_mdspan_types_compatible<OutputMdspan, Scalar, LhsMdspan, RhsMdspan>())
149template <uni20::MutableRankedMdspecLike<2> OutputMdspan,
class Scalar, uni20::RankedMdspecLike<2> LhsMdspan,
150 uni20::RankedMdspecLike<2> RhsMdspan>
154 RhsMdspan& rhs, Scalar
beta)
156 return detail::blas_backend::try_gemm(output, alpha, lhs, rhs,
beta);
160template <uni20::MutableRankedTensorView<2> OutputTensor,
class Scalar, uni20::RankedMdspecLike<2> LhsMdspan,
161 uni20::RankedMdspecLike<2> RhsMdspan>
162 requires BlasScalar<Scalar> && detail::blas_backend::HostAssignProductAccess<OutputTensor, LhsMdspan, RhsMdspan>
163consteval auto kernel_accepts_types(BlasBackend
const&, assign_product_op
const&, OutputTensor&, Scalar
const&,
164 LhsMdspan&, RhsMdspan&)
166 if constexpr (detail::blas_backend::assign_product_types_compatible<OutputTensor, Scalar, LhsMdspan, RhsMdspan>())
177template <uni20::MutableRankedTensorView<2> OutputTensor,
class Scalar, uni20::RankedMdspecLike<2> LhsMdspan,
178 uni20::RankedMdspecLike<2> RhsMdspan>
179 requires BlasScalar<Scalar> && detail::blas_backend::HostAssignProductAccess<OutputTensor, LhsMdspan, RhsMdspan>
180KernelAttempt try_kernel(BlasBackend, assign_product_op
const&, OutputTensor& output, Scalar alpha, LhsMdspan& lhs,
183 auto const shape = detail::matrix_product_shape(lhs, rhs);
187 return detail::blas_backend::try_gemm(output_span, alpha, lhs, rhs, Scalar{});
195 KernelAttempt const probe = detail::blas_backend::probe_assign_product<OutputTensor, Scalar>(shape, lhs, rhs);
200 KernelAttempt const attempt = detail::blas_backend::try_gemm(output_span, alpha, lhs, rhs, Scalar{});
206template <uni20::MutableRankedTensorView<2> OutputTensor,
class Scalar, uni20::RankedMdspecLike<2> LhsMdspan,
207 uni20::RankedMdspecLike<2> RhsMdspan>
208 requires BlasScalar<Scalar> && detail::blas_backend::HostAssignProductAccess<OutputTensor, LhsMdspan, RhsMdspan>
210 Scalar
const&, LhsMdspan&, RhsMdspan&)
212 if constexpr (detail::blas_backend::assign_product_types_compatible<OutputTensor, Scalar, LhsMdspan, RhsMdspan>())
219template <uni20::MutableRankedTensorView<2> OutputTensor,
class Scalar, uni20::RankedMdspecLike<2> LhsMdspan,
220 uni20::RankedMdspecLike<2> RhsMdspan>
221 requires BlasScalar<Scalar> && detail::blas_backend::HostAssignProductAccess<OutputTensor, LhsMdspan, RhsMdspan> &&
229 if (output_storage.
constructed())
return try_kernel(backend, assign_product_op{}, *output_storage, alpha, lhs, rhs);
231 auto const shape = detail::matrix_product_shape(lhs, rhs);
232 KernelAttempt const probe = detail::blas_backend::probe_assign_product<OutputTensor, Scalar>(shape, lhs, rhs);
237 KernelAttempt const attempt = detail::blas_backend::try_gemm(output_span, alpha, lhs, rhs, Scalar{});
RAII leases that resolve device descriptors and tensor views to mdspans.
A lightweight, thread-safe, reference-counted storage for a single object.
Definition shared_storage.hpp:94
bool constructed() const noexcept
Reports whether a value is currently constructed.
Definition shared_storage.hpp:234
Mdspec metadata supporting host read acquisition.
Definition access.hpp:688
Mutable mdspec metadata supporting host write acquisition.
Definition access.hpp:694
Mutable tensor output that can replace its shape and storage.
Definition tensor/output.hpp:76
Operation-tag backend dispatch over tensor-view operands.
Direct mdspan GEMM wrappers over the configured BLAS provider.
Backend-independent dense matrix-product shape validation.
KernelAttempt try_gemm(OutputMdspan &&output, Scalar alpha, LhsMdspan &&lhs, RhsMdspan &&rhs, Scalar beta)
Try a direct no-copy BLAS GEMM from mdspan-like operands.
Definition linalg/blas/gemm.hpp:255
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
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
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
std::remove_cvref_t< decltype(std::declval< detail::host_read_mdspan_lease_t< Mdspec > & >().mdspan())> host_read_mdspan_t
Read-only mdspan type resolved by host descriptor acquisition.
Definition access.hpp:679
Output & prepare_output(Output &output, RequiredExtents const &required)
Prepare a mutable tensor output with the specified shape.
Definition tensor/output.hpp:104
auto acquire_host_read_access_sync(Mdspan const &mdspan)
Acquire a directly host-accessible read-only mdspan.
Definition access.hpp:616
std::remove_cvref_t< decltype(std::declval< detail::host_write_mdspan_lease_t< Mdspec > & >().mdspan())> host_write_mdspan_t
Writable mdspan type resolved by host descriptor acquisition.
Definition access.hpp:684
constexpr decltype(auto) mdspec_of(Tensor &tensor) noexcept(noexcept(tensor.mdspec()))
Return a tensor's immediate or descriptor-backed multidimensional metadata.
Definition tensor/concepts.hpp:50
mpreal beta(mpreal const &a, mpreal const &x)
Real Beta function; positive rational/integer pairs retain exact values.
Definition mpreal_special.hpp:164
constexpr bool tensor_extents_equal(LhsExtents const &lhs, RhsExtents const &rhs) noexcept
Compare two tensor extent objects by rank and per-axis extent.
Definition tensor/output.hpp:31
auto acquire_host_write_access_sync(Mdspan &mdspan)
Acquire a directly host-accessible writable mdspan.
Definition access.hpp:626
Concepts for tensor-level objects that resolve mdspan kernel operands.
Shape preparation contracts for tensor operation outputs.
#define CHECK(cond,...)
Definition trace.hpp:299