Expression Templates Library (ETL)
transformers.hpp
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 
8 #pragma once
9 
10 #include "etl/tmp.hpp"
11 
12 //The transformers
13 #include "etl/op/flip_transformers.hpp"
14 #include "etl/op/rep_transformers.hpp"
15 #include "etl/op/reduc_transformers.hpp"
16 
17 namespace etl {
18 
24 template <typename L, typename R>
26  using left_type = L;
27  using right_type = R;
29 
32 
33  static constexpr bool gpu_computable = false;
34 
40  mm_mul_transformer(left_type left, right_type right) : left(left), right(right) {
41  check_mmul_sizes(left, right);
42  }
43 
49  value_type operator[](size_t i) const {
51  const auto n = etl::dim<1>(right);
52  return operator()(i / n, i % n);
53  } else {
54  const auto m = etl::dim<0>(left);
55  return operator()(i % m, i / m);
56  }
57  }
58 
65  value_type read_flat(size_t i) const {
67  const auto n = etl::dim<1>(right);
68  return operator()(i / n, i % n);
69  } else {
70  const auto m = etl::dim<0>(left);
71  return operator()(i % m, i / m);
72  }
73  }
74 
81  value_type operator()(size_t i, size_t j) const {
82  value_type c = 0;
83 
84  for (size_t k = 0; k < columns(left); k++) {
85  c += left(i, k) * right(k, j);
86  }
87 
88  return c;
89  }
90 
96  template <typename E>
97  bool alias(const E& rhs) const noexcept {
98  return left.alias(rhs) || right.alias(rhs);
99  }
100 
101  // Internals
102 
107  void visit(detail::evaluator_visitor& visitor) const {
108  left.visit(visitor);
109  right.visit(visitor);
110  }
111 
116  void ensure_cpu_up_to_date() const {
117  // Need to ensure both LHS and RHS
118  left.ensure_cpu_up_to_date();
119  right.ensure_cpu_up_to_date();
120  }
121 
126  void ensure_gpu_up_to_date() const {
127  // Need to ensure both LHS and RHS
128  left.ensure_gpu_up_to_date();
129  right.ensure_gpu_up_to_date();
130  }
131 
138  friend std::ostream& operator<<(std::ostream& os, const mm_mul_transformer& transformer) {
139  return os << "mm_mul(" << transformer.left << "," << transformer.right << ")";
140  }
141 
142 private:
143  template <typename A, typename B>
144  void check_mmul_sizes([[maybe_unused]] const A& a, [[maybe_unused]] const B& b) {
145  if constexpr (all_fast<A, B>) {
146  static_assert(etl_traits<A>::template dim<1>() == etl_traits<B>::template dim<0>() //interior dimensions
147  ,
148  "Invalid sizes for multiplication");
149  } else {
150  cpp_assert(dim<1>(a) == dim<0>(b) //interior dimensions
151  ,
152  "Invalid sizes for multiplication");
153  }
154  }
155 };
156 
161 template <etl_1d T>
163  using sub_type = T;
165 
166  static constexpr bool gpu_computable = false;
167 
169  size_t h;
170 
176  dyn_convmtx_transformer(sub_type expr, size_t h) : sub(expr), h(h) {}
177 
183  value_type operator[](size_t i) const {
185  size_t i_i = i / (etl::size(sub) + h - 1);
186  size_t i_j = i % (etl::size(sub) + h - 1);
187  return operator()(i_i, i_j);
188  } else {
189  size_t i_i = i % h;
190  size_t i_j = i / h;
191  return operator()(i_i, i_j);
192  }
193  }
194 
201  value_type read_flat(size_t i) const {
202  return operator[](i);
203  }
204 
211  value_type operator()(size_t i, size_t j) const {
212  if (j < i) {
213  return value_type(0);
214  } else if (j >= etl::size(sub) + i) {
215  return value_type(0);
216  } else {
217  return sub(j - i);
218  }
219  }
220 
226  template <typename E>
227  bool alias(const E& rhs) const noexcept {
228  return sub.alias(rhs);
229  }
230 
231  // Internals
236  void visit(detail::evaluator_visitor& visitor) const {
237  sub.visit(visitor);
238  }
239 
244  void ensure_cpu_up_to_date() const {
245  // Need to ensure sub value
246  sub.ensure_cpu_up_to_date();
247  }
248 
253  void ensure_gpu_up_to_date() const {
254  // Need to ensure both LHS and RHS
255  sub.ensure_gpu_up_to_date();
256  }
257 };
258 
263 template <etl_2d T>
265  using sub_type = T;
267 
268  static constexpr bool gpu_computable = false;
269 
271  const size_t k1;
272  const size_t k2;
273  size_t i1;
274  size_t i2;
275  size_t inner_paddings;
276  size_t inner_padding;
277 
278  dyn_convmtx2_transformer(sub_type sub, size_t k1, size_t k2) : sub(sub), k1(k1), k2(k2) {
279  i1 = etl::dim<0>(sub);
280  i2 = etl::dim<1>(sub);
281 
282  size_t c_height = (i1 + k1 - 1) * (i2 + k2 - 1);
283  size_t c_width = k1 * k2;
284 
285  auto max_fill = c_height - ((i1 + k1 - 1) * ((c_width - 1) / k1) + (c_width - 1) % k1);
286  inner_paddings = max_fill - (i1 * i2);
287  inner_padding = inner_paddings / (i2 - 1);
288  }
289 
295  value_type operator[](size_t i) const {
296  size_t i_i = i / (k1 * k2);
297  size_t i_j = i % (k1 * k2);
298  return (*this)(i_i, i_j);
299  }
300 
307  value_type read_flat(size_t i) const noexcept {
308  size_t i_i = i / (k1 * k2);
309  size_t i_j = i % (k1 * k2);
310  return (*this)(i_i, i_j);
311  }
312 
319  value_type operator()(size_t i, size_t j) const {
320  auto top_padding = (i1 + k1 - 1) * (j / k1) + j % k1;
321 
322  if (i < top_padding || i >= top_padding + (i1 * i2) + inner_paddings) {
323  return value_type(0);
324  } else {
325  auto inner = i - top_padding;
326  auto col = inner % (i1 + inner_padding);
327  auto block = inner / (i1 + inner_padding);
328 
329  if (col >= i1) {
330  return value_type(0);
331  } else {
332  return sub(col, block);
333  }
334  }
335  }
336 
342  template <typename E>
343  bool alias(const E& rhs) const noexcept {
344  return sub.alias(rhs);
345  }
346 
347  // Internals
348 
353  void visit(detail::evaluator_visitor& visitor) const {
354  sub.visit(visitor);
355  }
356 
361  void ensure_cpu_up_to_date() const {
362  // Need to ensure sub value
363  sub.ensure_cpu_up_to_date();
364  }
365 
370  void ensure_gpu_up_to_date() const {
371  // Need to ensure both LHS and RHS
372  sub.ensure_gpu_up_to_date();
373  }
374 };
375 
376 //TODO Make a temporary_expr out of this
377 
385 template <typename A, typename M>
386 void convmtx2_direct_t(M& m, A&& sub, size_t k1, size_t k2) {
387  const size_t i1 = etl::dim<0>(sub);
388  const size_t i2 = etl::dim<1>(sub);
389 
390  const size_t c_height = (i1 + k1 - 1) * (i2 + k2 - 1);
391  const size_t c_width = k1 * k2;
392 
393  const auto max_fill = c_height - ((i1 + k1 - 1) * ((c_width - 1) / k1) + (c_width - 1) % k1);
394  const auto inner_paddings = max_fill - (i1 * i2);
395  const auto inner_padding = inner_paddings / (i2 - 1);
396 
397  auto* __restrict mm = m.memory_start();
398  auto* __restrict ss = sub.memory_start();
399 
400  std::fill(mm, mm + etl::size(m), 0.0);
401 
402  for (size_t j = 0; j < c_width; ++j) {
403  size_t big_i = (i1 + k1 - 1) * (j / k1) + j % k1;
404 
405  for (size_t ii = 0; ii < etl::dim<1>(sub); ++ii) {
406  for (size_t jj = 0; jj < etl::dim<0>(sub); ++jj) {
407  mm[j * c_width + big_i] = ss[jj * i2 + ii];
408  ++big_i;
409  }
410  big_i += inner_padding;
411  }
412  }
413 }
414 
415 //TODO Adapt this to an expression
416 
424 template <typename A, typename M>
425 void im2col_direct(M& m, A&& sub, size_t k1, size_t k2) {
426  if constexpr (all_dma<A, M>) {
427  // This is a direct memory version
428  // On gcc and clang, this is significantly faster
429  const size_t i1 = etl::dim<0>(sub);
430  const size_t i2 = etl::dim<1>(sub);
431 
432  const auto m_width = (i1 - k1 + 1) * (i2 - k2 + 1);
433 
434  const auto mm = m.memory_start();
435  const auto ss = sub.memory_start();
436 
437  for (size_t b = 0; b < m_width; ++b) {
438  auto s_i = b % (i1 - k1 + 1);
439  auto s_j = b / (i1 - k1 + 1);
440 
441  for (size_t b_i = 0; b_i < k1; ++b_i) {
442  for (size_t b_j = 0; b_j < k2; ++b_j) {
443  mm[(b_j * k1 + b_i) * m_width + b] = ss[(s_i + b_i) * i2 + s_j + b_j];
444  }
445  }
446  }
447  } else {
448  const size_t i1 = etl::dim<0>(sub);
449  const size_t i2 = etl::dim<1>(sub);
450 
451  const size_t m_width = (i1 - k1 + 1) * (i2 - k2 + 1);
452 
453  for (size_t b = 0; b < m_width; ++b) {
454  auto s_i = b % (i1 - k1 + 1);
455  auto s_j = b / (i1 - k1 + 1);
456 
457  for (size_t b_i = 0; b_i < k1; ++b_i) {
458  for (size_t b_j = 0; b_j < k2; ++b_j) {
459  m(b_j * k1 + b_i, b) = sub(s_i + b_i, s_j + b_j);
460  }
461  }
462  }
463  }
464 }
465 
466 //im2col version without any need for transpose
467 
478 template <etl_dma A, etl_dma M>
479 void im2col_direct_tr(M& m, A&& sub, size_t k1, size_t k2) {
480  const size_t i1 = etl::dim<0>(sub);
481  const size_t i2 = etl::dim<1>(sub);
482 
483  const auto height = i1 - k1 + 1;
484  const auto width = i2 - k2 + 1;
485 
486  const auto mm = m.memory_start();
487  const auto ss = sub.memory_start();
488 
489  for (size_t c = 0; c < k1 * k2; ++c) {
490  const size_t w_source = c % k2;
491  const size_t h_source = (c / k2) % k1;
492  const size_t c_source = c / (k1 * k2);
493 
494  for (size_t h = 0; h < height; ++h) {
495  const size_t block_source = (c_source * i1 + h + h_source) * i2 + w_source;
496  const size_t block_target = (c * height + h) * width;
497 
498  direct_copy_n(ss + block_source, mm + block_target, width);
499  }
500  }
501 }
502 
513 template <etl_dma A, etl_dma M>
514 void im2col_direct_tr_multi(M& m, A&& sub, size_t k1, size_t k2) {
515  const auto N = etl::dim<0>(sub);
516  const auto i1 = etl::dim<1>(sub);
517  const auto i2 = etl::dim<2>(sub);
518 
519  const auto height = i1 - k1 + 1;
520  const auto width = i2 - k2 + 1;
521 
522  const auto mm = m.memory_start();
523  const auto ss = sub.memory_start();
524 
525  for (size_t w = 0; w < k1 * k2; ++w) {
526  const auto w_source = w % k2;
527  const auto h_source = (w / k2) % k1;
528  const auto c_source = w / (k1 * k2);
529 
530  for (size_t i = 0; i < N; ++i) {
531  for (size_t h = 0; h < height; ++h) {
532  const auto block_source = ((c_source * i1 + h + h_source) * i2 + w_source) + (i) * (i1 * i2);
533  const auto block_target = (w * N + i) * (height * width) + h * width;
534 
535  etl::direct_copy_n(ss + block_source, mm + block_target, width);
536  }
537  }
538  }
539 }
540 
544 template <typename LE, typename RE>
547  using left_expr_t = std::decay_t<LE>;
548  using right_expr_t = std::decay_t<RE>;
552 
553  static constexpr bool is_etl = true;
554  static constexpr bool is_transformer = true;
555  static constexpr bool is_view = false;
556  static constexpr bool is_magic_view = false;
557  static constexpr bool is_fast = l_traits::is_fast && r_traits::is_fast;
558  static constexpr bool is_linear = false;
559  static constexpr bool is_thread_safe = true;
560  static constexpr bool is_value = false;
561  static constexpr bool is_direct = false;
562  static constexpr bool is_generator = false;
563  static constexpr bool is_padded = false;
564  static constexpr bool is_aligned = false;
565  static constexpr bool is_temporary = l_traits::is_temporary || r_traits::is_temporary;
566  static constexpr bool gpu_computable = false;
567  static constexpr order storage_order = l_traits::is_generator ? r_traits::storage_order : l_traits::storage_order;
568 
574  template <vector_mode_t V>
575  static constexpr bool vectorizable = false;
576 
582  static size_t size(const expr_t& v) {
583  return dim(v, 0) * dim(v, 1);
584  }
585 
592  static size_t dim(const expr_t& v, size_t d) {
593  if (d == 0) {
594  return etl::dim(v.left, 0);
595  } else {
596  cpp_assert(d == 1, "Only 2D mmul are supported");
597 
598  return etl::dim(v.right, 1);
599  }
600  }
601 
606  static constexpr size_t size() {
608  }
609 
615  template <size_t D>
616  static constexpr size_t dim() requires(D < 2) {
617  return D == 0 ? etl_traits<left_expr_t>::template dim<0>() : etl_traits<right_expr_t>::template dim<1>();
618  }
619 
624  static constexpr size_t dimensions() {
625  return 2;
626  }
627 
632  static constexpr int complexity() noexcept {
633  return 5;
634  }
635 };
636 
640 template <typename E>
643  using sub_expr_t = std::decay_t<E>;
645 
646  static constexpr bool is_etl = true;
647  static constexpr bool is_transformer = true;
648  static constexpr bool is_view = false;
649  static constexpr bool is_magic_view = false;
650  static constexpr bool is_fast = false;
651  static constexpr bool is_linear = false;
652  static constexpr bool is_thread_safe = true;
653  static constexpr bool is_value = false;
654  static constexpr bool is_direct = false;
655  static constexpr bool is_generator = false;
656  static constexpr bool is_padded = false;
657  static constexpr bool is_aligned = false;
658  static constexpr bool is_temporary = etl_traits<sub_expr_t>::is_temporary;
659  static constexpr bool gpu_computable = false;
660  static constexpr order storage_order = etl_traits<sub_expr_t>::storage_order;
661 
667  template <vector_mode_t V>
668  static constexpr bool vectorizable = false;
669 
675  static size_t size(const expr_t& v) {
676  return v.h * (etl::size(v.sub) + v.h - 1);
677  }
678 
685  static size_t dim(const expr_t& v, size_t d) {
686  if (d == 0) {
687  return v.h;
688  } else {
689  return etl::size(v.sub) + v.h - 1;
690  }
691  }
692 
697  static constexpr size_t dimensions() {
698  return 2;
699  }
700 
705  static constexpr int complexity() noexcept {
706  return 5;
707  }
708 };
709 
713 template <typename E>
716  using sub_expr_t = std::decay_t<E>;
718 
719  static constexpr bool is_etl = true;
720  static constexpr bool is_transformer = true;
721  static constexpr bool is_view = false;
722  static constexpr bool is_magic_view = false;
723  static constexpr bool is_fast = false;
724  static constexpr bool is_linear = false;
725  static constexpr bool is_thread_safe = true;
726  static constexpr bool is_value = false;
727  static constexpr bool is_direct = false;
728  static constexpr bool is_generator = false;
729  static constexpr bool is_padded = false;
730  static constexpr bool is_aligned = false;
731  static constexpr bool is_temporary = etl_traits<sub_expr_t>::is_temporary;
732  static constexpr bool gpu_computable = false;
733  static constexpr order storage_order = etl_traits<sub_expr_t>::storage_order;
734 
740  template <vector_mode_t V>
741  static constexpr bool vectorizable = false;
742 
748  static size_t size(const expr_t& v) {
749  auto c_height = (etl::dim<0>(v.sub) + v.k1 - 1) * (etl::dim<1>(v.sub) + v.k2 - 1);
750  auto c_width = v.k1 * v.k2;
751  return c_height * c_width;
752  }
753 
760  static size_t dim(const expr_t& v, size_t d) {
761  if (d == 0) {
762  return (etl::dim<0>(v.sub) + v.k1 - 1) * (etl::dim<1>(v.sub) + v.k2 - 1);
763  } else {
764  return v.k1 * v.k2;
765  }
766  }
767 
772  static constexpr size_t dimensions() {
773  return 2;
774  }
775 
780  static constexpr int complexity() noexcept {
781  return 5;
782  }
783 };
784 
785 } //end of namespace etl
L left_type
The left side type.
Definition: transformers.hpp:26
static constexpr size_t dim() requires(D< 2)
Returns the Dth dimension of an expression of this type.
Definition: transformers.hpp:616
sub_type sub
The subexpression.
Definition: transformers.hpp:168
value_type operator()(size_t i, size_t j) const
Access to the value at the given (i, j) position.
Definition: transformers.hpp:319
static size_t size(const expr_t &v)
Returns the size of the given expression.
Definition: transformers.hpp:582
void ensure_gpu_up_to_date() const
Copy back from the GPU to the expression memory if necessary.
Definition: transformers.hpp:126
std::decay_t< E > sub_expr_t
The sub expression type.
Definition: transformers.hpp:643
const size_t k2
The second dimension of the kernel.
Definition: transformers.hpp:272
right_type right
The right expression.
Definition: transformers.hpp:31
static size_t size(const expr_t &v)
Returns the size of the given expression.
Definition: transformers.hpp:748
Transform that applies a lazy matrix multiplication to two matrices.
Definition: transformers.hpp:25
Transformer functor for optimizable expression.
Definition: expr_fwd.hpp:19
sub_type sub
The subexpression.
Definition: transformers.hpp:270
size_t h
The convmtx transformation size.
Definition: transformers.hpp:169
constexpr bool is_magic_view
Traits indicating if the given ETL type is a magic view expression.
Definition: traits.hpp:311
static constexpr size_t dimensions()
Returns the number of expressions for this type.
Definition: transformers.hpp:697
value_type read_flat(size_t i) const
Returns the value at the given index This function never has side effects.
Definition: transformers.hpp:201
value_type operator[](size_t i) const
Returns the value at the given index.
Definition: transformers.hpp:295
D D
The number of dimensions.
Definition: dyn_matrix_view.hpp:24
value_t< sub_expr_t > value_type
The value type.
Definition: transformers.hpp:644
friend std::ostream & operator<<(std::ostream &os, const mm_mul_transformer &transformer)
Display the transformer on the given stream.
Definition: transformers.hpp:138
T sub_type
The type on which the expression works.
Definition: transformers.hpp:163
order
Storage order of a matrix.
Definition: order.hpp:15
static size_t dim(const expr_t &v, size_t d)
Returns the dth dimension of the given expression.
Definition: transformers.hpp:685
static constexpr int complexity() noexcept
Estimate the complexity of computation.
Definition: transformers.hpp:780
std::decay_t< RE > right_expr_t
The right hand side expression type.
Definition: transformers.hpp:548
Transform that applies a convmtx transformation on a matrix.
Definition: transformers.hpp:162
R right_type
The right side type.
Definition: transformers.hpp:27
void im2col_direct_tr_multi(M &m, A &&sub, size_t k1, size_t k2)
Convert a sequence of images to a sequence of image columns to be multiplied by kernels of size (k1...
Definition: transformers.hpp:514
value_t< sub_expr_t > value_type
The type of value.
Definition: transformers.hpp:717
T sub_type
The type on which the expression works.
Definition: transformers.hpp:265
std::decay_t< LE > left_expr_t
The left hand side expression type.
Definition: transformers.hpp:547
Transform that applies a convmtx2 transformation on a matrix.
Definition: transformers.hpp:264
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< E > sub_expr_t
The sub expression type.
Definition: transformers.hpp:716
static size_t dim(const expr_t &v, size_t d)
Returns the dth dimension of the given expression.
Definition: transformers.hpp:592
Traits to get information about ETL types.
Definition: tmp.hpp:68
Root namespace for the ETL library.
Definition: adapter.hpp:15
void visit(detail::evaluator_visitor &visitor) const
Apply the given visitor to this expression and its descendants.
Definition: transformers.hpp:107
static constexpr int complexity() noexcept
Estimate the complexity of computation.
Definition: transformers.hpp:632
bool alias(const E &rhs) const noexcept
Test if this expression aliases with the given expression.
Definition: transformers.hpp:227
value_type read_flat(size_t i) const noexcept
Returns the value at the given index This function never has side effects.
Definition: transformers.hpp:307
value_type read_flat(size_t i) const
Returns the value at the given index This function never has side effects.
Definition: transformers.hpp:65
static constexpr size_t size()
Returns the size of an expression of this fast type.
Definition: transformers.hpp:606
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
value_t< left_expr_t > value_type
The value type.
Definition: transformers.hpp:549
bool alias(const E &rhs) const noexcept
Test if this expression aliases with the given expression.
Definition: transformers.hpp:343
size_t columns(const E &expr)
Returns the number of columns of the given ETL expression.
Definition: helpers.hpp:78
mm_mul_transformer(left_type left, right_type right)
Construct a new transformer around the given expressions.
Definition: transformers.hpp:40
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: transformers.hpp:361
size_t inner_padding
The inner padding.
Definition: transformers.hpp:276
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: transformers.hpp:244
static constexpr size_t dimensions()
Returns the number of expressions for this type.
Definition: transformers.hpp:772
void visit(detail::evaluator_visitor &visitor) const
Apply the given visitor to this expression and its descendants.
Definition: transformers.hpp:353
static size_t size(const expr_t &v)
Returns the size of the given expression.
Definition: transformers.hpp:675
Visitor to perform local evaluation when necessary.
Definition: eval_visitors.hpp:23
static size_t dim(const expr_t &v, size_t d)
Returns the dth dimension of the given expression.
Definition: transformers.hpp:760
void direct_copy_n(const S *source, T *target, size_t n)
Performs a direct memory copy.
Definition: memory.hpp:35
value_t< L > value_type
The value type.
Definition: transformers.hpp:28
constexpr bool is_transformer
Traits indicating if the given ETL type is a transformer expression.
Definition: traits.hpp:297
size_t i1
The first dimension of the input.
Definition: transformers.hpp:273
bool alias(const E &rhs) const noexcept
Test if this expression aliases with the given expression.
Definition: transformers.hpp:97
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
left_type left
The left expression.
Definition: transformers.hpp:30
void ensure_gpu_up_to_date() const
Copy back from the GPU to the expression memory if necessary.
Definition: transformers.hpp:253
value_t< T > value_type
The type of valuie.
Definition: transformers.hpp:164
auto col(E &&value, size_t i) -> detail::identity_helper< E, dim_view< detail::build_identity_type< E >, 2 >>
Returns view representing the ith column of the given expression.
Definition: view_expression_builder.hpp:47
void visit(detail::evaluator_visitor &visitor) const
Apply the given visitor to this expression and its descendants.
Definition: transformers.hpp:236
value_type operator()(size_t i, size_t j) const
Access to the value at the given (i, j) position.
Definition: transformers.hpp:81
void ensure_gpu_up_to_date() const
Copy back from the GPU to the expression memory if necessary.
Definition: transformers.hpp:370
size_t i2
The second dimension of the input.
Definition: transformers.hpp:274
static constexpr int complexity() noexcept
Estimate the complexity of computation.
Definition: transformers.hpp:705
value_t< T > value_type
The type of valuie.
Definition: transformers.hpp:266
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 dimensions()
Returns the number of expressions for this type.
Definition: transformers.hpp:624
typename decay_traits< E >::value_type value_t
Traits to extract the value type out of an ETL type.
Definition: tmp.hpp:81
value_type operator[](size_t i) const
Returns the value at the given index.
Definition: transformers.hpp:183
Row-Major storage.
value_type operator[](size_t i) const
Returns the value at the given index.
Definition: transformers.hpp:49
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: transformers.hpp:116
void im2col_direct(M &m, A &&sub, size_t k1, size_t k2)
Convert an image to a sequence of image columns to be multiplied by kernels of size (k1...
Definition: transformers.hpp:425
void im2col_direct_tr(M &m, A &&sub, size_t k1, size_t k2)
Convert an image to a sequence of image columns to be multiplied by kernels of size (k1...
Definition: transformers.hpp:479
size_t inner_paddings
The inner padding sum.
Definition: transformers.hpp:275
const size_t k1
The first dimension of the kernel.
Definition: transformers.hpp:271
dyn_convmtx_transformer(sub_type expr, size_t h)
Construct a new transformer around the given expression.
Definition: transformers.hpp:176
void convmtx2_direct_t(M &m, A &&sub, size_t k1, size_t k2)
Compute the convolution matrix of sub into m for a kernel of size (k1,k2)
Definition: transformers.hpp:386
value_type operator()(size_t i, size_t j) const
Access to the value at the given (i, j) position.
Definition: transformers.hpp:211