Expression Templates Library (ETL)
fast_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 
19 template <typename T, bool DMA, size_t... Dims>
20 struct fast_matrix_view;
21 
27 template <typename T, size_t... Dims>
28 struct fast_matrix_view<T, false, Dims...> final : iterable<fast_matrix_view<T, false, Dims...>, false>,
29  value_testable<fast_matrix_view<T, false, Dims...>>,
30  assignable<fast_matrix_view<T, false, Dims...>, value_t<T>> {
31  using sub_type = T;
32  using this_type = fast_matrix<T, false, Dims...>;
40 
44  template <typename V = default_vec>
45  using vec_type = typename V::template vec_type<value_type>;
46 
47  using assignable_base_type::operator=;
50 
51 private:
52  sub_type sub;
53 
54  static constexpr size_t n_dimensions = sizeof...(Dims);
55 
56  friend struct etl_traits<fast_matrix_view>;
57 
58 public:
63  explicit fast_matrix_view(sub_type sub) : sub(sub) {}
64 
70  const_return_type operator[](size_t j) const {
71  return sub[j];
72  }
73 
79  return_type operator[](size_t j) {
80  return sub[j];
81  }
82 
89  value_type read_flat(size_t j) const noexcept {
90  return sub.read_flat(j);
91  }
92 
98  template <size_c... S>
99  return_type operator()(S... args) requires (sizeof...(S) == sizeof...(Dims)) {
100  return sub[etl::fast_index<this_type>(static_cast<size_t>(args)...)];
101  }
102 
108  template <size_c... S>
109  const_return_type operator()(S... args) const noexcept requires (sizeof...(S) == sizeof...(Dims)) {
110  return sub[etl::fast_index<this_type>(static_cast<size_t>(args)...)];
111  }
112 
118  auto operator()(size_t i) noexcept requires sub_capable<this_type> {
119  return etl::sub(*this, i);
120  }
121 
127  auto operator()(size_t i) const noexcept requires sub_capable<this_type> {
128  return etl::sub(*this, i);
129  }
130 
137  template <typename V = default_vec>
138  auto load(size_t x) const noexcept {
139  return sub.template load<V>(x);
140  }
141 
148  template <typename V = default_vec>
149  auto loadu(size_t x) const noexcept {
150  return sub.template loadu<V>(x);
151  }
152 
159  template <typename V = default_vec>
160  void store(vec_type<V> in, size_t i) noexcept {
161  sub.template store<V>(in, i);
162  }
163 
170  template <typename V = default_vec>
171  void storeu(vec_type<V> in, size_t i) noexcept {
172  sub.template storeu<V>(in, i);
173  }
174 
181  template <typename V = default_vec>
182  void stream(vec_type<V> in, size_t i) noexcept {
183  sub.template stream<V>(in, i);
184  }
185 
191  template <typename E>
192  bool alias(const E& rhs) const noexcept {
193  return sub.alias(rhs);
194  }
195 
196  // Assignment functions
197 
202  template <typename L>
203  void assign_to(L&& lhs) const {
204  std_assign_evaluate(*this, std::forward<L>(lhs));
205  }
206 
211  template <typename L>
212  void assign_add_to(L&& lhs) const {
213  std_add_evaluate(*this, std::forward<L>(lhs));
214  }
215 
220  template <typename L>
221  void assign_sub_to(L&& lhs) const {
222  std_sub_evaluate(*this, std::forward<L>(lhs));
223  }
224 
229  template <typename L>
230  void assign_mul_to(L&& lhs) const {
231  std_mul_evaluate(*this, std::forward<L>(lhs));
232  }
233 
238  template <typename L>
239  void assign_div_to(L&& lhs) const {
240  std_div_evaluate(*this, std::forward<L>(lhs));
241  }
242 
247  template <typename L>
248  void assign_mod_to(L&& lhs) const {
249  std_mod_evaluate(*this, std::forward<L>(lhs));
250  }
251 
252  // Internals
253 
258  void visit(detail::evaluator_visitor& visitor) const {
259  sub.visit(visitor);
260  }
261 
266  void ensure_cpu_up_to_date() const {
267  // Need to ensure sub value
268  sub.ensure_cpu_up_to_date();
269  }
270 
275  void ensure_gpu_up_to_date() const {
276  // Need to ensure both LHS and RHS
277  sub.ensure_gpu_up_to_date();
278  }
279 
286  friend std::ostream& operator<<(std::ostream& os, const fast_matrix_view& v) {
287  return os << "reshape(" << v.sub << ")";
288  }
289 };
290 
296 template <typename T, size_t... Dims>
297 struct fast_matrix_view<T, true, Dims...> final : iterable<fast_matrix_view<T, true, Dims...>, true>,
298  value_testable<fast_matrix_view<T, true, Dims...>>,
299  assignable<fast_matrix_view<T, true, Dims...>, value_t<T>> {
300  using this_type = fast_matrix_view<T, true, Dims...>;
301  using sub_type = T;
309 
313  template <typename V = default_vec>
314  using vec_type = typename V::template vec_type<value_type>;
315 
316  using assignable_base_type::operator=;
319 
320 private:
321  sub_type sub;
322 
323  mutable memory_type memory;
324 
325  static constexpr size_t n_dimensions = sizeof...(Dims);
326 
327  friend struct etl_traits<fast_matrix_view>;
328 
329 public:
334  explicit fast_matrix_view(sub_type sub) : sub(sub) {
335  // Accessing the memory through fast sub views means evaluation
336  if constexpr (decay_traits<sub_type>::is_temporary) {
337  standard_evaluator::pre_assign_rhs(*this);
338  }
339 
340  this->memory = this->sub.memory_start();
341 
342  cpp_assert(this->memory, "Invalid memory");
343  }
344 
350  const_return_type operator[](size_t j) const {
351  cpp_assert(memory, "Memory has not been initialized");
353  return memory[j];
354  }
355 
362  cpp_assert(memory, "Memory has not been initialized");
364  invalidate_gpu();
365  return memory[j];
366  }
367 
374  value_type read_flat(size_t j) const noexcept(assert_nothrow) {
375  cpp_assert(memory, "Memory has not been initialized");
377  return memory[j];
378  }
379 
385  template <size_c... S>
386  return_type operator()(S... args) noexcept(assert_nothrow) requires(sizeof...(S) == sizeof...(Dims)) {
387  cpp_assert(memory, "Memory has not been initialized");
389  invalidate_gpu();
390  return memory[etl::fast_index<this_type>(static_cast<size_t>(args)...)];
391  }
392 
398  template <size_c... S>
399  const_return_type operator()(S... args) const noexcept(assert_nothrow) requires(sizeof...(S) == sizeof...(Dims)) {
400  cpp_assert(memory, "Memory has not been initialized");
402  return memory[etl::fast_index<this_type>(static_cast<size_t>(args)...)];
403  }
404 
410  auto operator()(size_t i) noexcept requires sub_capable<this_type> {
411  return etl::sub(*this, i);
412  }
413 
419  auto operator()(size_t i) const noexcept requires sub_capable<this_type> {
420  return etl::sub(*this, i);
421  }
422 
429  template <typename V = default_vec>
430  auto load(size_t x) const noexcept {
431  return V::loadu(memory + x);
432  }
433 
440  template <typename V = default_vec>
441  auto loadu(size_t x) const noexcept {
442  return V::loadu(memory + x);
443  }
444 
451  template <typename V = default_vec>
452  void stream(vec_type<V> in, size_t i) noexcept {
453  return V::stream(memory + i, in);
454  }
455 
462  template <typename V = default_vec>
463  void store(vec_type<V> in, size_t i) noexcept {
464  sub.template store<V>(in, i);
465  }
466 
473  template <typename V = default_vec>
474  void storeu(vec_type<V> in, size_t i) noexcept {
475  return V::storeu(memory + i, in);
476  }
477 
483  template <typename E>
484  bool alias(const E& rhs) const noexcept {
485  return sub.alias(rhs);
486  }
487 
492  memory_type memory_start() noexcept {
493  return sub.memory_start();
494  }
495 
500  const_memory_type memory_start() const noexcept {
501  return sub.memory_start();
502  }
503 
508  memory_type memory_end() noexcept {
509  return sub.memory_end();
510  }
511 
516  const_memory_type memory_end() const noexcept {
517  return sub.memory_end();
518  }
519 
520  // Assignment functions
521 
526  template <typename L>
527  void assign_to(L&& lhs) const {
528  std_assign_evaluate(*this, std::forward<L>(lhs));
529  }
530 
535  template <typename L>
536  void assign_add_to(L&& lhs) const {
537  std_add_evaluate(*this, std::forward<L>(lhs));
538  }
539 
544  template <typename L>
545  void assign_sub_to(L&& lhs) const {
546  std_sub_evaluate(*this, std::forward<L>(lhs));
547  }
548 
553  template <typename L>
554  void assign_mul_to(L&& lhs) const {
555  std_mul_evaluate(*this, std::forward<L>(lhs));
556  }
557 
562  template <typename L>
563  void assign_div_to(L&& lhs) const {
564  std_div_evaluate(*this, std::forward<L>(lhs));
565  }
566 
571  template <typename L>
572  void assign_mod_to(L&& lhs) const {
573  std_mod_evaluate(*this, std::forward<L>(lhs));
574  }
575 
576  // Internals
577 
582  void visit(detail::evaluator_visitor& visitor) const {
583  sub.visit(visitor);
584  }
585 
590  value_type* gpu_memory() const noexcept {
591  return sub.gpu_memory();
592  }
593 
597  void gpu_evict() const noexcept {
598  sub.gpu_evict();
599  }
600 
604  void invalidate_cpu() const noexcept {
605  sub.invalidate_cpu();
606  }
607 
611  void invalidate_gpu() const noexcept {
612  sub.invalidate_gpu();
613  }
614 
618  void validate_cpu() const noexcept {
619  sub.validate_cpu();
620  }
621 
625  void validate_gpu() const noexcept {
626  sub.validate_gpu();
627  }
628 
633  void ensure_gpu_allocated() const {
634  sub.ensure_gpu_allocated();
635  }
636 
640  void ensure_gpu_up_to_date() const {
641  sub.ensure_gpu_up_to_date();
642  }
643 
648  void ensure_cpu_up_to_date() const {
649  sub.ensure_cpu_up_to_date();
650  }
651 
656  void gpu_copy_from(const value_type* gpu_memory) const {
657  sub.gpu_copy_from(gpu_memory);
658  }
659 
664  bool is_cpu_up_to_date() const noexcept {
665  return sub.is_cpu_up_to_date();
666  }
667 
672  bool is_gpu_up_to_date() const noexcept {
673  return sub.is_gpu_up_to_date();
674  }
675 
682  friend std::ostream& operator<<(std::ostream& os, const fast_matrix_view& v) {
683  return os << "reshape(" << v.sub << ")";
684  }
685 };
686 
690 template <typename T, bool DMA, size_t... Dims>
691 struct etl_traits<etl::fast_matrix_view<T, DMA, Dims...>> {
692  using expr_t = etl::fast_matrix_view<T, DMA, Dims...>;
693  using sub_expr_t = std::decay_t<T>;
696 
697  static constexpr bool is_etl = true;
698  static constexpr bool is_transformer = false;
699  static constexpr bool is_view = true;
700  static constexpr bool is_magic_view = false;
701  static constexpr bool is_linear = sub_traits::is_linear;
702  static constexpr bool is_thread_safe = sub_traits::is_thread_safe;
703  static constexpr bool is_fast = true;
704  static constexpr bool is_value = false;
705  static constexpr bool is_direct = sub_traits::is_direct;
706  static constexpr bool is_generator = false;
707  static constexpr bool is_padded = false;
708  static constexpr bool is_aligned = false;
709  static constexpr bool is_temporary = sub_traits::is_temporary;
710  static constexpr bool gpu_computable = false;
711  static constexpr order storage_order = sub_traits::storage_order;
712 
718  template <vector_mode_t V>
719  static constexpr bool vectorizable = sub_traits::template vectorizable<V>;
720 
726  static constexpr size_t size([[maybe_unused]] const expr_t& v) {
727  return (Dims * ...);
728  }
729 
736  static size_t dim([[maybe_unused]] const expr_t& v, size_t d) {
737  return dyn_nth_size<Dims...>(d);
738  }
739 
744  static constexpr size_t size() {
745  return (Dims * ...);
746  }
747 
753  template <size_t D>
754  static constexpr size_t dim() {
755  return nth_size<D, 0, Dims...>();
756  }
757 
762  static constexpr size_t dimensions() {
763  return sizeof...(Dims);
764  }
765 
770  static constexpr int complexity() noexcept {
771  return -1;
772  }
773 };
774 
775 } //end of namespace etl
static constexpr size_t size([[maybe_unused]] const expr_t &v)
Returns the size of the given expression.
Definition: fast_matrix_view.hpp:726
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 size()
Returns the size of an expression of this fast type.
Definition: fast_matrix_view.hpp:744
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
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 assign_div_to(L &&lhs) const
Divide the given left-hand-side expression.
Definition: dyn_matrix_view.hpp:244
const_memory_t< sub_type > const_memory_type
The const memory access type.
Definition: fast_matrix_view.hpp:37
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
static size_t dim([[maybe_unused]] const expr_t &v, size_t d)
Returns the dth dimension of the given expression.
Definition: fast_matrix_view.hpp:736
constexpr bool is_magic_view
Traits indicating if the given ETL type is a magic view expression.
Definition: traits.hpp:311
memory_t< sub_type > memory_type
The memory acess type.
Definition: fast_matrix_view.hpp:36
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.
View to represent a fast matrix in top of an expression.
Definition: fast_matrix_view.hpp:297
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
memory_t< sub_type > memory_type
The memory acess type.
Definition: fast_matrix_view.hpp:305
static constexpr size_t dim()
Returns the Dth dimension of an expression of this type.
Definition: fast_matrix_view.hpp:754
Definition: expr_fwd.hpp:77
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
std::decay_t< T > sub_expr_t
The sub expression type.
Definition: fast_matrix_view.hpp:693
value_type read_flat(size_t j) const noexcept(assert_nothrow)
Returns the value at the given index This function never has side effects.
Definition: fast_matrix_view.hpp:374
const_return_helper< sub_type, decltype(std::declval< sub_type >()[0])> const_return_type
The const type return by the view.
Definition: fast_matrix_view.hpp:39
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
typename sub_traits::value_type value_type
The value type.
Definition: fast_matrix_view.hpp:695
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
fast_matrix_view(sub_type sub)
Construct a new fast_matrix_view over the given sub expression.
Definition: fast_matrix_view.hpp:63
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
typename V::template vec_type< value_type > vec_type
The vectorization type for V.
Definition: fast_matrix_view.hpp:314
Root namespace for the ETL library.
Definition: adapter.hpp:15
static constexpr size_t dimensions()
Returns the number of expressions for this type.
Definition: fast_matrix_view.hpp:762
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
const_return_type operator[](size_t j) const
Returns the element at the given index.
Definition: fast_matrix_view.hpp:350
void invalidate_gpu() const noexcept
Invalidates the GPU memory.
Definition: sub_view.hpp:695
return_type operator[](size_t j)
Returns the element at the given index.
Definition: fast_matrix_view.hpp:361
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
const_memory_t< sub_type > const_memory_type
The const memory access type.
Definition: fast_matrix_view.hpp:306
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
value_type read_flat(size_t j) const noexcept
Returns the value at the given index This function never has side effects.
Definition: fast_matrix_view.hpp:89
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
return_type operator[](size_t j)
Returns the element at the given index.
Definition: fast_matrix_view.hpp:79
Visitor to perform local evaluation when necessary.
Definition: eval_visitors.hpp:23
const_return_helper< sub_type, decltype(std::declval< sub_type >()[0])> const_return_type
The const type return by the view.
Definition: fast_matrix_view.hpp:308
void invalidate_cpu() const noexcept
Invalidates the CPU memory.
Definition: sub_view.hpp:688
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
const_return_type operator[](size_t j) const
Returns the element at the given index.
Definition: fast_matrix_view.hpp:70
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
T sub_type
The sub type.
Definition: fast_matrix_view.hpp:301
return_helper< sub_type, decltype(std::declval< sub_type >()[0])> return_type
The type returned by the view.
Definition: fast_matrix_view.hpp:307
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
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
T sub_type
The sub type.
Definition: fast_matrix_view.hpp:31
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
return_helper< sub_type, decltype(std::declval< sub_type >()[0])> return_type
The type returned by the view.
Definition: fast_matrix_view.hpp:38
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
static constexpr int complexity() noexcept
Estimate the complexity of computation.
Definition: fast_matrix_view.hpp:770
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
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
fast_matrix_view(sub_type sub)
Construct a new fast_matrix_view over the given sub expression.
Definition: fast_matrix_view.hpp:334
constexpr bool is_thread_safe
Traits to test if the given ETL expresion type is thread safe.
Definition: traits.hpp:687
typename V::template vec_type< value_type > vec_type
The vectorization type for V.
Definition: fast_matrix_view.hpp:45
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
value_t< sub_type > value_type
The value contained in the expression.
Definition: fast_matrix_view.hpp:302
void std_add_evaluate(Expr &&expr, Result &&result)
Compound add evaluation of the expr into result.
Definition: evaluator.hpp:1195
value_t< sub_type > value_type
The value contained in the expression.
Definition: fast_matrix_view.hpp:33
void assign_sub_to(L &&lhs) const
Sub from the given left-hand-side expression.
Definition: dyn_matrix_view.hpp:226