Uni20
Asynchronous tensor and runtime library.
Loading...
Searching...
No Matches
async/qr.hpp
Go to the documentation of this file.
1#pragma once
2
13#include <uni20/async/async.hpp>
16
17#include <type_traits>
18#include <utility>
19
20namespace uni20::linalg
21{
22namespace detail
23{
24template <class MatrixTensor>
25using preserving_qr_result_t = std::remove_cvref_t<decltype(uni20::linalg::qr(std::declval<MatrixTensor const&>()))>;
26
27template <class MatrixTensor>
28using consuming_qr_result_t = std::remove_cvref_t<decltype(uni20::linalg::qr(std::declval<MatrixTensor&&>()))>;
29
30template <class Result>
31using async_qr_result_t =
32 QrResult<async::Async<typename Result::q_tensor_type>, async::Async<typename Result::r_tensor_type>>;
33
34template <KernelBackendSelector BackendSelector, class QTensor, class RTensor, uni20::RankedTensorView<2> MatrixTensor>
35async::AsyncTask co_preserving_qr(BackendSelector const selector, async::WriteBuffer<QTensor> q,
37 std::optional<Precision> requested = {})
38{
39 auto q_storage_awaiter = q.storage();
40 auto r_storage_awaiter = r.storage();
41 auto& q_storage = co_await q_storage_awaiter;
42 auto& r_storage = co_await r_storage_awaiter;
43 auto const& matrix_value = co_await matrix;
44
45 auto result = uni20::linalg::qr(selector, matrix_value, requested);
46 q_storage.emplace(std::move(result.q));
47 r_storage.emplace(std::move(result.r));
48 co_return;
49}
50
51template <KernelBackendSelector BackendSelector, class QTensor, class RTensor,
54async::AsyncTask co_consuming_qr(BackendSelector const selector, async::WriteBuffer<QTensor> q,
56 std::optional<Precision> requested = {})
57{
58 auto q_storage_awaiter = q.storage();
59 auto r_storage_awaiter = r.storage();
60 auto& q_storage = co_await q_storage_awaiter;
61 auto& r_storage = co_await r_storage_awaiter;
62 // Retain the consumed writer gate until both outputs commit, so a failure is
63 // published to the input and both independent result epochs.
64 auto matrix_value = co_await matrix.take();
65
66 auto result = uni20::linalg::qr(selector, std::move(matrix_value), requested);
67 q_storage.emplace(std::move(result.q));
68 r_storage.emplace(std::move(result.r));
69 co_return;
70}
71
72template <KernelBackendSelector BackendSelector, uni20::RankedTensorView<2> MatrixTensor>
73[[nodiscard]] auto schedule_preserving_qr(BackendSelector selector, async::Async<MatrixTensor> const& matrix,
74 std::optional<Precision> requested = {})
75{
76 using result_type = preserving_qr_result_t<MatrixTensor>;
77 async_qr_result_t<result_type> outputs;
78 outputs.q.debug_name("qr.q");
79 outputs.r.debug_name("qr.r");
80
81 auto task = co_preserving_qr(std::move(selector), outputs.q.write(), outputs.r.write(), matrix.read(), requested);
82 task.debug_name("qr");
83 async::schedule(std::move(task));
84 return outputs;
85}
86
87template <KernelBackendSelector BackendSelector, uni20::MutableRankedTensorView<2> MatrixTensor>
89[[nodiscard]] auto schedule_consuming_qr(BackendSelector selector, async::Async<MatrixTensor>& matrix,
90 std::optional<Precision> requested = {})
91{
92 using result_type = consuming_qr_result_t<MatrixTensor>;
93 async_qr_result_t<result_type> outputs;
94 outputs.q.debug_name("qr.q");
95 outputs.r.debug_name("qr.r");
96
97 auto task = co_consuming_qr(std::move(selector), outputs.q.write(), outputs.r.write(), matrix.write(), requested);
98 task.debug_name("qr");
99 async::schedule(std::move(task));
100 return outputs;
101}
102} // namespace detail
103
107template <KernelBackendSelector BackendSelector, uni20::RankedTensorView<2> MatrixTensor>
108 requires detail::DecompositionScalar<uni20::tensor_element_t<MatrixTensor>>
109[[nodiscard]] auto qr(BackendSelector selector, async::Async<MatrixTensor> const& matrix,
110 std::optional<Precision> requested = {})
111{
112 return detail::schedule_preserving_qr(std::move(selector), matrix, requested);
113}
114
118template <uni20::RankedTensorView<2> MatrixTensor>
119 requires detail::DecompositionScalar<uni20::tensor_element_t<MatrixTensor>>
120[[nodiscard]] auto qr(async::Async<MatrixTensor> const& matrix, std::optional<Precision> requested = {})
121{
122 using work_type = detail::qr_matrix_tensor_t<MatrixTensor>;
123 auto selector = detail::select_qr_backend<work_type>();
124 return detail::schedule_preserving_qr(std::move(selector), matrix, requested);
125}
126
131template <KernelBackendSelector BackendSelector, class MatrixTensor>
133 detail::DecompositionScalar<uni20::tensor_element_t<MatrixTensor>>
134[[nodiscard]] auto qr(BackendSelector selector, async::Async<MatrixTensor>&& matrix,
135 std::optional<Precision> requested = {})
136{
137 return detail::schedule_consuming_qr(std::move(selector), matrix, requested);
138}
139
141template <class MatrixTensor>
143 detail::DecompositionScalar<uni20::tensor_element_t<MatrixTensor>>
144[[nodiscard]] auto qr(async::Async<MatrixTensor>&& matrix, std::optional<Precision> requested = {})
145{
146 using work_type = std::conditional_t<detail::can_use_qr_storage_as_workspace<MatrixTensor>(),
147 std::remove_cvref_t<MatrixTensor>, detail::qr_matrix_tensor_t<MatrixTensor>>;
148 auto selector = detail::select_qr_backend<work_type>();
149 return detail::schedule_consuming_qr(std::move(selector), matrix, requested);
150}
151
152} // namespace uni20::linalg
The Async<T> container: coroutine‐safe asynchronous read/write.
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
WriteBuffer< T > write()
Begin exclusive asynchronous access to the payload.
Definition async/async.hpp:346
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
auto take() &
Awaiter that takes the stored value.
Definition buffers.hpp:994
MutableTensorView with a specified static rank.
Definition tensor/concepts.hpp:166
Tensor-level object that owns the storage described by its multidimensional view.
Definition tensor/concepts.hpp:116
Coroutine scheduler for AsyncTask.
void schedule(AsyncTask &&task)
Schedule a task on the currently configured global scheduler.
Definition debug_scheduler.hpp:237
Definition linalg/async.hpp:28
auto qr(BackendSelector selector, async::Async< MatrixTensor > const &matrix, std::optional< Precision > requested={})
Schedule a preserving reduced real or complex QR factorization through an explicit selector.
Definition async/qr.hpp:109
Destructive-workspace and value-producing reduced real or complex QR factorizations.