30template <
class Mdspan>
consteval bool transform_value_is_readable()
32 using span_type = std::remove_cvref_t<Mdspan>;
33 return requires(
typename span_type::reference element) {
static_cast<typename span_type::value_type
>(element); };
36template <
class OutputMdspan,
class Function,
class... InputMdspans>
consteval bool overwrite_transform_is_supported()
38 using output_type = std::remove_cvref_t<OutputMdspan>;
41 !((output_type::rank() == std::remove_cvref_t<InputMdspans>::rank()) && ...))
47 return (transform_value_is_readable<InputMdspans>() && ...) &&
48 std::invocable<Function const&, typename std::remove_cvref_t<InputMdspans>::value_type...>&&
49 requires(
typename output_type::reference output, Function
const& function)
51 output = std::invoke(function, std::declval<
typename std::remove_cvref_t<InputMdspans>::value_type>()...);
56template <
class OutputMdspan,
class Function,
class... InputMdspans>
consteval bool update_transform_is_supported()
58 using output_type = std::remove_cvref_t<OutputMdspan>;
61 !((output_type::rank() == std::remove_cvref_t<InputMdspans>::rank()) && ...))
67 return transform_value_is_readable<OutputMdspan>() && (transform_value_is_readable<InputMdspans>() && ...) &&
68 std::invocable<Function
const&,
typename output_type::value_type,
69 typename std::remove_cvref_t<InputMdspans>::value_type...>&&
70 requires(
typename output_type::reference output, Function
const& function)
72 output = std::invoke(function, std::declval<typename output_type::value_type>(),
73 std::declval<
typename std::remove_cvref_t<InputMdspans>::value_type>()...);
78template <
class OutputMdspan,
class... InputMdspans>
79void check_transform_extents(OutputMdspan
const& output, InputMdspans
const&... inputs)
81 if constexpr (
sizeof...(InputMdspans) > 0)
83 constexpr std::size_t rank = std::remove_cvref_t<OutputMdspan>::rank();
84 if constexpr (rank > 0)
86 auto check_input = [&](
auto const& input) {
87 for (std::size_t axis = 0; axis < rank; ++axis)
88 CHECK_EQUAL(output.extent(axis), input.extent(axis));
90 (check_input(inputs), ...);
95template <
class Mdspan,
class Index, std::size_t... Axis>
96decltype(
auto) transform_element(Mdspan&&
span, Index
const& index, std::index_sequence<Axis...>)
98 using span_type = std::remove_cvref_t<Mdspan>;
99 using index_type =
typename span_type::index_type;
100 return std::forward<Mdspan>(
span)[
static_cast<index_type>(index[Axis])...];
103template <
bool ReadsOutput,
class Operation,
class OutputMdspan,
class Index,
class... InputMdspans>
104void apply_transform_element(Operation
const& operation, OutputMdspan& output, Index
const& index,
105 InputMdspans&... inputs)
107 constexpr auto axes = std::make_index_sequence<std::remove_cvref_t<OutputMdspan>::rank()>{};
108 auto&& output_element = transform_element(output, index, axes);
109 if constexpr (ReadsOutput)
111 using output_value =
typename std::remove_cvref_t<OutputMdspan>::value_type;
112 output_element = std::invoke(
113 operation.function,
static_cast<output_value
>(output_element),
114 static_cast<typename std::remove_cvref_t<InputMdspans>::value_type
>(transform_element(inputs, index, axes))...);
118 output_element = std::invoke(
120 static_cast<typename std::remove_cvref_t<InputMdspans>::value_type
>(transform_element(inputs, index, axes))...);
124template <std::size_t Axis,
bool ReadsOutput,
class Operation,
class OutputMdspan,
class Index,
class... InputMdspans>
125void transform_elements(Operation
const& operation, OutputMdspan& output, Index& index, InputMdspans&... inputs)
127 if constexpr (Axis == std::remove_cvref_t<OutputMdspan>::rank())
129 apply_transform_element<ReadsOutput>(operation, output, index, inputs...);
133 using output_index =
typename std::remove_cvref_t<OutputMdspan>::index_type;
134 for (output_index i = 0; i < static_cast<output_index>(output.extent(Axis)); ++i)
137 transform_elements<Axis + 1, ReadsOutput>(operation, output, index, inputs...);
142template <
bool ReadsOutput,
class Operation,
class OutputMdspan,
class... InputMdspans>
143void reference_transform(Operation
const& operation, OutputMdspan& output, InputMdspans&... inputs)
145 using output_type = std::remove_cvref_t<OutputMdspan>;
149 if constexpr (ReadsOutput)
151 auto invoke_with_values = [&operation](
auto&& output_value,
auto&&... input_values) {
152 return std::invoke(operation.function,
static_cast<typename output_type::value_type
>(output_value),
153 static_cast<typename std::remove_cvref_t<InputMdspans>::value_type
>(input_values)...);
155 cpu::detail::transform_strided<true>(output, std::cref(invoke_with_values), inputs...);
159 auto invoke_with_values = [&operation](
auto&&... input_values) {
160 return std::invoke(operation.function,
161 static_cast<typename std::remove_cvref_t<InputMdspans>::value_type
>(input_values)...);
163 cpu::detail::transform_strided<false>(output, std::cref(invoke_with_values), inputs...);
168 std::array<
typename output_type::index_type, output_type::rank()> index{};
169 transform_elements<0, ReadsOutput>(operation, output, index, inputs...);
182 if constexpr (detail::overwrite_transform_is_supported<output_span, Function,
193 InputMdspans&... inputs)
198 [&](
auto&... input_access) {
199 auto output_span = output_access.mdspan();
200 detail::check_transform_extents(output_span, input_access.mdspan()...);
201 detail::reference_transform<false>(operation, output_span, input_access.mdspan()...);
214 if constexpr (detail::update_transform_is_supported<output_span, Function,
225 InputMdspans&... inputs)
230 [&](
auto&... input_access) {
231 auto output_span = output_access.mdspan();
232 detail::check_transform_extents(output_span, input_access.mdspan()...);
233 detail::reference_transform<true>(operation, output_span, input_access.mdspan()...);
RAII leases that resolve device descriptors and tensor views to mdspans.
Mdspec metadata supporting host read acquisition.
Definition access.hpp:688
Mutable mdspec metadata supporting host write acquisition.
Definition access.hpp:694
A readable type implementing the mdspan observers and multidimensional subscript contract.
Definition mdspan/concepts.hpp:291
Mdspan metadata whose data handle is immediate or available through a data descriptor.
Definition mdspan/concepts.hpp:304
MdspanLike types whose accessor supports indexed assignment.
Definition mdspan/concepts.hpp:387
MdspecLike types whose eventual storage supports writes.
Definition mdspan/concepts.hpp:398
Mutable mdspan-like types whose layout reports they are always strided.
Definition mdspan/concepts.hpp:421
An mdspan-like type whose mapping is always strided and exposes stride observers.
Definition mdspan/concepts.hpp:406
Operation-tag backend dispatch over tensor-view operands.
Mdspan concept and accessor extensions for Uni20.
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::yes > kernel_types_yes
Report that a backend accepts every instance of the argument types.
Definition dispatch_error.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
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
std::ptrdiff_t index_type
Definition types.hpp:19
auto acquire_host_write_access_sync(Mdspan &mdspan)
Acquire a directly host-accessible writable mdspan.
Definition access.hpp:626
std::size_t span
Definition presentation.cpp:2017
Backend value for the reference host CPU dense linalg oracle.
Definition backend_selector.hpp:55
Concepts for tensor-level objects that resolve mdspan kernel operands.
#define CHECK_EQUAL(a, b,...)
Definition trace.hpp:309