Uni20
Asynchronous tensor and runtime library.
Loading...
Searching...
No Matches
tensor/async.hpp
Go to the documentation of this file.
1#pragma once
2
12#include <uni20/tensor/copy.hpp>
14
15#include <tuple>
16#include <type_traits>
17#include <utility>
18
19namespace uni20::async
20{
21
27template <uni20::TensorView Tensor>
29[[nodiscard]] auto conj(Async<Tensor> const& tensor)
30{
32 return make_async_alias<view_type>(tensor, tensor.storage().storage_address());
33}
34
36template <uni20::TensorView Tensor>
38[[nodiscard]] auto conj(Async<Tensor> const& tensor)
39{
40 using view_type = uni20::ConstTensorView<Tensor>;
41 return make_async_alias<view_type>(tensor, tensor.storage().storage_address());
42}
43
49template <uni20::MutableStridedTensorView Tensor, std::integral... Extents>
50 requires uni20::detail::CanonicalReshapeLayout<typename uni20::tensor_mdspec_t<Tensor>::layout_type>
51[[nodiscard]] auto reshape_view(Async<Tensor>& tensor, Extents... requested_extents)
52{
53 using layout_type = typename uni20::tensor_mdspec_t<Tensor>::layout_type;
55 return make_async_alias_from_parent<view_type>(tensor, requested_extents...);
56}
57
59template <uni20::StridedTensorView Tensor, std::integral... Extents>
60 requires uni20::detail::CanonicalReshapeLayout<typename uni20::tensor_mdspec_t<Tensor>::layout_type>
61[[nodiscard]] auto reshape_view(Async<Tensor> const& tensor, Extents... requested_extents)
62{
63 using layout_type = typename uni20::tensor_mdspec_t<Tensor>::layout_type;
65 return make_async_alias_from_parent<view_type>(tensor, requested_extents...);
66}
67
69template <uni20::MutableStridedTensorView Tensor, std::integral... Extents>
70[[nodiscard]] auto reshape_view_left(Async<Tensor>& tensor, Extents... requested_extents)
71{
73 return make_async_alias_from_parent<view_type>(tensor, requested_extents...);
74}
75
77template <uni20::StridedTensorView Tensor, std::integral... Extents>
78[[nodiscard]] auto reshape_view_left(Async<Tensor> const& tensor, Extents... requested_extents)
79{
80 using view_type =
82 return make_async_alias_from_parent<view_type>(tensor, requested_extents...);
83}
84
86template <uni20::MutableStridedTensorView Tensor, std::integral... Extents>
87[[nodiscard]] auto reshape_view_right(Async<Tensor>& tensor, Extents... requested_extents)
88{
90 return make_async_alias_from_parent<view_type>(tensor, requested_extents...);
91}
92
94template <uni20::StridedTensorView Tensor, std::integral... Extents>
95[[nodiscard]] auto reshape_view_right(Async<Tensor> const& tensor, Extents... requested_extents)
96{
97 using view_type =
99 return make_async_alias_from_parent<view_type>(tensor, requested_extents...);
100}
101
102} // namespace uni20::async
103
104namespace uni20
105{
106namespace detail
107{
108template <class Tensor, class... Extents>
109using preserving_async_reshape_result_t =
110 std::remove_cvref_t<decltype(uni20::reshape(std::declval<Tensor const&>(), std::declval<Extents>()...))>;
111
112template <class Tensor, class... Extents>
113using consuming_async_reshape_result_t =
114 std::remove_cvref_t<decltype(uni20::reshape(std::declval<Tensor&&>(), std::declval<Extents>()...))>;
115
116template <class ResultTensor, TensorView InputTensor, class... Extents>
118 Extents... requested_extents)
119{
120 auto output_storage = output.storage();
121 auto awaited = co_await async::all(output_storage, input);
122 auto& storage = std::get<0>(awaited);
123 auto const& input_value = std::get<1>(awaited);
124 storage.emplace(uni20::reshape(input_value, requested_extents...));
125 co_return;
126}
127
128template <class ResultTensor, class InputTensor, class... Extents>
129 requires OwningTensor<InputTensor> && MutableTensorView<InputTensor>
131 Extents... requested_extents)
132{
133 auto output_storage = output.storage();
134 auto& storage = co_await output_storage;
135 auto input_value = co_await input.take();
136 storage.emplace(uni20::reshape(std::move(input_value), requested_extents...));
137 co_return;
138}
139
140template <class Tensor, class... Extents>
141async::AsyncTask co_reshape_inplace(async::WriteBuffer<Tensor> input, Extents... requested_extents)
142{
143 auto storage_awaiter = input.storage();
144 auto& storage = co_await storage_awaiter;
145 if (!storage.constructed()) throw async::buffer_write_uninitialized{};
146 uni20::reshape_inplace(*storage, requested_extents...);
147 co_return;
148}
149} // namespace detail
150
154template <TensorView InputTensor, std::integral... Extents>
155 requires requires(InputTensor const& input, Extents... extents) { uni20::reshape(input, extents...); }
156[[nodiscard]] auto reshape(async::Async<InputTensor> const& input, Extents... requested_extents)
157{
158 using result_type = detail::preserving_async_reshape_result_t<InputTensor, Extents...>;
160 output.debug_name("reshape.result");
161 auto task = detail::co_preserving_reshape(output.write(), input.read(), requested_extents...);
162 task.debug_name("reshape");
163 async::schedule(std::move(task));
164 return output;
165}
166
170template <class InputTensor, std::integral... Extents>
171 requires OwningTensor<InputTensor> && MutableTensorView<InputTensor> &&
172 requires(InputTensor&& input, Extents... extents) { uni20::reshape(std::move(input), extents...); }
173[[nodiscard]] auto reshape(async::Async<InputTensor>&& input, Extents... requested_extents)
174{
175 using result_type = detail::consuming_async_reshape_result_t<InputTensor, Extents...>;
177 output.debug_name("reshape.result");
178 auto task = detail::co_consuming_reshape(output.write(), input.write(), requested_extents...);
179 task.debug_name("reshape");
180 async::schedule(std::move(task));
181 return output;
182}
183
187template <class Tensor, std::integral... Extents>
188 requires requires(Tensor& tensor, Extents... extents) { uni20::reshape_inplace(tensor, extents...); }
189void reshape_inplace(async::Async<Tensor>& input, Extents... requested_extents)
190{
191 auto task = detail::co_reshape_inplace(input.write(), requested_extents...);
192 task.debug_name("reshape_inplace");
193 async::schedule(std::move(task));
194}
195
196} // namespace uni20
The Async<T> container: coroutine‐safe asynchronous read/write.
Non-owning tensor view whose immediate or deferred metadata presents conjugated values.
Definition conjugate.hpp:102
Non-owning read-only view of a tensor-level object.
Definition conjugate.hpp:23
Tensor-level descriptor that resolves a reshape through its parent tensor.
Definition reshape.hpp:269
General-purpose owning tensor with immediate or deferred mdspan metadata.
Definition basic_tensor.hpp:109
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
shared_storage< T > const & storage() const
Access the shared storage control block.
Definition async/async.hpp:426
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
void write(U &&val)
Schedule assignment into this write buffer.
Definition buffers.hpp:1069
auto take() &
Awaiter that takes the stored value.
Definition buffers.hpp:994
Raised when a writer requests a mutable reference before construction.
Definition async_errors.hpp:74
Concept for complex scalar types.
Definition scalar_concepts.hpp:75
MutableTensorView whose readable and writable mdspecs are strided.
Definition tensor/concepts.hpp:157
TensorView whose readable mdspec is strided.
Definition tensor/concepts.hpp:153
Read-only lazy conjugation views for tensor-level objects.
Coroutine scheduler for AsyncTask.
This represents the reverse-mode adjoint for functions of complex variables, assuming a real-valued s...
Definition async/async.hpp:26
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
auto reshape_view_left(Async< Tensor > &tensor, Extents... requested_extents)
Return a mutable column-major structural reshape alias.
Definition tensor/async.hpp:70
auto reshape_view(Async< Tensor > &tensor, Extents... requested_extents)
Return a mutable structural reshape alias of an async tensor.
Definition tensor/async.hpp:51
auto reshape_view_right(Async< Tensor > &tensor, Extents... requested_extents)
Return a mutable row-major structural reshape alias.
Definition tensor/async.hpp:87
Async< T > conj(Async< T > const &x)
Schedules asynchronous conjugation.
Definition async_toys.hpp:96
Definition async/async.hpp:26
void reshape_inplace(async::Async< Tensor > &input, Extents... requested_extents)
Schedule an in-place mapping change on an async owning Tensor.
Definition tensor/async.hpp:189
auto reshape(async::Async< InputTensor > const &input, Extents... requested_extents)
Schedule a preserving owning reshape of an async Tensor.
Definition tensor/async.hpp:156
Tensor(InputTensor const &) -> Tensor< tensor_element_t< InputTensor >, tensor_mdspec_t< InputTensor >::rank(), HostStorage, detail::materialized_layout_t< void, tensor_mdspec_t< InputTensor > >, DefaultAccessorFactory >
Deduce a runtime-extents host tensor that materializes a tensor view.
std::remove_cvref_t< detail::normalized_const_mdspec_t< T > > tensor_mdspec_t
Normalized readable MdspecLike type exposed by a tensor-level object.
Definition tensor/concepts.hpp:123
Explicit aliasing, in-place, and owning tensor reshape operations.
Backend-dispatched tensor copies and inferred owning materialization.