Expression Templates Library (ETL)
sub_matrix_4d.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 <etl_expr T, bool Aligned>
26 struct sub_matrix_4d final : iterable<sub_matrix_4d<T, Aligned>, false>,
27  assignable<sub_matrix_4d<T, Aligned>, value_t<T>>,
28  value_testable<sub_matrix_4d<T, Aligned>>,
29  inplace_assignable<sub_matrix_4d<T, Aligned>> {
33  using sub_type = T;
41 
45  template <typename V = default_vec>
46  using vec_type = typename V::template vec_type<value_type>;
47 
48  using assignable_base_type::operator=;
51 
52 private:
53  sub_type sub_expr;
54  const size_t base_i;
55  const size_t base_j;
56  const size_t base_k;
57  const size_t base_l;
58  const size_t m;
59  const size_t n;
60  const size_t o;
61  const size_t p;
62 
63  friend struct etl_traits<sub_matrix_4d>;
64 
65  static constexpr order storage_order = decay_traits<sub_type>::storage_order;
66 
67 public:
73  sub_matrix_4d(sub_type sub_expr, size_t i, size_t j, size_t k, size_t l, size_t m, size_t n, size_t o, size_t p)
74  : sub_expr(sub_expr), base_i(i), base_j(j), base_k(k), base_l(l), m(m), n(n), o(o), p(p) {}
75 
81  const_return_type operator[](size_t f) const {
82  cpp_assert(f < m * n * o * p, "Invalid index inside sub_matrix_4d");
83 
84  if constexpr (storage_order == order::RowMajor) {
85  // Extract 4D indices from flat inside the view
86  auto my_i = f / (n * o * p);
87  auto t1 = f % (n * o * p);
88  auto my_j = t1 / (o * p);
89  auto t2 = t1 % (o * p);
90  auto my_k = t2 / p;
91  auto my_l = t2 % p;
92 
93  // Let the sub view compute the index
94  return sub_expr(base_i + my_i, base_j + my_j, base_k + my_k, base_l + my_l);
95  } else {
96  // Extract 4D indices from flat inside the view
97  auto my_l = f / (m * n * o);
98  auto t1 = f % (m * n * o);
99  auto my_k = t1 / (m * n);
100  auto t2 = t1 % (m * n);
101  auto my_j = t2 / m;
102  auto my_i = t2 % m;
103 
104  // Let the sub view compute the index
105  return sub_expr(base_i + my_i, base_j + my_j, base_k + my_k, base_l + my_l);
106  }
107  }
108 
115  cpp_assert(f < m * n * o * p, "Invalid index inside sub_matrix_4d");
116 
117  if constexpr (storage_order == order::RowMajor) {
118  // Extract 4D indices from flat inside the view
119  auto my_i = f / (n * o * p);
120  auto t1 = f % (n * o * p);
121  auto my_j = t1 / (o * p);
122  auto t2 = t1 % (o * p);
123  auto my_k = t2 / p;
124  auto my_l = t2 % p;
125 
126  // Let the sub view compute the index
127  return sub_expr(base_i + my_i, base_j + my_j, base_k + my_k, base_l + my_l);
128  } else {
129  // Extract 4D indices from flat inside the view
130  auto my_l = f / (m * n * o);
131  auto t1 = f % (m * n * o);
132  auto my_k = t1 / (m * n);
133  auto t2 = t1 % (m * n);
134  auto my_j = t2 / m;
135  auto my_i = t2 % m;
136 
137  // Let the sub view compute the index
138  return sub_expr(base_i + my_i, base_j + my_j, base_k + my_k, base_l + my_l);
139  }
140  }
141 
148  value_type read_flat(size_t f) const noexcept(assert_nothrow) {
149  cpp_assert(f < m * n * o * p, "Invalid index inside sub_matrix_4d");
150 
151  if constexpr (storage_order == order::RowMajor) {
152  // Extract 4D indices from flat inside the view
153  auto my_i = f / (n * o * p);
154  auto t1 = f % (n * o * p);
155  auto my_j = t1 / (o * p);
156  auto t2 = t1 % (o * p);
157  auto my_k = t2 / p;
158  auto my_l = t2 % p;
159 
160  // Let the sub view compute the index
161  return sub_expr(base_i + my_i, base_j + my_j, base_k + my_k, base_l + my_l);
162  } else {
163  // Extract 4D indices from flat inside the view
164  auto my_l = f / (m * n * o);
165  auto t1 = f % (m * n * o);
166  auto my_k = t1 / (m * n);
167  auto t2 = t1 % (m * n);
168  auto my_j = t2 / m;
169  auto my_i = t2 % m;
170 
171  // Let the sub view compute the index
172  return sub_expr(base_i + my_i, base_j + my_j, base_k + my_k, base_l + my_l);
173  }
174  }
175 
182  ETL_STRONG_INLINE(const_return_type) operator()(size_t i, size_t j, size_t k, size_t l) const {
183  cpp_assert(i < m, "Invalid 4d index inside sub_matrix_4d");
184  cpp_assert(j < n, "Invalid 4d index inside sub_matrix_4d");
185  cpp_assert(k < o, "Invalid 4d index inside sub_matrix_4d");
186  cpp_assert(l < p, "Invalid 4d index inside sub_matrix_4d");
187 
188  return sub_expr(base_i + i, base_j + j, base_k + k, base_l + l);
189  }
190 
197  ETL_STRONG_INLINE(return_type) operator()(size_t i, size_t j, size_t k, size_t l) {
198  cpp_assert(i < m, "Invalid 4d index inside sub_matrix_4d");
199  cpp_assert(j < n, "Invalid 4d index inside sub_matrix_4d");
200  cpp_assert(k < o, "Invalid 4d index inside sub_matrix_4d");
201  cpp_assert(l < p, "Invalid 4d index inside sub_matrix_4d");
202 
203  return sub_expr(base_i + i, base_j + j, base_k + k, base_l + l);
204  }
205 
211  auto operator()(size_t x) const {
212  return sub(*this, x);
213  }
214 
220  template <typename E>
221  bool alias(const E& rhs) const noexcept {
222  return sub_expr.alias(rhs);
223  }
224 
232  size_t& unsafe_dimension_access(size_t x) {
233  return sub_expr.unsafe_dimension_access(x);
234  }
235 
236  // Assignment functions
237 
242  template <typename L>
243  void assign_to(L&& lhs) const {
244  std_assign_evaluate(*this, std::forward<L>(lhs));
245  }
246 
251  template <typename L>
252  void assign_add_to(L&& lhs) const {
253  std_add_evaluate(*this, std::forward<L>(lhs));
254  }
255 
260  template <typename L>
261  void assign_sub_to(L&& lhs) const {
262  std_sub_evaluate(*this, std::forward<L>(lhs));
263  }
264 
269  template <typename L>
270  void assign_mul_to(L&& lhs) const {
271  std_mul_evaluate(*this, std::forward<L>(lhs));
272  }
273 
278  template <typename L>
279  void assign_div_to(L&& lhs) const {
280  std_div_evaluate(*this, std::forward<L>(lhs));
281  }
282 
287  template <typename L>
288  void assign_mod_to(L&& lhs) const {
289  std_mod_evaluate(*this, std::forward<L>(lhs));
290  }
291 
292  // Internals
293 
298  void ensure_cpu_up_to_date() const {
299  // The sub value must be ensured
300  sub_expr.ensure_cpu_up_to_date();
301  }
302 
307  void ensure_gpu_up_to_date() const {
308  // The sub value must be ensured
309  sub_expr.ensure_gpu_up_to_date();
310  }
311 
316  void visit(detail::evaluator_visitor& visitor) const {
317  sub_expr.visit(visitor);
318  }
319 
326  friend std::ostream& operator<<(std::ostream& os, const sub_matrix_4d& v) {
327  return os << "sub(" << v.sub_expr << ", " << v.base_i << ", " << v.base_j << ", " << v.base_k << ", " << v.base_l << ", " << v.m << ", " << v.n << ", "
328  << v.o << ", " << v.p << ")";
329  }
330 };
331 
335 template <typename T, bool Aligned>
336 struct etl_traits<etl::sub_matrix_4d<T, Aligned>> {
338  using sub_expr_t = std::decay_t<T>;
341 
342  static constexpr bool is_etl = true;
343  static constexpr bool is_transformer = false;
344  static constexpr bool is_view = true;
345  static constexpr bool is_magic_view = false;
346  static constexpr bool is_fast = false;
347  static constexpr bool is_linear = sub_traits::is_linear;
348  static constexpr bool is_thread_safe = sub_traits::is_thread_safe;
349  static constexpr bool is_value = false;
350  static constexpr bool is_direct = false;
351  static constexpr bool is_generator = false;
352  static constexpr bool is_padded = false;
353  static constexpr bool is_aligned = false;
354  static constexpr bool is_temporary = sub_traits::is_temporary;
355  static constexpr bool gpu_computable = false;
356  static constexpr order storage_order = sub_traits::storage_order;
357 
363  template <vector_mode_t V>
364  static constexpr bool vectorizable = false;
365 
371  static size_t size(const expr_t& v) noexcept {
372  return v.m * v.n * v.o * v.p;
373  }
374 
381  static size_t dim(const expr_t& v, size_t d) noexcept {
382  if (d == 0) {
383  return v.m;
384  } else if (d == 1) {
385  return v.n;
386  } else if (d == 2) {
387  return v.o;
388  } else {
389  return v.p;
390  }
391  }
392 
397  static constexpr size_t dimensions() noexcept {
398  return 4;
399  }
400 
405  static constexpr int complexity() noexcept {
406  return -1;
407  }
408 };
409 
410 } //end of namespace etl
CRTP class to inject iterators functions.
Definition: iterable.hpp:23
typename sub_traits::value_type value_type
The value type of the expression.
Definition: sub_matrix_4d.hpp:340
value_t< sub_type > value_type
The value contained in the expression.
Definition: sub_matrix_4d.hpp:34
void assign_sub_to(L &&lhs) const
Sub from the given left-hand-side expression.
Definition: sub_matrix_4d.hpp:261
bool alias(const E &rhs) const noexcept
Test if this expression aliases with the given expression.
Definition: sub_matrix_4d.hpp:221
friend std::ostream & operator<<(std::ostream &os, const sub_matrix_4d &v)
Print a representation of the view on the given stream.
Definition: sub_matrix_4d.hpp:326
void std_assign_evaluate(Expr &&expr, Result &&result)
Evaluation of the expr into result.
Definition: evaluator.hpp:1176
void assign_add_to(L &&lhs) const
Add to the given left-hand-side expression.
Definition: sub_matrix_4d.hpp:252
value_t< sub_type > value_type
The value contained in the expression.
Definition: dyn_matrix_view.hpp:31
constexpr bool is_magic_view
Traits indicating if the given ETL type is a magic view expression.
Definition: traits.hpp:311
auto operator()(size_t x) const
Creates a sub view of the matrix, effectively removing the first dimension and fixing it to the given...
Definition: sub_matrix_4d.hpp:211
static constexpr size_t dimensions() noexcept
Returns the number of expressions for this type.
Definition: sub_matrix_4d.hpp:397
return_type operator[](size_t f)
Returns the element at the given index.
Definition: sub_matrix_4d.hpp:114
order
Storage order of a matrix.
Definition: order.hpp:15
memory_t< sub_type > memory_type
The memory acess type.
Definition: sub_matrix_4d.hpp:35
typename V::template vec_type< value_type > vec_type
The vectorization type for V.
Definition: sub_matrix_4d.hpp:46
void ensure_gpu_up_to_date() const
Copy back from the GPU to the expression memory if necessary.
Definition: sub_matrix_4d.hpp:307
std::conditional_t< std::is_lvalue_reference_v< S >, const value_t< T > &, value_t< T > > const_return_helper
Definition: traits.hpp:872
static constexpr int complexity() noexcept
Estimate the complexity of computation.
Definition: sub_matrix_4d.hpp:405
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
Traits to get information about ETL types.
Definition: tmp.hpp:68
Root namespace for the ETL library.
Definition: adapter.hpp:15
size_t & unsafe_dimension_access(size_t x)
Returns a reference to the ith dimension value.
Definition: sub_matrix_4d.hpp:232
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 f) const
Returns the element at the given index.
Definition: sub_matrix_4d.hpp:81
void assign_div_to(L &&lhs) const
Divide the given left-hand-side expression.
Definition: sub_matrix_4d.hpp:279
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 assign_mod_to(L &&lhs) const
Modulo the given left-hand-side expression.
Definition: sub_matrix_4d.hpp:288
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
std::decay_t< T > sub_expr_t
The sub expression type.
Definition: sub_matrix_4d.hpp:338
Visitor to perform local evaluation when necessary.
Definition: eval_visitors.hpp:23
Configurable iterator for ETL expressions.
Definition: iterator.hpp:24
void visit(detail::evaluator_visitor &visitor) const
Apply the given visitor to this expression and its descendants.
Definition: sub_matrix_4d.hpp:316
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
void assign_mul_to(L &&lhs) const
Multiply the given left-hand-side expression.
Definition: sub_matrix_4d.hpp:270
return_helper< sub_type, decltype(std::declval< sub_type >()[0])> return_type
The type returned by the view.
Definition: sub_matrix_4d.hpp:37
void std_mul_evaluate(Expr &&expr, Result &&result)
Compound multiply evaluation of the expr into result.
Definition: evaluator.hpp:1233
constexpr bool is_transformer
Traits indicating if the given ETL type is a transformer expression.
Definition: traits.hpp:297
const_return_helper< sub_type, decltype(std::declval< sub_type >()[0])> const_return_type
The const type return by the view.
Definition: sub_matrix_4d.hpp:38
constexpr bool is_view
Traits indicating if the given ETL type is a view expression.
Definition: traits.hpp:304
View that shows a 4d sub matrix of an expression.
Definition: expr_fwd.hpp:68
CRTP class to inject assign operations to matrix and vector structures.
Definition: assignable.hpp:25
ETL_STRONG_INLINE(const_return_type) operator()(size_t i
Access to the element at the given (args...) position.
void std_sub_evaluate(Expr &&expr, Result &&result)
Compound subtract evaluation of the expr into result.
Definition: evaluator.hpp:1214
void assign_to(L &&lhs) const
Assign to the given left-hand-side expression.
Definition: sub_matrix_4d.hpp:243
constexpr bool is_thread_safe
Traits to test if the given ETL expresion type is thread safe.
Definition: traits.hpp:687
sub_matrix_4d(sub_type sub_expr, size_t i, size_t j, size_t k, size_t l, size_t m, size_t n, size_t o, size_t p)
Construct a new sub_matrix_4d over the given sub expression.
Definition: sub_matrix_4d.hpp:73
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: sub_matrix_4d.hpp:298
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.
static size_t dim(const expr_t &v, size_t d) noexcept
Returns the dth dimension of the given expression.
Definition: sub_matrix_4d.hpp:381
static size_t size(const expr_t &v) noexcept
Returns the size of the given expression.
Definition: sub_matrix_4d.hpp:371
const_memory_t< sub_type > const_memory_type
The const memory access type.
Definition: sub_matrix_4d.hpp:36
void std_add_evaluate(Expr &&expr, Result &&result)
Compound add evaluation of the expr into result.
Definition: evaluator.hpp:1195
value_type read_flat(size_t f) const noexcept(assert_nothrow)
Returns the value at the given index This function never has side effects.
Definition: sub_matrix_4d.hpp:148
T sub_type
The sub type.
Definition: sub_matrix_4d.hpp:33