Uni20
Asynchronous tensor and runtime library.
Loading...
Searching...
No Matches
async/self_adjoint_eigh.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_eigh_result_t =
26 std::remove_cvref_t<decltype(uni20::linalg::eigh(std::declval<MatrixTensor const&>(), MatrixTriangle::Upper))>;
27
28template <class MatrixTensor>
29using consuming_eigh_result_t =
30 std::remove_cvref_t<decltype(uni20::linalg::eigh(std::declval<MatrixTensor&&>(), MatrixTriangle::Upper))>;
31
32template <class Result>
33using async_eigh_result_t = SelfAdjointEighResult<async::Async<typename Result::eigenvalue_tensor_type>,
35
36template <class Result> [[nodiscard]] constexpr auto select_async_eigh_backend(MatrixTriangle triangle)
37{
38 return select_backend_for<typename Result::eigenvalue_tensor_type, typename Result::eigenvector_tensor_type>(
39 self_adjoint_eigh_op{.compute_vectors = true, .triangle = triangle});
40}
41
42template <KernelBackendSelector BackendSelector, class EigenvalueTensor, class EigenvectorTensor,
43 uni20::RankedTensorView<2> MatrixTensor>
44async::AsyncTask co_preserving_eigh(BackendSelector const selector, async::WriteBuffer<EigenvalueTensor> eigenvalues,
47 std::optional<Precision> requested = {})
48{
49 auto eigenvalue_storage_awaiter = eigenvalues.storage();
50 auto eigenvector_storage_awaiter = eigenvectors.storage();
51 auto& eigenvalue_storage = co_await eigenvalue_storage_awaiter;
52 auto& eigenvector_storage = co_await eigenvector_storage_awaiter;
53 auto const& matrix_value = co_await matrix;
54
55 auto result = uni20::linalg::eigh(selector, matrix_value, triangle, requested);
56 eigenvalue_storage.emplace(std::move(result.eigenvalues));
57 eigenvector_storage.emplace(std::move(result.eigenvectors));
58 co_return;
59}
60
61template <KernelBackendSelector BackendSelector, class EigenvalueTensor, class EigenvectorTensor,
64async::AsyncTask co_consuming_eigh(BackendSelector const selector, async::WriteBuffer<EigenvalueTensor> eigenvalues,
67 std::optional<Precision> requested = {})
68{
69 auto eigenvalue_storage_awaiter = eigenvalues.storage();
70 auto eigenvector_storage_awaiter = eigenvectors.storage();
71 auto& eigenvalue_storage = co_await eigenvalue_storage_awaiter;
72 auto& eigenvector_storage = co_await eigenvector_storage_awaiter;
73 // Retain the consumed writer gate until both outputs commit, so a failure is
74 // published to all three epochs before any dependent reader can resume.
75 auto matrix_value = co_await matrix.take();
76
77 auto result = uni20::linalg::eigh(selector, std::move(matrix_value), triangle, requested);
78 eigenvalue_storage.emplace(std::move(result.eigenvalues));
79 eigenvector_storage.emplace(std::move(result.eigenvectors));
80 co_return;
81}
82
83template <KernelBackendSelector BackendSelector, uni20::RankedTensorView<2> MatrixTensor>
84[[nodiscard]] auto schedule_preserving_eigh(BackendSelector selector, async::Async<MatrixTensor> const& matrix,
85 MatrixTriangle triangle, std::optional<Precision> requested = {})
86{
87 using result_type = preserving_eigh_result_t<MatrixTensor>;
88 async_eigh_result_t<result_type> outputs;
89 outputs.eigenvalues.debug_name("eigh.eigenvalues");
90 outputs.eigenvectors.debug_name("eigh.eigenvectors");
91
92 auto task = co_preserving_eigh(std::move(selector), outputs.eigenvalues.write(), outputs.eigenvectors.write(),
93 matrix.read(), triangle, requested);
94 task.debug_name("eigh");
95 async::schedule(std::move(task));
96 return outputs;
97}
98
99template <KernelBackendSelector BackendSelector, uni20::MutableRankedTensorView<2> MatrixTensor>
101[[nodiscard]] auto schedule_consuming_eigh(BackendSelector selector, async::Async<MatrixTensor>& matrix,
102 MatrixTriangle triangle, std::optional<Precision> requested = {})
103{
104 using result_type = consuming_eigh_result_t<MatrixTensor>;
105 async_eigh_result_t<result_type> outputs;
106 outputs.eigenvalues.debug_name("eigh.eigenvalues");
107 outputs.eigenvectors.debug_name("eigh.eigenvectors");
108
109 auto task = co_consuming_eigh(std::move(selector), outputs.eigenvalues.write(), outputs.eigenvectors.write(),
110 matrix.write(), triangle, requested);
111 task.debug_name("eigh");
112 async::schedule(std::move(task));
113 return outputs;
114}
115} // namespace detail
116
121template <KernelBackendSelector BackendSelector, uni20::RankedTensorView<2> MatrixTensor>
122[[nodiscard]] auto eigh(BackendSelector selector, async::Async<MatrixTensor> const& matrix,
123 MatrixTriangle triangle = MatrixTriangle::Upper, std::optional<Precision> requested = {})
124{
125 return detail::schedule_preserving_eigh(std::move(selector), matrix, triangle, requested);
126}
127
131template <uni20::RankedTensorView<2> MatrixTensor>
132[[nodiscard]] auto eigh(async::Async<MatrixTensor> const& matrix, MatrixTriangle triangle = MatrixTriangle::Upper,
133 std::optional<Precision> requested = {})
134{
135 using result_type = detail::preserving_eigh_result_t<MatrixTensor>;
136 auto selector = detail::select_async_eigh_backend<result_type>(triangle);
137 return detail::schedule_preserving_eigh(std::move(selector), matrix, triangle, requested);
138}
139
144template <KernelBackendSelector BackendSelector, class MatrixTensor>
146[[nodiscard]] auto eigh(BackendSelector selector, async::Async<MatrixTensor>&& matrix,
147 MatrixTriangle triangle = MatrixTriangle::Upper, std::optional<Precision> requested = {})
148{
149 return detail::schedule_consuming_eigh(std::move(selector), matrix, triangle, requested);
150}
151
156template <class MatrixTensor>
159 std::optional<Precision> requested = {})
160{
161 using result_type = detail::consuming_eigh_result_t<MatrixTensor>;
162 auto selector = detail::select_async_eigh_backend<result_type>(triangle);
163 return detail::schedule_consuming_eigh(std::move(selector), matrix, triangle, requested);
164}
165
167template <RankedTensorView<2> Matrix>
168[[nodiscard]] auto eigh(async::Async<Matrix> const& matrix, Precision p,
170{
171 return uni20::linalg::eigh(matrix, triangle, std::optional<Precision>{p});
172}
173
175template <RankedTensorView<2> Matrix>
177{
178 return uni20::linalg::eigh(std::move(matrix), triangle, std::optional<Precision>{p});
179}
180
182template <KernelBackendSelector Selector, RankedTensorView<2> Matrix>
183[[nodiscard]] auto eigh(Selector&& selector, async::Async<Matrix> const& matrix, Precision p,
185{
186 return uni20::linalg::eigh(std::forward<Selector>(selector), matrix, triangle, std::optional<Precision>{p});
187}
188
190template <KernelBackendSelector Selector, RankedTensorView<2> Matrix>
191[[nodiscard]] auto eigh(Selector&& selector, async::Async<Matrix>&& matrix, Precision p,
193{
194 return uni20::linalg::eigh(std::forward<Selector>(selector), std::move(matrix), triangle,
195 std::optional<Precision>{p});
196}
197
198} // namespace uni20::linalg
The Async<T> container: coroutine‐safe asynchronous read/write.
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.
void schedule(AsyncTask &&task)
Schedule a task on the currently configured global scheduler.
Definition debug_scheduler.hpp:237
Definition linalg/async.hpp:28
auto eigh(BackendSelector selector, async::Async< MatrixTensor > const &matrix, MatrixTriangle triangle=MatrixTriangle::Upper, std::optional< Precision > requested={})
Schedule a preserving self-adjoint eigensystem through an explicit selector.
Definition async/self_adjoint_eigh.hpp:122
MatrixTriangle
Triangle of a symmetric or Hermitian matrix supplied to an operation.
Definition operation_tags.hpp:226
Definition data_table.cpp:8
In-place and value-producing dense self-adjoint eigensystems.