Expression Templates Library (ETL)
custom_fast.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 <type_traits>
16 #include "etl/fast_base.hpp"
17 #include "etl/direct_fill.hpp" //direct_fill with GPU support
18 
19 namespace etl {
20 
26 template <typename T, typename ST, order SO, size_t... Dims>
27 struct custom_fast_matrix_impl final : fast_matrix_base<custom_fast_matrix_impl<T, ST, SO, Dims...>, T, ST, SO, Dims...>,
28  inplace_assignable<custom_fast_matrix_impl<T, ST, SO, Dims...>>,
29  expression_able<custom_fast_matrix_impl<T, ST, SO, Dims...>>,
30  value_testable<custom_fast_matrix_impl<T, ST, SO, Dims...>>,
31  iterable<custom_fast_matrix_impl<T, ST, SO, Dims...>, SO == order::RowMajor>,
32  dim_testable<custom_fast_matrix_impl<T, ST, SO, Dims...>> {
33  static_assert(sizeof...(Dims) > 0, "At least one dimension must be specified");
34 
35 public:
36  static constexpr size_t n_dimensions = sizeof...(Dims);
37  static constexpr size_t etl_size = (Dims * ...);
38  static constexpr order storage_order = SO;
39  static constexpr bool array_impl = !matrix_detail::is_vector<ST>;
40 
41  using this_type = custom_fast_matrix_impl<T, ST, SO, Dims...>;
42  using base_type = fast_matrix_base<this_type, T, ST, SO, Dims...>;
44  using value_type = T;
45  using storage_impl = ST;
47  using const_memory_type = const value_type*;
48 
49  using base_type::dim;
52  using base_type::size;
55 
59  template <typename V = default_vec>
60  using vec_type = typename V::template vec_type<T>;
61 
62 private:
63  using base_type::_data;
64 
65 public:
67 
72  explicit custom_fast_matrix_impl(memory_type memory) : base_type(storage_impl{memory, etl_size}) {
73  //Nothing else to init
74  }
75 
81  // Nothing else to init
82  }
83 
88  custom_fast_matrix_impl(custom_fast_matrix_impl&& rhs) noexcept : base_type(std::move(rhs)) {
89  // Nothing else to init
90  }
91 
92  // Assignment
93 
100  if (this != &rhs) {
101  direct_copy(rhs.memory_start(), rhs.memory_end(), memory_start());
102  }
103 
104  return *this;
105  }
106 
112  template <size_t... SDims>
114  validate_assign(*this, rhs);
115  rhs.assign_to(*this);
116  return *this;
117  }
118 
125  if (this != &rhs) {
126  _data = std::move(rhs._data);
127  }
128 
129  return *this;
130  }
131 
137  template <typename C>
138  custom_fast_matrix_impl& operator=(const C& container) noexcept requires(!std::same_as<C, value_type> && std::convertible_to<value_t<C>, value_type>) {
139  validate_assign(*this, container);
140  std::copy(container.begin(), container.end(), begin());
141 
142  this->validate_cpu();
143  this->invalidate_gpu();
144 
145  return *this;
146  }
147 
153  template <convertible_expr<value_type> E>
155  validate_assign(*this, e);
156 
157  // Avoid aliasing issues
158  if constexpr (!decay_traits<E>::is_linear) {
159  if (e.alias(*this)) {
160  // Create a temporary to hold the result
161  etl::fast_dyn_matrix_o<T, SO, Dims...> tmp;
162 
163  // Assign the expression to the temporary
164  tmp = e;
165 
166  // Assign the temporary to this matrix
167  *this = tmp;
168  } else {
169  e.assign_to(*this);
170  }
171  } else {
172  // Direct assignment of the expression into this matrix
173  e.assign_to(*this);
174  }
175 
176  return *this;
177  }
178 
184  template <typename VT>
185  custom_fast_matrix_impl& operator=(const VT& value) noexcept requires(std::convertible_to<VT, value_type> || std::assignable_from<T&, VT>) {
186  direct_fill(*this, value);
187 
188  return *this;
189  }
190 
195  template <typename Y>
196  auto& gpu_compute_hint([[maybe_unused]] Y& y) {
197  this->ensure_gpu_up_to_date();
198  return *this;
199  }
200 
205  template <typename Y>
206  const auto& gpu_compute_hint([[maybe_unused]] Y& y) const {
207  this->ensure_gpu_up_to_date();
208  return *this;
209  }
210 
211  // Swap operations
212 
218  using std::swap;
219  swap(_data, other._data);
220  }
221 
222  // Accessors
223 
230  template <typename V = default_vec>
231  void store(vec_type<V> in, size_t i) noexcept {
232  V::storeu(memory_start() + i, in);
233  }
234 
241  template <typename V = default_vec>
242  void storeu(vec_type<V> in, size_t i) noexcept {
243  V::storeu(memory_start() + i, in);
244  }
245 
252  template <typename V = default_vec>
253  void stream(vec_type<V> in, size_t i) noexcept {
254  V::storeu(memory_start() + i, in);
255  }
256 
263  template <typename V = default_vec>
264  vec_type<V> load(size_t i) const noexcept {
265  return V::loadu(memory_start() + i);
266  }
267 
274  template <typename V = default_vec>
275  vec_type<V> loadu(size_t i) const noexcept {
276  return V::loadu(memory_start() + i);
277  }
278 
279  // Assignment functions
280 
285  template <typename L>
286  void assign_to(L&& lhs) const {
287  std_assign_evaluate(*this, std::forward<L>(lhs));
288  }
289 
294  template <typename L>
295  void assign_add_to(L&& lhs) const {
296  std_add_evaluate(*this, std::forward<L>(lhs));
297  }
298 
303  template <typename L>
304  void assign_sub_to(L&& lhs) const {
305  std_sub_evaluate(*this, std::forward<L>(lhs));
306  }
307 
312  template <typename L>
313  void assign_mul_to(L&& lhs) const {
314  std_mul_evaluate(*this, std::forward<L>(lhs));
315  }
316 
321  template <typename L>
322  void assign_div_to(L&& lhs) const {
323  std_div_evaluate(*this, std::forward<L>(lhs));
324  }
325 
330  template <typename L>
331  void assign_mod_to(L&& lhs) const {
332  std_mod_evaluate(*this, std::forward<L>(lhs));
333  }
334 
335  // Internals
336 
341  void visit([[maybe_unused]] const detail::evaluator_visitor& visitor) const {}
342 
349  friend std::ostream& operator<<(std::ostream& os, [[maybe_unused]] const custom_fast_matrix_impl& matrix) {
350  if (sizeof...(Dims) == 1) {
351  return os << "V[" << concat_sizes(Dims...) << "]";
352  }
353 
354  return os << "M[" << concat_sizes(Dims...) << "]";
355  }
356 };
357 
358 #ifndef CPP_UTILS_ASSERT_EXCEPTION
359 static_assert(std::is_nothrow_default_constructible_v<fast_vector<double, 2>>, "fast_vector should be nothrow default constructible");
360 static_assert(std::is_nothrow_copy_constructible_v<fast_vector<double, 2>>, "fast_vector should be nothrow copy constructible");
361 static_assert(std::is_nothrow_move_constructible_v<fast_vector<double, 2>>, "fast_vector should be nothrow move constructible");
362 static_assert(std::is_nothrow_copy_assignable_v<fast_vector<double, 2>>, "fast_vector should be nothrow copy assignable");
363 static_assert(std::is_nothrow_move_assignable_v<fast_vector<double, 2>>, "fast_vector should be nothrow move assignable");
364 static_assert(std::is_nothrow_destructible_v<fast_vector<double, 2>>, "fast_vector should be nothrow destructible");
365 #endif
366 
372 template <typename T, typename ST, order SO, size_t... Dims>
374  lhs.swap(rhs);
375 }
376 
377 } //end of namespace etl
custom_fast_matrix_impl & operator=(custom_fast_matrix_impl &&rhs) noexcept
Move assign a fast matrix.
Definition: custom_fast.hpp:124
Contains static matrix implementation.
void assign_mod_to(L &&lhs) const
Modulo the given left-hand-side expression.
Definition: custom_fast.hpp:331
CRTP class to inject iterators functions.
Definition: iterable.hpp:23
memory_type memory_start() noexcept
Returns a pointer to the first element in memory.
Definition: fast_base.hpp:201
static constexpr size_t etl_size
The size of the matrix.
Definition: custom_fast.hpp:37
friend std::ostream & operator<<(std::ostream &os, [[maybe_unused]] const custom_fast_matrix_impl &matrix)
Prints a fast matrix type (not the contents) to the given stream.
Definition: custom_fast.hpp:349
void store(vec_type< V > in, size_t i) noexcept
Store several elements in the matrix at once.
Definition: custom_fast.hpp:231
const auto & gpu_compute_hint([[maybe_unused]] Y &y) const
Return a GPU computed version of this expression.
Definition: custom_fast.hpp:206
void std_assign_evaluate(Expr &&expr, Result &&result)
Evaluation of the expr into result.
Definition: evaluator.hpp:1176
custom_fast_matrix_impl(custom_fast_matrix_impl &&rhs) noexcept
Move construct a fast matrix.
Definition: custom_fast.hpp:88
value_type * memory_type
The memory type.
Definition: custom_fast.hpp:46
void visit([[maybe_unused]] const detail::evaluator_visitor &visitor) const
Apply the given visitor to this expression and its descendants.
Definition: custom_fast.hpp:341
void swap(custom_fast_matrix_impl< T, ST, SO, Dims... > &lhs, custom_fast_matrix_impl< T, ST, SO, Dims... > &rhs)
Swaps the given two matrices.
Definition: custom_fast.hpp:373
const value_type * const_memory_type
The const memory type.
Definition: custom_fast.hpp:47
Standard memory utilities.
custom_fast_matrix_impl & operator=(const VT &value) noexcept requires(std
Assign the value to each element.
Definition: custom_fast.hpp:185
static constexpr size_t dim() noexcept
Returns the Dth dimension of the matrix.
Definition: fast_base.hpp:266
void stream(vec_type< V > in, size_t i) noexcept
Store several elements in the matrix at once, using non-temporal store.
Definition: custom_fast.hpp:253
order
Storage order of a matrix.
Definition: order.hpp:15
void direct_copy(const S *first, const S *last, T *target)
Performs a direct memory copy.
Definition: memory.hpp:24
custom_fast_matrix_impl< T, ST, SO, Dims... > this_type
this type
Definition: custom_fast.hpp:41
void assign_div_to(L &&lhs) const
Divide to the given left-hand-side expression.
Definition: custom_fast.hpp:322
void assign_to(L &&lhs) const
Assign to the given left-hand-side expression.
Definition: custom_fast.hpp:286
vec_type< V > load(size_t i) const noexcept
Load several elements of the matrix at once.
Definition: custom_fast.hpp:264
std::string concat_sizes(Dims... sizes)
Returns a string representation of the given dimensions.
Definition: tmp.hpp:192
static constexpr order storage_order
The storage order.
Definition: custom_fast.hpp:38
CRTP class to inject functions testing values of the expressions.
Definition: value_testable.hpp:26
T value_type
The value type.
Definition: custom_fast.hpp:44
void storeu(vec_type< V > in, size_t i) noexcept
Store several elements in the matrix at once.
Definition: custom_fast.hpp:242
auto end() noexcept
Return an iterator to the past-the-end element of the matrix.
Definition: iterable.hpp:59
Traits to get information about ETL types.
Definition: tmp.hpp:68
Root namespace for the ETL library.
Definition: adapter.hpp:15
static constexpr bool array_impl
true if the storage is an std::arraw, false otherwise
Definition: custom_fast.hpp:39
void invalidate_gpu() const noexcept
Invalidates the GPU memory.
Definition: sub_view.hpp:695
CRTP class to inject functions creating new expressions.
Definition: expression_able.hpp:23
vec_type< V > loadu(size_t i) const noexcept
Load several elements of the matrix at once.
Definition: custom_fast.hpp:275
void assign_sub_to(L &&lhs) const
Subtract from the given left-hand-side expression.
Definition: custom_fast.hpp:304
Visitor to perform local evaluation when necessary.
Definition: eval_visitors.hpp:23
void storeu(vec_type< V > in, size_t i) noexcept
Store several elements in the matrix at once.
Definition: dyn_matrix_view.hpp:187
CRTP class to inject inplace operations to matrix and vector structures.
Definition: inplace_assignable.hpp:26
void std_mod_evaluate(Expr &&expr, Result &&result)
Compound modulo evaluation of the expr into result.
Definition: evaluator.hpp:1271
void swap(custom_fast_matrix_impl &other)
Swap the contents of the matrix with another matrix.
Definition: custom_fast.hpp:217
auto begin() noexcept
Return an iterator to the first element of the matrix.
Definition: iterable.hpp:46
void direct_fill(E &&mat, V value)
Fill the given ETL value class with the given value.
Definition: direct_fill.hpp:25
Definition: fast_base.hpp:87
void std_mul_evaluate(Expr &&expr, Result &&result)
Compound multiply evaluation of the expr into result.
Definition: evaluator.hpp:1233
auto loadu(size_t x) const noexcept
Load several elements of the expression at once.
Definition: dyn_matrix_view.hpp:154
Matrix with compile-time fixed dimensions.
Definition: fast.hpp:26
custom_fast_matrix_impl(memory_type memory)
Construction.
Definition: custom_fast.hpp:72
fast_matrix_base< this_type, T, ST, SO, Dims... > base_type
The base type.
Definition: custom_fast.hpp:42
static constexpr size_t n_dimensions
The number of dimensions.
Definition: custom_fast.hpp:36
requires(D > 0) struct dyn_base
Matrix with run-time fixed dimensions.
Definition: dyn_base.hpp:113
auto & gpu_compute_hint([[maybe_unused]] Y &y)
Return a GPU computed version of this expression.
Definition: custom_fast.hpp:196
void ensure_gpu_up_to_date() const
Copy back from the GPU to the expression memory if necessary.
Definition: dyn_matrix_view.hpp:280
void std_sub_evaluate(Expr &&expr, Result &&result)
Compound subtract evaluation of the expr into result.
Definition: evaluator.hpp:1214
custom_fast_matrix_impl & operator=(const C &container) noexcept requires(!std
Assign the values of the STL container to the fast matrix.
Definition: custom_fast.hpp:138
custom_fast_matrix_impl(const custom_fast_matrix_impl &rhs) noexcept
Copy construct a fast matrix.
Definition: custom_fast.hpp:80
memory_type memory_end() noexcept
Returns a pointer to the past-the-end element in memory.
Definition: fast_base.hpp:217
void assign_add_to(L &&lhs) const
Add to the given left-hand-side expression.
Definition: custom_fast.hpp:295
Matrix with compile-time fixed dimensions.
Definition: custom_fast.hpp:27
custom_fast_matrix_impl & operator=(E &&e)
Assign the values of the ETL expression to the fast matrix.
Definition: custom_fast.hpp:154
custom_fast_matrix_impl & operator=(const custom_fast_matrix_impl< T, ST, SO, SDims... > &rhs) noexcept
Copy assign a fast matrix from a different matrix fast matrix type.
Definition: custom_fast.hpp:113
storage_impl _data
The storage container.
Definition: fast_base.hpp:101
void assign_mul_to(L &&lhs) const
Multiply the given left-hand-side expression.
Definition: custom_fast.hpp:313
custom_fast_matrix_impl & operator=(const custom_fast_matrix_impl &rhs) noexcept
Copy assign a fast matrix.
Definition: custom_fast.hpp:99
typename decay_traits< E >::value_type value_t
Traits to extract the value type out of an ETL type.
Definition: tmp.hpp:81
void std_div_evaluate(Expr &&expr, Result &&result)
Compound divide evaluation of the expr into result.
Definition: evaluator.hpp:1252
static constexpr size_t size() noexcept
Returns the size of the matrix, in O(1)
Definition: fast_base.hpp:233
ST storage_impl
The storage implementation.
Definition: custom_fast.hpp:45
void validate_cpu() const noexcept
Validates the CPU memory.
Definition: sub_view.hpp:702
void std_add_evaluate(Expr &&expr, Result &&result)
Compound add evaluation of the expr into result.
Definition: evaluator.hpp:1195
typename V::template vec_type< T > vec_type
The vectorization type for V.
Definition: custom_fast.hpp:60
CRTP class to inject functions testing the dimensions.
Definition: dim_testable.hpp:45