Uni20
Asynchronous tensor and runtime library.
Loading...
Searching...
No Matches
backends/cpu/matrix_norm.hpp
Go to the documentation of this file.
1#pragma once
2
9#include "reductions.hpp"
10
21
22#include <algorithm>
23#include <cmath>
24#include <cstddef>
25#include <type_traits>
26#include <utility>
27
28namespace uni20::linalg
29{
30namespace detail::cpu_reference
31{
32
33template <class Result, class Candidate> void update_matrix_norm_max(Result& result, Candidate candidate)
34{
35 if (!(candidate == candidate))
36 {
37 result = candidate;
38 }
39 else if (candidate > result)
40 {
41 result = candidate;
42 }
43}
44
45template <class MatrixMdspan> consteval bool matrix_norm_input_is_supported()
46{
47 using matrix_type = std::remove_cvref_t<MatrixMdspan>;
48 using scalar_type = typename matrix_type::value_type;
49 if constexpr (!uni20::RealOrComplex<scalar_type> ||
50 !uni20::linalg::detail::reduction_value_is_readable<MatrixMdspan>())
51 {
52 return false;
53 }
54 else
55 {
56 using result_type = uni20::make_real_t<scalar_type>;
57 return requires(result_type result) { backends::cpu::detail::CompensatedRealSum<result_type>{}.add(result); };
58 }
59}
60
61template <class MatrixMdspan> auto matrix_norm(matrix_norm_op const& op, MatrixMdspan& matrix)
62{
63 using matrix_type = std::remove_cvref_t<MatrixMdspan>;
64 using scalar_type = typename matrix_type::value_type;
65 using result_type = uni20::make_real_t<scalar_type>;
66 using index_type = typename matrix_type::index_type;
67
68 auto magnitude = [&](index_type row, index_type col) {
69 using std::abs;
70 return static_cast<result_type>(abs(static_cast<scalar_type>(matrix[row, col])));
71 };
72
73 if (op.kind == MatrixNorm::Frobenius)
74 {
75 result_type result{};
76 uni20::linalg::detail::reference_norm(result, matrix);
77 return result;
78 }
79
80 result_type result{};
81 switch (op.kind)
82 {
84 for (index_type row = 0; row < matrix.extent(0); ++row)
85 for (index_type col = 0; col < matrix.extent(1); ++col)
86 update_matrix_norm_max(result, magnitude(row, col));
87 return result;
88
89 case MatrixNorm::One:
90 for (index_type col = 0; col < matrix.extent(1); ++col)
91 {
92 backends::cpu::detail::CompensatedRealSum<result_type> sum;
93 for (index_type row = 0; row < matrix.extent(0); ++row)
94 sum.add(magnitude(row, col));
95 update_matrix_norm_max(result, sum.value());
96 }
97 return result;
98
100 for (index_type row = 0; row < matrix.extent(0); ++row)
101 {
102 backends::cpu::detail::CompensatedRealSum<result_type> sum;
103 for (index_type col = 0; col < matrix.extent(1); ++col)
104 sum.add(magnitude(row, col));
105 update_matrix_norm_max(result, sum.value());
106 }
107 return result;
108
110 break;
111 }
112 PANIC("invalid MatrixNorm", std::to_underlying(op.kind));
113}
114
115template <class Output, class MatrixMdspan> consteval auto matrix_norm_acceptance()
116{
117 using scalar_type = typename MatrixMdspan::value_type;
118 using result_type = uni20::make_real_t<scalar_type>;
119 if constexpr (matrix_norm_input_is_supported<MatrixMdspan>() &&
120 reduction_detail::output_is_supported<Output, result_type, 0>())
121 return kernel_types_yes;
122 else
123 return kernel_types_no;
124}
125
126} // namespace detail::cpu_reference
127
129template <class Output, uni20::RankedMdspecLike<2> MatrixMdspec>
130 requires reduction_detail::HostOutput<Output> && uni20::HostReadableMdspec<MatrixMdspec>
131consteval auto kernel_accepts_types(CpuReferenceBackend const&, matrix_norm_op const&, Output&, MatrixMdspec&)
132{
133 using output_type = reduction_detail::host_output_t<Output>;
134 using matrix_span = uni20::host_read_mdspan_t<MatrixMdspec>;
135 constexpr auto acceptance = detail::cpu_reference::matrix_norm_acceptance<output_type, matrix_span>();
136 if constexpr (acceptance == KernelTypeAcceptance::yes)
137 return kernel_types_yes;
138 else
139 return kernel_types_no;
140}
141
143template <class Output, uni20::RankedMdspecLike<2> MatrixMdspec>
144 requires reduction_detail::HostOutput<Output> && uni20::HostReadableMdspec<MatrixMdspec>
145KernelAttempt try_kernel(CpuReferenceBackend, matrix_norm_op const& operation, Output& output, MatrixMdspec& matrix)
146{
147 auto matrix_access = acquire_host_read_access_sync(matrix);
148 auto matrix_span = matrix_access.mdspan();
149 return reduction_detail::with_host_output(output, [&](auto& resolved_output) {
150 auto result = detail::cpu_reference::matrix_norm(operation, matrix_span);
151 reduction_detail::write_host_output(resolved_output, result);
153 });
154}
155
156} // namespace uni20::linalg
RAII leases that resolve device descriptors and tensor views to mdspans.
Mdspec metadata supporting host read acquisition.
Definition access.hpp:688
Concept for types that are either real or complex.
Definition scalar_concepts.hpp:87
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
Mdspan concept and accessor extensions for Uni20.
DiagnosticMagnitude< R > magnitude(R const &value)
Definition gmres_diagnostics.hpp:98
typename HostOutputType< Output >::type host_output_t
Resolved output type used by a host reduction backend probe.
Definition reduction_output.hpp:56
void write_host_output(Output &output, Scalar value)
Store a scalar in either a resolved rank-zero mdspan or C++ scalar.
Definition reduction_output.hpp:59
KernelAttempt with_host_output(Output &output, Function &&function)
Invoke a synchronous reduction with a resolved host output.
Definition reduction_output.hpp:68
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
void matrix_norm(BackendSelector selector, async::Async< OutputTensor > &output, async::Async< MatrixTensor > const &matrix, MatrixNorm kind)
Schedule a matrix norm into an explicit async scalar Tensor.
Definition async/matrix_norm.hpp:126
@ One
Induced one-norm: largest column sum of entry magnitudes.
@ MaxAbs
Largest entry magnitude, max_ij abs(A[i,j]).
@ Frobenius
Frobenius norm: square root of the sum of squared entry magnitudes.
@ Infinity
Induced infinity-norm: largest row sum of entry magnitudes.
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
void sum(BackendSelector selector, async::Async< OutputTensor > &output, async::Async< InputTensor > const &input)
Schedule a full sum into an explicit async scalar tensor.
Definition linalg/async/reductions.hpp:309
constexpr auto abs(basic_half_int< T > value) -> basic_half_int< T >
Return the absolute value of a half-integer.
Definition half_int.hpp:431
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::ptrdiff_t index_type
Definition types.hpp:19
Backend-independent operation values used with normalized kernel operands.
Shared host-output handling for synchronous scalar reductions.
Backend value for the reference host CPU dense linalg oracle.
Definition backend_selector.hpp:55
Dense rank-two matrix norm operation tag.
Definition operation_tags.hpp:135
Concepts for tensor-level objects that resolve mdspan kernel operands.
Tensor sums, inner products, and Euclidean norms with explicit result residency.
#define PANIC(...)
Definition trace.hpp:382