Quickstart#
How do I build and read one array?
#include <aether/aether.h>, construct an aether::Array<T, Es...>
with however many samples you need, and read/write it through the
View its .hostView() hands back — indexed (component, sample),
the same shape you would use from NumPy with the axes swapped.
The umbrella header#
aether/aether.h pulls in the whole library: layout, views, expression
templates, arrays, random numbers, residency — everything this site’s
pages cover. There is no separate install step or Python package to reach
it from (see Interoperability for how aether reaches Python at all) — it is
a header-only C++23 library, so a consumer just includes
it and links nothing extra beyond the compiler’s own runtime.
aether::Array#
An aether::Array<T, Es...> (aether/array/Array.h) is the OWNING
convenience type: it allocates its own memory and follows the symmetry
rule — Array<T, Es...> always appends one more, dynamic dimension
(the number of samples) on top of the Es... you name, so
Array<double, 3> is an array of N 3-vectors, not a single one.
.samples() reports how many there are; .size() reports the total
scalar count (samples() * 3 for a 3-vector array).
On a build with a CUDA backend, an Array actually owns TWO buffers — a
host copy and a device copy — and .upload()/.download() move data
between them (see Memory ownership: Chunk, Array, View). In a CPU-only build there is
only one buffer, so those calls are harmless no-ops; the code above
compiles and behaves identically either way, which is the whole point of
the dual-mode design this library is built on.
A runnable example#
TEST_F(ArrayTest, SamplesAndSize)
{
aether::Array<double, 3> arr(10);
EXPECT_EQ(arr.samples(), 10u);
EXPECT_EQ(arr.size(), 30u);
}
Ten 3-component samples, so samples() == 10 and size() == 30. From
here, Views and Items covers how to actually read and write the
elements through a View, and Memory ownership: Chunk, Array, View covers what
Array is doing underneath.