Expression Templates Library (ETL)
checks.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 
16 #pragma once
17 
18 namespace etl {
19 
29 template <typename LE, typename RE>
30 void validate_expression_impl([[maybe_unused]] const LE& lhs, [[maybe_unused]] const RE& rhs) noexcept {
32  // Nothing to test, generators are of infinite size
33  } else if constexpr (all_etl_expr<LE, RE> && !all_fast<LE, RE>) {
34  cpp_assert(etl::size(lhs) == etl::size(rhs), "Cannot perform element-wise operations on collections of different size");
35  } else {
36  static_assert(etl_traits<LE>::size() == etl_traits<RE>::size(), "Cannot perform element-wise operations on collections of different size");
37  }
38 }
39 
40 // In relaxed mode, the expressions are only validated when assigned
41 // This allows for batch_hint to works
42 
43 #ifdef ETL_RELAXED
44 #define validate_expression(lhs, rhs) static_assert(all_etl_expr<decltype(lhs), decltype(rhs)>, "ETL functions are only made for ETL expressions ")
45 #else
46 #define validate_expression(lhs, rhs) \
47  static_assert(all_etl_expr<decltype(lhs), decltype(rhs)>, "ETL functions are only made for ETL expressions "); \
48  validate_expression_impl(lhs, rhs)
49 #endif
50 
51 template <etl_expr LE, typename RE>
52 void validate_assign([[maybe_unused]] const LE& lhs, [[maybe_unused]] const RE& rhs) {
53  if constexpr (etl_traits<RE>::is_generator) {
54  // Nothing to test, generators are of infinite size
55  } else if constexpr (is_etl_expr<RE> && all_fast<LE, RE> && !is_wrapper_expr<RE>) {
56  static_assert(etl_traits<LE>::size() == etl_traits<RE>::size(), "Cannot perform element-wise operations on collections of different size");
57  } else if constexpr (!is_etl_expr<RE> && !is_wrapper_expr<RE>) {
58  cpp_assert(etl::size(lhs) == rhs.size(), "Cannot perform element-wise operations on collections of different size");
59  } else {
60  cpp_assert(etl::size(lhs) == etl::size(rhs), "Cannot perform element-wise operations on collections of different size");
61  }
62 }
63 
72 template <etl_2d E>
73 void assert_square([[maybe_unused]] E&& expr) {
74  if constexpr (is_fast<E>) {
75  static_assert(decay_traits<E>::template dim<0>() == decay_traits<E>::template dim<1>(), "Function undefined for non-square matrix");
76  } else {
77  cpp_assert(etl::dim<0>(expr) == etl::dim<1>(expr), "Function undefined for non-square matrix");
78  }
79 }
80 
81 namespace detail {
82 
93 template <size_t C1, size_t C2, dyn_2d E>
94 void validate_pmax_pooling_impl([[maybe_unused]] const E& e) {
95  cpp_assert(etl::template dim<0>(e) % C1 == 0 && etl::template dim<1>(e) % C2 == 0, "Dimensions not divisible by the pooling ratio");
96 }
97 
101 template <size_t C1, size_t C2, dyn_3d E>
102 void validate_pmax_pooling_impl([[maybe_unused]] const E& e) {
103  cpp_assert(etl::template dim<1>(e) % C1 == 0 && etl::template dim<2>(e) % C2 == 0, "Dimensions not divisible by the pooling ratio");
104 }
105 
109 template <size_t C1, size_t C2, dyn_4d E>
110 void validate_pmax_pooling_impl([[maybe_unused]] const E& e) {
111  cpp_assert(etl::template dim<2>(e) % C1 == 0 && etl::template dim<3>(e) % C2 == 0, "Dimensions not divisible by the pooling ratio");
112 }
113 
117 template <size_t C1, size_t C2, fast_2d E>
118 void validate_pmax_pooling_impl(const E& /*unused*/) {
119  static_assert(etl_traits<E>::template dim<0>() % C1 == 0 && etl_traits<E>::template dim<1>() % C2 == 0, "Dimensions not divisible by the pooling ratio");
120 }
121 
125 template <size_t C1, size_t C2, fast_3d E>
126 void validate_pmax_pooling_impl(const E& /*unused*/) {
127  static_assert(etl_traits<E>::template dim<1>() % C1 == 0 && etl_traits<E>::template dim<2>() % C2 == 0, "Dimensions not divisible by the pooling ratio");
128 }
129 
133 template <size_t C1, size_t C2, fast_4d E>
134 void validate_pmax_pooling_impl(const E& /*unused*/) {
135  static_assert(etl_traits<E>::template dim<2>() % C1 == 0 && etl_traits<E>::template dim<3>() % C2 == 0, "Dimensions not divisible by the pooling ratio");
136 }
137 
148 template <etl_2d E>
149 void validate_pmax_pooling_impl([[maybe_unused]] const E& e, [[maybe_unused]] size_t c1, [[maybe_unused]] size_t c2) {
150  cpp_assert(etl::template dim<0>(e) % c1 == 0 && etl::template dim<1>(e) % c2 == 0, "Dimensions not divisible by the pooling ratio");
151 }
152 
156 template <etl_3d E>
157 void validate_pmax_pooling_impl([[maybe_unused]] const E& e, [[maybe_unused]] size_t c1, [[maybe_unused]] size_t c2) {
158  cpp_assert(etl::template dim<1>(e) % c1 == 0 && etl::template dim<2>(e) % c2 == 0, "Dimensions not divisible by the pooling ratio");
159 }
160 
164 template <etl_4d E>
165 void validate_pmax_pooling_impl([[maybe_unused]] const E& e, [[maybe_unused]] size_t c1, [[maybe_unused]] size_t c2) {
166  cpp_assert(etl::template dim<2>(e) % c1 == 0 && etl::template dim<3>(e) % c2 == 0, "Dimensions not divisible by the pooling ratio");
167 }
168 
169 } //end of namespace detail
170 
181 template <size_t C1, size_t C2, dimensions_between<2, 4> E>
182 void validate_pmax_pooling(const E& expr) {
183  detail::validate_pmax_pooling_impl<C1, C2>(expr);
184 }
185 
196 template <dimensions_between<2, 4> E>
197 void validate_pmax_pooling(const E& expr, size_t c1, size_t c2) {
198  detail::validate_pmax_pooling_impl(expr, c1, c2);
199 }
200 
201 } //end of namespace etl
void validate_expression_impl([[maybe_unused]] const LE &lhs, [[maybe_unused]] const RE &rhs) noexcept
Make sure the two expressions have the same size.
Definition: checks.hpp:30
void validate_pmax_pooling_impl([[maybe_unused]] const E &e)
Make sure that the pooling ratios are correct and that the expression can be pooled from...
Definition: checks.hpp:94
Traits to get information about ETL types.
Definition: tmp.hpp:68
Root namespace for the ETL library.
Definition: adapter.hpp:15
void validate_pmax_pooling(const E &expr)
Make sure that the pooling ratios are correct and that the expression can be pooled from...
Definition: checks.hpp:182
constexpr size_t size(const E &expr) noexcept
Returns the size of the given ETL expression.
Definition: helpers.hpp:108
void assert_square([[maybe_unused]] E &&expr)
Make sure that the expression is square.
Definition: checks.hpp:73