Uni20
Asynchronous tensor and runtime library.
Loading...
Searching...
No Matches
async/truncated_svd.hpp
Go to the documentation of this file.
1#pragma once
2
13#include <uni20/async/async.hpp>
17
18#include <type_traits>
19#include <utility>
20
21namespace uni20::linalg
22{
23namespace detail
24{
25template <class MatrixTensor>
26using svd_truncation_policy_t = SvdTruncationPolicy<uni20::make_real_t<uni20::tensor_element_t<MatrixTensor>>>;
27
28template <class MatrixTensor>
29using preserving_truncated_svd_result_t = std::remove_cvref_t<decltype(uni20::linalg::truncated_svd(
30 std::declval<MatrixTensor const&>(), std::declval<svd_truncation_policy_t<MatrixTensor>>()))>;
31
32template <class MatrixTensor>
33using consuming_truncated_svd_result_t = std::remove_cvref_t<decltype(uni20::linalg::truncated_svd(
34 std::declval<MatrixTensor&&>(), std::declval<svd_truncation_policy_t<MatrixTensor>>()))>;
35
36template <class Result>
37using async_truncated_svd_result_t =
38 TruncatedSvdResult<async::Async<typename Result::left_singular_vector_tensor_type>,
42
43template <KernelBackendSelector BackendSelector, class LeftTensor, class SingularValueTensor, class RightAdjointTensor,
44 class TruncationInfo, uni20::RankedTensorView<2> MatrixTensor>
46co_preserving_truncated_svd(BackendSelector const selector, async::WriteBuffer<LeftTensor> left_singular_vectors,
48 async::WriteBuffer<RightAdjointTensor> right_singular_vectors_adjoint,
50 svd_truncation_policy_t<MatrixTensor> const policy, std::optional<Precision> requested = {})
51{
52 auto left_storage_awaiter = left_singular_vectors.storage();
53 auto singular_value_storage_awaiter = singular_values.storage();
54 auto right_storage_awaiter = right_singular_vectors_adjoint.storage();
55 auto truncation_storage_awaiter = truncation.storage();
56 auto& left_storage = co_await left_storage_awaiter;
57 auto& singular_value_storage = co_await singular_value_storage_awaiter;
58 auto& right_storage = co_await right_storage_awaiter;
59 auto& truncation_storage = co_await truncation_storage_awaiter;
60 auto const& matrix_value = co_await matrix;
61
62 auto result = uni20::linalg::truncated_svd(selector, matrix_value, policy, requested);
63 left_storage.emplace(std::move(result.left_singular_vectors));
64 singular_value_storage.emplace(std::move(result.singular_values));
65 right_storage.emplace(std::move(result.right_singular_vectors_adjoint));
66 truncation_storage.emplace(std::move(result.truncation));
67 co_return;
68}
69
70template <KernelBackendSelector BackendSelector, class LeftTensor, class SingularValueTensor, class RightAdjointTensor,
71 class TruncationInfo, uni20::MutableRankedTensorView<2> MatrixTensor>
74co_consuming_truncated_svd(BackendSelector const selector, async::WriteBuffer<LeftTensor> left_singular_vectors,
76 async::WriteBuffer<RightAdjointTensor> right_singular_vectors_adjoint,
78 svd_truncation_policy_t<MatrixTensor> const policy, std::optional<Precision> requested = {})
79{
80 auto left_storage_awaiter = left_singular_vectors.storage();
81 auto singular_value_storage_awaiter = singular_values.storage();
82 auto right_storage_awaiter = right_singular_vectors_adjoint.storage();
83 auto truncation_storage_awaiter = truncation.storage();
84 auto& left_storage = co_await left_storage_awaiter;
85 auto& singular_value_storage = co_await singular_value_storage_awaiter;
86 auto& right_storage = co_await right_storage_awaiter;
87 auto& truncation_storage = co_await truncation_storage_awaiter;
88 auto matrix_value = co_await matrix.take();
89
90 auto result = uni20::linalg::truncated_svd(selector, std::move(matrix_value), policy, requested);
91 left_storage.emplace(std::move(result.left_singular_vectors));
92 singular_value_storage.emplace(std::move(result.singular_values));
93 right_storage.emplace(std::move(result.right_singular_vectors_adjoint));
94 truncation_storage.emplace(std::move(result.truncation));
95 co_return;
96}
97
98template <KernelBackendSelector BackendSelector, uni20::RankedTensorView<2> MatrixTensor>
99[[nodiscard]] auto schedule_preserving_truncated_svd(BackendSelector selector, async::Async<MatrixTensor> const& matrix,
100 svd_truncation_policy_t<MatrixTensor> policy,
101 std::optional<Precision> requested = {})
102{
103 using result_type = preserving_truncated_svd_result_t<MatrixTensor>;
104 async_truncated_svd_result_t<result_type> outputs;
105 outputs.left_singular_vectors.debug_name("truncated_svd.left_singular_vectors");
106 outputs.singular_values.debug_name("truncated_svd.singular_values");
107 outputs.right_singular_vectors_adjoint.debug_name("truncated_svd.right_singular_vectors_adjoint");
108 outputs.truncation.debug_name("truncated_svd.truncation");
109
110 auto task =
111 co_preserving_truncated_svd(std::move(selector), outputs.left_singular_vectors.write(),
112 outputs.singular_values.write(), outputs.right_singular_vectors_adjoint.write(),
113 outputs.truncation.write(), matrix.read(), std::move(policy), requested);
114 task.debug_name("truncated_svd");
115 async::schedule(std::move(task));
116 return outputs;
117}
118
119template <KernelBackendSelector BackendSelector, uni20::MutableRankedTensorView<2> MatrixTensor>
121[[nodiscard]] auto schedule_consuming_truncated_svd(BackendSelector selector, async::Async<MatrixTensor>& matrix,
122 svd_truncation_policy_t<MatrixTensor> policy,
123 std::optional<Precision> requested = {})
124{
125 using result_type = consuming_truncated_svd_result_t<MatrixTensor>;
126 async_truncated_svd_result_t<result_type> outputs;
127 outputs.left_singular_vectors.debug_name("truncated_svd.left_singular_vectors");
128 outputs.singular_values.debug_name("truncated_svd.singular_values");
129 outputs.right_singular_vectors_adjoint.debug_name("truncated_svd.right_singular_vectors_adjoint");
130 outputs.truncation.debug_name("truncated_svd.truncation");
131
132 auto task =
133 co_consuming_truncated_svd(std::move(selector), outputs.left_singular_vectors.write(),
134 outputs.singular_values.write(), outputs.right_singular_vectors_adjoint.write(),
135 outputs.truncation.write(), matrix.write(), std::move(policy), requested);
136 task.debug_name("truncated_svd");
137 async::schedule(std::move(task));
138 return outputs;
139}
140} // namespace detail
141
143template <KernelBackendSelector BackendSelector, uni20::RankedTensorView<2> MatrixTensor>
144[[nodiscard]] auto truncated_svd(BackendSelector selector, async::Async<MatrixTensor> const& matrix,
146 std::optional<Precision> requested = {})
147{
148 return detail::schedule_preserving_truncated_svd(std::move(selector), matrix, std::move(policy), requested);
149}
150
152template <uni20::RankedTensorView<2> MatrixTensor>
153[[nodiscard]] auto truncated_svd(async::Async<MatrixTensor> const& matrix,
155 std::optional<Precision> requested = {})
156{
157 using work_type = detail::svd_matrix_tensor_t<MatrixTensor>;
158 auto selector = detail::select_svd_backend<work_type>(SvdOptions{});
159 return detail::schedule_preserving_truncated_svd(std::move(selector), matrix, std::move(policy), requested);
160}
161
163template <KernelBackendSelector BackendSelector, class MatrixTensor>
165[[nodiscard]] auto truncated_svd(BackendSelector selector, async::Async<MatrixTensor>&& matrix,
167 std::optional<Precision> requested = {})
168{
169 return detail::schedule_consuming_truncated_svd(std::move(selector), matrix, std::move(policy), requested);
170}
171
173template <class MatrixTensor>
175[[nodiscard]] auto truncated_svd(async::Async<MatrixTensor>&& matrix,
177 std::optional<Precision> requested = {})
178{
179 using exact_result_type = detail::consuming_svd_result_t<MatrixTensor>;
180 auto selector = detail::select_async_consuming_svd_backend<exact_result_type, MatrixTensor>(SvdOptions{});
181 return detail::schedule_consuming_truncated_svd(std::move(selector), matrix, std::move(policy), requested);
182}
183
185template <RankedTensorView<2> Matrix>
186[[nodiscard]] auto truncated_svd(async::Async<Matrix> const& matrix, Precision p,
188{
189 return uni20::linalg::truncated_svd(matrix, std::move(policy), std::optional<Precision>{p});
190}
191
193template <RankedTensorView<2> Matrix>
194[[nodiscard]] auto truncated_svd(async::Async<Matrix>&& matrix, Precision p,
196{
197 return uni20::linalg::truncated_svd(std::move(matrix), std::move(policy), std::optional<Precision>{p});
198}
199
201template <KernelBackendSelector Selector, RankedTensorView<2> Matrix>
202[[nodiscard]] auto truncated_svd(Selector&& selector, async::Async<Matrix> const& matrix, Precision p,
204{
205 return uni20::linalg::truncated_svd(std::forward<Selector>(selector), matrix, std::move(policy),
206 std::optional<Precision>{p});
207}
208
210template <KernelBackendSelector Selector, RankedTensorView<2> Matrix>
211[[nodiscard]] auto truncated_svd(Selector&& selector, async::Async<Matrix>&& matrix, Precision p,
213{
214 return uni20::linalg::truncated_svd(std::forward<Selector>(selector), std::move(matrix), std::move(policy),
215 std::optional<Precision>{p});
216}
217
218} // namespace uni20::linalg
The Async<T> container: coroutine‐safe asynchronous read/write.
Async Tensor wrappers for exact dense singular value decompositions.
Exact arithmetic or an explicit binary working precision.
Definition core/precision.hpp:13
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
TensorView whose readable mdspec has a specified static rank.
Definition tensor/concepts.hpp:149
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
void schedule(AsyncTask &&task)
Schedule a task on the currently configured global scheduler.
Definition debug_scheduler.hpp:237
Definition linalg/async.hpp:28
auto truncated_svd(BackendSelector selector, async::Async< MatrixTensor > const &matrix, detail::svd_truncation_policy_t< MatrixTensor > policy={}, std::optional< Precision > requested={})
Schedule a preserving truncated SVD through an explicit selector.
Definition async/truncated_svd.hpp:144
auto singular_values(BackendSelector selector, async::Async< MatrixTensor > const &matrix, std::optional< Precision > requested={})
Schedule preserving exact singular values through an explicit selector.
Definition async/svd.hpp:416
Definition data_table.cpp:8
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
Tensor-facing truncated dense singular value decompositions.
Rank-selection policy for a truncated singular value decomposition.
Definition ops/truncated_svd.hpp:34