Expression Templates Library (ETL)
unary_expr.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 <random>
16 #include "etl/concepts_base.hpp"
17 namespace etl {
18 
24 struct identity_op {
25  static constexpr bool linear = true;
26  static constexpr bool thread_safe = true;
27 
33  template <vector_mode_t V>
34  static constexpr bool vectorizable = true;
35 
39  template <typename E>
40  static constexpr bool gpu_computable = false;
41 
46  static constexpr int complexity() {
47  return 1;
48  }
49 };
50 
56 struct transform_op {
57  static constexpr bool linear = false;
58  static constexpr bool thread_safe = true;
59 
65  template <vector_mode_t V>
66  static constexpr bool vectorizable = false;
67 
71  template <typename Expr>
72  static constexpr bool gpu_computable = Expr::gpu_computable;
73 
78  static constexpr int complexity() {
79  return 1;
80  }
81 };
82 
90 template <typename Sub>
91 struct stateful_op {
92  static constexpr bool linear = Sub::linear;
93  static constexpr bool thread_safe = Sub::thread_safe;
94 
95  using op = Sub;
96 
102  template <vector_mode_t V>
103  static constexpr bool vectorizable = Sub::template vectorizable<V>;
104 
108  template <typename E>
109  static constexpr bool gpu_computable = Sub::template gpu_computable<E>;
110 
115  static constexpr int complexity() {
116  return 1;
117  }
118 };
119 
125 template <typename T, expr_or_scalar<T> Expr, typename UnaryOp>
126 struct unary_expr final : value_testable<unary_expr<T, Expr, UnaryOp>>, dim_testable<unary_expr<T, Expr, UnaryOp>>, iterable<unary_expr<T, Expr, UnaryOp>> {
127 private:
129 
130  Expr value;
131 
132  friend struct etl_traits<unary_expr>;
133  friend struct optimizer<unary_expr>;
134  friend struct optimizable<unary_expr>;
135  friend struct transformer<unary_expr>;
136 
137 public:
138  using value_type = T;
139  using memory_type = void;
140  using const_memory_type = void;
141  using expr_t = Expr;
144 
148  template <typename V = default_vec>
149  using vec_type = typename V::template vec_type<T>;
150 
155  explicit unary_expr(Expr l) : value(std::forward<Expr>(l)) {
156  //Nothing else to init
157  }
158 
159  unary_expr(const unary_expr& rhs) = default;
160  unary_expr(unary_expr&& rhs) noexcept = default;
161 
162  //Expression are invariant
163  unary_expr& operator=(const unary_expr& rhs) = delete;
164  unary_expr& operator=(unary_expr&& rhs) = delete;
165 
171  value_type operator[](size_t i) const {
172  return UnaryOp::apply(value[i]);
173  }
174 
181  value_type read_flat(size_t i) const noexcept {
182  return UnaryOp::apply(value.read_flat(i));
183  }
184 
191  template <typename V = default_vec>
192  vec_type<V> load(size_t i) const {
193  return UnaryOp::template load<V>(value.template load<V>(i));
194  }
195 
202  template <typename V = default_vec>
203  vec_type<V> loadu(size_t i) const {
204  return UnaryOp::template load<V>(value.template loadu<V>(i));
205  }
206 
212  template <size_c... S>
213  value_type operator()(S... args) const {
214  return UnaryOp::apply(value(args...));
215  }
216 
222  template <typename E>
223  bool alias(const E& rhs) const noexcept {
224  return value.alias(rhs);
225  }
226 
231  template <typename Y>
232  decltype(auto) gpu_compute_hint(Y& y) const {
233  return UnaryOp::gpu_compute_hint(value, y);
234  }
235 
240  template <typename Y>
241  decltype(auto) gpu_compute(Y& y) const {
242  return UnaryOp::gpu_compute(value, y);
243  }
244 
245  // Assignment functions
246 
251  template <typename L>
252  void assign_to(L&& lhs) const {
253  std_assign_evaluate(*this, std::forward<L>(lhs));
254  }
255 
260  template <typename L>
261  void assign_add_to(L&& lhs) const {
262  std_add_evaluate(*this, std::forward<L>(lhs));
263  }
264 
269  template <typename L>
270  void assign_sub_to(L&& lhs) const {
271  std_sub_evaluate(*this, std::forward<L>(lhs));
272  }
273 
278  template <typename L>
279  void assign_mul_to(L&& lhs) const {
280  std_mul_evaluate(*this, std::forward<L>(lhs));
281  }
282 
287  template <typename L>
288  void assign_div_to(L&& lhs) const {
289  std_div_evaluate(*this, std::forward<L>(lhs));
290  }
291 
296  template <typename L>
297  void assign_mod_to(L&& lhs) const {
298  std_mod_evaluate(*this, std::forward<L>(lhs));
299  }
300 
301  // Internals
302 
307  void visit(detail::evaluator_visitor& visitor) const {
308  value.visit(visitor);
309  }
310 
315  void ensure_cpu_up_to_date() const {
316  // The sub value must be ensured
317  value.ensure_cpu_up_to_date();
318  }
319 
324  void ensure_gpu_up_to_date() const {
325  // The sub value must be ensured
326  value.ensure_gpu_up_to_date();
327  }
328 
335  friend std::ostream& operator<<(std::ostream& os, const unary_expr& expr) {
336  return os << UnaryOp::desc() << '(' << expr.value << ')';
337  }
338 };
339 
345 template <typename T, expr_or_scalar<T> Expr>
346 struct unary_expr<T, Expr, identity_op> : inplace_assignable<unary_expr<T, Expr, identity_op>>,
347  assignable<unary_expr<T, Expr, identity_op>, T>,
348  value_testable<unary_expr<T, Expr, identity_op>>,
349  dim_testable<unary_expr<T, Expr, identity_op>>,
350  iterable<unary_expr<T, Expr, identity_op>, is_dma<Expr>> {
351 private:
352  Expr value;
353  gpu_memory_handler<T> _gpu;
354 
355  static constexpr bool dma = is_dma<Expr>;
356 
360  static constexpr bool non_const_return_ref =
361  std::is_lvalue_reference_v<decltype(value[0])> && !std::is_const_v<std::remove_reference_t<decltype(value[0])>>;
362 
366  static constexpr bool const_return_ref = std::is_lvalue_reference_v<decltype(value[0])>;
367 
368  friend struct etl_traits<unary_expr>;
369  friend struct optimizer<unary_expr>;
370  friend struct optimizable<unary_expr>;
371  friend struct transformer<unary_expr>;
372 
373 public:
375  using value_type = T;
379  using return_type = std::conditional_t<non_const_return_ref, value_type&, value_type>;
380  using const_return_type = std::conditional_t<const_return_ref, const value_type&, value_type>;
381  using expr_t = Expr;
382  using iterator = std::conditional_t<dma, value_type*, etl::iterator<this_type>>;
383  using const_iterator = std::conditional_t<dma, const value_type*, etl::iterator<const this_type>>;
384 
388  template <typename V = default_vec>
389  using vec_type = typename V::template vec_type<value_type>;
390 
391  using assignable_base_type::operator=;
392 
397  explicit unary_expr(Expr l) noexcept : value(std::forward<Expr>(l)) {
398  //Nothing to init
399  }
400 
404  unary_expr(const unary_expr& rhs) = default;
405 
409  unary_expr(unary_expr&& rhs) noexcept = default;
410 
417  return value[i];
418  }
419 
425  const_return_type operator[](size_t i) const {
426  return value[i];
427  }
428 
435  value_type read_flat(size_t i) const noexcept {
436  return value.read_flat(i);
437  }
438 
445  template <typename V = default_vec>
446  void store(vec_type<V> in, size_t i) noexcept {
447  return value.template store<V>(in, i);
448  }
449 
456  template <typename V = default_vec>
457  void storeu(vec_type<V> in, size_t i) noexcept {
458  return value.template storeu<V>(in, i);
459  }
460 
467  template <typename V = default_vec>
468  void stream(vec_type<V> in, size_t i) noexcept {
469  return value.template stream<V>(in, i);
470  }
471 
478  template <typename V = default_vec>
479  ETL_STRONG_INLINE(vec_type<V>)
480  load(size_t i) const noexcept {
481  return value.template load<V>(i);
482  }
483 
490  template <typename V = default_vec>
491  ETL_STRONG_INLINE(vec_type<V>)
492  loadu(size_t i) const noexcept {
493  return value.template loadu<V>(i);
494  }
495 
503  size_t& unsafe_dimension_access(size_t i) {
504  return value.unsafe_dimension_access(i);
505  }
506 
512  auto operator()(size_t i) requires sub_capable<this_type> {
513  return sub(*this, i);
514  }
515 
521  auto operator()(size_t i) const requires sub_capable<this_type> {
522  return sub(*this, i);
523  }
524 
531  auto slice(size_t first, size_t last) noexcept {
532  return etl::slice(*this, first, last);
533  }
534 
541  auto slice(size_t first, size_t last) const noexcept {
542  return etl::slice(*this, first, last);
543  }
544 
550  template <size_c... S>
551  ETL_STRONG_INLINE(return_type)
552  operator()(S... args) noexcept(noexcept(value(args...))) requires (sizeof...(S) == safe_dimensions<this_type>) {
553  return value(args...);
554  }
555 
561  template <size_c... S>
562  ETL_STRONG_INLINE(const_return_type)
563  operator()(S... args) const noexcept(noexcept(value(args...))) requires(sizeof...(S) == safe_dimensions<this_type>) {
564  return value(args...);
565  }
566 
572  template <typename E>
573  bool alias(const E& rhs) const noexcept {
574  if constexpr (all_dma<E, Expr>) {
575  return memory_alias(memory_start(), memory_end(), rhs.memory_start(), rhs.memory_end());
576  } else {
577  return value.alias(rhs);
578  }
579  }
580 
585  memory_type memory_start() noexcept requires(etl_dma<Expr>) {
586  return value.memory_start();
587  }
588 
593  const_memory_type memory_start() const noexcept requires(etl_dma<Expr>) {
594  return value.memory_start();
595  }
596 
601  memory_type memory_end() noexcept requires(etl_dma<Expr>) {
602  return value.memory_end();
603  }
604 
609  const_memory_type memory_end() const noexcept requires(etl_dma<Expr>) {
610  return value.memory_end();
611  }
612 
617  template <size_t DD>
618  static constexpr size_t dim() requires fast<this_type> {
619  return etl_traits<this_type>::template dim<DD>();
620  }
621 
626  template <size_t DD>
627  size_t dim() const requires dyn<this_type> {
628  return etl_traits<this_type>::dim(*this, DD);
629  }
630 
635  template <size_t... I>
636  std::array<size_t, decay_traits<this_type>::dimensions()> dim_array(std::index_sequence<I...>) const {
637  return {{this->template dim<I>()...}};
638  }
639 
640  // Assignment functions
641 
646  template <typename L>
647  void assign_to(L&& lhs) const {
648  std_assign_evaluate(*this, std::forward<L>(lhs));
649  }
650 
655  template <typename L>
656  void assign_add_to(L&& lhs) const {
657  std_add_evaluate(*this, std::forward<L>(lhs));
658  }
659 
664  template <typename L>
665  void assign_sub_to(L&& lhs) const {
666  std_sub_evaluate(*this, std::forward<L>(lhs));
667  }
668 
673  template <typename L>
674  void assign_mul_to(L&& lhs) const {
675  std_mul_evaluate(*this, std::forward<L>(lhs));
676  }
677 
682  template <typename L>
683  void assign_div_to(L&& lhs) const {
684  std_div_evaluate(*this, std::forward<L>(lhs));
685  }
686 
691  template <typename L>
692  void assign_mod_to(L&& lhs) const {
693  std_mod_evaluate(*this, std::forward<L>(lhs));
694  }
695 
696  // Internals
697 
702  void visit(detail::evaluator_visitor& visitor) const {
703  value.visit(visitor);
704  }
705 
710  T* gpu_memory() const noexcept requires(etl_dma<Expr>) {
711  return _gpu.gpu_memory();
712  }
713 
717  void gpu_evict() const noexcept requires(etl_dma<Expr>) {
718  _gpu.gpu_evict();
719  }
720 
724  void invalidate_cpu() const noexcept requires(etl_dma<Expr>) {
725  _gpu.invalidate_cpu();
726  }
727 
731  void invalidate_gpu() const noexcept requires(etl_dma<Expr>) {
732  _gpu.invalidate_gpu();
733  }
734 
738  void validate_cpu() const noexcept requires(etl_dma<Expr>) {
739  _gpu.validate_cpu();
740  }
741 
745  void validate_gpu() const noexcept requires(etl_dma<Expr>) {
746  _gpu.validate_gpu();
747  }
748 
753  void ensure_gpu_allocated() const requires(etl_dma<Expr>) {
754  _gpu.ensure_gpu_allocated(etl::size(value));
755  }
756 
760  void ensure_gpu_up_to_date() const {
761  if constexpr (is_dma<Expr>) {
762  _gpu.ensure_gpu_up_to_date(memory_start(), etl::size(value));
763  } else {
764  value.ensure_gpu_up_to_date();
765  }
766  }
767 
772  void ensure_cpu_up_to_date() const {
773  if constexpr (is_dma<Expr>) {
774  _gpu.ensure_cpu_up_to_date(memory_start(), etl::size(value));
775  } else {
776  value.ensure_cpu_up_to_date();
777  }
778  }
779 
784  void gpu_copy_from(const T* gpu_memory) const requires(etl_dma<Expr>) {
785  _gpu.gpu_copy_from(gpu_memory, etl::size(value));
786  }
787 
792  bool is_cpu_up_to_date() const noexcept requires(etl_dma<Expr>) {
793  return _gpu.is_cpu_up_to_date();
794  }
795 
800  bool is_gpu_up_to_date() const noexcept requires(etl_dma<Expr>) {
801  return _gpu.is_gpu_up_to_date();
802  }
803 
810  friend std::ostream& operator<<(std::ostream& os, const unary_expr& expr) {
811  return os << expr.value;
812  }
813 
814 private:
819  void memory_set(const value_type& e) {
820  if constexpr (is_dma<Expr>) {
821  direct_fill(memory_start(), memory_end(), e);
822  } else {
823  for (size_t i = 0; i < size(*this); ++i) {
824  (*this)[i] = e;
825  }
826  }
827  }
828 };
829 
833 template <typename T, typename Expr>
836 private:
838 
839  Expr value;
840 
841  friend struct etl_traits<unary_expr>;
842  friend struct optimizer<unary_expr>;
843  friend struct optimizable<unary_expr>;
844  friend struct transformer<unary_expr>;
845 
846 public:
847  using value_type = T;
848  using memory_type = void;
849  using const_memory_type = void;
850  using expr_t = Expr;
853 
858  explicit unary_expr(Expr l) : value(std::forward<Expr>(l)) {
859  //Nothing else to init
860  }
861 
862  unary_expr(const unary_expr& rhs) = default;
863  unary_expr(unary_expr&& rhs) noexcept = default;
864 
865  //Expression are invariant
866  unary_expr& operator=(const unary_expr& e) = delete;
867  unary_expr& operator=(unary_expr&& e) = delete;
868 
874  value_type operator[](size_t i) const {
875  return value[i];
876  }
877 
884  value_type read_flat(size_t i) const noexcept {
885  return value.read_flat(i);
886  }
887 
893  auto operator()(size_t i) const requires sub_capable<this_type> {
894  return sub(*this, i);
895  }
896 
902  template <size_c... S>
903  value_type operator()(S... args) const requires(sizeof...(S) == safe_dimensions<this_type>) {
904  return value(args...);
905  }
906 
912  template <typename E>
913  bool alias(const E& rhs) const noexcept {
914  return value.alias(rhs);
915  }
916 
921  template <typename Y>
922  decltype(auto) gpu_compute_hint(Y& y) const {
923  return value.gpu_compute_hint(y);
924  }
925 
930  template <typename Y>
931  decltype(auto) gpu_compute(Y& y) const {
932  return value.gpu_compute(y);
933  }
934 
935  // Assignment functions
936 
941  template <typename L>
942  void assign_to(L&& lhs) const {
943  std_assign_evaluate(*this, std::forward<L>(lhs));
944  }
945 
950  template <typename L>
951  void assign_add_to(L&& lhs) const {
952  std_add_evaluate(*this, std::forward<L>(lhs));
953  }
954 
959  template <typename L>
960  void assign_sub_to(L&& lhs) const {
961  std_sub_evaluate(*this, std::forward<L>(lhs));
962  }
963 
968  template <typename L>
969  void assign_mul_to(L&& lhs) const {
970  std_mul_evaluate(*this, std::forward<L>(lhs));
971  }
972 
977  template <typename L>
978  void assign_div_to(L&& lhs) const {
979  std_div_evaluate(*this, std::forward<L>(lhs));
980  }
981 
986  template <typename L>
987  void assign_mod_to(L&& lhs) const {
988  std_mod_evaluate(*this, std::forward<L>(lhs));
989  }
990 
991  // Internals
992 
997  void visit(detail::evaluator_visitor& visitor) const {
998  value.visit(visitor);
999  }
1000 
1005  void ensure_cpu_up_to_date() const {
1006  // The sub value must be ensured
1007  value.ensure_cpu_up_to_date();
1008  }
1009 
1014  void ensure_gpu_up_to_date() const {
1015  // The sub value must be ensured
1016  value.ensure_gpu_up_to_date();
1017  }
1018 
1025  friend std::ostream& operator<<(std::ostream& os, const unary_expr& expr) {
1026  return os << expr.value;
1027  }
1028 };
1029 
1035 template <typename T, typename Expr, typename Op>
1036 struct unary_expr<T, Expr, stateful_op<Op>> : value_testable<unary_expr<T, Expr, stateful_op<Op>>>,
1037  dim_testable<unary_expr<T, Expr, stateful_op<Op>>>,
1038  iterable<unary_expr<T, Expr, stateful_op<Op>>> {
1039 private:
1041 
1042  Expr value;
1043  Op op;
1044 
1045  friend struct etl_traits<unary_expr>;
1046  friend struct optimizer<unary_expr>;
1047  friend struct optimizable<unary_expr>;
1048  friend struct transformer<unary_expr>;
1049 
1050 public:
1051  using value_type = T;
1052  using memory_type = void;
1053  using const_memory_type = void;
1054  using expr_t = Expr;
1057 
1061  template <typename V = default_vec>
1062  using vec_type = typename V::template vec_type<T>;
1063 
1069  template <typename... Args>
1070  explicit unary_expr(Expr l, Args&&... args) : value(std::forward<Expr>(l)), op(std::forward<Args>(args)...) {
1071  //Nothing else to init
1072  }
1073 
1074  unary_expr(const unary_expr& rhs) = default;
1075  unary_expr(unary_expr&& rhs) noexcept = default;
1076 
1077  //Expression are invariant
1078  unary_expr& operator=(const unary_expr& e) = delete;
1079  unary_expr& operator=(unary_expr&& e) = delete;
1080 
1086  value_type operator[](size_t i) const {
1087  return op.apply(value[i]);
1088  }
1089 
1096  value_type read_flat(size_t i) const {
1097  return op.apply(value.read_flat(i));
1098  }
1099 
1106  template <typename V = default_vec>
1107  vec_type<V> load(size_t i) const {
1108  return op.template load<V>(value.template load<V>(i));
1109  }
1110 
1117  template <typename V = default_vec>
1118  vec_type<V> loadu(size_t i) const {
1119  return op.template load<V>(value.template loadu<V>(i));
1120  }
1121 
1126  template <typename Y>
1127  decltype(auto) gpu_compute_hint(Y& y) const {
1128  return op.gpu_compute_hint(value, y);
1129  }
1130 
1135  template <typename Y>
1136  decltype(auto) gpu_compute(Y& y) const {
1137  return op.gpu_compute(value, y);
1138  }
1139 
1145  template <size_c... S>
1146  value_type operator()(S... args) const requires(sizeof...(S) == safe_dimensions<this_type>) {
1147  return op.apply(value(args...));
1148  }
1149 
1155  template <typename E>
1156  bool alias(const E& rhs) const noexcept {
1157  return value.alias(rhs);
1158  }
1159 
1160  // Assignment functions
1161 
1166  template <typename L>
1167  void assign_to(L&& lhs) const {
1168  std_assign_evaluate(*this, std::forward<L>(lhs));
1169  }
1170 
1175  template <typename L>
1176  void assign_add_to(L&& lhs) const {
1177  std_add_evaluate(*this, std::forward<L>(lhs));
1178  }
1179 
1184  template <typename L>
1185  void assign_sub_to(L&& lhs) const {
1186  std_sub_evaluate(*this, std::forward<L>(lhs));
1187  }
1188 
1193  template <typename L>
1194  void assign_mul_to(L&& lhs) const {
1195  std_mul_evaluate(*this, std::forward<L>(lhs));
1196  }
1197 
1202  template <typename L>
1203  void assign_div_to(L&& lhs) const {
1204  std_div_evaluate(*this, std::forward<L>(lhs));
1205  }
1206 
1211  template <typename L>
1212  void assign_mod_to(L&& lhs) const {
1213  std_mod_evaluate(*this, std::forward<L>(lhs));
1214  }
1215 
1216  // Internals
1217 
1222  void visit(detail::evaluator_visitor& visitor) const {
1223  value.visit(visitor);
1224  }
1225 
1230  void ensure_cpu_up_to_date() const {
1231  // The sub value must be ensured
1232  value.ensure_cpu_up_to_date();
1233  }
1234 
1239  void ensure_gpu_up_to_date() const {
1240  // The sub value must be ensured
1241  value.ensure_gpu_up_to_date();
1242  }
1243 
1250  friend std::ostream& operator<<(std::ostream& os, const unary_expr& expr) {
1251  return os << Op::desc() << '(' << expr.value << ')';
1252  }
1253 };
1254 
1258 template <typename T, typename Expr, typename UnaryOp>
1259 struct etl_traits<etl::unary_expr<T, Expr, UnaryOp>> {
1261  using sub_expr_t = std::decay_t<Expr>;
1263  using value_type = T;
1264 
1265  static constexpr bool is_etl = true;
1266  static constexpr bool is_transformer = false;
1267  static constexpr bool is_view = false;
1268  static constexpr bool is_magic_view = false;
1269  static constexpr bool is_fast = sub_traits::is_fast;
1270  static constexpr bool is_value = false;
1271  static constexpr bool is_direct =
1272  std::is_same_v<UnaryOp, identity_op> && sub_traits::is_direct;
1273  static constexpr bool is_linear = sub_traits::is_linear && UnaryOp::linear;
1274  static constexpr bool is_thread_safe = sub_traits::is_thread_safe && UnaryOp::thread_safe;
1275  static constexpr bool is_generator = sub_traits::is_generator;
1276  static constexpr bool is_temporary = sub_traits::is_temporary;
1277  static constexpr bool is_padded = is_linear && sub_traits::is_padded;
1278  static constexpr bool is_aligned = is_linear && sub_traits::is_aligned;
1279  static constexpr order storage_order = sub_traits::storage_order;
1280 
1284  static constexpr bool gpu_computable = is_gpu_computable<Expr> && UnaryOp::template gpu_computable<Expr> && (is_floating<Expr> || is_complex<Expr>);
1285 
1291  template <vector_mode_t V>
1292  static constexpr bool vectorizable = sub_traits::template vectorizable<V>&& UnaryOp::template vectorizable<V>;
1293 
1299  static size_t size(const expr_t& v) {
1300  return sub_traits::size(v.value);
1301  }
1302 
1309  static size_t dim(const expr_t& v, size_t d) {
1310  return sub_traits::dim(v.value, d);
1311  }
1312 
1317  static constexpr size_t size() {
1318  return sub_traits::size();
1319  }
1320 
1326  template <size_t D>
1327  static constexpr size_t dim() {
1328  return sub_traits::template dim<D>();
1329  }
1330 
1335  static constexpr size_t dimensions() {
1336  return sub_traits::dimensions();
1337  }
1338 
1343  static constexpr int complexity() noexcept {
1344  return UnaryOp::complexity() + sub_traits::complexity();
1345  }
1346 };
1347 
1348 } //end of namespace etl
bool is_cpu_up_to_date() const noexcept requires(etl_dma< Expr >)
Indicates if the CPU memory is up to date.
Definition: unary_expr.hpp:792
friend std::ostream & operator<<(std::ostream &os, const unary_expr &expr)
Prints the type of the unary expression to the stream.
Definition: unary_expr.hpp:810
CRTP class to inject iterators functions.
Definition: iterable.hpp:23
std::conditional_t< dma, const value_type *, etl::iterator< const this_type > > const_iterator
The const iterator type.
Definition: unary_expr.hpp:383
Specialization of unary expression for stateful op.
Definition: unary_expr.hpp:1036
void assign_add_to(L &&lhs) const
Add to the given left-hand-side expression.
Definition: dyn_matrix_view.hpp:217
bool alias(const E &rhs) const noexcept
Test if this expression aliases with the given expression.
Definition: unary_expr.hpp:223
vec_type< V > load(size_t i) const
Load several elements of the matrix at once.
Definition: unary_expr.hpp:192
unary_expr(Expr l) noexcept
Construct a new unary expression.
Definition: unary_expr.hpp:397
std::conditional_t< const_return_ref, const value_type &, value_type > const_return_type
The const type returned by the const functions.
Definition: unary_expr.hpp:380
void stream(vec_type< V > in, size_t i) noexcept
Store several elements in the matrix at once, using non-temporal store.
Definition: unary_expr.hpp:468
Simple unary op for identity operations.
Definition: unary_expr.hpp:24
unary_expr(Expr l, Args &&... args)
Construct a new unary_expr from the given sub-expression and construct the op by forwarding it the gi...
Definition: unary_expr.hpp:1070
std::decay_t< Expr > sub_expr_t
The sub expression type.
Definition: unary_expr.hpp:1261
Transformer functor for optimizable expression.
Definition: expr_fwd.hpp:19
T value_type
The value type.
Definition: unary_expr.hpp:1051
static constexpr size_t dimensions()
Returns the number of expressions for this type.
Definition: unary_expr.hpp:1335
unary_expr(Expr l)
Construct a new unary_expr from the given sub-expression.
Definition: unary_expr.hpp:858
auto slice(E &&value, size_t first, size_t last) -> slice_view< detail::build_identity_type< E >>
Returns view representing a slice view of the given expression.
Definition: view_expression_builder.hpp:112
std::conditional_t< dma, value_type *, etl::iterator< this_type > > iterator
The iterator type.
Definition: unary_expr.hpp:382
void std_assign_evaluate(Expr &&expr, Result &&result)
Evaluation of the expr into result.
Definition: evaluator.hpp:1176
Expr expr_t
The sub expression type.
Definition: unary_expr.hpp:1054
Sub op
The sub operator type.
Definition: unary_expr.hpp:95
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
void validate_gpu() const noexcept requires(etl_dma< Expr >)
Validates the GPU memory.
Definition: unary_expr.hpp:745
vec_type< V > loadu(size_t i) const
Load several elements of the matrix at once.
Definition: unary_expr.hpp:203
void assign_mul_to(L &&lhs) const
Multiply the given left-hand-side expression.
Definition: dyn_matrix_view.hpp:235
void memory_type
The memory type.
Definition: unary_expr.hpp:1052
void assign_to(L &&lhs) const
Assign to the given left-hand-side expression.
Definition: unary_expr.hpp:252
constexpr bool is_magic_view
Traits indicating if the given ETL type is a magic view expression.
Definition: traits.hpp:311
static constexpr int complexity()
Estimate the complexity of operator.
Definition: unary_expr.hpp:115
const_memory_t< Expr > const_memory_type
The const memory type.
Definition: unary_expr.hpp:378
void invalidate_cpu() const noexcept requires(etl_dma< Expr >)
Invalidates the CPU memory.
Definition: unary_expr.hpp:724
bool is_gpu_up_to_date() const noexcept requires(etl_dma< Expr >)
Indicates if the GPU memory is up to date.
Definition: unary_expr.hpp:800
T value_type
The value type.
Definition: unary_expr.hpp:138
auto operator()(size_t i) const requires sub_capable< this_type >
Creates a sub view of the matrix, effectively removing the first dimension and fixing it to the given...
Definition: unary_expr.hpp:521
value_type operator()(S... args) const
Returns the value at the position (args...)
Definition: unary_expr.hpp:213
void assign_to(L &&lhs) const
Assign to the given left-hand-side expression.
Definition: dyn_matrix_view.hpp:208
Simple unary op for transform operations.
Definition: unary_expr.hpp:56
memory_t< Expr > memory_type
The memory type.
Definition: unary_expr.hpp:377
static constexpr size_t size()
Returns the size of an expression of this fast type.
Definition: unary_expr.hpp:1317
vec_type< V > loadu(size_t i) const
Load several elements of the matrix at once.
Definition: unary_expr.hpp:1118
order
Storage order of a matrix.
Definition: order.hpp:15
void const_memory_type
The const memory type.
Definition: unary_expr.hpp:1053
static constexpr bool gpu_computable
Indicates if the operator can be computed on GPU.
Definition: unary_expr.hpp:40
value_type operator[](size_t i) const
Returns the element at the given index.
Definition: unary_expr.hpp:1086
void gpu_evict() const noexcept requires(etl_dma< Expr >)
Evict the expression from GPU.
Definition: unary_expr.hpp:717
void ensure_gpu_up_to_date() const
Copy back from the GPU to the expression memory if necessary.
Definition: unary_expr.hpp:324
value_type read_flat(size_t i) const noexcept
Returns the value at the given index This function never alters the state of the container.
Definition: unary_expr.hpp:181
void assign_add_to(L &&lhs) const
Add to the given left-hand-side expression.
Definition: unary_expr.hpp:261
An unary expression.
Definition: unary_expr.hpp:126
Simple unary op for stateful operations.
Definition: unary_expr.hpp:91
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
An optimizer for the given expression type.
Definition: expr_fwd.hpp:16
void assign_mod_to(L &&lhs) const
Modulo the given left-hand-side expression.
Definition: unary_expr.hpp:297
void assign_div_to(L &&lhs) const
Divide the given left-hand-side expression.
Definition: unary_expr.hpp:288
Expr expr_t
The sub expression type.
Definition: unary_expr.hpp:850
Specialization of unary expression for identity op.
Definition: unary_expr.hpp:346
value_type operator[](size_t i) const
Returns the element at the given index.
Definition: unary_expr.hpp:874
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
void assign_sub_to(L &&lhs) const
Sub from the given left-hand-side expression.
Definition: unary_expr.hpp:270
Root namespace for the ETL library.
Definition: adapter.hpp:15
value_type read_flat(size_t i) const noexcept
Returns the value at the given index This function never alters the state of the container.
Definition: unary_expr.hpp:435
value_type read_flat(size_t i) const
Returns the value at the given index This function never alters the state of the container.
Definition: unary_expr.hpp:1096
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 validate_cpu() const noexcept requires(etl_dma< Expr >)
Validates the CPU memory.
Definition: unary_expr.hpp:738
void assign_mul_to(L &&lhs) const
Multiply the given left-hand-side expression.
Definition: unary_expr.hpp:279
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
friend std::ostream & operator<<(std::ostream &os, const unary_expr &expr)
Prints the type of the unary expression to the stream.
Definition: unary_expr.hpp:335
typename V::template vec_type< T > vec_type
Definition: unary_expr.hpp:149
std::conditional_t< non_const_return_ref, value_type &, value_type > return_type
The type returned by the functions.
Definition: unary_expr.hpp:379
auto slice(size_t first, size_t last) const noexcept
Creates a slice view of the matrix, effectively reducing the first dimension.
Definition: unary_expr.hpp:541
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
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
return_type operator[](size_t i)
Returns the element at the given index.
Definition: unary_expr.hpp:416
Expr expr_t
The sub expression type.
Definition: unary_expr.hpp:381
Visitor to perform local evaluation when necessary.
Definition: eval_visitors.hpp:23
size_t & unsafe_dimension_access(size_t i)
Returns a reference to the ith dimension value.
Definition: unary_expr.hpp:503
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: unary_expr.hpp:307
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
void store(vec_type< V > in, size_t i) noexcept
Store several elements in the matrix at once.
Definition: unary_expr.hpp:446
static constexpr size_t dim()
Returns the Dth dimension of an expression of this type.
Definition: unary_expr.hpp:1327
const_return_type operator()(size_t j) const
Access to the element at the given position.
Definition: dyn_matrix_view.hpp:89
void ensure_gpu_up_to_date() const
Allocate memory on the GPU for the expression and copy the values into the GPU.
Definition: unary_expr.hpp:760
void direct_fill(E &&mat, V value)
Fill the given ETL value class with the given value.
Definition: direct_fill.hpp:25
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: unary_expr.hpp:315
vec_type< V > load(size_t i) const
Load several elements of the matrix at once.
Definition: unary_expr.hpp:1107
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
auto operator()(size_t i) requires sub_capable< this_type >
Creates a sub view of the matrix, effectively removing the first dimension and fixing it to the given...
Definition: unary_expr.hpp:512
constexpr bool is_transformer
Traits indicating if the given ETL type is a transformer expression.
Definition: traits.hpp:297
value_type read_flat(size_t i) const noexcept
Returns the value at the given index This function never alters the state of the container.
Definition: unary_expr.hpp:884
void ensure_gpu_allocated() const requires(etl_dma< Expr >)
Ensures that the GPU memory is allocated and that the GPU memory is up to date (to undefined value)...
Definition: unary_expr.hpp:753
void visit(detail::evaluator_visitor &visitor) const
Apply the given visitor to this expression and its descendants.
Definition: dyn_matrix_view.hpp:263
Expr expr_t
The sub expression type.
Definition: unary_expr.hpp:141
constexpr size_t size(const E &expr) noexcept
Returns the size of the given ETL expression.
Definition: helpers.hpp:108
void invalidate_gpu() const noexcept requires(etl_dma< Expr >)
Invalidates the GPU memory.
Definition: unary_expr.hpp:731
void ensure_cpu_up_to_date() const
Copy back from the GPU to the expression memory if necessary.
Definition: unary_expr.hpp:772
void gpu_copy_from(const T *gpu_memory) const requires(etl_dma< Expr >)
Copy from GPU to GPU.
Definition: unary_expr.hpp:784
value_type operator[](size_t i) const
Returns the element at the given index.
Definition: unary_expr.hpp:171
static constexpr int complexity()
Estimate the complexity of operator.
Definition: unary_expr.hpp:46
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
void ensure_gpu_up_to_date() const
Copy back from the GPU to the expression memory if necessary.
Definition: dyn_matrix_view.hpp:280
static constexpr bool linear
Indicates if the operator is linear.
Definition: unary_expr.hpp:25
static constexpr bool thread_safe
Indicates if the operator is thread safe.
Definition: unary_expr.hpp:26
Simple traits to test if an expression is optimizable.
Definition: expr_fwd.hpp:13
static constexpr int complexity() noexcept
Estimate the complexity of computation.
Definition: unary_expr.hpp:1343
static constexpr int complexity()
Estimate the complexity of operator.
Definition: unary_expr.hpp:78
CRTP class to inject assign operations to matrix and vector structures.
Definition: assignable.hpp:25
void storeu(vec_type< V > in, size_t i) noexcept
Store several elements in the matrix at once.
Definition: unary_expr.hpp:457
unary_expr(Expr l)
Construct a new unary_expr with the given sub expression.
Definition: unary_expr.hpp:155
void std_sub_evaluate(Expr &&expr, Result &&result)
Compound subtract evaluation of the expr into result.
Definition: evaluator.hpp:1214
T value_type
The value type.
Definition: unary_expr.hpp:1263
auto operator()(size_t i) const requires sub_capable< this_type >
Creates a sub view of the matrix, effectively removing the first dimension and fixing it to the given...
Definition: unary_expr.hpp:893
typename V::template vec_type< value_type > vec_type
Definition: unary_expr.hpp:389
void assign_mod_to(L &&lhs) const
Modulo the given left-hand-side expression.
Definition: dyn_matrix_view.hpp:253
void memory_type
The memory type.
Definition: unary_expr.hpp:139
auto slice(size_t first, size_t last) noexcept
Creates a slice view of the matrix, effectively reducing the first dimension.
Definition: unary_expr.hpp:531
constexpr bool is_thread_safe
Traits to test if the given ETL expresion type is thread safe.
Definition: traits.hpp:687
void const_memory_type
The const memory type.
Definition: unary_expr.hpp:140
typename V::template vec_type< T > vec_type
Definition: unary_expr.hpp:1062
void const_memory_type
The const memory type of the expression.
Definition: unary_expr.hpp:849
void memory_type
The memory type of the expression.
Definition: unary_expr.hpp:848
static size_t size(const expr_t &v)
Returns the size of the given expression.
Definition: unary_expr.hpp:1299
Specialization of unary expression for transform op.
Definition: unary_expr.hpp:834
const auto & gpu_compute_hint([[maybe_unused]] Y &y) const
Return a GPU computed version of this expression.
Definition: sub_view.hpp:653
T value_type
The value type.
Definition: unary_expr.hpp:375
void std_div_evaluate(Expr &&expr, Result &&result)
Compound divide evaluation of the expr into result.
Definition: evaluator.hpp:1252
const_return_type operator[](size_t i) const
Returns the element at the given index.
Definition: unary_expr.hpp:425
value_type * gpu_memory() const noexcept
Return GPU memory of this expression, if any.
Definition: sub_view.hpp:674
Definition: gpu_handler.hpp:549
static size_t dim(const expr_t &v, size_t d)
Returns the dth dimension of the given expression.
Definition: unary_expr.hpp:1309
T value_type
The value type of the expression.
Definition: unary_expr.hpp:847
static constexpr bool vectorizable
Indicates if the expression is vectorizable using the given vector mode.
Definition: unary_expr.hpp:34
void std_add_evaluate(Expr &&expr, Result &&result)
Compound add evaluation of the expr into result.
Definition: evaluator.hpp:1195
CRTP class to inject functions testing the dimensions.
Definition: dim_testable.hpp:45
void assign_sub_to(L &&lhs) const
Sub from the given left-hand-side expression.
Definition: dyn_matrix_view.hpp:226