Expression Templates Library (ETL)
dyn_matrix_view.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 
23 template <etl_expr T, size_t D>
24 requires(!is_dma<T>) struct dyn_matrix_view<T, D> final : iterable<dyn_matrix_view<T, D>, false>,
25  value_testable<dyn_matrix_view<T, D>>,
26  assignable<dyn_matrix_view<T, D>, value_t<T>> {
30  using sub_type = T;
38 
42  template <typename V = default_vec>
43  using vec_type = typename V::template vec_type<value_type>;
44 
45  using assignable_base_type::operator=;
48 
49 private:
50  T sub;
51  std::array<size_t, D> dimensions;
52  size_t _size;
53 
54  static constexpr order storage_order = decay_traits<sub_type>::storage_order;
55 
56  friend struct etl_traits<dyn_matrix_view>;
57 
58 public:
63  template <typename... S>
64  explicit dyn_matrix_view(sub_type sub, S... dims) : sub(sub), dimensions{{dims...}}, _size(etl::size(sub)) {}
65 
71  const_return_type operator[](size_t j) const {
72  return sub[j];
73  }
74 
80  return_type operator[](size_t j) {
81  return sub[j];
82  }
83 
89  const_return_type operator()(size_t j) const {
90  return sub[j];
91  }
92 
100  template <typename... S>
101  const_return_type operator()(size_t f1, size_t f2, S... sizes) const {
102  return sub[etl::dyn_index(*this, f1, f2, sizes...)];
103  }
104 
111  value_type read_flat(size_t j) const noexcept {
112  return sub.read_flat(j);
113  }
114 
120  return_type operator()(size_t j) {
121  return sub[j];
122  }
123 
131  template <typename... S>
132  return_type operator()(size_t f1, size_t f2, S... sizes) {
133  return sub[etl::dyn_index(*this, f1, f2, sizes...)];
134  }
135 
142  template <typename V = default_vec>
143  auto load(size_t x) const noexcept {
144  return sub.template load<V>(x);
145  }
146 
153  template <typename V = default_vec>
154  auto loadu(size_t x) const noexcept {
155  return sub.template loadu<V>(x);
156  }
157 
164  template <typename V = default_vec>
165  void stream(vec_type<V> in, size_t i) noexcept {
166  sub.template stream<V>(in, i);
167  }
168 
175  template <typename V = default_vec>
176  void store(vec_type<V> in, size_t i) noexcept {
177  sub.template store<V>(in, i);
178  }
179 
186  template <typename V = default_vec>
187  void storeu(vec_type<V> in, size_t i) noexcept {
188  sub.template storeu<V>(in, i);
189  }
190 
196  template <typename E>
197  bool alias(const E& rhs) const noexcept {
198  return sub.alias(rhs);
199  }
200 
201  // Assignment functions
202 
207  template <typename L>
208  void assign_to(L&& lhs) const {
209  std_assign_evaluate(*this, std::forward<L>(lhs));
210  }
211 
216  template <typename L>
217  void assign_add_to(L&& lhs) const {
218  std_add_evaluate(*this, std::forward<L>(lhs));
219  }
220 
225  template <typename L>
226  void assign_sub_to(L&& lhs) const {
227  std_sub_evaluate(*this, std::forward<L>(lhs));
228  }
229 
234  template <typename L>
235  void assign_mul_to(L&& lhs) const {
236  std_mul_evaluate(*this, std::forward<L>(lhs));
237  }
238 
243  template <typename L>
244  void assign_div_to(L&& lhs) const {
245  std_div_evaluate(*this, std::forward<L>(lhs));
246  }
247 
252  template <typename L>
253  void assign_mod_to(L&& lhs) const {
254  std_mod_evaluate(*this, std::forward<L>(lhs));
255  }
256 
257  // Internals
258 
263  void visit(detail::evaluator_visitor& visitor) const {
264  sub.visit(visitor);
265  }
266 
271  void ensure_cpu_up_to_date() const {
272  // Need to ensure sub value
273  sub.ensure_cpu_up_to_date();
274  }
275 
280  void ensure_gpu_up_to_date() const {
281  // Need to ensure both LHS and RHS
282  sub.ensure_gpu_up_to_date();
283  }
284 
291  friend std::ostream& operator<<(std::ostream& os, const dyn_matrix_view& v) {
292  return os << "reshape[" << D << "D](" << v.sub << ")";
293  }
294 };
295 
300 template <etl_expr T, size_t D>
301 requires(is_dma<T>) struct dyn_matrix_view<T, D> final : iterable<dyn_matrix_view<T, D>, true>,
302  value_testable<dyn_matrix_view<T, D>>,
303  assignable<dyn_matrix_view<T, D>, value_t<T>> {
307  using sub_type = T;
308  using value_type = value_t<sub_type>;
313  using iterator = value_type*;
314  using const_iterator = const value_type*;
315 
319  template <typename V = default_vec>
320  using vec_type = typename V::template vec_type<value_type>;
321 
322  using assignable_base_type::operator=;
325 
326 private:
327  T sub;
328  std::array<size_t, D> dimensions;
329  size_t _size;
330 
331  mutable memory_type memory;
332 
333  static constexpr order storage_order = decay_traits<sub_type>::storage_order;
334 
335  friend struct etl_traits<dyn_matrix_view>;
336 
337 public:
342  template <typename... S>
343  explicit dyn_matrix_view(sub_type sub, S... dims) : sub(sub), dimensions{{dims...}}, _size(etl::size(sub)) {
344  // Accessing the memory through fast sub views means evaluation
345  if constexpr (decay_traits<sub_type>::is_temporary) {
346  standard_evaluator::pre_assign_rhs(*this);
347  }
348 
349  this->memory = this->sub.memory_start();
350 
351  cpp_assert(this->memory, "Memory should have been evaluated");
352  }
353 
359  const_return_type operator[](size_t j) const {
361  return memory[j];
362  }
363 
369  return_type operator[](size_t j) {
371  invalidate_gpu();
372  return memory[j];
373  }
374 
380  const_return_type operator()(size_t j) const requires (D == 1) {
382  return memory[j];
383  }
384 
390  return_type operator()(size_t j) requires (D == 1) {
392  invalidate_gpu();
393  return memory[j];
394  }
395 
402  value_type read_flat(size_t j) const noexcept {
404  return memory[j];
405  }
406 
414  template <typename... S>
415  const_return_type operator()(size_t f1, size_t f2, S... sizes) const {
417  return memory[etl::dyn_index(*this, f1, f2, sizes...)];
418  }
419 
427  template <typename... S>
428  return_type operator()(size_t f1, size_t f2, S... sizes) {
430  invalidate_gpu();
431  return memory[etl::dyn_index(*this, f1, f2, sizes...)];
432  }
433 
439  auto operator()(size_t i) noexcept requires (D > 1) {
440  return etl::sub(*this, i);
441  }
442 
448  auto operator()(size_t i) const noexcept requires (D > 1) {
449  return etl::sub(*this, i);
450  }
451 
458  template <typename V = default_vec>
459  auto load(size_t x) const noexcept {
460  return V::loadu(memory + x);
461  }
462 
469  template <typename V = default_vec>
470  auto loadu(size_t x) const noexcept {
471  return V::loadu(memory + x);
472  }
473 
480  template <typename V = default_vec>
481  void stream(vec_type<V> in, size_t i) noexcept {
482  return V::stream(memory + i, in);
483  }
484 
491  template <typename V = default_vec>
492  void store(vec_type<V> in, size_t i) noexcept {
493  sub.template store<V>(in, i);
494  }
495 
502  template <typename V = default_vec>
503  void storeu(vec_type<V> in, size_t i) noexcept {
504  return V::storeu(memory + i, in);
505  }
506 
512  template <typename E>
513  bool alias(const E& rhs) const noexcept {
514  return sub.alias(rhs);
515  }
516 
521  memory_type memory_start() noexcept {
522  return memory;
523  }
524 
529  const_memory_type memory_start() const noexcept {
530  return memory;
531  }
532 
537  memory_type memory_end() noexcept {
538  return memory + _size;
539  }
540 
545  const_memory_type memory_end() const noexcept {
546  return memory + _size;
547  }
548 
549  // Assignment functions
550 
555  template <typename L>
556  void assign_to(L&& lhs) const {
557  std_assign_evaluate(*this, std::forward<L>(lhs));
558  }
559 
564  template <typename L>
565  void assign_add_to(L&& lhs) const {
566  std_add_evaluate(*this, std::forward<L>(lhs));
567  }
568 
573  template <typename L>
574  void assign_sub_to(L&& lhs) const {
575  std_sub_evaluate(*this, std::forward<L>(lhs));
576  }
577 
582  template <typename L>
583  void assign_mul_to(L&& lhs) const {
584  std_mul_evaluate(*this, std::forward<L>(lhs));
585  }
586 
591  template <typename L>
592  void assign_div_to(L&& lhs) const {
593  std_div_evaluate(*this, std::forward<L>(lhs));
594  }
595 
600  template <typename L>
601  void assign_mod_to(L&& lhs) const {
602  std_mod_evaluate(*this, std::forward<L>(lhs));
603  }
604 
605  // Internals
606 
611  void visit(detail::evaluator_visitor& visitor) const {
612  sub.visit(visitor);
613  }
614 
619  value_type* gpu_memory() const noexcept {
620  return sub.gpu_memory();
621  }
622 
626  void gpu_evict() const noexcept {
627  sub.gpu_evict();
628  }
629 
633  void invalidate_cpu() const noexcept {
634  sub.invalidate_cpu();
635  }
636 
640  void invalidate_gpu() const noexcept {
641  sub.invalidate_gpu();
642  }
643 
647  void validate_cpu() const noexcept {
648  sub.validate_cpu();
649  }
650 
654  void validate_gpu() const noexcept {
655  sub.validate_gpu();
656  }
657 
662  void ensure_gpu_allocated() const {
663  sub.ensure_gpu_allocated();
664  }
665 
669  void ensure_gpu_up_to_date() const {
670  sub.ensure_gpu_up_to_date();
671  }
672 
677  void ensure_cpu_up_to_date() const {
678  sub.ensure_cpu_up_to_date();
679  }
680 
685  void gpu_copy_from(const value_type* gpu_memory) const {
686  sub.gpu_copy_from(gpu_memory);
687  }
688 
693  bool is_cpu_up_to_date() const noexcept {
694  return sub.is_cpu_up_to_date();
695  }
696 
701  bool is_gpu_up_to_date() const noexcept {
702  return sub.is_gpu_up_to_date();
703  }
704 
711  friend std::ostream& operator<<(std::ostream& os, const dyn_matrix_view& v) {
712  return os << "reshape[" << D << "D](" << v.sub << ")";
713  }
714 };
715 
719 template <typename T, size_t D>
722  using sub_expr_t = std::decay_t<T>;
725 
726  static constexpr bool is_etl = true;
727  static constexpr bool is_transformer = false;
728  static constexpr bool is_view = true;
729  static constexpr bool is_magic_view = false;
730  static constexpr bool is_linear = sub_traits::is_linear;
731  static constexpr bool is_thread_safe = sub_traits::is_thread_safe;
732  static constexpr bool is_fast = false;
733  static constexpr bool is_value = false;
734  static constexpr bool is_direct = sub_traits::is_direct;
735  static constexpr bool is_generator = false;
736  static constexpr bool is_padded = false;
737  static constexpr bool is_aligned = false;
738  static constexpr bool is_temporary = sub_traits::is_temporary;
739  static constexpr bool gpu_computable = false;
740  static constexpr order storage_order = sub_traits::storage_order;
741 
747  template <vector_mode_t V>
748  static constexpr bool vectorizable = sub_traits::template vectorizable<V>;
749 
755  static size_t size(const expr_t& v) {
756  return v._size;
757  }
758 
765  static size_t dim(const expr_t& v, size_t d) {
766  return v.dimensions[d];
767  }
768 
773  static constexpr size_t dimensions() {
774  return D;
775  }
776 
781  static constexpr int complexity() noexcept {
782  return -1;
783  }
784 };
785 
786 } //end of namespace etl
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
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
void std_assign_evaluate(Expr &&expr, Result &&result)
Evaluation of the expr into result.
Definition: evaluator.hpp:1176
static constexpr size_t dimensions()
Returns the number of expressions for this type.
Definition: dyn_matrix_view.hpp:773
bool alias(const E &rhs) const noexcept
Test if this expression aliases with the given expression.
Definition: dyn_matrix_view.hpp:197
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
constexpr bool is_magic_view
Traits indicating if the given ETL type is a magic view expression.
Definition: traits.hpp:311
const_memory_t< sub_type > const_memory_type
The const memory access type.
Definition: dyn_matrix_view.hpp:33
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
Base class and utilities for dyn matrix implementations.
order
Storage order of a matrix.
Definition: order.hpp:15
dyn_matrix_view(sub_type sub, S... dims)
Construct a new dyn_matrix_view over the given sub expression.
Definition: dyn_matrix_view.hpp:64
typename V::template vec_type< value_type > vec_type
The vectorization type for V.
Definition: dyn_matrix_view.hpp:43
bool is_cpu_up_to_date() const noexcept
Indicates if the CPU memory is up to date.
Definition: sub_view.hpp:777
std::conditional_t< std::is_lvalue_reference_v< S >, const value_t< T > &, value_t< T > > const_return_helper
Definition: traits.hpp:872
void gpu_copy_from([[maybe_unused]] const value_type *new_gpu_memory) const
Copy from GPU to GPU.
Definition: sub_view.hpp:761
T sub_type
The sub type.
Definition: dyn_matrix_view.hpp:30
Definition: expr_fwd.hpp:80
memory_t< sub_type > memory_type
The memory acess type.
Definition: dyn_matrix_view.hpp:32
void gpu_evict() const noexcept
Evict the expression from GPU.
Definition: sub_view.hpp:681
CRTP class to inject functions testing values of the expressions.
Definition: value_testable.hpp:26
constexpr bool is_fast
Traits to test if the given ETL expresion type is fast (sizes known at compile-time) ...
Definition: traits.hpp:588
auto end() noexcept
Return an iterator to the past-the-end element of the matrix.
Definition: iterable.hpp:59
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
std::conditional_t< std::is_const_v< std::remove_reference_t< S > >, const value_t< T > &, std::conditional_t< std::is_lvalue_reference_v< S > &&!std::is_const_v< T >, value_t< T > &, value_t< T > >> return_helper
Definition: traits.hpp:866
void invalidate_gpu() const noexcept
Invalidates the GPU memory.
Definition: sub_view.hpp:695
std::conditional_t< std::is_const_v< std::remove_reference_t< S > >, typename std::decay_t< S >::const_memory_type, typename std::decay_t< S >::memory_type > memory_t
Traits to extract the direct memory type out of an ETL type.
Definition: tmp.hpp:88
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
typename std::decay_t< S >::const_memory_type const_memory_t
Traits to extract the direct const memory type out of an ETL type.
Definition: tmp.hpp:94
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
static size_t size(const expr_t &v)
Returns the size of the given expression.
Definition: dyn_matrix_view.hpp:755
Visitor to perform local evaluation when necessary.
Definition: eval_visitors.hpp:23
void invalidate_cpu() const noexcept
Invalidates the CPU memory.
Definition: sub_view.hpp:688
Configurable iterator for ETL expressions.
Definition: iterator.hpp:24
void storeu(vec_type< V > in, size_t i) noexcept
Store several elements in the matrix at once.
Definition: dyn_matrix_view.hpp:187
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
const_return_type operator()(size_t j) const
Access to the element at the given position.
Definition: dyn_matrix_view.hpp:89
typename sub_traits::value_type value_type
The value type of the expression.
Definition: dyn_matrix_view.hpp:724
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
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
static constexpr int complexity() noexcept
Estimate the complexity of computation.
Definition: dyn_matrix_view.hpp:781
constexpr bool is_transformer
Traits indicating if the given ETL type is a transformer expression.
Definition: traits.hpp:297
void visit(detail::evaluator_visitor &visitor) const
Apply the given visitor to this expression and its descendants.
Definition: dyn_matrix_view.hpp:263
constexpr size_t size(const E &expr) noexcept
Returns the size of the given ETL expression.
Definition: helpers.hpp:108
requires(D > 0) struct dyn_base
Matrix with run-time fixed dimensions.
Definition: dyn_base.hpp:113
constexpr bool is_view
Traits indicating if the given ETL type is a view expression.
Definition: traits.hpp:304
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
Definition: expr_fwd.hpp:59
auto sub(E &&value, size_t i, size_t j, size_t k, size_t l, size_t m, size_t n, size_t o, size_t p) -> sub_matrix_4d< detail::build_identity_type< E >, false >
Returns view representing a sub matrix view of the given expression.
Definition: view_expression_builder.hpp:100
void validate_gpu() const noexcept
Validates the GPU memory.
Definition: sub_view.hpp:709
CRTP class to inject assign operations to matrix and vector structures.
Definition: assignable.hpp:25
static size_t dim(const expr_t &v, size_t d)
Returns the dth dimension of the given expression.
Definition: dyn_matrix_view.hpp:765
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
const_return_type operator[](size_t j) const
Returns the element at the given index.
Definition: dyn_matrix_view.hpp:71
std::decay_t< T > sub_expr_t
The sub expression type.
Definition: dyn_matrix_view.hpp:722
constexpr bool is_thread_safe
Traits to test if the given ETL expresion type is thread safe.
Definition: traits.hpp:687
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
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
void std_add_evaluate(Expr &&expr, Result &&result)
Compound add evaluation of the expr into result.
Definition: evaluator.hpp:1195
const_return_helper< sub_type, decltype(std::declval< sub_type >()[0])> const_return_type
The const type return by the view.
Definition: dyn_matrix_view.hpp:35
return_helper< sub_type, decltype(std::declval< sub_type >()[0])> return_type
The type returned by the view.
Definition: dyn_matrix_view.hpp:34
size_t dyn_index([[maybe_unused]] const T &expression, size_t i) noexcept(assert_nothrow)
Compute the index for a 1D dynamic matrix.
Definition: index.hpp:187
void assign_sub_to(L &&lhs) const
Sub from the given left-hand-side expression.
Definition: dyn_matrix_view.hpp:226