Expression Templates Library (ETL)
fast_base.hpp
Go to the documentation of this file.
1 //=======================================================================
2 // Copyright (c) 2014-2023 Baptiste Wicht
3 // Distributed under the terms of the MIT License.
4 // (See accompanying file LICENSE or copy at
5 // http://opensource.org/licenses/MIT)
6 //=======================================================================
7 
13 #pragma once
14 
15 #include "etl/index.hpp"
16 
17 namespace etl {
18 
19 namespace matrix_detail {
20 
24 template <typename N>
25 struct is_vector_impl : std::false_type {};
26 
30 template <typename... Args>
31 struct is_vector_impl<std::vector<Args...>> : std::true_type {};
32 
36 template <typename... Args>
37 struct is_vector_impl<etl::simple_vector<Args...>> : std::true_type {};
38 
42 template <typename N>
44 
48 template <typename T>
49 struct iterator_type {
50  using iterator = typename T::iterator;
51  using const_iterator = typename T::const_iterator;
52 };
53 
57 template <typename T>
58 struct iterator_type<T*> {
59  using iterator = T*;
60  using const_iterator = const T*;
61 };
62 
66 template <typename T>
67 struct iterator_type<const T*> {
68  using iterator = const T*;
69  using const_iterator = const T*;
70 };
71 
75 template <typename T>
77 
81 template <typename T>
83 
84 } //end of namespace matrix_detail
85 
86 template <typename D, typename T, typename ST, order SO, size_t... Dims>
88  static constexpr size_t n_dimensions = sizeof...(Dims);
89  static constexpr size_t etl_size = (Dims * ...);
90 
91  using value_type = T;
92  using derived_t = D;
93  using storage_impl = ST;
95  using const_memory_type = const value_type*;
96 
97  using iterator = std::conditional_t<SO == order::RowMajor, value_type*, etl::iterator<derived_t>>;
98  using const_iterator = std::conditional_t<SO == order::RowMajor, const value_type*, etl::iterator<const derived_t>>;
99 
100 protected:
103 
107  void init() {
108  if constexpr (matrix_detail::is_vector<ST>) {
109  _data.resize(alloc_size_mat<value_type>(size(), dim<n_dimensions - 1>()));
110  }
111  }
112 
118  template <typename... S>
119  static constexpr size_t index(S... args) {
120  return etl::fast_index<derived_t>(args...);
121  }
122 
128  template <typename... S>
129  value_type& access(S... args) {
131  invalidate_gpu();
132  return _data[index(args...)];
133  }
134 
140  template <typename... S>
141  const value_type& access(S... args) const {
143  return _data[index(args...)];
144  }
145 
146 public:
150  fast_matrix_base() : _data() {
151  init();
152  }
153 
158  fast_matrix_base(storage_impl data) : _data(data) {
159  // Nothing else to init
160  }
161 
166  fast_matrix_base(const fast_matrix_base& rhs) : _data(), _gpu(rhs._gpu) {
167  // Only perform the copy if the CPU is up to date
168  if (rhs._gpu.is_cpu_up_to_date()) {
169  _data = rhs._data;
170  } else {
171  init();
172  }
173 
174  // The GPU updates are handled by gpu_handler
175  }
176 
181  fast_matrix_base(fast_matrix_base&& rhs) noexcept : _data(), _gpu(std::move(rhs._gpu)) {
182  // Only perform the copy if the CPU is up to date
183  if (_gpu.is_cpu_up_to_date()) {
184  _data = std::move(rhs._data);
185  } else {
186  init();
187  }
188 
189  // The GPU updates are handled by gpu_handler
190  }
191 
192  // Assignment must be handled by the derived class!
193 
194  fast_matrix_base& operator=(const fast_matrix_base& rhs) = delete;
195  fast_matrix_base& operator=(fast_matrix_base&& rhs) = delete;
196 
202  return _data.data();
203  }
204 
209  const_memory_type memory_start() const noexcept {
210  return _data.data();
211  }
212 
217  memory_type memory_end() noexcept {
218  return _data.data() +size();
219  }
220 
225  const_memory_type memory_end() const noexcept {
226  return _data.data() + size();
227  }
228 
233  static constexpr size_t size() noexcept {
234  return etl_size;
235  }
236 
241  static constexpr size_t rows() noexcept {
242  return dim<0>();
243  }
244 
249  static constexpr size_t columns() noexcept requires(n_dimensions > 1) {
250  return dim<1>();
251  }
252 
257  static constexpr size_t dimensions() noexcept {
258  return n_dimensions;
259  }
260 
265  template <size_t DD>
266  static constexpr size_t dim() noexcept {
267  return nth_size<DD, 0, Dims...>();
268  }
269 
275  size_t dim(size_t d) const noexcept {
276  return dyn_nth_size<Dims...>(d);
277  }
278 
284  auto operator()(size_t i) noexcept requires(n_dimensions > 1) {
285  return sub(as_derived(), i);
286  }
287 
293  auto operator()(size_t i) const noexcept requires(n_dimensions > 1) {
294  return sub(as_derived(), i);
295  }
296 
303  auto slice(size_t first, size_t last) noexcept {
304  return etl::slice(as_derived(), first, last);
305  }
306 
313  auto slice(size_t first, size_t last) const noexcept {
314  return etl::slice(as_derived(), first, last);
315  }
316 
322  template <size_c... S>
323  value_type& operator()(S... args) noexcept(assert_nothrow) requires (sizeof...(S) == sizeof...(Dims)) {
324  return access(static_cast<size_t>(args)...);
325  }
326 
332  template <size_c... S>
333  const value_type& operator()(S... args) const noexcept(assert_nothrow) requires (sizeof...(S) == sizeof...(Dims)) {
334  return access(static_cast<size_t>(args)...);
335  }
336 
342  template <size_c... S>
343  value_type& operator[](size_t first, S... args) noexcept(assert_nothrow) requires (sizeof...(S) >= 1 && (1 + sizeof...(S)) == sizeof...(Dims)) {
344  return access(first, static_cast<size_t>(args)...);
345  }
346 
352  template <size_c... S>
353  const value_type& operator[](size_t first, S... args) const noexcept(assert_nothrow) requires (sizeof...(S) >= 1 && (1 + sizeof...(S)) == sizeof...(Dims)) {
354  return access(first, static_cast<size_t>(args)...);
355  }
356 
362  const value_type& operator[](size_t i) const noexcept(assert_nothrow) {
363  cpp_assert(i < size(), "Out of bounds");
364 
366 
367  return _data[i];
368  }
369 
375  value_type& operator[](size_t i) noexcept(assert_nothrow) {
376  cpp_assert(i < size(), "Out of bounds");
377 
379  invalidate_gpu();
380 
381  return _data[i];
382  }
383 
390  value_type read_flat(size_t i) const noexcept(assert_nothrow) {
391  cpp_assert(i < size(), "Out of bounds");
392 
394 
395  return _data[i];
396  }
397 
403  template <typename E>
404  bool alias(const E& rhs) const noexcept {
405  if constexpr (is_dma<E>) {
406  return memory_alias(memory_start(), memory_end(), rhs.memory_start(), rhs.memory_end());
407  } else {
408  return rhs.alias(as_derived());
409  }
410  }
411 
416  T* gpu_memory() const noexcept {
417  return _gpu.gpu_memory();
418  }
419 
423  void gpu_evict() const noexcept {
424  _gpu.gpu_evict();
425  }
426 
430  void invalidate_cpu() const noexcept {
431  _gpu.invalidate_cpu();
432  }
433 
437  void invalidate_gpu() const noexcept {
438  _gpu.invalidate_gpu();
439  }
440 
444  void validate_cpu() const noexcept {
445  _gpu.validate_cpu();
446  }
447 
451  void validate_gpu() const noexcept {
452  _gpu.validate_gpu();
453  }
454 
459  void ensure_gpu_allocated() const {
460  _gpu.ensure_gpu_allocated(etl_size);
461  }
462 
466  void ensure_gpu_up_to_date() const {
467  _gpu.ensure_gpu_up_to_date(memory_start(), etl_size);
468  }
469 
474  void ensure_cpu_up_to_date() const {
475  _gpu.ensure_cpu_up_to_date(memory_start(), etl_size);
476  }
477 
482  void gpu_copy_from(const T* gpu_memory) const {
483  _gpu.gpu_copy_from(gpu_memory, etl_size);
484  }
485 
490  bool is_cpu_up_to_date() const noexcept {
491  return _gpu.is_cpu_up_to_date();
492  }
493 
498  bool is_gpu_up_to_date() const noexcept {
499  return _gpu.is_gpu_up_to_date();
500  }
501 
502 private:
507  derived_t& as_derived() noexcept {
508  return *static_cast<derived_t*>(this);
509  }
510 
515  const derived_t& as_derived() const noexcept {
516  return *static_cast<const derived_t*>(this);
517  }
518 };
519 
520 } //end of namespace etl
typename T::iterator iterator
The iterator type.
Definition: fast_base.hpp:50
fast_matrix_base(fast_matrix_base &&rhs) noexcept
Move Construct a fast_matrix_base.
Definition: fast_base.hpp:181
value_type & access(S... args)
Return the value at the given indices.
Definition: fast_base.hpp:129
memory_type memory_start() noexcept
Returns a pointer to the first element in memory.
Definition: fast_base.hpp:201
void ensure_gpu_allocated() const
Ensures that the GPU memory is allocated and that the GPU memory is up to date (to undefined value)...
Definition: sub_view.hpp:717
static constexpr size_t rows() noexcept
Returns the number of rows of the matrix (the first dimension), in O(1)
Definition: fast_base.hpp:241
value_type * memory_type
The memory type.
Definition: fast_base.hpp:94
auto slice(E &&value, size_t first, size_t last) -> slice_view< detail::build_identity_type< E >>
Returns view representing a slice view of the given expression.
Definition: view_expression_builder.hpp:112
const value_type & access(S... args) const
Return the value at the given indices.
Definition: fast_base.hpp:141
ST storage_impl
The storage implementation.
Definition: fast_base.hpp:93
bool alias(const E &rhs) const noexcept
Test if this expression aliases with the given expression.
Definition: dyn_matrix_view.hpp:197
size_t dyn_nth_size(size_t i)
Returns the dth (dynamic) dimension from the variadic list D.
Definition: tmp.hpp:116
void ensure_gpu_up_to_date([[maybe_unused]] const T *cpu_memory, [[maybe_unused]] size_t etl_size) const
Allocate memory on the GPU for the expression and copy the values into the GPU.
Definition: gpu_handler.hpp:611
std::conditional_t< SO==order::RowMajor, value_type *, etl::iterator< derived_t > > iterator
The iterator type.
Definition: fast_base.hpp:97
void gpu_evict() const noexcept
Evict the expression from GPU.
Definition: gpu_handler.hpp:577
typename T::const_iterator const_iterator
The const iterator type.
Definition: fast_base.hpp:51
auto operator()(size_t i) const noexcept requires(n_dimensions > 1)
Creates a sub view of the matrix, effectively removing the first dimension and fixing it to the given...
Definition: fast_base.hpp:293
etl::iterator< this_type > iterator
The iterator type.
Definition: dyn_matrix_view.hpp:36
D D
The number of dimensions.
Definition: dyn_matrix_view.hpp:24
static constexpr size_t dim() noexcept
Returns the Dth dimension of the matrix.
Definition: fast_base.hpp:266
static constexpr size_t index(S... args)
Compute the 1D index from the given indices.
Definition: fast_base.hpp:119
Base class and utilities for dyn matrix implementations.
order
Storage order of a matrix.
Definition: order.hpp:15
constexpr size_t nth_size()
Traits to get the Sth dimension in Dims..
Definition: tmp.hpp:102
T * gpu_memory() const noexcept
Return GPU memory of this expression, if any.
Definition: gpu_handler.hpp:554
const T * const_iterator
The const iterator type.
Definition: fast_base.hpp:69
bool is_gpu_up_to_date() const noexcept
Indicates if the GPU memory is up to date.
Definition: gpu_handler.hpp:570
size_t dim(size_t d) const noexcept
Returns the dth dimension of the matrix.
Definition: fast_base.hpp:275
void init()
Init the container if necessary.
Definition: fast_base.hpp:107
bool is_cpu_up_to_date() const noexcept
Indicates if the CPU memory is up to date.
Definition: sub_view.hpp:777
void gpu_copy_from([[maybe_unused]] const value_type *new_gpu_memory) const
Copy from GPU to GPU.
Definition: sub_view.hpp:761
void validate_gpu() const noexcept
Validates the GPU memory.
Definition: gpu_handler.hpp:597
void gpu_evict() const noexcept
Evict the expression from GPU.
Definition: sub_view.hpp:681
fast_matrix_base()
Construct a default fast_matrix_base.
Definition: fast_base.hpp:150
const T * const_iterator
The const iterator type.
Definition: fast_base.hpp:60
static constexpr size_t columns() noexcept requires(n_dimensions > 1)
Returns the number of columns of the matrix (the second dimension), in O(1)
Definition: fast_base.hpp:249
Root namespace for the ETL library.
Definition: adapter.hpp:15
void invalidate_gpu() const noexcept
Invalidates the GPU memory.
Definition: gpu_handler.hpp:587
typename iterator_type< T >::const_iterator const_iterator_t
Helper to get the const iterator type from a type.
Definition: fast_base.hpp:82
bool memory_alias(const P1 *a_begin, const P1 *a_end, const P2 *b_begin, const P2 *b_end)
Test if two memory ranges overlap.
Definition: helpers.hpp:264
void invalidate_gpu() const noexcept
Invalidates the GPU memory.
Definition: sub_view.hpp:695
fast_matrix_base(const fast_matrix_base &rhs)
Copy Construct a fast_matrix_base.
Definition: fast_base.hpp:166
std::conditional_t< SO==order::RowMajor, const value_type *, etl::iterator< const derived_t > > const_iterator
The iterator type.
Definition: fast_base.hpp:98
void ensure_cpu_up_to_date() const
Ensures that the GPU memory is allocated and that the GPU memory is up to date (to undefined value)...
Definition: dyn_matrix_view.hpp:271
const value_type * const_memory_type
The const memory type.
Definition: fast_base.hpp:95
void invalidate_cpu() const noexcept
Invalidates the CPU memory.
Definition: sub_view.hpp:688
const T * iterator
The iterator type.
Definition: fast_base.hpp:68
const_memory_type memory_start() const noexcept
Returns a pointer to the first element in memory.
Definition: fast_base.hpp:209
bool is_cpu_up_to_date() const noexcept
Indicates if the CPU memory is up to date.
Definition: gpu_handler.hpp:562
const_return_type operator()(size_t j) const
Access to the element at the given position.
Definition: dyn_matrix_view.hpp:89
Traits to extract iterator types from a type.
Definition: fast_base.hpp:49
void ensure_gpu_allocated([[maybe_unused]] size_t etl_size) const
Ensures that the GPU memory is allocated and that the GPU memory is up to date (to undefined value)...
Definition: gpu_handler.hpp:604
T * iterator
The iterator type.
Definition: fast_base.hpp:59
value_type read_flat(size_t j) const noexcept
Returns the value at the given index This function never has side effects.
Definition: dyn_matrix_view.hpp:111
A simple std::vector to work with bool.
Definition: aligned_vector.hpp:26
Definition: fast_base.hpp:87
etl::iterator< const this_type > const_iterator
The const iterator type.
Definition: dyn_matrix_view.hpp:37
requires(D > 0) struct dyn_base
Matrix with run-time fixed dimensions.
Definition: dyn_base.hpp:113
const_memory_type memory_end() const noexcept
Returns a pointer to the past-the-end element in memory.
Definition: fast_base.hpp:225
bool is_gpu_up_to_date() const noexcept
Indicates if the GPU memory is up to date.
Definition: sub_view.hpp:785
void ensure_gpu_up_to_date() const
Copy back from the GPU to the expression memory if necessary.
Definition: dyn_matrix_view.hpp:280
typename iterator_type< T >::iterator iterator_t
Helper to get the iterator type from a type.
Definition: fast_base.hpp:76
void validate_gpu() const noexcept
Validates the GPU memory.
Definition: sub_view.hpp:709
auto slice(size_t first, size_t last) const noexcept
Creates a slice view of the matrix, effectively reducing the first dimension.
Definition: fast_base.hpp:313
void validate_cpu() const noexcept
Validates the CPU memory.
Definition: gpu_handler.hpp:592
void invalidate_cpu() const noexcept
Invalidates the CPU memory.
Definition: gpu_handler.hpp:582
memory_type memory_end() noexcept
Returns a pointer to the past-the-end element in memory.
Definition: fast_base.hpp:217
const_return_type operator[](size_t j) const
Returns the element at the given index.
Definition: dyn_matrix_view.hpp:71
gpu_memory_handler< T > _gpu
The GPU memory handler.
Definition: fast_base.hpp:102
Matrix with compile-time fixed dimensions.
Definition: custom_fast.hpp:27
constexpr bool is_vector
Traits to test if a type is a std::vector.
Definition: fast_base.hpp:43
void ensure_cpu_up_to_date([[maybe_unused]] const T *cpu_memory, [[maybe_unused]] size_t etl_size) const
Copy back from the GPU to the expression memory if necessary.
Definition: gpu_handler.hpp:619
auto slice(size_t first, size_t last) noexcept
Creates a slice view of the matrix, effectively reducing the first dimension.
Definition: fast_base.hpp:303
storage_impl _data
The storage container.
Definition: fast_base.hpp:101
fast_matrix_base(storage_impl data)
Construct a default fast_matrix_base from storage.
Definition: fast_base.hpp:158
static constexpr size_t dimensions() noexcept
Returns the number of dimensions of the matrix.
Definition: fast_base.hpp:257
auto operator()(size_t i) noexcept requires(n_dimensions > 1)
Creates a sub view of the matrix, effectively removing the first dimension and fixing it to the given...
Definition: fast_base.hpp:284
static constexpr size_t size() noexcept
Returns the size of the matrix, in O(1)
Definition: fast_base.hpp:233
void validate_cpu() const noexcept
Validates the CPU memory.
Definition: sub_view.hpp:702
value_type * gpu_memory() const noexcept
Return GPU memory of this expression, if any.
Definition: sub_view.hpp:674
Definition: gpu_handler.hpp:549
Traits to test if a type is a std::vector.
Definition: fast_base.hpp:25
void gpu_copy_from([[maybe_unused]] const T *gpu_memory, [[maybe_unused]] size_t etl_size) const
Copy from GPU to GPU.
Definition: gpu_handler.hpp:626