diff options
-rw-r--r-- | arm_compute/core/Helpers.h | 74 | ||||
-rw-r--r-- | arm_compute/core/Helpers.inl | 15 | ||||
-rw-r--r-- | arm_compute/core/utils/misc/utility.h | 58 | ||||
-rw-r--r-- | arm_compute/graph/nodes/BranchLayer.h | 4 | ||||
-rw-r--r-- | src/core/NEON/kernels/NEWarpKernel.cpp | 32 | ||||
-rw-r--r-- | tests/validation/reference/ConvolutionLayer.cpp | 2 | ||||
-rw-r--r-- | tests/validation/reference/FullyConnectedLayer.cpp | 2 | ||||
-rw-r--r-- | tests/validation/reference/Scale.cpp | 7 |
8 files changed, 89 insertions, 105 deletions
diff --git a/arm_compute/core/Helpers.h b/arm_compute/core/Helpers.h index c02f14aecc..3575fcf1b9 100644 --- a/arm_compute/core/Helpers.h +++ b/arm_compute/core/Helpers.h @@ -253,72 +253,6 @@ inline uint8_t pixel_bilinear_c1_clamp(const T *first_pixel_ptr, size_t stride, */ inline uint8_t pixel_area_c1u8_clamp(const uint8_t *first_pixel_ptr, size_t stride, size_t width, size_t height, float wr, float hr, int x, int y); -/** Performs clamping among a lower and upper value. - * - * @param[in] n Value to clamp. - * @param[in] lower Lower threshold. - * @param[in] upper Upper threshold. - * - * @return Clamped value. - */ -template <typename T> -inline T clamp(const T &n, const T &lower, const T &upper) -{ - return std::max(lower, std::min(n, upper)); -} - -/** Base case of for_each. Does nothing. */ -template <typename F> -inline void for_each(F &&) -{ -} - -/** Call the function for each of the arguments - * - * @param[in] func Function to be called - * @param[in] arg Argument passed to the function - * @param[in] args Remaining arguments - */ -template <typename F, typename T, typename... Ts> -inline void for_each(F &&func, T &&arg, Ts &&... args) -{ - func(arg); - for_each(func, args...); -} - -/** Base case of foldl. - * - * @return value. - */ -template <typename F, typename T> -inline T foldl(F &&, const T &value) -{ - return value; -} - -/** Base case of foldl. - * - * @return Function evaluation for value1 and value2 - */ -template <typename F, typename T, typename U> -inline auto foldl(F &&func, T &&value1, U &&value2) -> decltype(func(value1, value2)) -{ - return func(value1, value2); -} - -/** Fold left. - * - * @param[in] func Function to be called - * @param[in] initial Initial value - * @param[in] value Argument passed to the function - * @param[in] values Remaining arguments - */ -template <typename F, typename I, typename T, typename... Vs> -inline I foldl(F &&func, I &&initial, T &&value, Vs &&... values) -{ - return foldl(std::forward<F>(func), func(std::forward<I>(initial), std::forward<T>(value)), std::forward<Vs>(values)...); -} - /** Iterator updated by @ref execute_window_loop for each window element */ class Iterator { @@ -408,7 +342,7 @@ bool update_window_and_padding(Window &win, Ts &&... patterns) { bool window_changed = false; - for_each([&](const IAccessWindow & w) + utility::for_each([&](const IAccessWindow & w) { window_changed |= w.update_window_if_needed(win); }, @@ -416,7 +350,7 @@ bool update_window_and_padding(Window &win, Ts &&... patterns) bool padding_changed = false; - for_each([&](const IAccessWindow & w) + utility::for_each([&](const IAccessWindow & w) { padding_changed |= w.update_padding_if_needed(win); }, @@ -464,7 +398,7 @@ Window calculate_max_enlarged_window(const ITensorInfo &info, const Steps &steps * @return Intersection of all regions. */ template <typename... Ts> -ValidRegion intersect_valid_regions(Ts &&... regions) +ValidRegion intersect_valid_regions(const Ts &... regions) { auto intersect = [](const ValidRegion & r1, const ValidRegion & r2) -> ValidRegion { @@ -483,7 +417,7 @@ ValidRegion intersect_valid_regions(Ts &&... regions) return region; }; - return foldl(intersect, std::forward<Ts>(regions)...); + return utility::foldl(intersect, regions...); } /** Create a strides object based on the provided strides and the tensor dimensions. diff --git a/arm_compute/core/Helpers.inl b/arm_compute/core/Helpers.inl index 3672692814..4121fb1e8d 100644 --- a/arm_compute/core/Helpers.inl +++ b/arm_compute/core/Helpers.inl @@ -80,17 +80,12 @@ struct IncrementIterators template <typename T, typename... Ts> static void unroll(T &&it, Ts &&... iterators) { - it.increment(dimension); - IncrementIterators<dimension>::unroll<Ts...>(std::forward<Ts>(iterators)...); - } - - template <typename T> - static void unroll(T &&it) - { - it.increment(dimension); - // End of recursion + auto increment = [](T && it) + { + it.increment(dimension); + }; + utility::for_each(increment, std::forward<T>(it), std::forward<Ts>(iterators)...); } - static void unroll() { // End of recursion diff --git a/arm_compute/core/utils/misc/utility.h b/arm_compute/core/utils/misc/utility.h index 898d0cdea8..45b3b5268e 100644 --- a/arm_compute/core/utils/misc/utility.h +++ b/arm_compute/core/utils/misc/utility.h @@ -67,6 +67,62 @@ std::array<typename std::iterator_traits<Iterator>::value_type, N> make_array(It { return detail::make_array(first, index_sequence_t<N> {}); } -} // namespace misc + +/** Performs clamping among a lower and upper value. + * + * @param[in] n Value to clamp. + * @param[in] lower Lower threshold. + * @param[in] upper Upper threshold. + * + * @return Clamped value. + */ +template <typename T> +inline T clamp(const T &n, const T &lower, const T &upper) +{ + return std::max(lower, std::min(n, upper)); +} + +/** Base case of for_each. Does nothing. */ +template <typename F> +inline void for_each(F &&) +{ +} + +/** Call the function for each of the arguments + * + * @param[in] func Function to be called + * @param[in] arg Argument passed to the function + * @param[in] args Remaining arguments + */ +template <typename F, typename T, typename... Ts> +inline void for_each(F &&func, T &&arg, Ts &&... args) +{ + func(std::forward<T>(arg)); + for_each(std::forward<F>(func), std::forward<Ts>(args)...); +} + +/** Base case of foldl. + * + * @return value. + */ +template <typename F, typename T> +inline T &&foldl(F &&, T &&value) +{ + return std::forward<T>(value); +} + +/** Fold left. + * + * @param[in] func Function to be called + * @param[in] initial Initial value + * @param[in] value Argument passed to the function + * @param[in] values Remaining arguments + */ +template <typename F, typename T, typename U, typename... Us> +inline auto foldl(F &&func, T &&initial, U &&value, Us &&... values) -> decltype(func(std::forward<T>(initial), std::forward<U>(value))) +{ + return foldl(std::forward<F>(func), func(std::forward<T>(initial), std::forward<U>(value)), std::forward<Us>(values)...); +} +} // namespace utility } // namespace arm_compute #endif /* __ARM_COMPUTE_MISC_UTILITY_H__ */ diff --git a/arm_compute/graph/nodes/BranchLayer.h b/arm_compute/graph/nodes/BranchLayer.h index dd05315909..5e4a8d98b1 100644 --- a/arm_compute/graph/nodes/BranchLayer.h +++ b/arm_compute/graph/nodes/BranchLayer.h @@ -31,7 +31,7 @@ #include "arm_compute/graph/SubTensor.h" #include "arm_compute/graph/Types.h" -#include "arm_compute/core/Helpers.h" +#include "arm_compute/core/utils/misc/utility.h" #include <vector> @@ -58,7 +58,7 @@ public: _sub_graphs.push_back(arm_compute::support::cpp14::make_unique<SubGraph>(std::move(sub_graph1))); _sub_graphs.push_back(arm_compute::support::cpp14::make_unique<SubGraph>(std::move(sub_graph2))); - for_each([&](SubGraph & sub_graph) + utility::for_each([&](SubGraph && sub_graph) { _sub_graphs.push_back(arm_compute::support::cpp14::make_unique<SubGraph>(std::move(sub_graph))); }, diff --git a/src/core/NEON/kernels/NEWarpKernel.cpp b/src/core/NEON/kernels/NEWarpKernel.cpp index ab8ab14ae5..0fa8278fe3 100644 --- a/src/core/NEON/kernels/NEWarpKernel.cpp +++ b/src/core/NEON/kernels/NEWarpKernel.cpp @@ -287,10 +287,10 @@ void NEWarpAffineKernel<interpolation>::warp_constant(const Window &window) break; case InterpolationPolicy::BILINEAR: { - const auto xi = clamp<int>(std::floor(x0), min_x - 1, max_x); - const auto yi = clamp<int>(std::floor(y0), min_y - 1, max_y); - const auto xi_1 = clamp<int>(std::floor(x0 + 1), min_x - 1, max_x); - const auto yi_1 = clamp<int>(std::floor(y0 + 1), min_y - 1, max_y); + const auto xi = utility::clamp<int>(std::floor(x0), min_x - 1, max_x); + const auto yi = utility::clamp<int>(std::floor(y0), min_y - 1, max_y); + const auto xi_1 = utility::clamp<int>(std::floor(x0 + 1), min_x - 1, max_x); + const auto yi_1 = utility::clamp<int>(std::floor(y0 + 1), min_y - 1, max_y); const float dx = x0 - std::floor(x0); const float dy = y0 - std::floor(y0); @@ -396,8 +396,8 @@ void NEWarpAffineKernel<interpolation>::warp_replicate(const Window &window) else { // Clamp coordinates - const auto xi = clamp<int>(std::floor(x0), min_x, max_x - 1); - const auto yi = clamp<int>(std::floor(y0), min_y, max_y - 1); + const auto xi = utility::clamp<int>(std::floor(x0), min_x, max_x - 1); + const auto yi = utility::clamp<int>(std::floor(y0), min_y, max_y - 1); switch(interpolation) { case InterpolationPolicy::NEAREST_NEIGHBOR: @@ -405,8 +405,8 @@ void NEWarpAffineKernel<interpolation>::warp_replicate(const Window &window) break; case InterpolationPolicy::BILINEAR: { - const auto xi_1 = clamp<int>(std::floor(x0 + 1), min_x, max_x - 1); - const auto yi_1 = clamp<int>(std::floor(y0 + 1), min_y, max_y - 1); + const auto xi_1 = utility::clamp<int>(std::floor(x0 + 1), min_x, max_x - 1); + const auto yi_1 = utility::clamp<int>(std::floor(y0 + 1), min_y, max_y - 1); const float dx = x0 - std::floor(x0); const float dy = y0 - std::floor(y0); @@ -636,10 +636,10 @@ void NEWarpPerspectiveKernel<interpolation>::warp_constant(const Window &window) break; case InterpolationPolicy::BILINEAR: { - const auto xi = clamp<int>(std::floor(xn), min_x - 1, max_x); - const auto yi = clamp<int>(std::floor(yn), min_y - 1, max_y); - const auto xi_1 = clamp<int>(std::floor(xn + 1), min_x - 1, max_x); - const auto yi_1 = clamp<int>(std::floor(yn + 1), min_y - 1, max_y); + const auto xi = utility::clamp<int>(std::floor(xn), min_x - 1, max_x); + const auto yi = utility::clamp<int>(std::floor(yn), min_y - 1, max_y); + const auto xi_1 = utility::clamp<int>(std::floor(xn + 1), min_x - 1, max_x); + const auto yi_1 = utility::clamp<int>(std::floor(yn + 1), min_y - 1, max_y); const float dx = xn - std::floor(xn); const float dy = yn - std::floor(yn); @@ -762,8 +762,8 @@ void NEWarpPerspectiveKernel<interpolation>::warp_replicate(const Window &window else { // Clamp coordinates - const auto xi = clamp<int>(std::floor(xn), min_x, max_x - 1); - const auto yi = clamp<int>(std::floor(yn), min_y, max_y - 1); + const auto xi = utility::clamp<int>(std::floor(xn), min_x, max_x - 1); + const auto yi = utility::clamp<int>(std::floor(yn), min_y, max_y - 1); switch(interpolation) { case InterpolationPolicy::NEAREST_NEIGHBOR: @@ -771,8 +771,8 @@ void NEWarpPerspectiveKernel<interpolation>::warp_replicate(const Window &window break; case InterpolationPolicy::BILINEAR: { - const auto xi_1 = clamp<int>(std::floor(xn + 1), min_x, max_x - 1); - const auto yi_1 = clamp<int>(std::floor(yn + 1), min_y, max_y - 1); + const auto xi_1 = utility::clamp<int>(std::floor(xn + 1), min_x, max_x - 1); + const auto yi_1 = utility::clamp<int>(std::floor(yn + 1), min_y, max_y - 1); const float dx = xn - std::floor(xn); const float dy = yn - std::floor(yn); diff --git a/tests/validation/reference/ConvolutionLayer.cpp b/tests/validation/reference/ConvolutionLayer.cpp index 10664119fb..567fac0f5e 100644 --- a/tests/validation/reference/ConvolutionLayer.cpp +++ b/tests/validation/reference/ConvolutionLayer.cpp @@ -210,7 +210,7 @@ void convolution3d(const SimpleTensor<uint8_t> &in, const SimpleTensor<uint8_t> acc = asymm_rounding_divide_by_pow2(asymm_int_mult(acc, output_multiplier), output_shift); acc += output_offset; - acc = clamp<int32_t>(acc, 0, 255); + acc = utility::clamp<int32_t>(acc, 0, 255); // Store the result *out_ptr = acc; diff --git a/tests/validation/reference/FullyConnectedLayer.cpp b/tests/validation/reference/FullyConnectedLayer.cpp index c24881e2b4..5384715ace 100644 --- a/tests/validation/reference/FullyConnectedLayer.cpp +++ b/tests/validation/reference/FullyConnectedLayer.cpp @@ -138,7 +138,7 @@ void vector_matrix_multiply(const SimpleTensor<uint8_t> &src, const SimpleTensor acc = asymm_rounding_divide_by_pow2(asymm_int_mult(acc, output_multiplier), output_shift); acc += output_offset; - acc = clamp<int32_t>(acc, 0, 255); + acc = utility::clamp<int32_t>(acc, 0, 255); // Store the result dst_ptr[y] = static_cast<uint8_t>(acc); diff --git a/tests/validation/reference/Scale.cpp b/tests/validation/reference/Scale.cpp index 727325f675..0cc96abcf3 100644 --- a/tests/validation/reference/Scale.cpp +++ b/tests/validation/reference/Scale.cpp @@ -22,10 +22,9 @@ * SOFTWARE. */ -#include "arm_compute/core/Helpers.h" - #include "Scale.h" #include "Utils.h" +#include "arm_compute/core/utils/misc/utility.h" #include "support/ToolchainSupport.h" namespace arm_compute @@ -119,8 +118,8 @@ SimpleTensor<T> scale(const SimpleTensor<T> &in, float scale_x, float scale_y, I } else if(border_mode == BorderMode::REPLICATE) { - id.set(0, clamp(static_cast<int>(x_src), 0, width - 1)); - id.set(1, clamp(static_cast<int>(y_src), 0, height - 1)); + id.set(0, utility::clamp<int>(x_src, 0, width - 1)); + id.set(1, utility::clamp<int>(y_src, 0, height - 1)); out[element_idx] = in[coord2index(in.shape(), id)]; } } |