Uni20
Asynchronous tensor and runtime library.
Loading...
Searching...
No Matches
async/lq.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_lq_result_t = std::remove_cvref_t<decltype(uni20::linalg::lq(std::declval<MatrixTensor const&>()))>;
26
27template <class MatrixTensor>
28using consuming_lq_result_t = std::remove_cvref_t<decltype(uni20::linalg::lq(std::declval<MatrixTensor&&>()))>;
29
30template <class Result>
31using async_lq_result_t =
32 LqResult<async::Async<typename Result::l_tensor_type>, async::Async<typename Result::q_tensor_type>>;
33
34template <KernelBackendSelector BackendSelector, class LTensor, class QTensor, uni20::RankedTensorView<2> MatrixTensor>
35async::AsyncTask co_preserving_lq(BackendSelector const selector, async::WriteBuffer<LTensor> l,
37 std::optional<Precision> requested = {})
38{
39 auto l_storage_awaiter = l.storage();
40 auto q_storage_awaiter = q.storage();
41 auto& l_storage = co_await l_storage_awaiter;
42 auto& q_storage = co_await q_storage_awaiter;
43 auto const& matrix_value = co_await matrix;
44
45 auto result = uni20::linalg::lq(selector, matrix_value, requested);
46 l_storage.emplace(std::move(result.l));
47 q_storage.emplace(std::move(result.q));
48 co_return;
49}
50
51template <KernelBackendSelector BackendSelector, class LTensor, class QTensor,
54async::AsyncTask co_consuming_lq(BackendSelector const selector, async::WriteBuffer<LTensor> l,
56 std::optional<Precision> requested = {})
57{
58 auto l_storage_awaiter = l.storage();
59 auto q_storage_awaiter = q.storage();
60 auto& l_storage = co_await l_storage_awaiter;
61 auto& q_storage = co_await q_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::lq(selector, std::move(matrix_value), requested);
67 l_storage.emplace(std::move(result.l));
68 q_storage.emplace(std::move(result.q));
69 co_return;
70}
71
72template <KernelBackendSelector BackendSelector, uni20::RankedTensorView<2> MatrixTensor>
73[[nodiscard]] auto schedule_preserving_lq(BackendSelector selector, async::Async<MatrixTensor> const& matrix,
74 std::optional<Precision> requested = {})
75{
76 using result_type = preserving_lq_result_t<MatrixTensor>;
77 async_lq_result_t<result_type> outputs;
78 outputs.l.debug_name("lq.l");
79 outputs.q.debug_name("lq.q");
80
81 auto task = co_preserving_lq(std::move(selector), outputs.l.write(), outputs.q.write(), matrix.read(), requested);
82 task.debug_name("lq");
83 async::schedule(std::move(task));
84 return outputs;
85}
86
87template <KernelBackendSelector BackendSelector, uni20::MutableRankedTensorView<2> MatrixTensor>
89[[nodiscard]] auto schedule_consuming_lq(BackendSelector selector, async::Async<MatrixTensor>& matrix,
90 std::optional<Precision> requested = {})
91{
92 using result_type = consuming_lq_result_t<MatrixTensor>;
93 async_lq_result_t<result_type> outputs;
94 outputs.l.debug_name("lq.l");
95 outputs.q.debug_name("lq.q");
96
97 auto task = co_consuming_lq(std::move(selector), outputs.l.write(), outputs.q.write(), matrix.write(), requested);
98 task.debug_name("lq");
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 lq(BackendSelector selector, async::Async<MatrixTensor> const& matrix,
110 std::optional<Precision> requested = {})
111{
112 return detail::schedule_preserving_lq(std::move(selector), matrix, requested);
113}
114
118template <uni20::RankedTensorView<2> MatrixTensor>
119 requires detail::DecompositionScalar<uni20::tensor_element_t<MatrixTensor>>
120[[nodiscard]] auto lq(async::Async<MatrixTensor> const& matrix, std::optional<Precision> requested = {})
121{
122 using work_type = detail::lq_matrix_tensor_t<MatrixTensor>;
123 auto selector = detail::select_lq_backend<work_type>();
124 return detail::schedule_preserving_lq(std::move(selector), matrix, requested);
125}
126
131template <KernelBackendSelector BackendSelector, class MatrixTensor>
133 detail::DecompositionScalar<uni20::tensor_element_t<MatrixTensor>>
134[[nodiscard]] auto lq(BackendSelector selector, async::Async<MatrixTensor>&& matrix,
135 std::optional<Precision> requested = {})
136{
137 return detail::schedule_consuming_lq(std::move(selector), matrix, requested);
138}
139
141template <class MatrixTensor>
143 detail::DecompositionScalar<uni20::tensor_element_t<MatrixTensor>>
144[[nodiscard]] auto lq(async::Async<MatrixTensor>&& matrix, std::optional<Precision> requested = {})
145{
146 using work_type = std::conditional_t<detail::can_use_lq_storage_as_workspace<MatrixTensor>(),
147 std::remove_cvref_t<MatrixTensor>, detail::lq_matrix_tensor_t<MatrixTensor>>;
148 auto selector = detail::select_lq_backend<work_type>();
149 return detail::schedule_consuming_lq(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 lq(BackendSelector selector, async::Async< MatrixTensor > const &matrix, std::optional< Precision > requested={})
Schedule a preserving reduced real or complex LQ factorization through an explicit selector.
Definition async/lq.hpp:109
Destructive-workspace and value-producing reduced real or complex LQ factorizations.