TRIQS/nda 1.3.0
Multi-dimensional array library for C++
|
#include <nda/layout/idx_map.hpp>
Layout that specifies how to map multi-dimensional indices to a linear/flat index.
It stores the shape of the array, i.e. the length of each dimension, and the strides of each dimension. The stride of dimension i
is the number of elements to skip in memory when the index of dimension i
is incremented by one. For example:
(25, 5, 1)
.(2)
.(1, 20)
.(2, 10)
.The template parameters StaticExtents
and StrideOrder
are encoded as uint64_t
. They can be decoded to a std::array<int, Rank>
using the nda::decode function. The encoding limits the number of dimensions, i.e. the rank, to 16.
The static extent array specifies the length of each dimension at compile-time. A zero value means that the length in this dimension is dynamic and will be specified at runtime. Note that static lengths cannot exceed 16 (due to the encoding). For example:
StaticExtents = nda::encode(std::array<int, Rank>{0, 10, 0, 5})
corresponds to a 4D array with dynamic extents in dimension 0 and 2, and static extents of length 10 and 5 in dimension 1 and 3, respectively.The stride order specifies the order in which the dimensions are stored in memory. In its array form, it can be any permutation of the integer values from 0
to Rank - 1
. The slowest varying dimension is the first element of the array and the fastest varying dimension is the last element of the array. For example:
StrideOrder = nda::encode(std::array<int, Rank>{0, 1, ..., Rank - 2, Rank - 1})
.StrideOrder = nda::encode(std::array<int, Rank>{Rank - 1, Rank - 2, ..., 1, 0})
.LayoutProp
is an enum flag that can be used to make further compile-time guarantees about the layout of the data in memory (see nda::layout_prop_e).
Rank | Number of dimensions. |
StaticExtent | Compile-time known shape (zero if fully dynamic). |
StrideOrder | Order in which the dimensions are stored in memory. |
LayoutProp | Compile-time guarantees about the layout of the data in memory. |
Definition at line 103 of file idx_map.hpp.
Public Member Functions | |
idx_map () | |
Default constructor. | |
idx_map (idx_map &&)=default | |
Default move constructor. | |
idx_map (idx_map const &)=default | |
Default copy constructor. | |
template<uint64_t SE, uint64_t SO, layout_prop_e LP> requires (stride_order_encoded != SO) | |
idx_map (idx_map< Rank, SE, SO, LP > const &) | |
Construct a new map from an existing map with a different stride order. | |
template<uint64_t SE, layout_prop_e LP> | |
idx_map (idx_map< Rank, SE, StrideOrder, LP > const &idxm) noexcept(false) | |
Construct a new map from an existing map with different layout properties and different static extents. | |
template<layout_prop_e LP> | |
idx_map (idx_map< Rank, StaticExtents, StrideOrder, LP > const &idxm) noexcept | |
Construct a new map from an existing map with different layout properties. | |
template<std::integral Int = long> | |
idx_map (std::array< Int, Rank > const &shape) noexcept | |
Construct a new map from a given shape and with contiguous strides. | |
idx_map (std::array< long, n_dynamic_extents > const &shape) noexcept | |
Construct a new map from an array with its dynamic extents. | |
template<int R> requires (R != Rank) | |
idx_map (std::array< long, R > const &) | |
Construct a new map with a shape of a different rank. | |
idx_map (std::array< long, Rank > const &shape, std::array< long, Rank > const &strides) noexcept(!check_stride_order) | |
Construct a new map from a given shape and strides. | |
bool | has_positive_strides () const noexcept |
Are all strides positive? | |
bool | is_contiguous () const noexcept |
Is the data contiguous in memory? | |
bool | is_stride_order_valid () const |
Check if the shape and strides of the current map are compatible with its stride order. | |
bool | is_strided_1d () const noexcept |
Is the data strided in memory with a constant stride? | |
std::array< long, Rank > const & | lengths () const noexcept |
Get the extents of all dimensions. | |
long | min_stride () const noexcept |
Get the value of the smallest stride (positive or negative). | |
template<typename... Args> | |
__inline__ long | operator() (Args const &...args) const noexcept(true) |
Function call operator to map a given multi-dimensional index to a linear index. | |
idx_map & | operator= (idx_map &&)=default |
Default move assignment operator. | |
idx_map & | operator= (idx_map const &)=default |
Default copy assignment operator. | |
template<int R, uint64_t SE, uint64_t SO, layout_prop_e LP> | |
bool | operator== (idx_map< R, SE, SO, LP > const &rhs) const |
Equal-to operator for two nda::idx_map objects. | |
long | size () const noexcept |
Get the total number of elements. | |
template<typename... Args> | |
auto | slice (Args const &...args) const |
Get a new nda::idx_map by taking a slice of the current one. | |
std::array< long, Rank > const & | strides () const noexcept |
Get the strides of all dimensions. | |
std::array< long, Rank > | to_idx (long lin_idx) const |
Calculate the multi-dimensional index from a given linear index. | |
template<uint64_t Permutation> | |
auto | transpose () const |
Create a new map by permuting the indices/dimensions of the current map with a given permutation. | |
Static Public Member Functions | |
static constexpr long | ce_size () noexcept |
Get the size known at compile-time. | |
static constexpr bool | is_stride_order_C () |
Is the stride order equal to C-order? | |
static constexpr bool | is_stride_order_Fortran () |
Is the stride order equal to Fortran-order? | |
template<std::integral Int> | |
static bool | is_stride_order_valid (Int *lenptr, Int *strptr) |
Check if a given shape and strides are compatible with the stride order. | |
static constexpr int | rank () noexcept |
Get the rank of the map. | |
Static Public Attributes | |
template<typename T > | |
static constexpr int | argument_is_allowed_for_call = std::is_constructible_v<long, T> |
Alias template to check if type T can be used to access a single element. | |
template<typename T > | |
static constexpr int | argument_is_allowed_for_call_or_slice |
Alias template to check if type T can be used to either access a single element or a slice of elements. | |
static constexpr layout_info_t | layout_info = layout_info_t{stride_order_encoded, layout_prop} |
Compile-time information about the layout (stride order and layout properties). | |
static constexpr layout_prop_e | layout_prop = LayoutProp |
Compile-time memory layout properties. | |
static constexpr std::array< int, Rank > | static_extents = decode<Rank>(StaticExtents) |
Decoded static extents. | |
static constexpr uint64_t | static_extents_encoded = StaticExtents |
Encoded static extents. | |
static constexpr std::array< int, Rank > | stride_order = (StrideOrder == 0 ? permutations::identity<Rank>() : decode<Rank>(StrideOrder)) |
Decoded stride order. | |
static constexpr uint64_t | stride_order_encoded = encode(stride_order) |
Encoded stride order. | |
Static Protected Attributes | |
static constexpr int | n_dynamic_extents |
Number of dynamic dimensions/extents. | |
|
inline |
Default constructor.
For purely static maps, the shape is set to the static extents and the strides are assumed to be contiguous.
For all other maps, the shape is set to zero and the strides are not initialized.
Definition at line 318 of file idx_map.hpp.
|
inlinenoexcept |
Construct a new map from an existing map with different layout properties.
LP | Layout properties of the other nda::idx_map. |
idxm | Other nda::idx_map object. |
Definition at line 332 of file idx_map.hpp.
|
inline |
Construct a new map from an existing map with different layout properties and different static extents.
SE | Static extents of the other nda::idx_map. |
LP | Layout properties of the other nda::idx_map. |
idxm | Other nda::idx_map object. |
Definition at line 355 of file idx_map.hpp.
|
inlinenoexcept |
Construct a new map from a given shape and strides.
shape | Shape of the new map. |
strides | Strides of the new map. |
Definition at line 379 of file idx_map.hpp.
|
inlinenoexcept |
Construct a new map from a given shape and with contiguous strides.
Int | Integer type. |
shape | Shape of the new map. |
Definition at line 395 of file idx_map.hpp.
|
inlinenoexcept |
Construct a new map from an array with its dynamic extents.
The missing extents are taken from the static extents, i.e. if a static extent is zero, it is replaced by the corresponding dynamic extent.
shape | std::array with the dynamic extents only. |
Definition at line 409 of file idx_map.hpp.
|
inline |
Construct a new map from an existing map with a different stride order.
SE | Static extents of the other nda::idx_map. |
SO | Stride order of the other nda::idx_map. |
LP | Layout properties of the other nda::idx_map. |
Definition at line 423 of file idx_map.hpp.
|
inline |
Construct a new map with a shape of a different rank.
R | Rank of the given shape. |
Definition at line 435 of file idx_map.hpp.
|
inlinestaticconstexprnoexcept |
Get the size known at compile-time.
Definition at line 166 of file idx_map.hpp.
|
inlinenodiscardnoexcept |
Are all strides positive?
Definition at line 211 of file idx_map.hpp.
|
inlinenodiscardnoexcept |
Is the data contiguous in memory?
The data is contiguous in memory if the size of the map is equal to the number of memory locations spanned by the map, i.e. the absolute value of the product of the largest stride times the length of the corresponding dimension.
Definition at line 201 of file idx_map.hpp.
|
inlinestaticconstexpr |
Is the stride order equal to C-order?
Definition at line 235 of file idx_map.hpp.
|
inlinestaticconstexpr |
Is the stride order equal to Fortran-order?
Definition at line 241 of file idx_map.hpp.
|
inlinenodiscard |
Check if the shape and strides of the current map are compatible with its stride order.
See idx_map::is_stride_order_valid(Int *lenptr, Int *strptr)).
Definition at line 267 of file idx_map.hpp.
|
inlinestaticnodiscard |
Check if a given shape and strides are compatible with the stride order.
Int | Integer type. |
lenptr | Pointer to a shape array. |
strptr | Pointer to a stride array. |
Definition at line 252 of file idx_map.hpp.
|
inlinenodiscardnoexcept |
Is the data strided in memory with a constant stride?
The data is strided in memory with a constant stride if the size of the map times the absolute value of the stride of the fastest dimension with an extent bigger than 1 is equal to the number of memory locations spanned by the map, i.e. the absolute value of the product of the largest stride times the length of the corresponding dimension.
Definition at line 223 of file idx_map.hpp.
|
inlinenodiscardnoexcept |
Get the extents of all dimensions.
std::array<long, Rank>
containing the extent of each dimension. Definition at line 178 of file idx_map.hpp.
|
inlinenodiscardnoexcept |
Get the value of the smallest stride (positive or negative).
Definition at line 190 of file idx_map.hpp.
|
inlinenoexcept |
Function call operator to map a given multi-dimensional index to a linear index.
All arguments are either convertible to type long
or are of type nda::ellipsis. The number of non-ellipsis arguments must be equal to the rank of the map and there must be at most one nda::ellipsis. If an nda::ellipsis is present, it is skipped and does not influence the result.
Let \( (a_0, ..., a_{n-1}) \) be the given multi-dimensional index and let \( (s_0, ..., s_{n-1}) \) be the strides of the index map. Then the equation that maps the multi-dimensional index to the corresponding linear index \( f \) is as follows:
\[ f = \sum_{i=0}^{n-1} a_i * s_i \; . \]
Args | Types of the arguments. |
args | Multi-dimensional index. |
Definition at line 517 of file idx_map.hpp.
|
inline |
Equal-to operator for two nda::idx_map objects.
R | Rank of the other nda::idx_map. |
SE | Static extents of the other nda::idx_map. |
SO | Stride order of the other nda::idx_map. |
LP | Layout properties of the other nda::idx_map. |
rhs | Right hand side nda::idx_map operand. |
Definition at line 590 of file idx_map.hpp.
|
inlinestaticconstexprnoexcept |
|
inlinenodiscardnoexcept |
Get the total number of elements.
Definition at line 160 of file idx_map.hpp.
|
inline |
Get a new nda::idx_map by taking a slice of the current one.
See nda::slice_static::slice_idx_map for more information.
Args | Types of the arguments. |
args | Multi-dimensional index consisting of long , nda::range , nda::range::all_t or nda::ellipsis objects. |
Definition at line 575 of file idx_map.hpp.
|
inlinenodiscardnoexcept |
Get the strides of all dimensions.
std::array<long, Rank>
containing the stride of each dimension. Definition at line 184 of file idx_map.hpp.
|
inline |
Calculate the multi-dimensional index from a given linear index.
Let \( f \) be the given linear index and let \( (s_0, ..., s_{n-1}) \) be the strides of the index map. Then the corresponding multi-dimensional index \( (a_0, ..., a_{n-1}) \) satisfies the following equation:
\[ f = \sum_{i=0}^{n-1} a_i * s_i \; . \]
Furthermore, if \( (p_0, ..., p_{n-1}) \) is the stride order of the map, let us define the residues \( r_{p_i} \) as
\[ r_{p_i} = \sum_{j=i}^{n-1} s_{p_j} * a_{p_j} \; , \]
with the property that \( s_{p_i} \leq r_{p_i} < s_{p_{i-1}} \) for \( i = 1, ..., n-1 \) and \( s_{p_0} \leq r_{p_0} = f \). We can use this property to first calculate the residues and then recover the multi-dimensional index.
lin_idx | Linear/Flat index. |
Definition at line 548 of file idx_map.hpp.
|
inline |
Create a new map by permuting the indices/dimensions of the current map with a given permutation.
Let A
be the current and A'
the new, permuted index map. P
is the given permutation. We define the permuted nda::idx_map A'
to be the one with the following properties:
A'(i_0,...,i_{n-1}) = A(i_{P[0]},...,i_{P[n-1]})
A'.lengths()[k] == A.lengths()[P^{-1}[k]]
A'.strides()[k] == A.strides()[P^{-1}[k]]
A'
is the composition of P
and the stride order of A
(note that the stride order itself is a permutation).Permutation | Permutation to apply. |
Definition at line 609 of file idx_map.hpp.