![]() |
batmat
0.0.18
Batched linear algebra routines
|
#include <batmat/matrix/view.hpp>
Non-owning view of an array of matrices, stored in an efficient batched format.
A view is a pointer to a buffer of elements, together with a layout describing how the elements are arranged in memory. Conceptually, a batmat::matrix::View represents a 3D array of shape (depth, rows, cols), where depth is the number of matrices in the array. We refer to a single matrix in the batch as a "layer". A single layer can be accessed using view(layer), and individual elements can be accessed using view(layer, row, col). Each layer is either stored in column-major or row-major order, depending on the storage order of the view. Slicing and tiling are made possible by dynamic outer strides (leading dimension in BLAS parlance) and layer strides.
To enable efficient vectorization of linear algebra operations on views, the data is not stored in memory as a 3D array, but rather as a 4D array with an additional "batch" dimension, i.e. with shape (batch_size, rows, cols, num_batches), where batch_size is the number of layers in each batch, and num_batches = ceil(depth / batch_size). The corresponding strides are (1, batch_size, outer_stride, layer_stride) for the column-major case, and (1, outer_stride, batch_size, layer_stride) for the row-major case.
Batches can be accessed using the batch() method, which returns a view of the batch with the same layout but with depth equal to batch_size. If the total depth is not a multiple of the batch size, the last batch is padded.
| T | Element value type (possibly const-qualified). |
| I | Index and size type. Usually std::ptrdiff_t or int. |
| S | Inner stride type (batch size). Usually std::integral_constant<I, N> for some N. |
| D | Batch depth type. Usually equal to S for a single batch, or I for a dynamic depth. |
| L | Layer stride type. Usually DefaultStride (which implies that the layer stride is equal to outer_stride() * outer_size()), or I for a dynamic layer stride. Dynamic strides are used for subviews of views with a larger outer_size(). |
| O | Matrix storage order, RowMajor or ColMajor. |
Constructors | |
| constexpr | View (PlainBatchedMatrixView p={}) |
| Create a new view. | |
| constexpr | View (std::span< T > data, layout_type layout) |
| Create a new view with the given layout, using the given buffer. | |
| constexpr | View (value_type *data, layout_type layout) |
| Create a new view with the given layout, using the given buffer. | |
| View (const View &)=default | |
| Copy a view. No data is copied. | |
| View & | reassign (View other) |
| Reassign the buffer and layout of this view to those of another view. No data is copied. | |
Element access | |
| value_type & | operator() (index_type l, index_type r, index_type c) const |
Access a single element at layer l, row r and column c. | |
Batch-wise slicing | |
| batch_view_type | batch (index_type b) const |
Access a batch of batch_size() layers, starting at batch index b (i.e. | |
| View< T, I, S, I, L, O > | batch_dyn (index_type b) const |
| Same as batch(), but returns a view with a dynamic batch size. | |
| View< T, I, S, I, I, O > | middle_batches (index_type b, index_type n, index_type stride=1) const |
Get a view of n batches starting at batch b, with a stride of stride layers. | |
Layer-wise slicing | |
| guanaqo::MatrixView< T, I, standard_stride_type, O > | operator() (index_type l) const |
Access a single layer l as a non-batched view. | |
| template<class N> | |
| View< T, I, S, N, L, O > | first_layers (N n) const |
Get a view of the first n layers. Note that n can be a compile-time constant. | |
| template<class N> | |
| View< T, I, S, N, L, O > | middle_layers (index_type l, N n) const |
Get a view of n layers starting at layer l. | |
Iterators and buffer access | |
| T * | data () const |
| Get a pointer to the first element of the first layer. | |
| linear_iterator | begin () const |
| Iterate linearly (in storage order) over all elements of the view. | |
| std::default_sentinel_t | end () const |
| Sentinel for begin(). | |
Dimensions | |
| constexpr index_type | size () const |
| Total number of elements in the view (excluding padding). | |
| constexpr index_type | padded_size () const |
| Total number of elements in the view (including all padding). | |
| constexpr depth_type | depth () const |
| Number of layers in the view (i.e. depth). | |
| constexpr index_type | ceil_depth () const |
| The depth rounded up to a multiple of the batch size. | |
| constexpr batch_size_type | batch_size () const |
| The batch size, i.e. the number of layers in each batch. Equals the inner stride. | |
| constexpr index_type | num_batches () const |
| Number of batches in the view, i.e. ceil_depth() / batch_size(). | |
| constexpr index_type | rows () const |
| Number of rows of the matrices. | |
| constexpr index_type | cols () const |
| Number of columns of the matrices. | |
| constexpr index_type | outer_size () const |
| The size of the outer dimension, i.e. | |
| constexpr index_type | inner_size () const |
| The size of the inner dimension, i.e. | |
Strides | |
| constexpr index_type | outer_stride () const |
| Outer stride of the matrices (leading dimension in BLAS parlance). | |
| constexpr auto | inner_stride () const |
| The inner stride of the matrices. | |
| constexpr auto | row_stride () const |
| The row stride of the matrices, i.e. | |
| constexpr auto | col_stride () const |
| The column stride of the matrices, i.e. | |
| constexpr index_type | layer_stride () const |
| The layer stride, i.e. | |
| constexpr bool | has_full_layer_stride () const |
| Whether the layer_stride() == outer_stride() * outer_size(). | |
| constexpr bool | has_full_outer_stride () const |
| Whether the outer_stride() == inner_stride() * inner_size(). | |
| constexpr bool | has_full_inner_stride () const |
| Whether the inner_stride() == 1. Always true. | |
Reshaping and slicing | |
| general_slice_view_type | reshaped (index_type rows, index_type cols) const |
| Reshape the view to the given dimensions. The total size should not change. | |
| row_slice_view_type | top_rows (index_type n) const |
Get a view of the first n rows. | |
| col_slice_view_type | left_cols (index_type n) const |
Get a view of the first n columns. | |
| row_slice_view_type | bottom_rows (index_type n) const |
Get a view of the last n rows. | |
| col_slice_view_type | right_cols (index_type n) const |
Get a view of the last n columns. | |
| row_slice_view_type | middle_rows (index_type r, index_type n) const |
Get a view of n rows starting at row r. | |
| row_slice_view_type | middle_rows (index_type r, index_type n, index_type stride) const |
Get a view of n rows starting at row r, with stride stride. | |
| col_slice_view_type | middle_cols (index_type c, index_type n) const |
Get a view of n columns starting at column c. | |
| col_slice_view_type | middle_cols (index_type c, index_type n, index_type stride) const |
Get a view of n columns starting at column c, with stride stride. | |
| general_slice_view_type | top_left (index_type nr, index_type nc) const |
Get a view of the top-left nr by nc block of the matrices. | |
| general_slice_view_type | top_right (index_type nr, index_type nc) const |
Get a view of the top-right nr by nc block of the matrices. | |
| general_slice_view_type | bottom_left (index_type nr, index_type nc) const |
Get a view of the bottom-left nr by nc block of the matrices. | |
| general_slice_view_type | bottom_right (index_type nr, index_type nc) const |
Get a view of the bottom-right nr by nc block of the matrices. | |
| general_slice_view_type | block (index_type r, index_type c, index_type nr, index_type nc) const |
Get a view of the nr by nc block of the matrices starting at row r and column c. | |
| auto | transposed () const |
| Get a transposed view of the matrices. | |
| static View | as_column (std::span< T > v) |
| Get a view of the given span as a column vector. | |
Value manipulation | |
| void | add_to_diagonal (const value_type &t) |
| void | set_constant (value_type t) |
| void | negate () |
| template<class Other> | |
| void | copy_values (const Other &other) const |
| View & | operator= (const View &other) |
| Copy assignment copies the values from another view with the same layout to this view. | |
| template<class U, class J, class R, class E, class M> | |
| View & | operator= (View< U, J, R, E, M, O > other) |
| Copy values from another view with a compatible value type and the same layout to this view. | |
| template<class U, class J, class R, class E, class M> | |
| View & | operator+= (View< U, J, R, E, M, O > other) |
View conversions | |
| View | view () const |
| Returns the same view. For consistency with Matrix. | |
| const_view_type | as_const () const |
| Explicit conversion to a const view. | |
| operator const_view_type () const | |
| Non-const views implicitly convert to const views. | |
| operator guanaqo::MatrixView< T, I, standard_stride_type, O > () const | |
| If we have a single layer at compile time, we can implicitly convert to a non-batched view. | |
| operator View< T, I, S, integral_value_type_t< D >, L, O > () const | |
| Implicit conversion to a view with a dynamic depth. | |
| operator View< const T, I, S, integral_value_type_t< D >, L, O > () const | |
| Implicit conversion to a view with a dynamic depth, going from non-const to const. | |
| operator View< T, I, S, D, I, O > () const | |
| Implicit conversion to a view with a dynamic layer stride. | |
| operator View< const T, I, S, D, I, O > () const | |
| Implicit conversion to a view with a dynamic layer stride, going from non-const to const. | |
Classes | |
| struct | PlainBatchedMatrixView |
| POD helper struct to enable designated initializers during construction. More... | |
| struct | linear_iterator |
| Iterator over all elements of a view. More... | |
Public Types | |
| using | layout_type = Layout<I, S, D, L, O> |
| using | value_type = T |
| using | index_type = typename layout_type::index_type |
| using | batch_size_type = typename layout_type::batch_size_type |
| using | depth_type = typename layout_type::depth_type |
| using | layer_stride_type = typename layout_type::layer_stride_type |
| using | standard_stride_type = typename layout_type::standard_stride_type |
| using | const_view_type = View<const T, I, S, D, L, O> |
| using | batch_view_type = View<T, I, S, S, DefaultStride, O> |
| When extracing a single batch, the depth equals the batch size, and the layer stride is no longer relevant. | |
| using | general_slice_view_type |
| When slicing along the outer dimension, the layer stride stays the same, but the outer size may be smaller, which means that even if the original view has a default layer stride, the sliced view may require a dynamic layer stride. | |
| using | col_slice_view_type = std::conditional_t<is_row_major, View, general_slice_view_type> |
| View with the correct layer stride when slicing along the column dimension. | |
| using | row_slice_view_type = std::conditional_t<is_column_major, View, general_slice_view_type> |
| View with the correct layer stride when slicing along the row dimension. | |
Public Attributes | |
| value_type * | data_ptr |
| Pointer to the first element of the first layer. | |
| layout_type | layout |
| Layout describing the dimensions and strides of the view. | |
Static Public Attributes | |
| static constexpr StorageOrder | storage_order = layout_type::storage_order |
| static constexpr bool | is_column_major = layout_type::is_column_major |
| static constexpr bool | is_row_major = layout_type::is_row_major |
| static constexpr bool | has_single_batch_at_compile_time |
| True if batch_size() and depth() are compile-time constants and are equal. | |
| static constexpr bool | has_single_layer_at_compile_time = requires { D::value; } && D{} == 1 |
| True if depth() is a compile-time constant and is equal to one. | |
Private Member Functions | |
| template<class V> | |
| constexpr auto | get_layer_stride_for () const |
| struct batmat::matrix::View::PlainBatchedMatrixView |
| Class Members | ||
|---|---|---|
| value_type * | data = nullptr | |
| depth_type | depth = guanaqo::default_stride<depth_type>::value | |
| index_type | rows = 0 | |
| index_type | cols = rows == 0 ? 0 : 1 | |
| index_type | outer_stride = is_row_major ? cols : rows | |
| batch_size_type | batch_size | |
| layer_stride_type | layer_stride | |
| using batmat::matrix::View< T, I, S, D, L, O >::layout_type = Layout<I, S, D, L, O> |
| using batmat::matrix::View< T, I, S, D, L, O >::value_type = T |
| using batmat::matrix::View< T, I, S, D, L, O >::index_type = typename layout_type::index_type |
| using batmat::matrix::View< T, I, S, D, L, O >::batch_size_type = typename layout_type::batch_size_type |
| using batmat::matrix::View< T, I, S, D, L, O >::depth_type = typename layout_type::depth_type |
| using batmat::matrix::View< T, I, S, D, L, O >::layer_stride_type = typename layout_type::layer_stride_type |
| using batmat::matrix::View< T, I, S, D, L, O >::standard_stride_type = typename layout_type::standard_stride_type |
| using batmat::matrix::View< T, I, S, D, L, O >::const_view_type = View<const T, I, S, D, L, O> |
| using batmat::matrix::View< T, I, S, D, L, O >::batch_view_type = View<T, I, S, S, DefaultStride, O> |
| using batmat::matrix::View< T, I, S, D, L, O >::general_slice_view_type |
When slicing along the outer dimension, the layer stride stays the same, but the outer size may be smaller, which means that even if the original view has a default layer stride, the sliced view may require a dynamic layer stride.
For a single batch, the layer stride is not relevant, so it is preserved.
| using batmat::matrix::View< T, I, S, D, L, O >::col_slice_view_type = std::conditional_t<is_row_major, View, general_slice_view_type> |
View with the correct layer stride when slicing along the column dimension.
For row-major storage, slicing along columns does not change the outer size, in which case the layer stride is still correct. For column-major storage, slicing along columns does change the outer size, in which case we need a dynamic layer stride.
| using batmat::matrix::View< T, I, S, D, L, O >::row_slice_view_type = std::conditional_t<is_column_major, View, general_slice_view_type> |
View with the correct layer stride when slicing along the row dimension.
|
inlineconstexpr |
|
inlineconstexpr |
|
inlineconstexpr |
|
default |
Copy a view. No data is copied.
|
inline |
|
inlinenodiscard |
|
inlinenodiscard |
Access a batch of batch_size() layers, starting at batch index b (i.e.
starting at layer b * batch_size()).
|
inlinenodiscard |
|
inlinenodiscard |
|
inlinenodiscard |
|
inlinenodiscard |
|
inlinenodiscard |
Get a view of n layers starting at layer l.
Note that n can be a compile-time constant.
|
inline |
|
inlinenodiscard |
Iterate linearly (in storage order) over all elements of the view.
|
inlinenodiscard |
|
inlinenodiscardconstexpr |
|
inlinenodiscardconstexpr |
|
inlinenodiscardconstexpr |
|
inlinenodiscardconstexpr |
|
inlinenodiscardconstexpr |
|
inlinenodiscardconstexpr |
Number of batches in the view, i.e. ceil_depth() / batch_size().
|
inlinenodiscardconstexpr |
|
inlinenodiscardconstexpr |
|
inlinenodiscardconstexpr |
|
inlinenodiscardconstexpr |
|
inlinenodiscardconstexpr |
|
inlinenodiscardconstexpr |
|
inlinenodiscardconstexpr |
|
inlinenodiscardconstexpr |
|
inlinenodiscardconstexpr |
|
inlinenodiscardconstexpr |
Whether the layer_stride() == outer_stride() * outer_size().
|
inlinenodiscardconstexpr |
Whether the outer_stride() == inner_stride() * inner_size().
|
inlinenodiscardconstexpr |
Whether the inner_stride() == 1. Always true.
|
inlineconstexprprivate |
|
inlinenodiscard |
|
inlinenodiscard |
|
inlinenodiscard |
|
inlinenodiscard |
|
inlinenodiscard |
|
inlinenodiscard |
|
inlinenodiscard |
|
inlinenodiscard |
|
inlinenodiscard |
|
inlinenodiscard |
|
inlinenodiscard |
|
inlinenodiscard |
|
inlinenodiscard |
|
inlinenodiscard |
|
inlinestaticnodiscard |
|
inlinenodiscard |
|
inline |
|
inline |
|
inline |
|
inline |
|
inline |
|
inline |
|
inline |
|
inlinenodiscard |
|
inlinenodiscard |
|
inline |
|
inline |
|
inline |
|
inline |
|
inline |
|
inline |
|
staticconstexpr |
|
staticconstexpr |
|
staticconstexpr |
|
staticconstexpr |
True if batch_size() and depth() are compile-time constants and are equal.
|
staticconstexpr |
| value_type* batmat::matrix::View< T, I, S, D, L, O >::data_ptr |
| layout_type batmat::matrix::View< T, I, S, D, L, O >::layout |