batmat develop
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(index_type,index_type)
182 [[nodiscard]] auto middle_batches(index_type b, index_type n) {
183 return view().middle_batches(b, n);
184 }
185 /// @copydoc View::middle_batches(index_type,index_type,index_type)
186 [[nodiscard]] auto middle_batches(index_type b, index_type n, index_type stride) {
187 return view().middle_batches(b, n, stride);
188 }
189 /// @copydoc View::middle_batches(index_type,index_type)
190 [[nodiscard]] auto middle_batches(index_type b, index_type n) const {
191 return view().middle_batches(b, n);
192 }
193 /// @copydoc View::middle_batches(index_type,index_type,index_type)
194 [[nodiscard]] auto middle_batches(index_type b, index_type n, index_type stride) const {
195 return view().middle_batches(b, n, stride);
196 }
197
198 /// @}
199
200 /// @name Layer-wise slicing
201 /// @{
202
203 /// Access a single layer @p l as a non-batched view.
207 /// Access a single layer @p l as a non-batched view.
210 return view()(l);
211 }
212 /// @copydoc View::first_layers()
213 template <class N>
214 [[nodiscard]] auto first_layers(N n) {
215 return view().first_layers(n);
216 }
217 /// @copydoc View::first_layers()
218 template <class N>
219 [[nodiscard]] auto first_layers(N n) const {
220 return view().first_layers(n);
221 }
222 /// @copydoc View::middle_layers()
223 template <class N>
224 [[nodiscard]] auto middle_layers(index_type l, N n) {
225 return view().middle_layers(l, n);
226 }
227 /// @copydoc View::middle_layers()
228 template <class N>
229 [[nodiscard]] auto middle_layers(index_type l, N n) const {
230 return view().middle_layers(l, n);
231 }
232
233 /// @}
234
235 /// @name Iterators and buffer access
236 /// @{
237
238 /// @copydoc View::data()
239 [[nodiscard]] value_type *data() { return view().data(); }
240 /// @copydoc View::data()
241 [[nodiscard]] const value_type *data() const { return view().data(); }
242 /// @copydoc View::begin()
243 [[nodiscard]] auto begin() { return view().begin(); }
244 /// @copydoc View::begin()
245 [[nodiscard]] auto begin() const { return view().begin(); }
246 /// @copydoc View::end()
247 [[nodiscard]] auto end() { return view().end(); }
248 /// @copydoc View::end()
249 [[nodiscard]] auto end() const { return view().end(); }
250
251 /// @}
252
253 /// @name Dimensions
254 /// @{
255
256 [[nodiscard]] layout_type layout() const { return view_.layout; }
257 /// @copydoc View::size()
258 [[nodiscard]] index_type size() const { return view().size(); }
259 /// @copydoc View::padded_size()
260 [[nodiscard]] index_type padded_size() const { return view().padded_size(); }
261 /// @copydoc View::depth()
262 [[nodiscard]] depth_type depth() const { return view().depth(); }
263 /// @copydoc View::ceil_depth()
264 [[nodiscard]] index_type ceil_depth() const { return view().ceil_depth(); }
265 /// @copydoc View::num_batches()
266 [[nodiscard]] index_type num_batches() const { return view().num_batches(); }
267 /// @copydoc View::rows()
268 [[nodiscard]] index_type rows() const { return view().rows(); }
269 /// @copydoc View::cols()
270 [[nodiscard]] index_type cols() const { return view().cols(); }
271 /// @copydoc View::outer_size()
272 [[nodiscard]] index_type outer_size() const { return view().outer_size(); }
273 /// @copydoc View::inner_size()
274 [[nodiscard]] index_type inner_size() const { return view().inner_size(); }
275
276 /// @}
277
278 /// @name Strides
279 /// @{
280
281 /// @copydoc View::outer_stride()
282 [[nodiscard]] index_type outer_stride() const { return view().outer_stride(); }
283 /// @copydoc View::inner_stride()
284 [[nodiscard]] constexpr auto inner_stride() const { return view().inner_stride(); }
285 /// @copydoc View::row_stride()
286 [[nodiscard]] constexpr auto row_stride() const { return view().row_stride(); }
287 /// @copydoc View::col_stride()
288 [[nodiscard]] constexpr auto col_stride() const { return view().col_stride(); }
289 /// @copydoc View::layer_stride()
290 [[nodiscard]] index_type layer_stride() const { return view().layer_stride(); }
291 /// @copydoc View::has_full_layer_stride()
292 [[nodiscard]] bool has_full_layer_stride() const { return view().has_full_layer_stride(); }
293 /// @copydoc View::has_full_outer_stride()
294 [[nodiscard]] bool has_full_outer_stride() const { return view().has_full_outer_stride(); }
295 /// @copydoc View::has_full_inner_stride()
296 [[nodiscard]] bool has_full_inner_stride() const { return view().has_full_inner_stride(); }
297 /// @copydoc View::batch_size()
298 [[nodiscard]] batch_size_type batch_size() const { return view().batch_size(); }
299
300 /// @}
301
302 /// @name Reshaping and slicing
303 /// @{
304
305 /// @copydoc View::reshaped()
306 [[nodiscard]] auto reshaped(index_type rows, index_type cols) {
307 return view().reshaped(rows, cols);
308 }
309 /// @copydoc View::reshaped()
310 [[nodiscard]] auto reshaped(index_type rows, index_type cols) const {
311 return view().reshaped(rows, cols);
312 }
313 /// @copydoc View::top_rows()
314 [[nodiscard]] auto top_rows(index_type n) { return view().top_rows(n); }
315 /// @copydoc View::top_rows()
316 [[nodiscard]] auto top_rows(index_type n) const { return view().top_rows(n); }
317 /// @copydoc View::left_cols()
318 [[nodiscard]] auto left_cols(index_type n) { return view().left_cols(n); }
319 /// @copydoc View::left_cols()
320 [[nodiscard]] auto left_cols(index_type n) const { return view().left_cols(n); }
321 /// @copydoc View::bottom_rows()
322 [[nodiscard]] auto bottom_rows(index_type n) { return view().bottom_rows(n); }
323 /// @copydoc View::bottom_rows()
324 [[nodiscard]] auto bottom_rows(index_type n) const { return view().bottom_rows(n); }
325 /// @copydoc View::right_cols()
326 [[nodiscard]] auto right_cols(index_type n) { return view().right_cols(n); }
327 /// @copydoc View::right_cols()
328 [[nodiscard]] auto right_cols(index_type n) const { return view().right_cols(n); }
329 /// @copydoc View::middle_rows
330 [[nodiscard]] auto middle_rows(index_type r, index_type n) { return view().middle_rows(r, n); }
331 /// @copydoc View::middle_rows
332 [[nodiscard]] auto middle_rows(index_type r, index_type n) const {
333 return view().middle_rows(r, n);
334 }
335 /// @copydoc View::middle_rows
336 [[nodiscard]] auto middle_rows(index_type r, index_type n, index_type stride)
338 {
339 return view().middle_rows(r, n, stride);
340 }
341 /// @copydoc View::middle_rows
342 [[nodiscard]] auto middle_rows(index_type r, index_type n, index_type stride) const
344 {
345 return view().middle_rows(r, n, stride);
346 }
347 /// @copydoc View::middle_cols
348 [[nodiscard]] auto middle_cols(index_type c, index_type n) { return view().middle_cols(c, n); }
349 /// @copydoc View::middle_cols
350 [[nodiscard]] auto middle_cols(index_type c, index_type n) const {
351 return view().middle_cols(c, n);
352 }
353 /// @copydoc View::middle_cols
354 [[nodiscard]] auto middle_cols(index_type c, index_type n, index_type stride)
356 {
357 return view().middle_cols(c, n, stride);
358 }
359 /// @copydoc View::middle_cols
360 [[nodiscard]] auto middle_cols(index_type c, index_type n, index_type stride) const
362 {
363 return view().middle_cols(c, n, stride);
364 }
365 /// @copydoc View::top_left()
366 [[nodiscard]] auto top_left(index_type nr, index_type nc) { return view().top_left(nr, nc); }
367 /// @copydoc View::top_left()
368 [[nodiscard]] auto top_left(index_type nr, index_type nc) const {
369 return view().top_left(nr, nc);
370 }
371 /// @copydoc View::top_right()
372 [[nodiscard]] auto top_right(index_type nr, index_type nc) { return view().top_right(nr, nc); }
373 /// @copydoc View::top_right()
374 [[nodiscard]] auto top_right(index_type nr, index_type nc) const {
375 return view().top_right(nr, nc);
376 }
377 /// @copydoc View::bottom_left()
378 [[nodiscard]] auto bottom_left(index_type nr, index_type nc) {
379 return view().bottom_left(nr, nc);
380 }
381 /// @copydoc View::bottom_left()
382 [[nodiscard]] auto bottom_left(index_type nr, index_type nc) const {
383 return view().bottom_left(nr, nc);
384 }
385 /// @copydoc View::bottom_right()
386 [[nodiscard]] auto bottom_right(index_type nr, index_type nc) {
387 return view().bottom_right(nr, nc);
388 }
389 /// @copydoc View::bottom_right()
390 [[nodiscard]] auto bottom_right(index_type nr, index_type nc) const {
391 return view().bottom_right(nr, nc);
392 }
393 /// @copydoc View::block()
394 [[nodiscard]] auto block(index_type r, index_type c, index_type nr, index_type nc) {
395 return view().block(r, c, nr, nc);
396 }
397 /// @copydoc View::block()
398 [[nodiscard]] auto block(index_type r, index_type c, index_type nr, index_type nc) const {
399 return view().block(r, c, nr, nc);
400 }
401 /// @copydoc View::transposed()
402 [[nodiscard]] auto transposed() { return view().transposed(); }
403 /// @copydoc View::transposed()
404 [[nodiscard]] auto transposed() const { return view().transposed(); }
405
406 /// @}
407
408 /// @name Value manipulation
409 /// @{
410
411 /// Copy the values of another matrix, resizing if necessary.
413 if (&o != this) {
414 clear();
415 view_.reassign({allocate(o.layout()).release(), o.layout()});
416 // TODO: use allocate_for_overwrite or similar to avoid copy
417 // assignment
418 this->view_.copy_values(o.view_); // TODO: exception safety
419 }
420 return *this;
421 }
422
423 /// Copy the values from a compatible view, resizing if necessary.
424 template <class U, class J, class R, class E, class M>
425 requires(std::convertible_to<U, T> && std::equality_comparable_with<index_type, J>)
426 Matrix &operator=(View<U, J, R, E, M, O> other) {
427 assign_from_view(other);
428 return *this;
429 }
430
431 /// @copydoc View::set_constant()
433 /// @copydoc View::set_diagonal()
434 void set_diagonal(const value_type &t) { view().set_diagonal(t); }
435 /// @copydoc View::add_to_diagonal()
437 /// @copydoc View::negate()
438 void negate() { view().negate(); }
439 /// @copydoc View::copy_values()
440 template <class Other>
441 void copy_values(const Other &other) {
442 view().copy_values(other);
443 }
444 /// @copydoc View::operator+=()
445 template <class U, class J, class R, class E, class M>
446 requires(std::convertible_to<U, T> && std::equality_comparable_with<index_type, J>)
447 Matrix &operator+=(View<U, J, R, E, M, O> other) {
448 view() += other;
449 return *this;
450 }
451
452 /// @}
453
454 /// @name View conversions
455 /// @{
456
457 /// @copydoc View::view()
458 [[nodiscard, gnu::always_inline]] view_type view() { return view_; }
459 /// @copydoc View::view()
460 [[nodiscard, gnu::always_inline]] const_view_type view() const { return view_.as_const(); }
461 /// @copydoc View::as_const()
462 [[nodiscard]] auto as_const() const { return view(); }
463
464 operator view_type() { return view(); }
465 operator const_view_type() const { return view(); }
466 operator View<T, I, S, D, I, O>() { return view(); }
467 operator View<const T, I, S, D, I, O>() const { return view(); }
469 requires(!std::same_as<integral_value_type_t<D>, D>)
470 {
471 return view();
472 }
474 requires(!std::same_as<integral_value_type_t<D>, D>)
475 {
476 return view();
477 }
488
489 /// @}
490};
491
492template <class T, class I, class S, class D, class A, StorageOrder O>
493constexpr auto data(Matrix<T, I, S, D, O, A> &v) {
494 return v.data();
495}
496template <class T, class I, class S, class D, class A, StorageOrder O>
497constexpr auto data(Matrix<T, I, S, D, O, A> &&v) = delete;
498template <class T, class I, class S, class D, class A, StorageOrder O>
499constexpr auto data(const Matrix<T, I, S, D, O, A> &v) {
500 return v.data();
501}
502template <class T, class I, class S, class D, class A, StorageOrder O>
503constexpr auto rows(const Matrix<T, I, S, D, O, A> &v) {
504 return v.rows();
505}
506template <class T, class I, class S, class D, class A, StorageOrder O>
507constexpr auto cols(const Matrix<T, I, S, D, O, A> &v) {
508 return v.cols();
509}
510template <class T, class I, class S, class D, class A, StorageOrder O>
511constexpr auto outer_stride(const Matrix<T, I, S, D, O, A> &v) {
512 return v.outer_stride();
513}
514template <class T, class I, class S, class D, class A, StorageOrder O>
515constexpr auto depth(const Matrix<T, I, S, D, O, A> &v) {
516 return v.depth();
517}
518
519} // 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:507
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:493
constexpr auto outer_stride(const Matrix< T, I, S, D, O, A > &v)
Definition matrix.hpp:511
constexpr auto rows(const Matrix< T, I, S, D, O, A > &v)
Definition matrix.hpp:503
constexpr auto depth(const Matrix< T, I, S, D, O, A > &v)
Definition matrix.hpp:515
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:374
void set_diagonal(const value_type &t)
Replace the diagonal elements of all matrices by the scalar t (without modifying any other elements).
Definition matrix.hpp:434
bool has_full_inner_stride() const
Whether the inner_stride() == 1. Always true.
Definition matrix.hpp:296
void add_to_diagonal(const value_type &t)
Add the scalar t to the diagonal elements of all matrices.
Definition matrix.hpp:436
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:324
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:382
auto middle_layers(index_type l, N n)
Get a view of n layers starting at layer l.
Definition matrix.hpp:224
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 middle_batches(index_type b, index_type n, index_type stride)
Definition matrix.hpp:186
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:219
Matrix(plain_layout_type p)
Definition matrix.hpp:127
Matrix(plain_layout_type p, uninitialized_t init)
Definition matrix.hpp:128
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:310
auto middle_layers(index_type l, N n) const
Get a view of n layers starting at layer l.
Definition matrix.hpp:229
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:260
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:298
value_type * data()
Get a pointer to the first element of the first layer.
Definition matrix.hpp:239
index_type size() const
Total number of elements in the view (excluding padding).
Definition matrix.hpp:258
Matrix & operator=(const Matrix &o)
Copy the values of another matrix, resizing if necessary.
Definition matrix.hpp:412
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:394
auto top_rows(index_type n) const
Get a view of the first n rows.
Definition matrix.hpp:316
auto transposed() const
Get a transposed view of the matrices.
Definition matrix.hpp:404
index_type rows() const
Number of rows of the matrices.
Definition matrix.hpp:268
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:306
void set_constant(value_type t)
Replace the elements of all matrices by the scalar t.
Definition matrix.hpp:432
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:368
auto middle_batches(index_type b, index_type n, index_type stride) const
Definition matrix.hpp:194
auto bottom_rows(index_type n)
Get a view of the last n rows.
Definition matrix.hpp:322
auto left_cols(index_type n)
Get a view of the first n columns.
Definition matrix.hpp:318
constexpr auto inner_stride() const
The inner stride of the matrices.
Definition matrix.hpp:284
auto left_cols(index_type n) const
Get a view of the first n columns.
Definition matrix.hpp:320
auto middle_cols(index_type c, index_type n)
Get a view of n columns starting at column c.
Definition matrix.hpp:348
auto top_rows(index_type n)
Get a view of the first n rows.
Definition matrix.hpp:314
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:350
auto right_cols(index_type n)
Get a view of the last n columns.
Definition matrix.hpp:326
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:390
void copy_values(const Other &other)
Definition matrix.hpp:441
view_type view()
Returns the same view. For consistency with Matrix.
Definition matrix.hpp:458
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:372
auto end()
Sentinel for begin().
Definition matrix.hpp:247
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:214
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:378
bool has_full_outer_stride() const
Whether the outer_stride() == inner_stride() * inner_size().
Definition matrix.hpp:294
index_type layer_stride() const
The layer stride, i.e.
Definition matrix.hpp:290
bool has_full_layer_stride() const
Whether the layer_stride() == outer_stride() * outer_size().
Definition matrix.hpp:292
auto right_cols(index_type n) const
Get a view of the last n columns.
Definition matrix.hpp:328
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:274
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:209
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:366
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:336
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:282
Matrix(Matrix &&o) noexcept
Definition matrix.hpp:133
const_view_type view() const
Returns the same view. For consistency with Matrix.
Definition matrix.hpp:460
index_type outer_size() const
The size of the outer dimension, i.e.
Definition matrix.hpp:272
auto middle_batches(index_type b, index_type n)
Definition matrix.hpp:182
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:286
auto middle_batches(index_type b, index_type n) const
Definition matrix.hpp:190
auto begin() const
Iterate linearly (in storage order) over all elements of the view.
Definition matrix.hpp:245
constexpr auto col_stride() const
The column stride of the matrices, i.e.
Definition matrix.hpp:288
auto end() const
Sentinel for begin().
Definition matrix.hpp:249
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:398
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:264
auto middle_rows(index_type r, index_type n) const
Get a view of n rows starting at row r.
Definition matrix.hpp:332
auto begin()
Iterate linearly (in storage order) over all elements of the view.
Definition matrix.hpp:243
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:386
auto transposed()
Get a transposed view of the matrices.
Definition matrix.hpp:402
auto as_const() const
Explicit conversion to a const view.
Definition matrix.hpp:462
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:360
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:204
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:354
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:342
auto middle_rows(index_type r, index_type n)
Get a view of n rows starting at row r.
Definition matrix.hpp:330
index_type cols() const
Number of columns of the matrices.
Definition matrix.hpp:270
const value_type * data() const
Get a pointer to the first element of the first layer.
Definition matrix.hpp:241
depth_type depth() const
Number of layers in the view (i.e. depth).
Definition matrix.hpp:262
index_type num_batches() const
Number of batches in the view, i.e. ceil_depth() / batch_size().
Definition matrix.hpp:266
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:232
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:559
constexpr bool has_full_outer_stride() const
Whether the outer_stride() == inner_stride() * inner_size().
Definition view.hpp:402
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:564
void set_constant(value_type t)
Replace the elements of all matrices by the scalar t.
Definition view.hpp:622
auto transposed() const
Get a transposed view of the matrices.
Definition view.hpp:576
constexpr auto inner_stride() const
The inner stride of the matrices.
Definition view.hpp:378
constexpr index_type num_batches() const
Number of batches in the view, i.e. ceil_depth() / batch_size().
Definition view.hpp:348
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:520
constexpr index_type padded_size() const
Total number of elements in the view (including all padding).
Definition view.hpp:335
void add_to_diagonal(const value_type &t)
Add the scalar t to the diagonal elements of all matrices.
Definition view.hpp:593
linear_iterator begin() const
Iterate linearly (in storage order) over all elements of the view.
Definition view.hpp:298
row_slice_view_type bottom_rows(index_type n) const
Get a view of the last n rows.
Definition view.hpp:466
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:426
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:247
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:388
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:554
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:496
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:344
constexpr index_type cols() const
Number of columns of the matrices.
Definition view.hpp:354
std::default_sentinel_t end() const
Sentinel for begin().
Definition view.hpp:325
col_slice_view_type right_cols(index_type n) const
Get a view of the last n columns.
Definition view.hpp:481
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:406
col_slice_view_type left_cols(index_type n) const
Get a view of the first n columns.
Definition view.hpp:453
constexpr bool has_full_layer_stride() const
Whether the layer_stride() == outer_stride() * outer_size().
Definition view.hpp:398
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:440
constexpr index_type rows() const
Number of rows of the matrices.
Definition view.hpp:352
constexpr index_type inner_size() const
The size of the inner dimension, i.e.
Definition view.hpp:362
constexpr index_type ceil_depth() const
The depth rounded up to a multiple of the batch size.
Definition view.hpp:340
constexpr index_type size() const
Total number of elements in the view (excluding padding).
Definition view.hpp:333
View< T, I, S, I, L, O > middle_batches(index_type b, index_type n) const
Get a view of n batches starting at batch b.
Definition view.hpp:189
constexpr auto row_stride() const
The row stride of the matrices, i.e.
Definition view.hpp:383
void set_diagonal(const value_type &t)
Replace the diagonal elements of all matrices by the scalar t (without modifying any other elements).
Definition view.hpp:608
T * data() const
Get a pointer to the first element of the first layer.
Definition view.hpp:265
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:544
constexpr index_type outer_size() const
The size of the outer dimension, i.e.
Definition view.hpp:357
constexpr index_type layer_stride() const
The layer stride, i.e.
Definition view.hpp:394
static constexpr bool is_row_major
Definition view.hpp:70
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:549
constexpr depth_type depth() const
Number of layers in the view (i.e. depth).
Definition view.hpp:338
void copy_values(const Other &other) const
Definition view.hpp:651
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:373
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.