aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--arm_compute/core/Helpers.h74
-rw-r--r--arm_compute/core/Helpers.inl15
-rw-r--r--arm_compute/core/utils/misc/utility.h58
-rw-r--r--arm_compute/graph/nodes/BranchLayer.h4
-rw-r--r--src/core/NEON/kernels/NEWarpKernel.cpp32
-rw-r--r--tests/validation/reference/ConvolutionLayer.cpp2
-rw-r--r--tests/validation/reference/FullyConnectedLayer.cpp2
-rw-r--r--tests/validation/reference/Scale.cpp7
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)];
}
}