Expression Templates Library (ETL)
sub_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 #ifdef ETL_CUDA
16 #include "etl/impl/cublas/cuda.hpp"
17 #endif
18 
19 namespace etl {
20 
25 template <matrix T, bool Aligned>
26 requires(!fast_sub_view_able<T>)
27 struct sub_view<T, Aligned> final : iterable<sub_view<T, Aligned>, false>,
28  assignable<sub_view<T, Aligned>, value_t<T>>,
29  value_testable<sub_view<T, Aligned>>,
30  inplace_assignable<sub_view<T, Aligned>> {
34  using sub_type = T;
42 
46  template <typename V = default_vec>
47  using vec_type = typename V::template vec_type<value_type>;
48 
49  using assignable_base_type::operator=;
52 
53 private:
54  sub_type sub_expr;
55  const size_t i;
56  const size_t sub_offset;
57 
58  friend struct etl_traits<sub_view>;
59 
60  static constexpr order storage_order = decay_traits<sub_type>::storage_order;
61 
62 public:
68  sub_view(sub_type sub_expr, size_t i) : sub_expr(sub_expr), i(i), sub_offset(i * subsize(sub_expr)) {}
69 
75  const_return_type operator[](size_t j) const {
76  return storage_order == order::RowMajor ? sub_expr[sub_offset + j] : sub_expr[i + dim<0>(sub_expr) * j];
77  }
78 
84  return_type operator[](size_t j) {
85  return storage_order == order::RowMajor ? sub_expr[sub_offset + j] : sub_expr[i + dim<0>(sub_expr) * j];
86  }
87 
94  value_type read_flat(size_t j) const noexcept {
95  return storage_order == order::RowMajor ? sub_expr.read_flat(sub_offset + j) : sub_expr.read_flat(i + dim<0>(sub_expr) * j);
96  }
97 
103  template <typename... S>
104  ETL_STRONG_INLINE(const_return_type)
105  operator()(S... args) const requires(sizeof...(S) + 1 == decay_traits<sub_type>::dimensions()) {
106  return sub_expr(i, static_cast<size_t>(args)...);
107  }
108 
114  template <typename... S>
115  ETL_STRONG_INLINE(return_type)
116  operator()(S... args) requires(sizeof...(S) + 1 == decay_traits<sub_type>::dimensions()) {
117  return sub_expr(i, static_cast<size_t>(args)...);
118  }
119 
125  auto operator()(size_t x) const requires(decay_traits<sub_type>::dimensions() > 2) {
126  return sub(*this, x);
127  }
128 
135  template <typename V = default_vec>
136  void store(vec_type<V> in, size_t x) noexcept {
137  return sub_expr.template storeu<V>(in, x + sub_offset);
138  }
139 
146  template <typename V = default_vec>
147  void storeu(vec_type<V> in, size_t x) noexcept {
148  return sub_expr.template storeu<V>(in, x + sub_offset);
149  }
150 
157  template <typename V = default_vec>
158  void stream(vec_type<V> in, size_t x) noexcept {
159  return sub_expr.template storeu<V>(in, x + sub_offset);
160  }
161 
168  template <typename V = default_vec>
169  ETL_STRONG_INLINE(vec_type<V>)
170  load(size_t x) const noexcept {
171  return sub_expr.template loadu<V>(x + sub_offset);
172  }
173 
180  template <typename V = default_vec>
181  ETL_STRONG_INLINE(vec_type<V>)
182  loadu(size_t x) const noexcept {
183  return sub_expr.template loadu<V>(x + sub_offset);
184  }
185 
191  template <typename E>
192  bool alias(const E& rhs) const noexcept {
193  return sub_expr.alias(rhs);
194  }
195 
203  size_t& unsafe_dimension_access(size_t x) {
204  return sub_expr.unsafe_dimension_access(x + 1);
205  }
206 
207  // Assignment functions
208 
213  template <typename L>
214  void assign_to(L&& lhs) const {
215  std_assign_evaluate(*this, std::forward<L>(lhs));
216  }
217 
222  template <typename L>
223  void assign_add_to(L&& lhs) const {
224  std_add_evaluate(*this, std::forward<L>(lhs));
225  }
226 
231  template <typename L>
232  void assign_sub_to(L&& lhs) const {
233  std_sub_evaluate(*this, std::forward<L>(lhs));
234  }
235 
240  template <typename L>
241  void assign_mul_to(L&& lhs) const {
242  std_mul_evaluate(*this, std::forward<L>(lhs));
243  }
244 
249  template <typename L>
250  void assign_div_to(L&& lhs) const {
251  std_div_evaluate(*this, std::forward<L>(lhs));
252  }
253 
258  template <typename L>
259  void assign_mod_to(L&& lhs) const {
260  std_mod_evaluate(*this, std::forward<L>(lhs));
261  }
262 
263  // Internals
264 
269  void visit(detail::evaluator_visitor& visitor) const {
270  sub_expr.visit(visitor);
271  }
272 
277  void ensure_cpu_up_to_date() const {
278  // The sub value must be ensured
279  sub_expr.ensure_cpu_up_to_date();
280  }
281 
286  void ensure_gpu_up_to_date() const {
287  // The sub value must be ensured
288  sub_expr.ensure_gpu_up_to_date();
289  }
290 
297  friend std::ostream& operator<<(std::ostream& os, const sub_view& v) {
298  return os << "sub(" << v.sub_expr << ", " << v.i << ")";
299  }
300 };
301 
306 template <matrix T, bool Aligned>
307 requires(fast_sub_view_able<T>)
308 struct sub_view<T, Aligned> : iterable<sub_view<T, Aligned>, true>,
309  assignable<sub_view<T, Aligned>, value_t<T>>,
310  value_testable<sub_view<T, Aligned>>,
311  inplace_assignable<sub_view<T, Aligned>> {
312  static_assert(decay_traits<T>::storage_order == order::RowMajor, "sub_view<T, true> should only be done with RowMajor");
313 
317  using sub_type = T;
318  using value_type = value_t<sub_type>;
323  using iterator = value_type*;
324  using const_iterator = const value_type*;
325 
329  template <typename V = default_vec>
330  using vec_type = typename V::template vec_type<value_type>;
331 
334  using assignable_base_type::operator=;
335 
336 private:
337  T sub_expr;
338  const size_t i;
339  const size_t sub_size;
340 
341  static constexpr size_t n_dimensions = decay_traits<sub_type>::dimensions() - 1;
342  static constexpr order storage_order = decay_traits<sub_type>::storage_order;
343 
344  mutable memory_type memory;
345 
346  mutable bool cpu_up_to_date;
347  mutable bool gpu_up_to_date;
348 
349  friend struct etl_traits<sub_view>;
350 
351 public:
357  sub_view(sub_type sub_expr, size_t i) : sub_expr(sub_expr), i(i), sub_size(subsize(sub_expr)) {
358  // Accessing the memory through fast sub views means evaluation
359  if constexpr (decay_traits<sub_type>::is_temporary) {
360  standard_evaluator::pre_assign_rhs(*this);
361  }
362 
363  this->memory = this->sub_expr.memory_start() + i * sub_size;
364 
365  // A sub view inherits the CPU/GPU from parent
366  this->cpu_up_to_date = this->sub_expr.is_cpu_up_to_date();
367  this->gpu_up_to_date = this->sub_expr.is_gpu_up_to_date();
368 
369  cpp_assert(this->memory, "Invalid memory");
370  }
371 
372  ~sub_view() {
373  if (this->memory) {
374  // Propagate the status on the parent
375  if (!this->cpu_up_to_date) {
376  if (sub_expr.is_gpu_up_to_date()) {
377  sub_expr.invalidate_cpu();
378  } else {
379  // If the GPU is not up to date, cannot invalidate the CPU too
381  }
382  }
383 
384  if (!this->gpu_up_to_date) {
385  if (sub_expr.is_cpu_up_to_date()) {
386  sub_expr.invalidate_gpu();
387  } else {
388  // If the GPU is not up to date, cannot invalidate the CPU too
390  }
391  }
392  }
393  }
394 
400  const_return_type operator[](size_t j) const {
402  return memory[j];
403  }
404 
410  return_type operator[](size_t j) {
412  invalidate_gpu();
413  return memory[j];
414  }
415 
422  value_type read_flat(size_t j) const noexcept {
424  return memory[j];
425  }
426 
432  template <typename... S>
433  ETL_STRONG_INLINE(const_return_type)
434  operator()(S... args) const requires (sizeof...(S) == n_dimensions) {
436  return memory[dyn_index(*this, args...)];
437  }
438 
444  template <typename... S>
445  ETL_STRONG_INLINE(return_type)
446  operator()(S... args) requires (sizeof...(S) == n_dimensions) {
448  return memory[dyn_index(*this, args...)];
449  }
450 
456  auto operator()(size_t x) const requires(n_dimensions > 1) {
457  return sub(*this, x);
458  }
459 
466  template <typename V = default_vec>
467  void store(vec_type<V> in, size_t x) noexcept {
468  return V::storeu(memory + x, in);
469  }
470 
477  template <typename V = default_vec>
478  void storeu(vec_type<V> in, size_t x) noexcept {
479  return V::storeu(memory + x, in);
480  }
481 
488  template <typename V = default_vec>
489  void stream(vec_type<V> in, size_t x) noexcept {
490  //TODO If the sub view is aligned (at compile-time), use stream store here
491  return V::storeu(memory + x, in);
492  }
493 
500  template <typename V = default_vec>
501  vec_type<V> load(size_t x) const noexcept {
502  return V::loadu(memory + x);
503  }
504 
511  template <typename V = default_vec>
512  vec_type<V> loadu(size_t x) const noexcept {
513  return V::loadu(memory + x);
514  }
515 
521  template <typename E>
522  bool alias(const E& rhs) const noexcept {
523  if constexpr (is_dma<E>) {
524  return memory_alias(memory_start(), memory_end(), rhs.memory_start(), rhs.memory_end());
525  } else {
526  return sub_expr.alias(rhs);
527  }
528  }
529 
534  ETL_STRONG_INLINE(memory_type) memory_start() noexcept {
535  return memory;
536  }
537 
542  ETL_STRONG_INLINE(const_memory_type) memory_start() const noexcept {
543  return memory;
544  }
545 
550  ETL_STRONG_INLINE(memory_type) memory_end() noexcept {
551  return memory + sub_size;
552  }
553 
558  ETL_STRONG_INLINE(const_memory_type) memory_end() const noexcept {
559  return memory + sub_size;
560  }
561 
569  size_t& unsafe_dimension_access(size_t x) {
570  return sub_expr.unsafe_dimension_access(x + 1);
571  }
572 
577  template <size_t... I>
578  std::array<size_t, decay_traits<this_type>::dimensions()> dim_array(std::index_sequence<I...>) const {
579  return {{decay_traits<this_type>::dim(*this, I)...}};
580  }
581 
582  // Assignment functions
583 
588  template <typename L>
589  void assign_to(L&& lhs) const {
590  std_assign_evaluate(*this, std::forward<L>(lhs));
591  }
592 
597  template <typename L>
598  void assign_add_to(L&& lhs) const {
599  std_add_evaluate(*this, std::forward<L>(lhs));
600  }
601 
606  template <typename L>
607  void assign_sub_to(L&& lhs) const {
608  std_sub_evaluate(*this, std::forward<L>(lhs));
609  }
610 
615  template <typename L>
616  void assign_mul_to(L&& lhs) const {
617  std_mul_evaluate(*this, std::forward<L>(lhs));
618  }
619 
624  template <typename L>
625  void assign_div_to(L&& lhs) const {
626  std_div_evaluate(*this, std::forward<L>(lhs));
627  }
628 
633  template <typename L>
634  void assign_mod_to(L&& lhs) const {
635  std_mod_evaluate(*this, std::forward<L>(lhs));
636  }
637 
642  template <typename Y>
643  auto& gpu_compute_hint([[maybe_unused]] Y& y) {
644  this->ensure_gpu_up_to_date();
645  return *this;
646  }
647 
652  template <typename Y>
653  const auto& gpu_compute_hint([[maybe_unused]] Y& y) const {
654  this->ensure_gpu_up_to_date();
655  return *this;
656  }
657 
658  // Internals
659 
664  void visit(detail::evaluator_visitor& visitor) const {
665  sub_expr.visit(visitor);
666  }
667 
668  // GPU functions
669 
674  value_type* gpu_memory() const noexcept {
675  return sub_expr.gpu_memory() + i * sub_size;
676  }
677 
681  void gpu_evict() const noexcept {
682  sub_expr.gpu_evict();
683  }
684 
688  void invalidate_cpu() const noexcept {
689  this->cpu_up_to_date = false;
690  }
691 
695  void invalidate_gpu() const noexcept {
696  this->gpu_up_to_date = false;
697  }
698 
702  void validate_cpu() const noexcept {
703  this->cpu_up_to_date = true;
704  }
705 
709  void validate_gpu() const noexcept {
710  this->gpu_up_to_date = true;
711  }
712 
717  void ensure_gpu_allocated() const {
718  // Allocate is done by the sub
719  sub_expr.ensure_gpu_allocated();
720  }
721 
725  void ensure_gpu_up_to_date() const {
726  sub_expr.ensure_gpu_allocated();
727 
728 #ifdef ETL_CUDA
729  if (!this->gpu_up_to_date) {
730  cuda_check_assert(cudaMemcpy(const_cast<std::remove_const_t<value_type>*>(gpu_memory()),
731  const_cast<std::remove_const_t<value_type>*>(memory_start()), sub_size * sizeof(value_type), cudaMemcpyHostToDevice));
732 
733  this->gpu_up_to_date = true;
734 
735  inc_counter("gpu:sub:cpu_to_gpu");
736  }
737 #endif
738  }
739 
744  void ensure_cpu_up_to_date() const {
745 #ifdef ETL_CUDA
746  if (!this->cpu_up_to_date) {
747  cuda_check_assert(cudaMemcpy(const_cast<std::remove_const_t<value_type>*>(memory_start()),
748  const_cast<std::remove_const_t<value_type>*>(gpu_memory()), sub_size * sizeof(value_type), cudaMemcpyDeviceToHost));
749 
750  inc_counter("gpu:sub:gpu_to_cpu");
751  }
752 #endif
753 
754  this->cpu_up_to_date = true;
755  }
756 
761  void gpu_copy_from([[maybe_unused]] const value_type* new_gpu_memory) const {
762  cpp_assert(sub_expr.gpu_memory(), "GPU must be allocated before copy");
763 
764 #ifdef ETL_CUDA
765  cuda_check_assert(cudaMemcpy(const_cast<std::remove_const_t<value_type>*>(gpu_memory()), const_cast<std::remove_const_t<value_type>*>(new_gpu_memory),
766  sub_size * sizeof(value_type), cudaMemcpyDeviceToDevice));
767 #endif
768 
769  gpu_up_to_date = true;
770  cpu_up_to_date = false;
771  }
772 
777  bool is_cpu_up_to_date() const noexcept {
778  return cpu_up_to_date;
779  }
780 
785  bool is_gpu_up_to_date() const noexcept {
786  return gpu_up_to_date;
787  }
788 
795  friend std::ostream& operator<<(std::ostream& os, const sub_view& v) {
796  return os << "sub(" << v.sub_expr << ", " << v.i << ")";
797  }
798 };
799 
803 template <typename T, bool Aligned>
804 struct etl_traits<etl::sub_view<T, Aligned>> {
806  using sub_expr_t = std::decay_t<T>;
809 
810  static constexpr bool is_etl = true;
811  static constexpr bool is_transformer = false;
812  static constexpr bool is_view = true;
813  static constexpr bool is_magic_view = false;
814  static constexpr bool is_fast = sub_traits::is_fast;
815  static constexpr bool is_linear = sub_traits::is_linear;
816  static constexpr bool is_thread_safe = sub_traits::is_thread_safe;
817  static constexpr bool is_value = false;
818  static constexpr bool is_direct =
819  sub_traits::is_direct && sub_traits::storage_order == order::RowMajor;
820  static constexpr bool is_generator = false;
821  static constexpr bool is_padded = false;
822  static constexpr bool is_aligned = false;
823  static constexpr bool is_temporary = sub_traits::is_temporary;
824  static constexpr bool gpu_computable = fast_sub_view_able<T>;
825  static constexpr order storage_order = sub_traits::storage_order;
826 
832  template <vector_mode_t V>
833  static constexpr bool vectorizable = sub_traits::template vectorizable<V>&& storage_order == order::RowMajor;
834 
840  static size_t size(const expr_t& v) noexcept {
841  return sub_traits::size(v.sub_expr) / sub_traits::dim(v.sub_expr, 0);
842  }
843 
850  static size_t dim(const expr_t& v, size_t d) noexcept {
851  return sub_traits::dim(v.sub_expr, d + 1);
852  }
853 
858  static constexpr size_t size() noexcept {
859  return sub_traits::size() / sub_traits::template dim<0>();
860  }
861 
867  template <size_t D>
868  static constexpr size_t dim() noexcept {
869  return sub_traits::template dim<D + 1>();
870  }
871 
876  static constexpr size_t dimensions() noexcept {
877  return sub_traits::dimensions() - 1;
878  }
879 
884  static constexpr int complexity() noexcept {
885  return -1;
886  }
887 };
888 
889 } //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
typename sub_traits::value_type value_type
The value type of the expression.
Definition: sub_view.hpp:808
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
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
static size_t dim(const expr_t &v, size_t d) noexcept
Returns the dth dimension of the given expression.
Definition: sub_view.hpp:850
std::decay_t< T > sub_expr_t
The sub expression type.
Definition: sub_view.hpp:806
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
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
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
static constexpr size_t dimensions() noexcept
Returns the number of expressions for this type.
Definition: sub_view.hpp:876
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
static constexpr size_t dimensions()
Return the number of dimensions of the expression.
Definition: traits_base.hpp:31
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
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
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
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
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
const_return_type operator()(size_t j) const
Access to the element at the given position.
Definition: dyn_matrix_view.hpp:89
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
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
sub_view(sub_type sub_expr, size_t i)
Construct a new sub_view over the given sub expression.
Definition: sub_view.hpp:68
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
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
static size_t size(const expr_t &v) noexcept
Returns the size of the given expression.
Definition: sub_view.hpp:840
void assign_mod_to(L &&lhs) const
Modulo the given left-hand-side expression.
Definition: dyn_matrix_view.hpp:253
static constexpr int complexity() noexcept
Estimate the complexity of computation.
Definition: sub_view.hpp:884
const_return_type operator[](size_t j) const
Returns the element at the given index.
Definition: dyn_matrix_view.hpp:71
constexpr bool is_thread_safe
Traits to test if the given ETL expresion type is thread safe.
Definition: traits.hpp:687
static constexpr size_t dim() noexcept
Returns the Dth dimension of an expression of this type.
Definition: sub_view.hpp:868
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
Row-Major storage.
void inc_counter([[maybe_unused]] const char *name)
Increase the given counter.
Definition: counters.hpp:25
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
size_t subsize(const E &expr)
Returns the sub-size of the given ETL expression, i.e. the size not considering the first dimension...
Definition: helpers.hpp:118
void std_add_evaluate(Expr &&expr, Result &&result)
Compound add evaluation of the expr into result.
Definition: evaluator.hpp:1195
static constexpr size_t size() noexcept
Returns the size of an expression of this fast type.
Definition: sub_view.hpp:858
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