Uni20
Asynchronous tensor and runtime library.
Loading...
Searching...
No Matches
linalg/backends/cpu/copy.hpp
Go to the documentation of this file.
1#pragma once
2
16
17#include <array>
18#include <cstddef>
19#include <type_traits>
20#include <utility>
21
22namespace uni20::linalg
23{
24namespace detail::cpu_reference
25{
26template <class OutputMdspan, class InputMdspan, std::size_t... Axis>
27consteval bool copy_element_is_assignable(std::index_sequence<Axis...>)
28{
29 using output_index = typename OutputMdspan::index_type;
30 using input_index = typename InputMdspan::index_type;
31 return requires(OutputMdspan& output, InputMdspan& input, output_index output_i, input_index input_i) {
32 output.operator[](((void)Axis, output_i)...) = input.operator[](((void)Axis, input_i)...);
33 };
34}
35
36template <class OutputMdspan, class InputMdspan, std::size_t... Axis>
37void copy_element(OutputMdspan& output, InputMdspan& input,
38 std::array<typename OutputMdspan::index_type, OutputMdspan::rank()> const& index,
39 std::index_sequence<Axis...>)
40{
41 using input_index = typename InputMdspan::index_type;
42 output.operator[](index[Axis]...) = input.operator[](static_cast<input_index>(index[Axis])...);
43}
44
45template <std::size_t Depth, bool ColumnMajor, class OutputMdspan, class InputMdspan>
46void copy_elements(OutputMdspan& output, InputMdspan& input,
47 std::array<typename OutputMdspan::index_type, OutputMdspan::rank()>& index)
48{
49 if constexpr (Depth == OutputMdspan::rank())
50 {
51 copy_element(output, input, index, std::make_index_sequence<OutputMdspan::rank()>{});
52 }
53 else
54 {
55 constexpr std::size_t axis = ColumnMajor ? OutputMdspan::rank() - Depth - 1 : Depth;
56 using output_index = typename OutputMdspan::index_type;
57 for (output_index i = 0; i < static_cast<output_index>(output.extent(axis)); ++i)
58 {
59 index[axis] = i;
60 copy_elements<Depth + 1, ColumnMajor>(output, input, index);
61 }
62 }
63}
64
66template <uni20::MutableMdspanLike OutputMdspan, uni20::MdspanLike InputMdspan> consteval auto copy_acceptance()
67{
68 if constexpr (OutputMdspan::rank() == InputMdspan::rank() &&
69 copy_element_is_assignable<OutputMdspan, InputMdspan>(std::make_index_sequence<OutputMdspan::rank()>{}))
70 {
71 return kernel_types_yes;
72 }
73 else
74 {
75 return kernel_types_no;
76 }
77}
78
81template <uni20::MutableMdspanLike OutputMdspan, uni20::MdspanLike InputMdspan>
82KernelAttempt copy(OutputMdspan&& output, InputMdspan&& input)
83{
84 using output_type = std::remove_cvref_t<OutputMdspan>;
85 static_assert(output_type::rank() == std::remove_cvref_t<InputMdspan>::rank());
86
87 if constexpr (output_type::rank() > 0)
88 {
89 for (std::size_t axis = 0; axis < output_type::rank(); ++axis)
90 CHECK_EQUAL(output.extent(axis), input.extent(axis));
91 }
92
95 {
96 cpu::detail::transform_strided<false>(
97 output, [](auto&& value) -> decltype(auto) { return std::forward<decltype(value)>(value); }, input);
98 }
99 else
100 {
101 std::array<typename output_type::index_type, output_type::rank()> index{};
102 if constexpr (std::same_as<typename output_type::layout_type, stdex::layout_left>)
103 copy_elements<0, true>(output, input, index);
104 else
105 copy_elements<0, false>(output, input, index);
106 }
108}
109} // namespace detail::cpu_reference
110
112template <uni20::MutableMdspecLike OutputMdspan, uni20::MdspecLike InputMdspan>
114consteval auto kernel_accepts_types(CpuReferenceBackend const&, copy_op const&, OutputMdspan&, InputMdspan&)
115{
118 constexpr auto acceptance = detail::cpu_reference::copy_acceptance<output_span, input_span>();
119 if constexpr (acceptance == KernelTypeAcceptance::yes)
120 return kernel_types_yes;
121 else
122 return kernel_types_no;
123}
124
126template <uni20::MutableMdspecLike OutputMdspan, uni20::MdspecLike InputMdspan>
128KernelAttempt try_kernel(CpuReferenceBackend, copy_op const&, OutputMdspan& output, InputMdspan& input)
129{
130 auto output_access = acquire_host_write_access_sync(output);
131 auto input_access = acquire_host_read_access_sync(input);
132 auto output_span = output_access.mdspan();
133 auto input_span = input_access.mdspan();
134 return detail::cpu_reference::copy(output_span, input_span);
135}
136
137} // namespace uni20::linalg
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
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
locale_t value
Definition data_table.cpp:49
Operation-tag backend dispatch over tensor-view operands.
Mdspan concept and accessor extensions for Uni20.
void copy(std::span< Scalar > destination, std::span< Scalar const > source)
Copy a local dense vector.
Definition dense_linalg.hpp:183
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
stdex::layout_left ColumnMajor
Conventional column-major contiguous mdspan layout.
Definition tensor.hpp:33
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
auto acquire_host_write_access_sync(Mdspan &mdspan)
Acquire a directly host-accessible writable mdspan.
Definition access.hpp:626
Backend-independent operation values used with normalized kernel operands.
CPU executor for compact strided elementwise iteration plans.
Backend value for the reference host CPU dense linalg oracle.
Definition backend_selector.hpp:55
Accessor-respecting element copy operation tag.
Definition operation_tags.hpp:33
Concepts for tensor-level objects that resolve mdspan kernel operands.
#define CHECK_EQUAL(a, b,...)
Definition trace.hpp:309