Evaluation and assignment¶
How an expression is computed into memory: assignment, aliasing, the cost model and scratch buffers.
Concepts¶
| Name | Description |
|---|---|
advances_along | A cursor that can be moved any number of positions along Axis, back ones included. |
steps_along | A cursor that can be moved one position along Axis. |
tensor_cursor | A position in a tensor of Rank axes that a traversal can read and move. |
writable_cursor | A cursor that can also write the element it is at: element() is a reference that is not const. |
Types¶
| Name | Description |
|---|---|
NoAlias | An expression, and the promise that it reads no element of the destination but where that element is written. |
Scratch | E itself, and where an evaluation takes the memory of its buffers from. |
Functions¶
assign¶
template <typename T, shape_like S, layout_for<S> Layout, typename E>
constexpr void assign(const TensorView<T, S, Layout> &destination, const E &source)
Writes destination[i...] = source[i...] for every index, converting each value to the element type; what destination = source does, as a function.
source is a tensor of the destination's shape, or a scalar for every element. Where it reads the destination other than each element where it is written (a = permute<1, 0>(a), unlike a = a + b), it is computed whole into a buffer first, from the root's scratch or Aligned<>; otherwise the destination is written in place, with no buffer. The functions an expression calls are not looked into: a lambda that captured a view of the destination goes unseen. Assigned as it is, noalias(source) skips the check, as promised.
Parameters
| Name | Description |
|---|---|
destination | The view written. |
source | The tensor or scalar read; lazy until this call. |
Precondition
Each extent of destination equals that of source.
Variables¶
noalias¶
Promises that an expression does not alias the destination it is assigned to.
noalias(x) and x | noalias give a NoAlias of x, to be assigned with =, the compound operators or assign. It ends an assignment: nothing is piped on from it. The expression must read no element of the destination but where that element is written, as c * 2 does into c; see NoAlias.
materializes¶
template <typename E>
constexpr bool materializes =
std::tuple_size_v<decltype(detail::evaluate(std::declval<const E&>()).buffers)> != 0
Whether evaluating E computes a part of it into a buffer first.
Decided at compile time by the cost model: a part is buffered when reading it from a buffer is cheaper than computing it again at each read. Use it as static_assert(materializes<E>) where a buffer is expected, or its negation where none is. What it says may change as the model is tuned.
Template parameters
| Name | Description |
|---|---|
E | An expression type. |
scratch¶
Names the memory the buffers of an evaluation take.
scratch(x, memory) and x | scratch(memory) give a Scratch of x. Memory is an allocator, a memory policy, or a std::pmr::memory_resource* (taken as a std::pmr::polymorphic_allocator over it). scratch(memory) alone waits for its expression. It is a value that can be reused for many evaluations. Without it, buffers come from the heap, aligned.
nothrow_read¶
Whether reading cursor C does not throw.
nothrow_step¶
template <typename C, std::size_t... Axes>
constexpr bool nothrow_step = (noexcept(std::declval<C&>().template step<Axes>()) && ...)
Whether stepping cursor C along each of Axes does not throw.
nothrow_advance¶
template <typename C, std::size_t... Axes>
constexpr bool nothrow_advance = (noexcept(std::declval<C&>().template advance<Axes>(std::ptrdiff_t{})) && ...)
Whether moving cursor C any number of positions along each of Axes does not throw.
nothrow_advance_all¶
template <typename C, std::size_t Rank>
constexpr bool nothrow_advance_all = detail::advances_nothrow<C>(std::make_index_sequence<Rank>{})
Whether moving cursor C any number of positions does not throw along any axis of a tensor of Rank axes.
Aliases¶
cursor_value_t¶
template <typename C>
using strata::cursor_value_t = std::remove_cvref_t<decltype(std::declval<const C&>().read())>
The type of the values a cursor reads, without const and references.