Expression Templates Library (ETL)
sub_matrix_2d.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_2d final : iterable<sub_matrix_2d<T, Aligned>, false>,
27  assignable<sub_matrix_2d<T, Aligned>, value_t<T>>,
28  value_testable<sub_matrix_2d<T, Aligned>>,
29  inplace_assignable<sub_matrix_2d<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 m;
57  const size_t n;
58  const size_t base_m;
59  const size_t base_n;
60 
61  friend struct etl_traits<sub_matrix_2d>;
62 
63  static constexpr order storage_order = decay_traits<sub_type>::storage_order;
64 
65 public:
71  sub_matrix_2d(sub_type sub_expr, size_t i, size_t j, size_t m, size_t n)
72  : sub_expr(sub_expr), base_i(i), base_j(j), m(m), n(n), base_m(etl::dim<0>(sub_expr)), base_n(etl::dim<1>(sub_expr)) {}
73 
79  const_return_type operator[](size_t j) const {
80  cpp_assert(j < m * n, "Invalid index inside sub_matrix_2d");
81 
82  if constexpr (storage_order == order::RowMajor) {
83  auto ii = base_i + j / n;
84  auto jj = base_j + j % n;
85 
86  return sub_expr[ii * base_n + jj];
87  } else {
88  auto ii = base_i + j % m;
89  auto jj = base_j + j / m;
90 
91  return sub_expr[ii + jj * base_m];
92  }
93  }
94 
101  cpp_assert(j < m * n, "Invalid index inside sub_matrix_2d");
102 
103  if constexpr (storage_order == order::RowMajor) {
104  auto ii = base_i + j / n;
105  auto jj = base_j + j % n;
106 
107  return sub_expr[ii * base_n + jj];
108  } else {
109  auto ii = base_i + j % m;
110  auto jj = base_j + j / m;
111 
112  return sub_expr[ii + jj * base_m];
113  }
114  }
115 
122  value_type read_flat(size_t j) const noexcept(assert_nothrow) {
123  cpp_assert(j < m * n, "Invalid index inside sub_matrix_2d");
124 
125  if constexpr (storage_order == order::RowMajor) {
126  auto ii = base_i + j / n;
127  auto jj = base_j + j % n;
128 
129  return sub_expr.read_flat(ii * base_n + jj);
130  } else {
131  auto ii = base_i + j % m;
132  auto jj = base_j + j / m;
133 
134  return sub_expr.read_flat(ii + jj * base_m);
135  }
136  }
137 
144  ETL_STRONG_INLINE(const_return_type) operator()(size_t i, size_t j) const {
145  cpp_assert(i < m, "Invalid 2D index inside sub_matrix_2d");
146  cpp_assert(j < n, "Invalid 2D index inside sub_matrix_2d");
147 
148  return sub_expr(base_i + i, base_j + j);
149  }
150 
157  ETL_STRONG_INLINE(return_type) operator()(size_t i, size_t j) {
158  cpp_assert(i < m, "Invalid 2D index inside sub_matrix_2d");
159  cpp_assert(j < n, "Invalid 2D index inside sub_matrix_2d");
160 
161  return sub_expr(base_i + i, base_j + j);
162  }
163 
169  auto operator()(size_t x) const {
170  return sub(*this, x);
171  }
172 
178  template <typename E>
179  bool alias(const E& rhs) const noexcept {
180  return sub_expr.alias(rhs);
181  }
182 
190  size_t& unsafe_dimension_access(size_t x) {
191  return sub_expr.unsafe_dimension_access(x);
192  }
193 
194  // Assignment functions
195 
200  template <typename L>
201  void assign_to(L&& lhs) const {
202  std_assign_evaluate(*this, std::forward<L>(lhs));
203  }
204 
209  template <typename L>
210  void assign_add_to(L&& lhs) const {
211  std_add_evaluate(*this, std::forward<L>(lhs));
212  }
213 
218  template <typename L>
219  void assign_sub_to(L&& lhs) const {
220  std_sub_evaluate(*this, std::forward<L>(lhs));
221  }
222 
227  template <typename L>
228  void assign_mul_to(L&& lhs) const {
229  std_mul_evaluate(*this, std::forward<L>(lhs));
230  }
231 
236  template <typename L>
237  void assign_div_to(L&& lhs) const {
238  std_div_evaluate(*this, std::forward<L>(lhs));
239  }
240 
245  template <typename L>
246  void assign_mod_to(L&& lhs) const {
247  std_mod_evaluate(*this, std::forward<L>(lhs));
248  }
249 
250  // Internals
251 
256  void ensure_cpu_up_to_date() const {
257  // The sub value must be ensured
258  sub_expr.ensure_cpu_up_to_date();
259  }
260 
265  void ensure_gpu_up_to_date() const {
266  // The sub value must be ensured
267  sub_expr.ensure_gpu_up_to_date();
268  }
269 
274  void visit(detail::evaluator_visitor& visitor) const {
275  sub_expr.visit(visitor);
276  }
277 
278  // TODO A sub_matrix_2d can be vectorized in 2D, but not in 1D
279 
286  friend std::ostream& operator<<(std::ostream& os, const sub_matrix_2d& v) {
287  return os << "sub(" << v.sub_expr << ", " << v.base_i << ", " << v.base_j << ", " << v.base_m << ", " << v.base_n << ")";
288  }
289 };
290 
294 template <typename T, bool Aligned>
295 struct etl_traits<etl::sub_matrix_2d<T, Aligned>> {
297  using sub_expr_t = std::decay_t<T>;
300 
301  static constexpr bool is_etl = true;
302  static constexpr bool is_transformer = false;
303  static constexpr bool is_view = true;
304  static constexpr bool is_magic_view = false;
305  static constexpr bool is_fast = false;
306  static constexpr bool is_linear = sub_traits::is_linear;
307  static constexpr bool is_thread_safe = sub_traits::is_thread_safe;
308  static constexpr bool is_value = false;
309  static constexpr bool is_direct = false;
310  static constexpr bool is_generator = false;
311  static constexpr bool is_padded = false;
312  static constexpr bool is_aligned = false;
313  static constexpr bool is_temporary = sub_traits::is_temporary;
314  static constexpr bool gpu_computable = false;
315  static constexpr order storage_order = sub_traits::storage_order;
316 
322  template <vector_mode_t V>
323  static constexpr bool vectorizable = false;
324 
330  static size_t size(const expr_t& v) noexcept {
331  return v.m * v.n;
332  }
333 
340  static size_t dim(const expr_t& v, size_t d) noexcept {
341  if (d == 0) {
342  return v.m;
343  } else {
344  return v.n;
345  }
346  }
347 
352  static constexpr size_t dimensions() noexcept {
353  return 2;
354  }
355 
360  static constexpr int complexity() noexcept {
361  return -1;
362  }
363 };
364 
365 } //end of namespace etl
CRTP class to inject iterators functions.
Definition: iterable.hpp:23
static constexpr size_t dimensions() noexcept
Returns the number of expressions for this type.
Definition: sub_matrix_2d.hpp:352
const_return_type operator[](size_t j) const
Returns the element at the given index.
Definition: sub_matrix_2d.hpp:79
void visit(detail::evaluator_visitor &visitor) const
Apply the given visitor to this expression and its descendants.
Definition: sub_matrix_2d.hpp:274
void std_assign_evaluate(Expr &&expr, Result &&result)
Evaluation of the expr into result.
Definition: evaluator.hpp:1176
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
size_t & unsafe_dimension_access(size_t x)
Returns a reference to the ith dimension value.
Definition: sub_matrix_2d.hpp:190
order
Storage order of a matrix.
Definition: order.hpp:15
bool alias(const E &rhs) const noexcept
Test if this expression aliases with the given expression.
Definition: sub_matrix_2d.hpp:179
void assign_div_to(L &&lhs) const
Divide the given left-hand-side expression.
Definition: sub_matrix_2d.hpp:237
const_return_helper< sub_type, decltype(std::declval< sub_type >()[0])> const_return_type
The const type return by the view.
Definition: sub_matrix_2d.hpp:38
std::conditional_t< std::is_lvalue_reference_v< S >, const value_t< T > &, value_t< T > > const_return_helper
Definition: traits.hpp:872
constexpr bool is_fast
Traits to test if the given ETL expresion type is fast (sizes known at compile-time) ...
Definition: traits.hpp:588
std::decay_t< T > sub_expr_t
The sub expression type.
Definition: sub_matrix_2d.hpp:297
static size_t dim(const expr_t &v, size_t d) noexcept
Returns the dth dimension of the given expression.
Definition: sub_matrix_2d.hpp:340
auto end() noexcept
Return an iterator to the past-the-end element of the matrix.
Definition: iterable.hpp:59
sub_matrix_2d(sub_type sub_expr, size_t i, size_t j, size_t m, size_t n)
Construct a new sub_matrix_2d over the given sub expression.
Definition: sub_matrix_2d.hpp:71
Traits to get information about ETL types.
Definition: tmp.hpp:68
Root namespace for the ETL library.
Definition: adapter.hpp:15
value_t< sub_type > value_type
The value contained in the expression.
Definition: sub_matrix_2d.hpp:34
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: sub_matrix_2d.hpp:122
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
friend std::ostream & operator<<(std::ostream &os, const sub_matrix_2d &v)
Print a representation of the view on the given stream.
Definition: sub_matrix_2d.hpp:286
void ensure_gpu_up_to_date() const
Copy back from the GPU to the expression memory if necessary.
Definition: sub_matrix_2d.hpp:265
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
typename sub_traits::value_type value_type
The value type of the expression.
Definition: sub_matrix_2d.hpp:299
typename V::template vec_type< value_type > vec_type
The vectorization type for V.
Definition: sub_matrix_2d.hpp:46
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
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
return_type operator[](size_t j)
Returns the element at the given index.
Definition: sub_matrix_2d.hpp:100
Visitor to perform local evaluation when necessary.
Definition: eval_visitors.hpp:23
Configurable iterator for ETL expressions.
Definition: iterator.hpp:24
const_memory_t< sub_type > const_memory_type
The const memory access type.
Definition: sub_matrix_2d.hpp:36
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_to(L &&lhs) const
Assign to the given left-hand-side expression.
Definition: sub_matrix_2d.hpp:201
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_2d.hpp:169
void std_mul_evaluate(Expr &&expr, Result &&result)
Compound multiply evaluation of the expr into result.
Definition: evaluator.hpp:1233
View that shows a 2D sub matrix of an expression.
Definition: expr_fwd.hpp:62
constexpr bool is_transformer
Traits indicating if the given ETL type is a transformer expression.
Definition: traits.hpp:297
T sub_type
The sub type.
Definition: sub_matrix_2d.hpp:33
static constexpr int complexity() noexcept
Estimate the complexity of computation.
Definition: sub_matrix_2d.hpp:360
constexpr bool is_view
Traits indicating if the given ETL type is a view expression.
Definition: traits.hpp:304
void assign_add_to(L &&lhs) const
Add to the given left-hand-side expression.
Definition: sub_matrix_2d.hpp:210
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_2d.hpp:256
void assign_mul_to(L &&lhs) const
Multiply the given left-hand-side expression.
Definition: sub_matrix_2d.hpp:228
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: sub_matrix_2d.hpp:246
void assign_sub_to(L &&lhs) const
Sub from the given left-hand-side expression.
Definition: sub_matrix_2d.hpp:219
ETL_STRONG_INLINE(const_return_type) operator()(size_t i
Access to the element at the given (args...) position.
constexpr bool is_thread_safe
Traits to test if the given ETL expresion type is thread safe.
Definition: traits.hpp:687
return_helper< sub_type, decltype(std::declval< sub_type >()[0])> return_type
The type returned by the view.
Definition: sub_matrix_2d.hpp:37
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.
memory_t< sub_type > memory_type
The memory acess type.
Definition: sub_matrix_2d.hpp:35
static size_t size(const expr_t &v) noexcept
Returns the size of the given expression.
Definition: sub_matrix_2d.hpp:330
void std_add_evaluate(Expr &&expr, Result &&result)
Compound add evaluation of the expr into result.
Definition: evaluator.hpp:1195