Expression Templates Library (ETL)
custom_dyn.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 <concepts>
16 #include "etl/dyn_base.hpp" //The base class and utilities
17 #include "etl/direct_fill.hpp" //direct_fill with GPU support
18 
19 namespace etl {
20 
26 template <typename T, order SO, size_t D>
27 struct custom_dyn_matrix_impl final : dense_dyn_base<custom_dyn_matrix_impl<T, SO, D>, T, SO, D>,
28  inplace_assignable<custom_dyn_matrix_impl<T, SO, D>>,
29  expression_able<custom_dyn_matrix_impl<T, SO, D>>,
30  value_testable<custom_dyn_matrix_impl<T, SO, D>>,
31  iterable<custom_dyn_matrix_impl<T, SO, D>, SO == order::RowMajor>,
32  dim_testable<custom_dyn_matrix_impl<T, SO, D>> {
33  static constexpr size_t n_dimensions = D;
34  static constexpr order storage_order = SO;
35  static constexpr size_t alignment = 1;
36 
40  using value_type = T;
41  using dimension_storage_impl = std::array<size_t, n_dimensions>;
43  using const_memory_type = const value_type*;
44 
45  using iterator = std::conditional_t<SO == order::RowMajor, value_type*, etl::iterator<this_type>>;
46  using const_iterator = std::conditional_t<SO == order::RowMajor, const value_type*, etl::iterator<const this_type>>;
47 
51  template <typename V = default_vec>
52  using vec_type = typename V::template vec_type<T>;
53 
54 private:
55  using base_type::_dimensions;
56  using base_type::_memory;
57  using base_type::_size;
58 
59  using base_type::check_invariants;
60 
61 public:
62  using base_type::dim;
63  using base_type::memory_end;
64  using base_type::memory_start;
67 
68  // Construction
69 
75  _memory = rhs._memory;
76  }
77 
82  custom_dyn_matrix_impl(custom_dyn_matrix_impl&& rhs) noexcept : base_type(std::move(rhs)) {
83  _memory = rhs._memory;
84  rhs._memory = nullptr;
85  }
86 
98  template <typename... S>
99  explicit custom_dyn_matrix_impl(value_type* memory, S... sizes) noexcept requires (sizeof...(S) == D) : base_type(util::size(sizes...), {{static_cast<size_t>(sizes)...}}) {
100  _memory = memory;
101  //Nothing else to init
102  }
103 
109  custom_dyn_matrix_impl& operator=(const custom_dyn_matrix_impl& rhs) noexcept {
110  if (this != &rhs) {
111  _size = rhs._size;
112  _dimensions = rhs._dimensions;
113  _memory = rhs._memory;
114  }
115 
116  check_invariants();
117 
118  return *this;
119  }
120 
129  custom_dyn_matrix_impl& operator=(custom_dyn_matrix_impl&& rhs) noexcept {
130  if (this != &rhs) {
131  _size = rhs._size;
132  _dimensions = std::move(rhs._dimensions);
133  _memory = rhs._memory;
134 
135  rhs._size = 0;
136  rhs._memory = nullptr;
137  }
138 
139  check_invariants();
140 
141  return *this;
142  }
143 
149  template <etl_expr E>
150  custom_dyn_matrix_impl& operator=(E&& e) noexcept requires(!std::same_as<std::decay_t<E>, custom_dyn_matrix_impl<T, SO, D>> && std::convertible_to<value_t<E>, value_type>) {
151  validate_assign(*this, e);
152 
153  // Avoid aliasing issues
154  if constexpr (!decay_traits<E>::is_linear) {
155  if (e.alias(*this)) {
156  // Create a temporary to hold the result
158 
159  // Assign the expression to the temporary
160  tmp = e;
161 
162  // Assign the temporary to this matrix
163  *this = tmp;
164  } else {
165  e.assign_to(*this);
166  }
167  } else {
168  // Direct assignment of the expression into this matrix
169  e.assign_to(*this);
170  }
171 
172  check_invariants();
173 
174  return *this;
175  }
176 
182  template <std_container Container>
183  custom_dyn_matrix_impl& operator=(const Container& vec) requires(std::convertible_to<typename Container::value_type, value_type>) {
184  validate_assign(*this, vec);
185 
186  std::copy(vec.begin(), vec.end(), begin());
187 
188  this->validate_cpu();
189  this->invalidate_gpu();
190 
191  check_invariants();
192 
193  return *this;
194  }
195 
201  custom_dyn_matrix_impl& operator=(const value_type& value) noexcept {
202  direct_fill(*this, value);
203 
204  check_invariants();
205 
206  return *this;
207  }
208 
212  ~custom_dyn_matrix_impl() noexcept {
213  // Nothing to do
214  }
215 
220  template <typename Y>
221  auto& gpu_compute_hint([[maybe_unused]] Y& y) {
222  this->ensure_gpu_up_to_date();
223  return *this;
224  }
225 
230  template <typename Y>
231  const auto& gpu_compute_hint([[maybe_unused]] Y& y) const {
232  this->ensure_gpu_up_to_date();
233  return *this;
234  }
235 
240  void swap(custom_dyn_matrix_impl& other) {
241  using std::swap;
242  swap(_size, other._size);
243  swap(_dimensions, other._dimensions);
244  swap(_memory, other._memory);
245 
246  //TODO swap is likely screwing up GPU memory!
247 
248  check_invariants();
249  }
250 
251  // Accessors
252 
259  template <typename V = default_vec>
260  void store(vec_type<V> in, size_t i) noexcept {
261  V::storeu(memory_start() + i, in);
262  }
263 
270  template <typename V = default_vec>
271  void storeu(vec_type<V> in, size_t i) noexcept {
272  V::storeu(memory_start() + i, in);
273  }
274 
281  template <typename V = default_vec>
282  void stream(vec_type<V> in, size_t i) noexcept {
283  V::storeu(memory_start() + i, in);
284  }
285 
292  template <typename V = default_vec>
293  vec_type<V> load(size_t i) const noexcept {
294  return V::loadu(_memory + i);
295  }
296 
303  template <typename V = default_vec>
304  vec_type<V> loadu(size_t i) const noexcept {
305  return V::loadu(_memory + i);
306  }
307 
308  // Assignment functions
309 
314  template <typename L>
315  void assign_to(L&& lhs) const {
316  std_assign_evaluate(*this, std::forward<L>(lhs));
317  }
318 
323  template <typename L>
324  void assign_add_to(L&& lhs) const {
325  std_add_evaluate(*this, std::forward<L>(lhs));
326  }
327 
332  template <typename L>
333  void assign_sub_to(L&& lhs) const {
334  std_sub_evaluate(*this, std::forward<L>(lhs));
335  }
336 
341  template <typename L>
342  void assign_mul_to(L&& lhs) const {
343  std_mul_evaluate(*this, std::forward<L>(lhs));
344  }
345 
350  template <typename L>
351  void assign_div_to(L&& lhs) const {
352  std_div_evaluate(*this, std::forward<L>(lhs));
353  }
354 
359  template <typename L>
360  void assign_mod_to(L&& lhs) const {
361  std_mod_evaluate(*this, std::forward<L>(lhs));
362  }
363 
364  // Internals
365 
370  void visit([[maybe_unused]] const detail::evaluator_visitor& visitor) const {}
371 
378  friend std::ostream& operator<<(std::ostream& os, const custom_dyn_matrix_impl& mat) {
379  if (D == 1) {
380  return os << "CV[" << mat.size() << "]";
381  }
382 
383  os << "CM[" << mat.dim(0);
384 
385  for (size_t i = 1; i < D; ++i) {
386  os << "," << mat.dim(i);
387  }
388 
389  return os << "]";
390  }
391 };
392 
393 static_assert(std::is_nothrow_move_constructible_v<dyn_vector<double>>, "dyn_vector should be nothrow move constructible");
394 static_assert(std::is_nothrow_move_assignable_v<dyn_vector<double>>, "dyn_vector should be nothrow move assignable");
395 static_assert(std::is_nothrow_destructible_v<dyn_vector<double>>, "dyn_vector should be nothrow destructible");
396 
402 template <typename T, order SO, size_t D>
404  lhs.swap(rhs);
405 }
406 
407 } //end of namespace etl
T value_type
The value type.
Definition: custom_dyn.hpp:40
custom_dyn_matrix_impl(const custom_dyn_matrix_impl &rhs) noexcept
Copy construct a custom_dyn_matrix_impl.
Definition: custom_dyn.hpp:74
const value_type * const_memory_type
The const memory type.
Definition: custom_dyn.hpp:43
CRTP class to inject iterators functions.
Definition: iterable.hpp:23
void assign_add_to(L &&lhs) const
Add to the given left-hand-side expression.
Definition: dyn_matrix_view.hpp:217
static constexpr size_t n_dimensions
The number of dimensions.
Definition: custom_dyn.hpp:33
Dense Matrix with run-time fixed dimensions. The matrix support an arbitrary number of dimensions...
Definition: dyn_base.hpp:294
void std_assign_evaluate(Expr &&expr, Result &&result)
Evaluation of the expr into result.
Definition: evaluator.hpp:1176
typename V::template vec_type< T > vec_type
The vectorization type for V.
Definition: custom_dyn.hpp:52
std::conditional_t< SO==order::RowMajor, value_type *, etl::iterator< this_type > > iterator
The iterator type.
Definition: custom_dyn.hpp:45
void assign_div_to(L &&lhs) const
Divide the given left-hand-side expression.
Definition: dyn_matrix_view.hpp:244
value_t< sub_type > value_type
The value contained in the expression.
Definition: dyn_matrix_view.hpp:31
void assign_mul_to(L &&lhs) const
Multiply the given left-hand-side expression.
Definition: dyn_matrix_view.hpp:235
void assign_to(L &&lhs) const
Assign to the given left-hand-side expression.
Definition: dyn_matrix_view.hpp:208
D D
The number of dimensions.
Definition: dyn_matrix_view.hpp:24
Standard memory utilities.
order
Storage order of a matrix.
Definition: order.hpp:15
typename V::template vec_type< value_type > vec_type
The vectorization type for V.
Definition: dyn_matrix_view.hpp:43
CRTP class to inject functions testing values of the expressions.
Definition: value_testable.hpp:26
auto end() noexcept
Return an iterator to the past-the-end element of the matrix.
Definition: iterable.hpp:59
static constexpr order storage_order
The storage order.
Definition: custom_dyn.hpp:34
std::array< size_t, n_dimensions > dimension_storage_impl
The type used to store the dimensions.
Definition: custom_dyn.hpp:41
auto load(size_t x) const noexcept
Load several elements of the expression at once.
Definition: dyn_matrix_view.hpp:143
Traits to get information about ETL types.
Definition: tmp.hpp:68
Root namespace for the ETL library.
Definition: adapter.hpp:15
void invalidate_gpu() const noexcept
Invalidates the GPU memory.
Definition: sub_view.hpp:695
auto dim(E &&value, size_t i) -> detail::identity_helper< E, dim_view< detail::build_identity_type< E >, D >>
Return a view representing the ith Dth dimension.
Definition: view_expression_builder.hpp:25
CRTP class to inject functions creating new expressions.
Definition: expression_able.hpp:23
void store(vec_type< V > in, size_t i) noexcept
Store several elements in the matrix at once.
Definition: dyn_matrix_view.hpp:176
void stream(vec_type< V > in, size_t i) noexcept
Store several elements in the matrix at once, using non-temporal store.
Definition: dyn_matrix_view.hpp:165
std::ostream & operator<<(std::ostream &os, const etl::complex< T > &c)
Outputs a textual representation of the complex number in the given stream.
Definition: complex.hpp:576
Visitor to perform local evaluation when necessary.
Definition: eval_visitors.hpp:23
static constexpr size_t alignment
The memory alignment.
Definition: custom_dyn.hpp:35
void storeu(vec_type< V > in, size_t i) noexcept
Store several elements in the matrix at once.
Definition: dyn_matrix_view.hpp:187
value_type * memory_type
The memory type.
Definition: custom_dyn.hpp:42
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
auto begin() noexcept
Return an iterator to the first element of the matrix.
Definition: iterable.hpp:46
Matrix with run-time fixed dimensions.
Definition: dyn.hpp:26
void direct_fill(E &&mat, V value)
Fill the given ETL value class with the given value.
Definition: direct_fill.hpp:25
std::conditional_t< SO==order::RowMajor, const value_type *, etl::iterator< const this_type > > const_iterator
The const iterator type.
Definition: custom_dyn.hpp:46
void std_mul_evaluate(Expr &&expr, Result &&result)
Compound multiply evaluation of the expr into result.
Definition: evaluator.hpp:1233
void swap(custom_dyn_matrix_impl< T, SO, D > &lhs, custom_dyn_matrix_impl< T, SO, D > &rhs)
Swap two dyn matrix.
Definition: custom_dyn.hpp:403
auto loadu(size_t x) const noexcept
Load several elements of the expression at once.
Definition: dyn_matrix_view.hpp:154
Base class and utilities for dyn matrix implementations.
void visit(detail::evaluator_visitor &visitor) const
Apply the given visitor to this expression and its descendants.
Definition: dyn_matrix_view.hpp:263
requires(D > 0) struct dyn_base
Matrix with run-time fixed dimensions.
Definition: dyn_base.hpp:113
void ensure_gpu_up_to_date() const
Copy back from the GPU to the expression memory if necessary.
Definition: dyn_matrix_view.hpp:280
Matrix with run-time fixed dimensions.
Definition: custom_dyn.hpp:27
void std_sub_evaluate(Expr &&expr, Result &&result)
Compound subtract evaluation of the expr into result.
Definition: evaluator.hpp:1214
void assign_mod_to(L &&lhs) const
Modulo the given left-hand-side expression.
Definition: dyn_matrix_view.hpp:253
dense_dyn_base< custom_dyn_matrix_impl< T, SO, D >, T, SO, D > base_type
The base type.
Definition: custom_dyn.hpp:39
const auto & gpu_compute_hint([[maybe_unused]] Y &y) const
Return a GPU computed version of this expression.
Definition: sub_view.hpp:653
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
custom_dyn_matrix_impl(custom_dyn_matrix_impl &&rhs) noexcept
Move construct a matrix.
Definition: custom_dyn.hpp:82
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
value_type *ETL_RESTRICT _memory
Pointer to the allocated memory.
Definition: dyn_base.hpp:312
CRTP class to inject functions testing the dimensions.
Definition: dim_testable.hpp:45
void assign_sub_to(L &&lhs) const
Sub from the given left-hand-side expression.
Definition: dyn_matrix_view.hpp:226