Uni20
Asynchronous tensor and runtime library.
Loading...
Searching...
No Matches
async/matrix_norm.hpp
Go to the documentation of this file.
1#pragma once
2
15
16#include <memory>
17#include <tuple>
18#include <type_traits>
19#include <utility>
20
21namespace uni20::linalg
22{
23namespace detail
24{
25template <class MatrixTensor>
26using preserving_matrix_norm_result_t = std::remove_cvref_t<decltype(uni20::linalg::matrix_norm(
27 std::declval<MatrixTensor const&>(), MatrixNorm::Frobenius))>;
28
29template <class BackendSelector, class ResultTensor, uni20::RankedTensorView<2> MatrixTensor>
30async::AsyncTask co_matrix_norm(BackendSelector const selector, async::WriteBuffer<ResultTensor> output,
32{
33 auto output_storage = output.storage();
34 auto awaited = co_await async::all(output_storage, matrix);
35 auto& storage = std::get<0>(awaited);
36 auto const& matrix_value = std::get<1>(awaited);
37
38 auto result = uni20::linalg::matrix_norm(selector, matrix_value, kind);
39 storage.emplace(std::move(result));
40 co_return;
41}
42
43template <class BackendSelector, uni20::RankedTensorView<2> MatrixTensor>
45co_matrix_norm_host(BackendSelector const selector,
48{
49 auto output_storage = output.storage();
50 auto awaited = co_await async::all(output_storage, matrix);
51 auto& storage = std::get<0>(awaited);
52 auto const& matrix_value = std::get<1>(awaited);
53
54 auto result = uni20::linalg::matrix_norm_host(selector, matrix_value, kind);
55 storage.emplace(std::move(result));
56 co_return;
57}
58
59template <class BackendSelector, uni20::AsyncTensorOutput OutputTensor, uni20::RankedTensorView<2> MatrixTensor>
60async::AsyncTask co_matrix_norm_output(BackendSelector const selector, async::WriteBuffer<OutputTensor> output,
62{
63 if constexpr (async::is_async_alias_v<OutputTensor>)
64 {
65 uni20::detail::AsyncAliasWriteDescriptorAwaiter output_descriptor_awaiter(output);
66 auto awaited = co_await async::all(output_descriptor_awaiter, matrix);
67 auto output_value = std::get<0>(awaited);
68 uni20::linalg::matrix_norm(selector, output_value, std::get<1>(awaited), kind);
69 }
70 else
71 {
72 auto output_storage = output.storage();
73 auto awaited = co_await async::all(output_storage, matrix);
74 auto& output_value = uni20::detail::prepare_async_scalar_output<OutputTensor>(std::get<0>(awaited));
75 uni20::linalg::matrix_norm(selector, output_value, std::get<1>(awaited), kind);
76 }
77 co_return;
78}
79
80template <class BackendSelector, uni20::RankedTensorView<2> MatrixTensor>
81[[nodiscard]] auto schedule_matrix_norm(BackendSelector selector, async::Async<MatrixTensor> const& matrix,
82 MatrixNorm kind)
83{
84 using result_type = preserving_matrix_norm_result_t<MatrixTensor>;
86 output.debug_name("matrix_norm.result");
87 auto task = co_matrix_norm(std::move(selector), output.write(), matrix.read(), kind);
88 task.debug_name("matrix_norm");
89 async::schedule(std::move(task));
90 return output;
91}
92
93template <class BackendSelector, uni20::RankedTensorView<2> MatrixTensor>
94[[nodiscard]] auto schedule_matrix_norm_host(BackendSelector selector, async::Async<MatrixTensor> const& matrix,
95 MatrixNorm kind)
96{
99 output.debug_name("matrix_norm_host.result");
100 auto task = co_matrix_norm_host(std::move(selector), output.write(), matrix.read(), kind);
101 task.debug_name("matrix_norm_host");
102 async::schedule(std::move(task));
103 return output;
104}
105
106template <class BackendSelector, uni20::AsyncTensorOutput OutputTensor, uni20::RankedTensorView<2> MatrixTensor>
107void schedule_matrix_norm_output(BackendSelector selector, async::Async<OutputTensor>& output,
108 async::Async<MatrixTensor> const& matrix, MatrixNorm kind)
109{
110 ERROR_IF(std::addressof(output.queue()) == std::addressof(matrix.queue()),
111 "async matrix-norm output must not share an epoch queue with its input");
112 auto task = co_matrix_norm_output(std::move(selector), output.write(), matrix.read(), kind);
113 task.debug_name("matrix_norm");
114 async::schedule(std::move(task));
115}
116} // namespace detail
117
120template <KernelBackendSelector BackendSelector, uni20::AsyncTensorOutput OutputTensor,
121 uni20::RankedTensorView<2> MatrixTensor>
124 std::same_as<uni20::tensor_element_t<OutputTensor>,
126void matrix_norm(BackendSelector selector, async::Async<OutputTensor>& output, async::Async<MatrixTensor> const& matrix,
127 MatrixNorm kind)
128{
129 detail::schedule_matrix_norm_output(std::move(selector), output, matrix, kind);
130}
131
134template <uni20::AsyncTensorOutput OutputTensor, uni20::RankedTensorView<2> MatrixTensor>
137 std::same_as<uni20::tensor_element_t<OutputTensor>,
140{
141 auto selector = select_backend_for<OutputTensor, MatrixTensor>(matrix_norm_op{.kind = kind});
142 detail::schedule_matrix_norm_output(std::move(selector), output, matrix, kind);
143}
144
146template <KernelBackendSelector BackendSelector, uni20::RankedTensorView<2> MatrixTensor>
148 requires(MatrixTensor const& matrix) { uni20::norm(matrix); }
149[[nodiscard]] auto matrix_norm(BackendSelector selector, async::Async<MatrixTensor> const& matrix, MatrixNorm kind)
150{
151 return detail::schedule_matrix_norm(std::move(selector), matrix, kind);
152}
153
155template <uni20::RankedTensorView<2> MatrixTensor>
157 requires(MatrixTensor const& matrix) { uni20::norm(matrix); }
158[[nodiscard]] auto matrix_norm(async::Async<MatrixTensor> const& matrix, MatrixNorm kind)
159{
160 auto selector = select_backend_for<MatrixTensor>(matrix_norm_op{.kind = kind});
161 return detail::schedule_matrix_norm(std::move(selector), matrix, kind);
162}
163
165template <KernelBackendSelector BackendSelector, uni20::RankedTensorView<2> MatrixTensor>
167[[nodiscard]] auto matrix_norm_host(BackendSelector selector, async::Async<MatrixTensor> const& matrix, MatrixNorm kind)
168{
169 return detail::schedule_matrix_norm_host(std::move(selector), matrix, kind);
170}
171
173template <uni20::RankedTensorView<2> MatrixTensor>
175[[nodiscard]] auto matrix_norm_host(async::Async<MatrixTensor> const& matrix, MatrixNorm kind)
176{
177 auto selector = select_backend_for<MatrixTensor>(matrix_norm_op{.kind = kind});
178 return detail::schedule_matrix_norm_host(std::move(selector), matrix, kind);
179}
180
181} // namespace uni20::linalg
The Async<T> container: coroutine‐safe asynchronous read/write.
Utilities for awaiting on Async<T>: co_await overload, all(), try_await().
Canonical host-oriented coroutine task type.
Definition async_task.hpp:196
Async<T> is a container for coroutine-safe asynchronous read/write.
Definition async/async.hpp:93
ReadBuffer< T > read() const
Begin an asynchronous read of the value.
Definition async/async.hpp:339
EpochQueue const & queue() const
Inspect the shared epoch queue.
Definition async/async.hpp:423
WriteBuffer< T > write()
Begin exclusive asynchronous access to the payload.
Definition async/async.hpp:346
Async & debug_name(std::string const &label)
Assign an optional debug label for task-registry graph output.
Definition async/async.hpp:212
RAII handle for reading the value from an Async container at a given epoch.
Definition buffers.hpp:53
Exclusive mutable-access buffer for one Async<T> epoch.
Definition buffers.hpp:859
auto storage() &
Awaiter yielding direct access to writer shared storage.
Definition buffers.hpp:1029
Mutable Tensor output supported by async operation wrappers.
Definition linalg/async/concepts.hpp:25
MutableTensorView whose writable mdspec has rank zero.
Definition tensor/concepts.hpp:175
TensorView whose readable mdspec has a specified static rank.
Definition tensor/concepts.hpp:149
Concept for types that are either real or complex.
Definition scalar_concepts.hpp:87
Coroutine scheduler for AsyncTask.
typename make_real< T >::type make_real_t
Alias for the underlying real-valued type of T.
Definition scalar_traits.hpp:168
Shared output capabilities for Async Tensor operation wrappers.
void schedule(AsyncTask &&task)
Schedule a task on the currently configured global scheduler.
Definition debug_scheduler.hpp:237
auto all(Aw &&... aw) noexcept
Build an awaitable that waits for all of the provided awaitables.
Definition awaiters.hpp:200
Definition linalg/async.hpp:28
auto matrix_norm_host(BackendSelector selector, async::Async< MatrixTensor > const &matrix, MatrixNorm kind)
Schedule a dense matrix norm returning a host C++ scalar through an explicit selector.
Definition async/matrix_norm.hpp:167
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
MatrixNorm
Matrix norm selected by matrix_norm_op.
Definition operation_tags.hpp:119
@ Frobenius
Frobenius norm: square root of the sum of squared entry magnitudes.
mpreal norm(mpcomplex const &z)
Definition mpcomplex.hpp:494
std::remove_cv_t< typename tensor_mdspec_t< T >::element_type > tensor_element_t
Scalar value type exposed by a tensor-level object.
Definition tensor/concepts.hpp:126
Dense matrix norm front ends over operation-tag dispatch.
Dense rank-two matrix norm operation tag.
Definition operation_tags.hpp:135
MatrixNorm kind
Definition operation_tags.hpp:137
#define ERROR_IF(cond,...)
Definition trace.hpp:389