batmat 0.0.17
Batched linear algebra routines
Loading...
Searching...
No Matches
matrix.hpp
Go to the documentation of this file.
1#pragma once
2
3/// @file
4/// Class for a batch of matrices that owns its storage.
5/// @ingroup topic-matrix
6
9
10#include <type_traits>
11#include <utility>
12
13namespace batmat::matrix {
14
15namespace detail {
16
17template <class, class I, class Stride>
19 using type = std::integral_constant<I, 0>;
20};
21template <class T, class I, class Stride>
22 requires requires {
23 { Stride::value } -> std::convertible_to<I>;
24 }
25struct default_alignment<T, I, Stride> {
26 using type = std::integral_constant<I, alignof(T) * Stride::value>;
27};
28template <class T, class I, class Stride>
30
33
34} // namespace detail
35
36/// Owning array of matrices, stored in an efficient batched format.
37///
38/// @see @ref batmat::matrix::View for a detailed description of the layout and the available
39/// operations on arrays or batches of matrices.
40///
41/// @tparam T
42/// Element value type.
43/// @tparam I
44/// Index and size type. Usually `std::ptrdiff_t` or `int`.
45/// @tparam S
46/// Inner stride type (batch size). Usually `std::integral_constant<I, N>` for some `N`.
47/// @tparam D
48/// Batch depth type. Usually equal to @p S for a single batch, or @p I for a dynamic depth.
49/// @tparam O
50/// %Matrix storage order, @ref guanaqo::StorageOrder::RowMajor "RowMajor" or
51/// @ref guanaqo::StorageOrder::ColMajor "ColMajor".
52/// @tparam A
53/// Batch alignment type. Should be `std::integral_constant<I, N>` for some `N` that is a
54/// multiple of the alignment requirements of @p T. To enable vectorization, this should be
55/// `std::integral_constant<I, alignof(T) * S::value>`, which is the default.
56/// @ingroup topic-matrix
57template <class T, class I = index_t, class S = std::integral_constant<I, 1>, class D = I,
58 StorageOrder O = StorageOrder::ColMajor, class A = detail::default_alignment_t<T, I, S>>
59struct Matrix {
60 static_assert(!std::is_const_v<T>);
64 using plain_layout_type = typename layout_type::PlainLayout;
65 using value_type = T;
66 using index_type = typename layout_type::index_type;
67 using batch_size_type = typename layout_type::batch_size_type;
68 using depth_type = typename layout_type::depth_type;
69 using standard_stride_type = typename layout_type::standard_stride_type;
70 using alignment_type = A;
73 static constexpr bool is_row_major = view_type::is_row_major;
74 static constexpr bool has_single_batch_at_compile_time =
76 static constexpr bool has_single_layer_at_compile_time =
78
79 private:
81
82 static constexpr auto default_alignment(layout_type layout) {
83 if constexpr (std::is_integral_v<alignment_type>)
84 return alignof(T) * static_cast<size_t>(layout.batch_size); // TODO
85 if constexpr (alignment_type::value == 0)
86 return alignof(T) * static_cast<size_t>(layout.batch_size);
87 else
88 return alignment_type{};
89 }
90 [[nodiscard]] static auto allocate(layout_type layout) {
91 const auto alignment = default_alignment(layout);
92 return make_aligned_unique_ptr<T>(layout.padded_size(), alignment);
93 }
94 [[nodiscard]] static auto allocate(layout_type layout, uninitialized_t init) {
95 const auto alignment = default_alignment(layout);
96 return make_aligned_unique_ptr<T>(layout.padded_size(), alignment, init);
97 }
98 void clear() {
99 const auto alignment = default_alignment(view_.layout);
100 if (auto d = std::exchange(view_.data_ptr, nullptr))
101 aligned_deleter<T, decltype(alignment)>(view_.layout.padded_size(), alignment)(d);
102 view_.layout.rows = 0;
103 }
104
105 template <class U, class J, class R, class E, class M>
106 requires(std::convertible_to<U, T> && std::equality_comparable_with<index_type, J>)
108 layout_type new_layout{{.depth = static_cast<depth_type>(other.depth()),
109 .rows = other.rows(),
110 .cols = other.cols(),
111 .batch_size = static_cast<batch_size_type>(other.batch_size())}};
112 resize(new_layout);
113 view().copy_values(other); // TODO: exception safety
114 }
115
116 public:
117 /// @name Constructors, assignment and resizing
118 /// @{
119
120 // TODO: allowing the user to specify strides during construction is kind of pointless,
121 // because it introduces many padding elements, which can never be accessed.
122
123 Matrix() = default;
129 /// Copy the values from another matrix.
130 Matrix(const Matrix &o) : Matrix{o.layout()} {
131 this->view().copy_values(o.view()); // TODO: exception safety
132 }
133 Matrix(Matrix &&o) noexcept : view_{o.view()} { o.view_.reassign({}); }
134 /// Cheap move assignment. No data is copied.
135 Matrix &operator=(Matrix &&o) noexcept {
136 using std::swap;
137 if (&o != this) {
138 swap(o.view_.data_ptr, this->view_.data_ptr);
139 swap(o.view_.layout, this->view_.layout);
140 }
141 return *this;
142 }
143 ~Matrix() { clear(); }
144
145 /// Resize the matrix to a new layout, reallocating if the padded size changes.
146 void resize(layout_type new_layout) {
147 if (new_layout.padded_size() != layout().padded_size()) {
148 clear();
149 view_.data_ptr = allocate(new_layout).release();
150 }
151 view_.layout = new_layout;
152 }
153
154 /// @}
155
156 /// @name Element access
157 /// @{
158
159 /// Access a single element at layer @p l, row @p r and column @p c.
161 return view()(l, r, c);
162 }
163 /// Access a single element at layer @p l, row @p r and column @p c.
164 [[nodiscard]] const value_type &operator()(index_type l, index_type r, index_type c) const {
165 return view()(l, r, c);
166 }
167
168 /// @}
169
170 /// @name Batch-wise slicing
171 /// @{
172
173 /// @copydoc View::batch()
174 [[nodiscard]] auto batch(index_type b) { return view().batch(b); }
175 /// @copydoc View::batch()
176 [[nodiscard]] auto batch(index_type b) const { return view().batch(b); }
177 /// @copydoc View::batch_dyn()
178 [[nodiscard]] auto batch_dyn(index_type b) { return view().batch_dyn(b); }
179 /// @copydoc View::batch_dyn()
180 [[nodiscard]] auto batch_dyn(index_type b) const { return view().batch_dyn(b); }
181 /// @copydoc View::middle_batches()
182 [[nodiscard]] auto middle_batches(index_type b, index_type n, index_type stride = 1) {
183 return view().middle_batches(b, n, stride);
184 }
185 /// @copydoc View::middle_batches()
186 [[nodiscard]] auto middle_batches(index_type b, index_type n, index_type stride = 1) const {
187 return view().middle_batches(b, n, stride);
188 }
189
190 /// @}
191
192 /// @name Layer-wise slicing
193 /// @{
194
195 /// Access a single layer @p l as a non-batched view.
199 /// Access a single layer @p l as a non-batched view.
202 return view()(l);
203 }
204 /// @copydoc View::first_layers()
205 template <class N>
206 [[nodiscard]] auto first_layers(N n) {
207 return view().first_layers(n);
208 }
209 /// @copydoc View::first_layers()
210 template <class N>
211 [[nodiscard]] auto first_layers(N n) const {
212 return view().first_layers(n);
213 }
214 /// @copydoc View::middle_layers()
215 template <class N>
216 [[nodiscard]] auto middle_layers(index_type l, N n) {
217 return view().middle_layers(l, n);
218 }
219 /// @copydoc View::middle_layers()
220 template <class N>
221 [[nodiscard]] auto middle_layers(index_type l, N n) const {
222 return view().middle_layers(l, n);
223 }
224
225 /// @}
226
227 /// @name Iterators and buffer access
228 /// @{
229
230 /// @copydoc View::data()
231 [[nodiscard]] value_type *data() { return view().data(); }
232 /// @copydoc View::data()
233 [[nodiscard]] const value_type *data() const { return view().data(); }
234 /// @copydoc View::begin()
235 [[nodiscard]] auto begin() { return view().begin(); }
236 /// @copydoc View::begin()
237 [[nodiscard]] auto begin() const { return view().begin(); }
238 /// @copydoc View::end()
239 [[nodiscard]] auto end() { return view().end(); }
240 /// @copydoc View::end()
241 [[nodiscard]] auto end() const { return view().end(); }
242
243 /// @}
244
245 /// @name Dimensions
246 /// @{
247
248 [[nodiscard]] layout_type layout() const { return view_.layout; }
249 /// @copydoc View::size()
250 [[nodiscard]] index_type size() const { return view().size(); }
251 /// @copydoc View::padded_size()
252 [[nodiscard]] index_type padded_size() const { return view().padded_size(); }
253 /// @copydoc View::depth()
254 [[nodiscard]] depth_type depth() const { return view().depth(); }
255 /// @copydoc View::ceil_depth()
256 [[nodiscard]] index_type ceil_depth() const { return view().ceil_depth(); }
257 /// @copydoc View::num_batches()
258 [[nodiscard]] index_type num_batches() const { return view().num_batches(); }
259 /// @copydoc View::rows()
260 [[nodiscard]] index_type rows() const { return view().rows(); }
261 /// @copydoc View::cols()
262 [[nodiscard]] index_type cols() const { return view().cols(); }
263 /// @copydoc View::outer_size()
264 [[nodiscard]] index_type outer_size() const { return view().outer_size(); }
265 /// @copydoc View::inner_size()
266 [[nodiscard]] index_type inner_size() const { return view().inner_size(); }
267
268 /// @}
269
270 /// @name Strides
271 /// @{
272
273 /// @copydoc View::outer_stride()
274 [[nodiscard]] index_type outer_stride() const { return view().outer_stride(); }
275 /// @copydoc View::inner_stride()
276 [[nodiscard]] constexpr auto inner_stride() const { return view().inner_stride(); }
277 /// @copydoc View::row_stride()
278 [[nodiscard]] constexpr auto row_stride() const { return view().row_stride(); }
279 /// @copydoc View::col_stride()
280 [[nodiscard]] constexpr auto col_stride() const { return view().col_stride(); }
281 /// @copydoc View::layer_stride()
282 [[nodiscard]] index_type layer_stride() const { return view().layer_stride(); }
283 /// @copydoc View::has_full_layer_stride()
284 [[nodiscard]] bool has_full_layer_stride() const { return view().has_full_layer_stride(); }
285 /// @copydoc View::has_full_outer_stride()
286 [[nodiscard]] bool has_full_outer_stride() const { return view().has_full_outer_stride(); }
287 /// @copydoc View::has_full_inner_stride()
288 [[nodiscard]] bool has_full_inner_stride() const { return view().has_full_inner_stride(); }
289 /// @copydoc View::batch_size()
290 [[nodiscard]] batch_size_type batch_size() const { return view().batch_size(); }
291
292 /// @}
293
294 /// @name Reshaping and slicing
295 /// @{
296
297 /// @copydoc View::reshaped()
298 [[nodiscard]] auto reshaped(index_type rows, index_type cols) {
299 return view().reshaped(rows, cols);
300 }
301 /// @copydoc View::reshaped()
302 [[nodiscard]] auto reshaped(index_type rows, index_type cols) const {
303 return view().reshaped(rows, cols);
304 }
305 /// @copydoc View::top_rows()
306 [[nodiscard]] auto top_rows(index_type n) { return view().top_rows(n); }
307 /// @copydoc View::top_rows()
308 [[nodiscard]] auto top_rows(index_type n) const { return view().top_rows(n); }
309 /// @copydoc View::left_cols()
310 [[nodiscard]] auto left_cols(index_type n) { return view().left_cols(n); }
311 /// @copydoc View::left_cols()
312 [[nodiscard]] auto left_cols(index_type n) const { return view().left_cols(n); }
313 /// @copydoc View::bottom_rows()
314 [[nodiscard]] auto bottom_rows(index_type n) { return view().bottom_rows(n); }
315 /// @copydoc View::bottom_rows()
316 [[nodiscard]] auto bottom_rows(index_type n) const { return view().bottom_rows(n); }
317 /// @copydoc View::right_cols()
318 [[nodiscard]] auto right_cols(index_type n) { return view().right_cols(n); }
319 /// @copydoc View::right_cols()
320 [[nodiscard]] auto right_cols(index_type n) const { return view().right_cols(n); }
321 /// @copydoc View::middle_rows
322 [[nodiscard]] auto middle_rows(index_type r, index_type n) { return view().middle_rows(r, n); }
323 /// @copydoc View::middle_rows
324 [[nodiscard]] auto middle_rows(index_type r, index_type n) const {
325 return view().middle_rows(r, n);
326 }
327 /// @copydoc View::middle_rows
328 [[nodiscard]] auto middle_rows(index_type r, index_type n, index_type stride)
330 {
331 return view().middle_rows(r, n, stride);
332 }
333 /// @copydoc View::middle_rows
334 [[nodiscard]] auto middle_rows(index_type r, index_type n, index_type stride) const
336 {
337 return view().middle_rows(r, n, stride);
338 }
339 /// @copydoc View::middle_cols
340 [[nodiscard]] auto middle_cols(index_type c, index_type n) { return view().middle_cols(c, n); }
341 /// @copydoc View::middle_cols
342 [[nodiscard]] auto middle_cols(index_type c, index_type n) const {
343 return view().middle_cols(c, n);
344 }
345 /// @copydoc View::middle_cols
346 [[nodiscard]] auto middle_cols(index_type c, index_type n, index_type stride)
348 {
349 return view().middle_cols(c, n, stride);
350 }
351 /// @copydoc View::middle_cols
352 [[nodiscard]] auto middle_cols(index_type c, index_type n, index_type stride) const
354 {
355 return view().middle_cols(c, n, stride);
356 }
357 /// @copydoc View::top_left()
358 [[nodiscard]] auto top_left(index_type nr, index_type nc) { return view().top_left(nr, nc); }
359 /// @copydoc View::top_left()
360 [[nodiscard]] auto top_left(index_type nr, index_type nc) const {
361 return view().top_left(nr, nc);
362 }
363 /// @copydoc View::top_right()
364 [[nodiscard]] auto top_right(index_type nr, index_type nc) { return view().top_right(nr, nc); }
365 /// @copydoc View::top_right()
366 [[nodiscard]] auto top_right(index_type nr, index_type nc) const {
367 return view().top_right(nr, nc);
368 }
369 /// @copydoc View::bottom_left()
370 [[nodiscard]] auto bottom_left(index_type nr, index_type nc) {
371 return view().bottom_left(nr, nc);
372 }
373 /// @copydoc View::bottom_left()
374 [[nodiscard]] auto bottom_left(index_type nr, index_type nc) const {
375 return view().bottom_left(nr, nc);
376 }
377 /// @copydoc View::bottom_right()
378 [[nodiscard]] auto bottom_right(index_type nr, index_type nc) {
379 return view().bottom_right(nr, nc);
380 }
381 /// @copydoc View::bottom_right()
382 [[nodiscard]] auto bottom_right(index_type nr, index_type nc) const {
383 return view().bottom_right(nr, nc);
384 }
385 /// @copydoc View::block()
386 [[nodiscard]] auto block(index_type r, index_type c, index_type nr, index_type nc) {
387 return view().block(r, c, nr, nc);
388 }
389 /// @copydoc View::block()
390 [[nodiscard]] auto block(index_type r, index_type c, index_type nr, index_type nc) const {
391 return view().block(r, c, nr, nc);
392 }
393 /// @copydoc View::transposed()
394 [[nodiscard]] auto transposed() { return view().transposed(); }
395 /// @copydoc View::transposed()
396 [[nodiscard]] auto transposed() const { return view().transposed(); }
397
398 /// @}
399
400 /// @name Value manipulation
401 /// @{
402
403 /// Copy the values of another matrix, resizing if necessary.
405 if (&o != this) {
406 clear();
407 view_.reassign({allocate(o.layout()).release(), o.layout()});
408 // TODO: use allocate_for_overwrite or similar to avoid copy
409 // assignment
410 this->view_.copy_values(o.view_); // TODO: exception safety
411 }
412 return *this;
413 }
414
415 /// Copy the values from a compatible view, resizing if necessary.
416 template <class U, class J, class R, class E, class M>
417 requires(std::convertible_to<U, T> && std::equality_comparable_with<index_type, J>)
418 Matrix &operator=(View<U, J, R, E, M, O> other) {
419 assign_from_view(other);
420 return *this;
421 }
422
423 /// @copydoc View::set_constant()
425 /// @copydoc View::add_to_diagonal()
427 /// @copydoc View::negate()
428 void negate() { view().negate(); }
429 /// @copydoc View::copy_values()
430 template <class Other>
431 void copy_values(const Other &other) {
432 view().copy_values(other);
433 }
434 /// @copydoc View::operator+=()
435 template <class U, class J, class R, class E, class M>
436 requires(std::convertible_to<U, T> && std::equality_comparable_with<index_type, J>)
437 Matrix &operator+=(View<U, J, R, E, M, O> other) {
438 view() += other;
439 return *this;
440 }
441
442 /// @}
443
444 /// @name View conversions
445 /// @{
446
447 /// @copydoc View::view()
448 [[nodiscard, gnu::always_inline]] view_type view() { return view_; }
449 /// @copydoc View::view()
450 [[nodiscard, gnu::always_inline]] const_view_type view() const { return view_.as_const(); }
451 /// @copydoc View::as_const()
452 [[nodiscard]] auto as_const() const { return view(); }
453
454 operator view_type() { return view(); }
455 operator const_view_type() const { return view(); }
456 operator View<T, I, S, D, I, O>() { return view(); }
457 operator View<const T, I, S, D, I, O>() const { return view(); }
459 requires(!std::same_as<integral_value_type_t<D>, D>)
460 {
461 return view();
462 }
464 requires(!std::same_as<integral_value_type_t<D>, D>)
465 {
466 return view();
467 }
478
479 /// @}
480};
481
482template <class T, class I, class S, class D, class A, StorageOrder O>
483constexpr auto data(Matrix<T, I, S, D, O, A> &v) {
484 return v.data();
485}
486template <class T, class I, class S, class D, class A, StorageOrder O>
487constexpr auto data(Matrix<T, I, S, D, O, A> &&v) = delete;
488template <class T, class I, class S, class D, class A, StorageOrder O>
489constexpr auto data(const Matrix<T, I, S, D, O, A> &v) {
490 return v.data();
491}
492template <class T, class I, class S, class D, class A, StorageOrder O>
493constexpr auto rows(const Matrix<T, I, S, D, O, A> &v) {
494 return v.rows();
495}
496template <class T, class I, class S, class D, class A, StorageOrder O>
497constexpr auto cols(const Matrix<T, I, S, D, O, A> &v) {
498 return v.cols();
499}
500template <class T, class I, class S, class D, class A, StorageOrder O>
501constexpr auto outer_stride(const Matrix<T, I, S, D, O, A> &v) {
502 return v.outer_stride();
503}
504template <class T, class I, class S, class D, class A, StorageOrder O>
505constexpr auto depth(const Matrix<T, I, S, D, O, A> &v) {
506 return v.depth();
507}
508
509} // namespace batmat::matrix
auto make_aligned_unique_ptr(size_t size, A align)
Returns a smart pointer to an array of T that satisfies the given alignment requirements.
Definition storage.hpp:77
std::integral_constant< I, 0 > type
Definition matrix.hpp:19
typename default_alignment< T, I, Stride >::type default_alignment_t
Definition matrix.hpp:29
std::integral_constant< I, alignof(T) *Stride::value > type
Definition matrix.hpp:26
constexpr auto cols(const Matrix< T, I, S, D, O, A > &v)
Definition matrix.hpp:497
typename integral_value_type< T >::type integral_value_type_t
Definition layout.hpp:25
constexpr auto data(Matrix< T, I, S, D, O, A > &v)
Definition matrix.hpp:483
constexpr auto outer_stride(const Matrix< T, I, S, D, O, A > &v)
Definition matrix.hpp:501
constexpr auto rows(const Matrix< T, I, S, D, O, A > &v)
Definition matrix.hpp:493
constexpr auto depth(const Matrix< T, I, S, D, O, A > &v)
Definition matrix.hpp:505
Aligned allocation for matrix storage.
Owning array of matrices, stored in an efficient batched format.
Definition matrix.hpp:59
auto top_right(index_type nr, index_type nc) const
Get a view of the top-right nr by nc block of the matrices.
Definition matrix.hpp:366
bool has_full_inner_stride() const
Whether the inner_stride() == 1. Always true.
Definition matrix.hpp:288
void add_to_diagonal(const value_type &t)
Definition matrix.hpp:426
Matrix(const Matrix &o)
Copy the values from another matrix.
Definition matrix.hpp:130
auto bottom_rows(index_type n) const
Get a view of the last n rows.
Definition matrix.hpp:316
auto bottom_left(index_type nr, index_type nc) const
Get a view of the bottom-left nr by nc block of the matrices.
Definition matrix.hpp:374
auto middle_layers(index_type l, N n)
Get a view of n layers starting at layer l.
Definition matrix.hpp:216
auto batch_dyn(index_type b)
Same as batch(), but returns a view with a dynamic batch size.
Definition matrix.hpp:178
void assign_from_view(View< U, J, R, E, M, O > other)
Definition matrix.hpp:107
View< S, index_t, simd_stride_t, index_t, DefaultStride, O > view_type
Definition matrix.hpp:61
auto first_layers(N n) const
Get a view of the first n layers. Note that n can be a compile-time constant.
Definition matrix.hpp:211
auto middle_batches(index_type b, index_type n, index_type stride=1)
Get a view of n batches starting at batch b, with a stride of stride layers.
Definition matrix.hpp:182
Matrix(plain_layout_type p)
Definition matrix.hpp:127
Matrix(plain_layout_type p, uninitialized_t init)
Definition matrix.hpp:128
auto 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.
Definition matrix.hpp:186
Matrix & operator=(Matrix &&o) noexcept
Cheap move assignment. No data is copied.
Definition matrix.hpp:135
auto reshaped(index_type rows, index_type cols) const
Reshape the view to the given dimensions. The total size should not change.
Definition matrix.hpp:302
auto middle_layers(index_type l, N n) const
Get a view of n layers starting at layer l.
Definition matrix.hpp:221
static auto allocate(layout_type layout)
Definition matrix.hpp:90
index_type padded_size() const
Total number of elements in the view (including all padding).
Definition matrix.hpp:252
void resize(layout_type new_layout)
Resize the matrix to a new layout, reallocating if the padded size changes.
Definition matrix.hpp:146
batch_size_type batch_size() const
The batch size, i.e. the number of layers in each batch. Equals the inner stride.
Definition matrix.hpp:290
value_type * data()
Get a pointer to the first element of the first layer.
Definition matrix.hpp:231
index_type size() const
Total number of elements in the view (excluding padding).
Definition matrix.hpp:250
Matrix & operator=(const Matrix &o)
Copy the values of another matrix, resizing if necessary.
Definition matrix.hpp:404
auto block(index_type r, index_type c, index_type nr, index_type nc)
Get a view of the nr by nc block of the matrices starting at row r and column c.
Definition matrix.hpp:386
auto top_rows(index_type n) const
Get a view of the first n rows.
Definition matrix.hpp:308
auto transposed() const
Get a transposed view of the matrices.
Definition matrix.hpp:396
index_type rows() const
Number of rows of the matrices.
Definition matrix.hpp:260
Matrix(layout_type layout)
Definition matrix.hpp:124
auto reshaped(index_type rows, index_type cols)
Reshape the view to the given dimensions. The total size should not change.
Definition matrix.hpp:298
void set_constant(value_type t)
Definition matrix.hpp:424
auto top_left(index_type nr, index_type nc) const
Get a view of the top-left nr by nc block of the matrices.
Definition matrix.hpp:360
auto bottom_rows(index_type n)
Get a view of the last n rows.
Definition matrix.hpp:314
auto left_cols(index_type n)
Get a view of the first n columns.
Definition matrix.hpp:310
constexpr auto inner_stride() const
The inner stride of the matrices.
Definition matrix.hpp:276
auto left_cols(index_type n) const
Get a view of the first n columns.
Definition matrix.hpp:312
auto middle_cols(index_type c, index_type n)
Get a view of n columns starting at column c.
Definition matrix.hpp:340
auto top_rows(index_type n)
Get a view of the first n rows.
Definition matrix.hpp:306
auto batch(index_type b)
Access a batch of batch_size() layers, starting at batch index b (i.e.
Definition matrix.hpp:174
auto middle_cols(index_type c, index_type n) const
Get a view of n columns starting at column c.
Definition matrix.hpp:342
auto right_cols(index_type n)
Get a view of the last n columns.
Definition matrix.hpp:318
auto bottom_right(index_type nr, index_type nc) const
Get a view of the bottom-right nr by nc block of the matrices.
Definition matrix.hpp:382
void copy_values(const Other &other)
Definition matrix.hpp:431
view_type view()
Returns the same view. For consistency with Matrix.
Definition matrix.hpp:448
auto top_right(index_type nr, index_type nc)
Get a view of the top-right nr by nc block of the matrices.
Definition matrix.hpp:364
auto end()
Sentinel for begin().
Definition matrix.hpp:239
auto first_layers(N n)
Get a view of the first n layers. Note that n can be a compile-time constant.
Definition matrix.hpp:206
auto bottom_left(index_type nr, index_type nc)
Get a view of the bottom-left nr by nc block of the matrices.
Definition matrix.hpp:370
bool has_full_outer_stride() const
Whether the outer_stride() == inner_stride() * inner_size().
Definition matrix.hpp:286
index_type layer_stride() const
The layer stride, i.e.
Definition matrix.hpp:282
bool has_full_layer_stride() const
Whether the layer_stride() == outer_stride() * outer_size().
Definition matrix.hpp:284
auto right_cols(index_type n) const
Get a view of the last n columns.
Definition matrix.hpp:320
Matrix(layout_type layout, uninitialized_t init)
Definition matrix.hpp:125
index_type inner_size() const
The size of the inner dimension, i.e.
Definition matrix.hpp:266
guanaqo::MatrixView< const T, I, standard_stride_type, O > operator()(index_type l) const
Access a single layer l as a non-batched view.
Definition matrix.hpp:201
static constexpr auto default_alignment(layout_type layout)
Definition matrix.hpp:82
auto top_left(index_type nr, index_type nc)
Get a view of the top-left nr by nc block of the matrices.
Definition matrix.hpp:358
auto batch_dyn(index_type b) const
Same as batch(), but returns a view with a dynamic batch size.
Definition matrix.hpp:180
auto middle_rows(index_type r, index_type n, index_type stride)
Get a view of n rows starting at row r.
Definition matrix.hpp:328
value_type & operator()(index_type l, index_type r, index_type c)
Access a single element at layer l, row r and column c.
Definition matrix.hpp:160
index_type outer_stride() const
Outer stride of the matrices (leading dimension in BLAS parlance).
Definition matrix.hpp:274
Matrix(Matrix &&o) noexcept
Definition matrix.hpp:133
const_view_type view() const
Returns the same view. For consistency with Matrix.
Definition matrix.hpp:450
index_type outer_size() const
The size of the outer dimension, i.e.
Definition matrix.hpp:264
auto batch(index_type b) const
Access a batch of batch_size() layers, starting at batch index b (i.e.
Definition matrix.hpp:176
constexpr auto row_stride() const
The row stride of the matrices, i.e.
Definition matrix.hpp:278
auto begin() const
Iterate linearly (in storage order) over all elements of the view.
Definition matrix.hpp:237
constexpr auto col_stride() const
The column stride of the matrices, i.e.
Definition matrix.hpp:280
auto end() const
Sentinel for begin().
Definition matrix.hpp:241
auto 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.
Definition matrix.hpp:390
static auto allocate(layout_type layout, uninitialized_t init)
Definition matrix.hpp:94
const 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.
Definition matrix.hpp:164
index_type ceil_depth() const
The depth rounded up to a multiple of the batch size.
Definition matrix.hpp:256
auto middle_rows(index_type r, index_type n) const
Get a view of n rows starting at row r.
Definition matrix.hpp:324
auto begin()
Iterate linearly (in storage order) over all elements of the view.
Definition matrix.hpp:235
auto bottom_right(index_type nr, index_type nc)
Get a view of the bottom-right nr by nc block of the matrices.
Definition matrix.hpp:378
auto transposed()
Get a transposed view of the matrices.
Definition matrix.hpp:394
auto as_const() const
Explicit conversion to a const view.
Definition matrix.hpp:452
auto middle_cols(index_type c, index_type n, index_type stride) const
Get a view of n columns starting at column c.
Definition matrix.hpp:352
guanaqo::MatrixView< T, I, standard_stride_type, O > operator()(index_type l)
Access a single layer l as a non-batched view.
Definition matrix.hpp:196
auto middle_cols(index_type c, index_type n, index_type stride)
Get a view of n columns starting at column c.
Definition matrix.hpp:346
auto middle_rows(index_type r, index_type n, index_type stride) const
Get a view of n rows starting at row r.
Definition matrix.hpp:334
auto middle_rows(index_type r, index_type n)
Get a view of n rows starting at row r.
Definition matrix.hpp:322
index_type cols() const
Number of columns of the matrices.
Definition matrix.hpp:262
const value_type * data() const
Get a pointer to the first element of the first layer.
Definition matrix.hpp:233
depth_type depth() const
Number of layers in the view (i.e. depth).
Definition matrix.hpp:254
index_type num_batches() const
Number of batches in the view, i.e. ceil_depth() / batch_size().
Definition matrix.hpp:258
Non-owning view of an array of matrices, stored in an efficient batched format.
Definition view.hpp:59
Layout< I, S, D, L, O > layout_type
Definition view.hpp:60
static constexpr bool is_column_major
Definition view.hpp:69
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.
Definition view.hpp:218
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.
Definition view.hpp:545
constexpr bool has_full_outer_stride() const
Whether the outer_stride() == inner_stride() * inner_size().
Definition view.hpp:388
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.
Definition view.hpp:550
void set_constant(value_type t)
Definition view.hpp:591
auto transposed() const
Get a transposed view of the matrices.
Definition view.hpp:562
constexpr auto inner_stride() const
The inner stride of the matrices.
Definition view.hpp:364
constexpr index_type num_batches() const
Number of batches in the view, i.e. ceil_depth() / batch_size().
Definition view.hpp:334
col_slice_view_type middle_cols(index_type c, index_type n) const
Get a view of n columns starting at column c.
Definition view.hpp:506
constexpr index_type padded_size() const
Total number of elements in the view (including all padding).
Definition view.hpp:321
void add_to_diagonal(const value_type &t)
Definition view.hpp:578
linear_iterator begin() const
Iterate linearly (in storage order) over all elements of the view.
Definition view.hpp:284
row_slice_view_type bottom_rows(index_type n) const
Get a view of the last n rows.
Definition view.hpp:452
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.
Definition view.hpp:412
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.
Definition view.hpp:233
static constexpr bool has_single_batch_at_compile_time
True if batch_size() and depth() are compile-time constants and are equal.
Definition view.hpp:75
constexpr auto col_stride() const
The column stride of the matrices, i.e.
Definition view.hpp:374
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.
Definition view.hpp:540
View< const T, I, S, D, L, O > const_view_type
Definition view.hpp:67
row_slice_view_type middle_rows(index_type r, index_type n) const
Get a view of n rows starting at row r.
Definition view.hpp:482
constexpr batch_size_type batch_size() const
The batch size, i.e. the number of layers in each batch. Equals the inner stride.
Definition view.hpp:330
constexpr index_type cols() const
Number of columns of the matrices.
Definition view.hpp:340
std::default_sentinel_t end() const
Sentinel for begin().
Definition view.hpp:311
col_slice_view_type right_cols(index_type n) const
Get a view of the last n columns.
Definition view.hpp:467
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.
Definition view.hpp:175
constexpr bool has_full_inner_stride() const
Whether the inner_stride() == 1. Always true.
Definition view.hpp:392
col_slice_view_type left_cols(index_type n) const
Get a view of the first n columns.
Definition view.hpp:439
constexpr bool has_full_layer_stride() const
Whether the layer_stride() == outer_stride() * outer_size().
Definition view.hpp:384
static constexpr bool has_single_layer_at_compile_time
True if depth() is a compile-time constant and is equal to one.
Definition view.hpp:80
row_slice_view_type top_rows(index_type n) const
Get a view of the first n rows.
Definition view.hpp:426
constexpr index_type rows() const
Number of rows of the matrices.
Definition view.hpp:338
constexpr index_type inner_size() const
The size of the inner dimension, i.e.
Definition view.hpp:348
constexpr index_type ceil_depth() const
The depth rounded up to a multiple of the batch size.
Definition view.hpp:326
constexpr index_type size() const
Total number of elements in the view (excluding padding).
Definition view.hpp:319
constexpr auto row_stride() const
The row stride of the matrices, i.e.
Definition view.hpp:369
T * data() const
Get a pointer to the first element of the first layer.
Definition view.hpp:251
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.
Definition view.hpp:530
constexpr index_type outer_size() const
The size of the outer dimension, i.e.
Definition view.hpp:343
constexpr index_type layer_stride() const
The layer stride, i.e.
Definition view.hpp:380
static constexpr bool is_row_major
Definition view.hpp:70
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.
Definition view.hpp:189
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.
Definition view.hpp:535
constexpr depth_type depth() const
Number of layers in the view (i.e. depth).
Definition view.hpp:324
void copy_values(const Other &other) const
Definition view.hpp:620
static constexpr StorageOrder storage_order
Definition view.hpp:68
constexpr index_type outer_stride() const
Outer stride of the matrices (leading dimension in BLAS parlance).
Definition view.hpp:359
batch_view_type batch(index_type b) const
Access a batch of batch_size() layers, starting at batch index b (i.e.
Definition view.hpp:163
Deleter for aligned memory allocated with operator new(size, align_val).
Definition storage.hpp:31
Non-owning view of a batch of matrices.