Uni20
Asynchronous tensor and runtime library.
Loading...
Searching...
No Matches
async_toys.hpp
Go to the documentation of this file.
1#pragma once
2
8#include "async.hpp"
9#include "scheduler.hpp"
10#include <cmath>
11#include <fmt/format.h>
12#include <iostream>
13#include <uni20/core/math.hpp>
14
15namespace uni20::async
16{
17
22template <typename T> AsyncTask co_sin(ReadBuffer<T> in, WriteBuffer<T> out)
23{
24 using std::sin;
25 // The owning proxy from `co_await in.transfer()` transfers ownership of the read buffer.
26 // We explicitly call `release()` immediately after `get()`, before write-buffer acquisition.
27 // This ordering matters because it is possible that
28 // there are data dependencies that mean that we cannot get the WriteBuffer until after the Read
29 // has finished. For example consider
30 // Async<double> x = 1.0;
31 // auto rbuf = x.read();
32 // x *= 2;
33 // auto wbuf = x.write();
34 // schedule(co_sin(std::move(rbuf), std::move(wbuf)));
35 // GCC 13 limitation: `(co_await in.transfer()).get()` can fail with
36 // "insufficient contextual information to determine type" in templates.
37 // This is fixed in GCC 14+, where the one-liner below is preferred:
38 // auto const input = (co_await in.transfer()).get();
39 auto input_buffer = co_await in.transfer();
40 auto const input = input_buffer.get();
41 input_buffer.release();
42 co_await out = sin(input);
43}
44
49template <typename T> Async<T> sin(Async<T> const& x)
50{
51 Async<T> Result;
52 schedule(co_sin(x.read(), Result.write()));
53 return Result;
54}
55
60template <typename T> AsyncTask co_cos(ReadBuffer<T> in, WriteBuffer<T> out)
61{
62 using std::cos;
63 auto input_buffer = co_await in.transfer();
64 auto const input = input_buffer.get();
65 input_buffer.release();
66 co_await out = cos(input);
67}
68
73template <typename T> Async<T> cos(Async<T> const& x)
74{
75 Async<T> Result;
76 schedule(co_cos(x.read(), Result.write()));
77 return Result;
78}
79
84template <typename T> AsyncTask co_conj(ReadBuffer<T> in, WriteBuffer<T> out)
85{
86 auto input_buffer = co_await in.transfer();
87 auto const input = input_buffer.get();
88 input_buffer.release();
89 co_await out = uni20::conj(input);
90}
91
96template <typename T> Async<T> conj(Async<T> const& x)
97{
98 Async<T> Result;
99 schedule(co_conj(x.read(), Result.write()));
100 return Result;
101}
102
108{
109 using uni20::real;
110 auto input_buffer = co_await in.transfer();
111 auto const input = input_buffer.get();
112 input_buffer.release();
113 co_await out = real(input);
114}
115
120template <typename T> Async<uni20::make_real_t<T>> real(Async<T> const& x)
121{
123 schedule(co_real(x.read(), Result.write()));
124 return Result;
125}
126
132{
133 using uni20::imag;
134 auto input_buffer = co_await in.transfer();
135 auto const input = input_buffer.get();
136 input_buffer.release();
137 co_await out = imag(input);
138}
139
144template <typename T> Async<uni20::make_real_t<T>> imag(Async<T> const& x)
145{
147 schedule(co_imag(x.read(), Result.write()));
148 return Result;
149}
150
155template <typename T> AsyncTask co_herm(ReadBuffer<T> in, WriteBuffer<T> out)
156{
157 using uni20::conj;
158 auto input_buffer = co_await in.transfer();
159 auto const input = input_buffer.get();
160 input_buffer.release();
161 co_await out = herm(input);
162}
163
168template <typename T> Async<T> herm(Async<T> const& x)
169{
170 Async<T> Result;
171 schedule(co_herm(x.read(), Result.write()));
172 return Result;
173}
174
179template <typename T> void async_print(std::string Format, Async<T> x)
180{
181 schedule([](std::string Format, ReadBuffer<T> in) static -> AsyncTask {
182 auto x = co_await in;
183 fmt::print(fmt::runtime(Format), x);
184 }(std::move(Format), x.read()));
185}
186
191template <typename T> void async_read(std::string Prompt, Async<T>& x)
192{
193 schedule([](std::string Prompt, WriteBuffer<T> out) static -> AsyncTask {
194 fmt::print("{}", Prompt);
195 T value{};
196 std::cin >> value;
197 co_await out = std::move(value);
198 }(std::move(Prompt), x.write()));
199}
200
201} // namespace uni20::async
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
void release() noexcept
Manually release the epoch reader before awaitable destruction.
Definition buffers.hpp:143
ReadBuffer && transfer() &noexcept
Transfer this read buffer into the owning-await path.
Definition buffers.hpp:147
Exclusive mutable-access buffer for one Async<T> epoch.
Definition buffers.hpp:859
locale_t value
Definition data_table.cpp:49
uni20::complex< T > conj(detail::standard_complex< T > x)
Returns the complex conjugate for complex-valued scalars.
Definition math.hpp:70
constexpr T & imag(detail::standard_complex< T > &z) noexcept
Provides mutable access to the imaginary component of a uni20::complex value.
Definition math.hpp:184
typename make_real< T >::type make_real_t
Alias for the underlying real-valued type of T.
Definition scalar_traits.hpp:168
constexpr T & real(detail::standard_complex< T > &z) noexcept
Provides mutable access to the real component of a uni20::complex value.
Definition math.hpp:173
Scalar math helper utilities.
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
AsyncTask co_conj(ReadBuffer< T > in, WriteBuffer< T > out)
Coroutine implementation of complex conjugation over async buffers.
Definition async_toys.hpp:84
AsyncTask co_real(ReadBuffer< T > in, WriteBuffer< uni20::make_real_t< T > > out)
Coroutine implementation of real-part extraction over async buffers.
Definition async_toys.hpp:107
AsyncTask co_herm(ReadBuffer< T > in, WriteBuffer< T > out)
Coroutine implementation of Hermitian conjugation over async buffers.
Definition async_toys.hpp:155
AsyncTask co_cos(ReadBuffer< T > in, WriteBuffer< T > out)
Coroutine implementation of cos over async buffers.
Definition async_toys.hpp:60
Async< T > sin(Async< T > const &x)
Schedules asynchronous sine evaluation.
Definition async_toys.hpp:49
Async< T > cos(Async< T > const &x)
Schedules asynchronous cosine evaluation.
Definition async_toys.hpp:73
Async< T > conj(Async< T > const &x)
Schedules asynchronous conjugation.
Definition async_toys.hpp:96
void async_print(std::string Format, Async< T > x)
Schedules a formatted print once an async value is ready.
Definition async_toys.hpp:179
AsyncTask co_sin(ReadBuffer< T > in, WriteBuffer< T > out)
Coroutine implementation of sin over async buffers.
Definition async_toys.hpp:22
void async_read(std::string Prompt, Async< T > &x)
Schedules reading a value from std::cin into an async slot.
Definition async_toys.hpp:191
Async< T > herm(Async< T > const &x)
Schedules asynchronous Hermitian conjugation.
Definition async_toys.hpp:168
AsyncTask co_imag(ReadBuffer< T > in, WriteBuffer< uni20::make_real_t< T > > out)
Coroutine implementation of imaginary-part extraction over async buffers.
Definition async_toys.hpp:131
Defines internal task routing and the host-oriented scheduler interface.
Async aliases for lazy tensor-level views.