From 04a8f8c4994f1c32b3f16a832c0e6f2599364c02 Mon Sep 17 00:00:00 2001 From: Giorgio Arena Date: Thu, 23 Nov 2017 11:45:24 +0000 Subject: COMPMID-692 Consistent names for the interfaces Change-Id: I4b1f3f0da9ff5342c7de7083736fe91871d14e5b Reviewed-on: https://eu-gerrit-1.euhpc.arm.com/110351 Tested-by: BSG Visual Compute Jenkins server to access repositories on http://mpd-gerrit.cambridge.arm.com Reviewed-by: Georgios Pinitas Reviewed-by: Anthony Barbier --- tests/validation/CPP/DepthConvert.cpp | 157 ----------------- tests/validation/CPP/DepthConvert.h | 56 ------ tests/validation/CPP/DepthConvertLayer.cpp | 157 +++++++++++++++++ tests/validation/CPP/DepthConvertLayer.h | 56 ++++++ tests/validation/CPP/DepthwiseConvolution.cpp | 195 --------------------- tests/validation/CPP/DepthwiseConvolution.h | 44 ----- tests/validation/CPP/DepthwiseConvolutionLayer.cpp | 195 +++++++++++++++++++++ tests/validation/CPP/DepthwiseConvolutionLayer.h | 44 +++++ .../CPP/DepthwiseSeparableConvolutionLayer.cpp | 2 +- tests/validation/CPP/L2Normalize.cpp | 88 ---------- tests/validation/CPP/L2Normalize.h | 44 ----- tests/validation/CPP/L2NormalizeLayer.cpp | 88 ++++++++++ tests/validation/CPP/L2NormalizeLayer.h | 44 +++++ 13 files changed, 585 insertions(+), 585 deletions(-) delete mode 100644 tests/validation/CPP/DepthConvert.cpp delete mode 100644 tests/validation/CPP/DepthConvert.h create mode 100644 tests/validation/CPP/DepthConvertLayer.cpp create mode 100644 tests/validation/CPP/DepthConvertLayer.h delete mode 100644 tests/validation/CPP/DepthwiseConvolution.cpp delete mode 100644 tests/validation/CPP/DepthwiseConvolution.h create mode 100644 tests/validation/CPP/DepthwiseConvolutionLayer.cpp create mode 100644 tests/validation/CPP/DepthwiseConvolutionLayer.h delete mode 100644 tests/validation/CPP/L2Normalize.cpp delete mode 100644 tests/validation/CPP/L2Normalize.h create mode 100644 tests/validation/CPP/L2NormalizeLayer.cpp create mode 100644 tests/validation/CPP/L2NormalizeLayer.h (limited to 'tests/validation/CPP') diff --git a/tests/validation/CPP/DepthConvert.cpp b/tests/validation/CPP/DepthConvert.cpp deleted file mode 100644 index 110174a73f..0000000000 --- a/tests/validation/CPP/DepthConvert.cpp +++ /dev/null @@ -1,157 +0,0 @@ -/* - * Copyright (c) 2017 ARM Limited. - * - * SPDX-License-Identifier: MIT - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -#include "DepthConvert.h" - -#include "tests/validation/FixedPoint.h" -#include "tests/validation/Helpers.h" - -#include "tests/Types.h" - -namespace arm_compute -{ -namespace test -{ -namespace validation -{ -namespace reference -{ -template < typename T1, typename T2, typename std::enable_if < std::is_integral::value &&std::is_floating_point::value, int >::type > -SimpleTensor depth_convert(const SimpleTensor &src, DataType dt_out, ConvertPolicy policy, uint32_t shift) -{ - ARM_COMPUTE_UNUSED(policy); - ARM_COMPUTE_UNUSED(shift); - - using namespace fixed_point_arithmetic; - SimpleTensor result(src.shape(), dt_out); - - const int fixed_point_position = src.fixed_point_position(); - - for(int i = 0; i < src.num_elements(); ++i) - { - result[i] = static_cast(fixed_point(src[i], fixed_point_position, true)); - } - - return result; -} - -template < typename T1, typename T2, typename std::enable_if < std::is_floating_point::value &&std::is_integral::value, int >::type > -SimpleTensor depth_convert(const SimpleTensor &src, DataType dt_out, ConvertPolicy policy, uint32_t shift) -{ - ARM_COMPUTE_UNUSED(policy); - ARM_COMPUTE_UNUSED(shift); - - using namespace fixed_point_arithmetic; - SimpleTensor result(src.shape(), dt_out, 1, src.fixed_point_position()); - - const int fixed_point_position = result.fixed_point_position(); - - for(int i = 0; i < src.num_elements(); ++i) - { - result[i] = fixed_point(src[i], fixed_point_position).raw(); - } - - return result; -} - -template < typename T1, typename T2, typename std::enable_if < std::is_integral::value &&std::is_integral::value &&!std::is_same::value, int >::type > -SimpleTensor depth_convert(const SimpleTensor &src, DataType dt_out, ConvertPolicy policy, uint32_t shift) -{ - SimpleTensor result(src.shape(), dt_out); - - // Up-casting - if(src.data_type() <= dt_out) - { - for(int i = 0; i < src.num_elements(); ++i) - { - result[i] = src[i] << shift; - } - } - // Down-casting - else - { - for(int i = 0; i < src.num_elements(); ++i) - { - T1 val = src[i] >> shift; - result[i] = (policy == ConvertPolicy::SATURATE) ? saturate_cast(val) : static_cast(val); - } - } - return result; -} - -template < typename T1, typename T2, typename std::enable_if < std::is_integral::value &&std::is_integral::value &&std::is_same::value, int >::type > -SimpleTensor depth_convert(const SimpleTensor &src, DataType dt_out, ConvertPolicy policy, uint32_t shift) -{ - ARM_COMPUTE_UNUSED(policy); - - using namespace fixed_point_arithmetic; - - SimpleTensor result(src.shape(), dt_out); - - bool is_in_place = (&src == &result); - - const int fixed_point_position_in = src.fixed_point_position(); - const int fixed_point_position_out = (is_in_place) ? static_cast(shift) : result.fixed_point_position(); - - if(!is_in_place || (fixed_point_position_in != fixed_point_position_out)) - { - for(int i = 0; i < src.num_elements(); ++i) - { - auto x = fixed_point(src[i], fixed_point_position_in, true); - x.resacle(fixed_point_position_out); - result[i] = x.raw(); - } - } - - return result; -} - -template < typename T1, typename T2, typename std::enable_if < std::is_floating_point::value &&is_floating_point::value, int >::type > -SimpleTensor depth_convert(const SimpleTensor &src, DataType dt_out, ConvertPolicy policy, uint32_t shift) -{ - ARM_COMPUTE_UNUSED(policy); - ARM_COMPUTE_UNUSED(shift); - - SimpleTensor result(src.shape(), dt_out); - - for(int i = 0; i < src.num_elements(); ++i) - { - result[i] = static_cast(src[i]); - } -} - -template SimpleTensor depth_convert(const SimpleTensor &src, DataType dt_out, ConvertPolicy policy, uint32_t shift); -template SimpleTensor depth_convert(const SimpleTensor &src, DataType dt_out, ConvertPolicy policy, uint32_t shift); -template SimpleTensor depth_convert(const SimpleTensor &src, DataType dt_out, ConvertPolicy policy, uint32_t shift); -template SimpleTensor depth_convert(const SimpleTensor &src, DataType dt_out, ConvertPolicy policy, uint32_t shift); -template SimpleTensor depth_convert(const SimpleTensor &src, DataType dt_out, ConvertPolicy policy, uint32_t shift); -template SimpleTensor depth_convert(const SimpleTensor &src, DataType dt_out, ConvertPolicy policy, uint32_t shift); -template SimpleTensor depth_convert(const SimpleTensor &src, DataType dt_out, ConvertPolicy policy, uint32_t shift); -template SimpleTensor depth_convert(const SimpleTensor &src, DataType dt_out, ConvertPolicy policy, uint32_t shift); -template SimpleTensor depth_convert(const SimpleTensor &src, DataType dt_out, ConvertPolicy policy, uint32_t shift); -template SimpleTensor depth_convert(const SimpleTensor &src, DataType dt_out, ConvertPolicy policy, uint32_t shift); -template SimpleTensor depth_convert(const SimpleTensor &src, DataType dt_out, ConvertPolicy policy, uint32_t shift); -} // namespace reference -} // namespace validation -} // namespace test -} // namespace arm_compute diff --git a/tests/validation/CPP/DepthConvert.h b/tests/validation/CPP/DepthConvert.h deleted file mode 100644 index 1446bfda5b..0000000000 --- a/tests/validation/CPP/DepthConvert.h +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Copyright (c) 2017 ARM Limited. - * - * SPDX-License-Identifier: MIT - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -#ifndef __ARM_COMPUTE_TEST_DEPTH_CONVERT_H__ -#define __ARM_COMPUTE_TEST_DEPTH_CONVERT_H__ - -#include "tests/SimpleTensor.h" -#include "tests/validation/Helpers.h" - -namespace arm_compute -{ -namespace test -{ -namespace validation -{ -namespace reference -{ -template < typename T1, typename T2, typename std::enable_if < std::is_integral::value &&std::is_floating_point::value, int >::type = 0 > -SimpleTensor depth_convert(const SimpleTensor &src, DataType dt_out, ConvertPolicy policy, uint32_t shift); - -template < typename T1, typename T2, typename std::enable_if < std::is_floating_point::value &&std::is_integral::value, int >::type = 0 > -SimpleTensor depth_convert(const SimpleTensor &src, DataType dt_out, ConvertPolicy policy, uint32_t shift); - -template < typename T1, typename T2, typename std::enable_if < std::is_integral::value &&std::is_integral::value &&!std::is_same::value, int >::type = 0 > -SimpleTensor depth_convert(const SimpleTensor &src, DataType dt_out, ConvertPolicy policy, uint32_t shift); - -template < typename T1, typename T2, typename std::enable_if < std::is_integral::value &&std::is_integral::value &&std::is_same::value, int >::type = 0 > -SimpleTensor depth_convert(const SimpleTensor &src, DataType dt_out, ConvertPolicy policy, uint32_t shift); - -template < typename T1, typename T2, typename std::enable_if < std::is_floating_point::value &&is_floating_point::value, int >::type = 0 > -SimpleTensor depth_convert(const SimpleTensor &src, DataType dt_out, ConvertPolicy policy, uint32_t shift); -} // namespace reference -} // namespace validation -} // namespace test -} // namespace arm_compute -#endif /* __ARM_COMPUTE_TEST_DEPTH_CONVERT_H__ */ diff --git a/tests/validation/CPP/DepthConvertLayer.cpp b/tests/validation/CPP/DepthConvertLayer.cpp new file mode 100644 index 0000000000..dd095b8912 --- /dev/null +++ b/tests/validation/CPP/DepthConvertLayer.cpp @@ -0,0 +1,157 @@ +/* + * Copyright (c) 2017 ARM Limited. + * + * SPDX-License-Identifier: MIT + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#include "DepthConvertLayer.h" + +#include "tests/validation/FixedPoint.h" +#include "tests/validation/Helpers.h" + +#include "tests/Types.h" + +namespace arm_compute +{ +namespace test +{ +namespace validation +{ +namespace reference +{ +template < typename T1, typename T2, typename std::enable_if < std::is_integral::value &&std::is_floating_point::value, int >::type > +SimpleTensor depth_convert(const SimpleTensor &src, DataType dt_out, ConvertPolicy policy, uint32_t shift) +{ + ARM_COMPUTE_UNUSED(policy); + ARM_COMPUTE_UNUSED(shift); + + using namespace fixed_point_arithmetic; + SimpleTensor result(src.shape(), dt_out); + + const int fixed_point_position = src.fixed_point_position(); + + for(int i = 0; i < src.num_elements(); ++i) + { + result[i] = static_cast(fixed_point(src[i], fixed_point_position, true)); + } + + return result; +} + +template < typename T1, typename T2, typename std::enable_if < std::is_floating_point::value &&std::is_integral::value, int >::type > +SimpleTensor depth_convert(const SimpleTensor &src, DataType dt_out, ConvertPolicy policy, uint32_t shift) +{ + ARM_COMPUTE_UNUSED(policy); + ARM_COMPUTE_UNUSED(shift); + + using namespace fixed_point_arithmetic; + SimpleTensor result(src.shape(), dt_out, 1, src.fixed_point_position()); + + const int fixed_point_position = result.fixed_point_position(); + + for(int i = 0; i < src.num_elements(); ++i) + { + result[i] = fixed_point(src[i], fixed_point_position).raw(); + } + + return result; +} + +template < typename T1, typename T2, typename std::enable_if < std::is_integral::value &&std::is_integral::value &&!std::is_same::value, int >::type > +SimpleTensor depth_convert(const SimpleTensor &src, DataType dt_out, ConvertPolicy policy, uint32_t shift) +{ + SimpleTensor result(src.shape(), dt_out); + + // Up-casting + if(src.data_type() <= dt_out) + { + for(int i = 0; i < src.num_elements(); ++i) + { + result[i] = src[i] << shift; + } + } + // Down-casting + else + { + for(int i = 0; i < src.num_elements(); ++i) + { + T1 val = src[i] >> shift; + result[i] = (policy == ConvertPolicy::SATURATE) ? saturate_cast(val) : static_cast(val); + } + } + return result; +} + +template < typename T1, typename T2, typename std::enable_if < std::is_integral::value &&std::is_integral::value &&std::is_same::value, int >::type > +SimpleTensor depth_convert(const SimpleTensor &src, DataType dt_out, ConvertPolicy policy, uint32_t shift) +{ + ARM_COMPUTE_UNUSED(policy); + + using namespace fixed_point_arithmetic; + + SimpleTensor result(src.shape(), dt_out); + + bool is_in_place = (&src == &result); + + const int fixed_point_position_in = src.fixed_point_position(); + const int fixed_point_position_out = (is_in_place) ? static_cast(shift) : result.fixed_point_position(); + + if(!is_in_place || (fixed_point_position_in != fixed_point_position_out)) + { + for(int i = 0; i < src.num_elements(); ++i) + { + auto x = fixed_point(src[i], fixed_point_position_in, true); + x.resacle(fixed_point_position_out); + result[i] = x.raw(); + } + } + + return result; +} + +template < typename T1, typename T2, typename std::enable_if < std::is_floating_point::value &&is_floating_point::value, int >::type > +SimpleTensor depth_convert(const SimpleTensor &src, DataType dt_out, ConvertPolicy policy, uint32_t shift) +{ + ARM_COMPUTE_UNUSED(policy); + ARM_COMPUTE_UNUSED(shift); + + SimpleTensor result(src.shape(), dt_out); + + for(int i = 0; i < src.num_elements(); ++i) + { + result[i] = static_cast(src[i]); + } +} + +template SimpleTensor depth_convert(const SimpleTensor &src, DataType dt_out, ConvertPolicy policy, uint32_t shift); +template SimpleTensor depth_convert(const SimpleTensor &src, DataType dt_out, ConvertPolicy policy, uint32_t shift); +template SimpleTensor depth_convert(const SimpleTensor &src, DataType dt_out, ConvertPolicy policy, uint32_t shift); +template SimpleTensor depth_convert(const SimpleTensor &src, DataType dt_out, ConvertPolicy policy, uint32_t shift); +template SimpleTensor depth_convert(const SimpleTensor &src, DataType dt_out, ConvertPolicy policy, uint32_t shift); +template SimpleTensor depth_convert(const SimpleTensor &src, DataType dt_out, ConvertPolicy policy, uint32_t shift); +template SimpleTensor depth_convert(const SimpleTensor &src, DataType dt_out, ConvertPolicy policy, uint32_t shift); +template SimpleTensor depth_convert(const SimpleTensor &src, DataType dt_out, ConvertPolicy policy, uint32_t shift); +template SimpleTensor depth_convert(const SimpleTensor &src, DataType dt_out, ConvertPolicy policy, uint32_t shift); +template SimpleTensor depth_convert(const SimpleTensor &src, DataType dt_out, ConvertPolicy policy, uint32_t shift); +template SimpleTensor depth_convert(const SimpleTensor &src, DataType dt_out, ConvertPolicy policy, uint32_t shift); +} // namespace reference +} // namespace validation +} // namespace test +} // namespace arm_compute diff --git a/tests/validation/CPP/DepthConvertLayer.h b/tests/validation/CPP/DepthConvertLayer.h new file mode 100644 index 0000000000..1446bfda5b --- /dev/null +++ b/tests/validation/CPP/DepthConvertLayer.h @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2017 ARM Limited. + * + * SPDX-License-Identifier: MIT + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#ifndef __ARM_COMPUTE_TEST_DEPTH_CONVERT_H__ +#define __ARM_COMPUTE_TEST_DEPTH_CONVERT_H__ + +#include "tests/SimpleTensor.h" +#include "tests/validation/Helpers.h" + +namespace arm_compute +{ +namespace test +{ +namespace validation +{ +namespace reference +{ +template < typename T1, typename T2, typename std::enable_if < std::is_integral::value &&std::is_floating_point::value, int >::type = 0 > +SimpleTensor depth_convert(const SimpleTensor &src, DataType dt_out, ConvertPolicy policy, uint32_t shift); + +template < typename T1, typename T2, typename std::enable_if < std::is_floating_point::value &&std::is_integral::value, int >::type = 0 > +SimpleTensor depth_convert(const SimpleTensor &src, DataType dt_out, ConvertPolicy policy, uint32_t shift); + +template < typename T1, typename T2, typename std::enable_if < std::is_integral::value &&std::is_integral::value &&!std::is_same::value, int >::type = 0 > +SimpleTensor depth_convert(const SimpleTensor &src, DataType dt_out, ConvertPolicy policy, uint32_t shift); + +template < typename T1, typename T2, typename std::enable_if < std::is_integral::value &&std::is_integral::value &&std::is_same::value, int >::type = 0 > +SimpleTensor depth_convert(const SimpleTensor &src, DataType dt_out, ConvertPolicy policy, uint32_t shift); + +template < typename T1, typename T2, typename std::enable_if < std::is_floating_point::value &&is_floating_point::value, int >::type = 0 > +SimpleTensor depth_convert(const SimpleTensor &src, DataType dt_out, ConvertPolicy policy, uint32_t shift); +} // namespace reference +} // namespace validation +} // namespace test +} // namespace arm_compute +#endif /* __ARM_COMPUTE_TEST_DEPTH_CONVERT_H__ */ diff --git a/tests/validation/CPP/DepthwiseConvolution.cpp b/tests/validation/CPP/DepthwiseConvolution.cpp deleted file mode 100644 index 229e044783..0000000000 --- a/tests/validation/CPP/DepthwiseConvolution.cpp +++ /dev/null @@ -1,195 +0,0 @@ -/* - * Copyright (c) 2017 ARM Limited. - * - * SPDX-License-Identifier: MIT - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -#include "DepthwiseConvolution.h" - -#include "ConvolutionLayer.h" -#include "Utils.h" - -#include "tests/validation/CPP/Utils.h" -#include "tests/validation/CPP/UtilsQuantizedAsymm.h" -#include "tests/validation/FixedPoint.h" -#include "tests/validation/Helpers.h" - -#include "arm_compute/core/utils/quantization/AsymmHelpers.h" - -namespace arm_compute -{ -namespace test -{ -namespace validation -{ -namespace reference -{ -/** Perform a depthwise convolution - * - * - Three dimensions tensors - * - Third dimention is number of channels - * - Depths of input tensor and filter are equals - * - Padding, stride and output shape "match" - * - */ -template -SimpleTensor depthwise_convolution(const SimpleTensor &src, const SimpleTensor &weights, const SimpleTensor &biases, const TensorShape &dst_shape, const PadStrideInfo &conv_info) -{ - // Create reference - SimpleTensor dst{ dst_shape, src.data_type(), 1, src.fixed_point_position() }; - - // Compute reference - const int filter_width = weights.shape().x(); - const int filter_height = weights.shape().y(); - const int filter_plane = filter_width * filter_height; - const int input_width = src.shape().x(); - const int input_height = src.shape().y(); - const int input_depth = src.shape().z(); - const int num_batches = src.shape().total_size() / (input_width * input_height * input_depth); - - const int filter_half_width = filter_width / 2; - const int filter_half_height = filter_height / 2; - - const int pad_left = std::min(static_cast(conv_info.pad_left()), filter_half_width); - const int pad_top = std::min(static_cast(conv_info.pad_top()), filter_half_height); - const int pad_right = std::min(static_cast(conv_info.pad_right()), filter_half_width); - const int pad_bottom = std::min(static_cast(conv_info.pad_bottom()), filter_half_height); - - const int minimum_x = -pad_left + filter_half_width; - const int minimum_y = -pad_top + filter_half_height; - const int maximum_x = input_width + pad_left - filter_half_width + pad_right - filter_half_width; - const int maximum_y = input_height + pad_top - filter_half_height + pad_bottom - filter_half_height; - - int out_pos = 0; - for(int r = 0; r < num_batches; ++r) - { - for(int z = 0; z < input_depth; ++z) - { - for(int y = minimum_y; y < minimum_y + maximum_y; y += conv_info.stride().second) - { - for(int x = minimum_x; x < minimum_x + maximum_x; x += conv_info.stride().first) - { - Coordinates coords(static_cast(x), static_cast(y), static_cast(z), static_cast(r)); - size_t filter_offset = filter_plane * z; - - T val = 0; - for(int j = y - filter_half_height; j <= static_cast(y + filter_half_height); ++j) - { - for(int i = x - filter_half_width; i <= static_cast(x + filter_half_width); ++i) - { - coords.set(0, i); - coords.set(1, j); - val += *(weights.data() + filter_offset) * tensor_elem_at(src, coords, BorderMode::CONSTANT, 0.f); - ++filter_offset; - } - } - coords.set(0, x); - coords.set(1, y); - dst[out_pos++] = saturate_cast(val + *static_cast(biases(Coordinates(z)))); - } - } - } - } - - return dst; -} - -template <> -SimpleTensor depthwise_convolution(const SimpleTensor &src, const SimpleTensor &weights, const SimpleTensor &biases, const TensorShape &dst_shape, - const PadStrideInfo &conv_info) -{ - // Create reference - SimpleTensor dst{ dst_shape, src.data_type(), 1, src.fixed_point_position(), src.quantization_info() }; - - const int input_offset = -src.quantization_info().offset; - const float input_scale = src.quantization_info().scale; - const int weights_offset = -weights.quantization_info().offset; - const float weights_scale = weights.quantization_info().scale; - const int output_offset = dst.quantization_info().offset; - const float output_scale = dst.quantization_info().scale; - - int output_multiplier; - int output_shift; - const float multiplier = input_scale * weights_scale / output_scale; - arm_compute::quantization::calculate_quantized_multiplier_less_than_one(multiplier, &output_multiplier, &output_shift); - - // Compute reference - const int filter_width = weights.shape().x(); - const int filter_height = weights.shape().y(); - const int filter_plane = filter_width * filter_height; - const int input_width = src.shape().x(); - const int input_height = src.shape().y(); - const int input_depth = src.shape().z(); - const int num_batches = src.shape().total_size() / (input_width * input_height * input_depth); - - const int filter_half_size = filter_width / 2; - const int pad_x = std::min(filter_half_size, static_cast(conv_info.pad().first)); - const int pad_y = std::min(filter_half_size, static_cast(conv_info.pad().second)); - const int minimum_x = -pad_x + filter_half_size; - const int minimum_y = -pad_y + filter_half_size; - - int out_pos = 0; - for(int r = 0; r < num_batches; ++r) - { - for(int z = 0; z < input_depth; ++z) - { - int32_t bias_val = *static_cast(biases(Coordinates(z))); - for(int y = minimum_y; y < input_height + pad_y - filter_half_size; y += conv_info.stride().second) - { - for(int x = minimum_x; x < input_width + pad_x - filter_half_size; x += conv_info.stride().first) - { - Coordinates coords(x, y, z); - int filter_offset = filter_plane * z; - - uint32_t val = 0; - for(int j = y - filter_half_size; j <= (y + filter_half_size); ++j) - { - for(int i = x - filter_half_size; i <= (x + filter_half_size); ++i) - { - coords.set(0, i); - coords.set(1, j); - auto in_val = tensor_elem_at(src, coords, BorderMode::CONSTANT, 0); - uint8_t w_val = *(weights.data() + filter_offset); - val += (in_val + input_offset) * (w_val + weights_offset); - ++filter_offset; - } - } - val += bias_val; - val = asymm_rounding_divide_by_pow2(asymm_int_mult(val, output_multiplier), output_shift); - val += output_offset; - val = std::max(val, 0); - val = std::min(val, 255); - - // Store the result - dst[out_pos++] = val; - } - } - } - } - - return dst; -} - -template SimpleTensor depthwise_convolution(const SimpleTensor &src, const SimpleTensor &weights, const SimpleTensor &biases, const TensorShape &dst_shape, - const PadStrideInfo &conv_info); -} // namespace reference -} // namespace validation -} // namespace test -} // namespace arm_compute diff --git a/tests/validation/CPP/DepthwiseConvolution.h b/tests/validation/CPP/DepthwiseConvolution.h deleted file mode 100644 index df743a5b8e..0000000000 --- a/tests/validation/CPP/DepthwiseConvolution.h +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright (c) 2017 ARM Limited. - * - * SPDX-License-Identifier: MIT - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -#ifndef __ARM_COMPUTE_TEST_DEPTHWISE_CONVOLUTION_H__ -#define __ARM_COMPUTE_TEST_DEPTHWISE_CONVOLUTION_H__ - -#include "tests/SimpleTensor.h" -#include "tests/validation/Helpers.h" - -namespace arm_compute -{ -namespace test -{ -namespace validation -{ -namespace reference -{ -template -SimpleTensor depthwise_convolution(const SimpleTensor &src, const SimpleTensor &weights, const SimpleTensor &biases, const TensorShape &dst_shape, const PadStrideInfo &conv_info); -} // namespace reference -} // namespace validation -} // namespace test -} // namespace arm_compute -#endif /* __ARM_COMPUTE_TEST_DEPTHWISE_SEPARABLE_CONVOLUTION_LAYER_H__ */ diff --git a/tests/validation/CPP/DepthwiseConvolutionLayer.cpp b/tests/validation/CPP/DepthwiseConvolutionLayer.cpp new file mode 100644 index 0000000000..99baa4b3c7 --- /dev/null +++ b/tests/validation/CPP/DepthwiseConvolutionLayer.cpp @@ -0,0 +1,195 @@ +/* + * Copyright (c) 2017 ARM Limited. + * + * SPDX-License-Identifier: MIT + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#include "DepthwiseConvolutionLayer.h" + +#include "ConvolutionLayer.h" +#include "Utils.h" + +#include "tests/validation/CPP/Utils.h" +#include "tests/validation/CPP/UtilsQuantizedAsymm.h" +#include "tests/validation/FixedPoint.h" +#include "tests/validation/Helpers.h" + +#include "arm_compute/core/utils/quantization/AsymmHelpers.h" + +namespace arm_compute +{ +namespace test +{ +namespace validation +{ +namespace reference +{ +/** Perform a depthwise convolution + * + * - Three dimensions tensors + * - Third dimention is number of channels + * - Depths of input tensor and filter are equals + * - Padding, stride and output shape "match" + * + */ +template +SimpleTensor depthwise_convolution(const SimpleTensor &src, const SimpleTensor &weights, const SimpleTensor &biases, const TensorShape &dst_shape, const PadStrideInfo &conv_info) +{ + // Create reference + SimpleTensor dst{ dst_shape, src.data_type(), 1, src.fixed_point_position() }; + + // Compute reference + const int filter_width = weights.shape().x(); + const int filter_height = weights.shape().y(); + const int filter_plane = filter_width * filter_height; + const int input_width = src.shape().x(); + const int input_height = src.shape().y(); + const int input_depth = src.shape().z(); + const int num_batches = src.shape().total_size() / (input_width * input_height * input_depth); + + const int filter_half_width = filter_width / 2; + const int filter_half_height = filter_height / 2; + + const int pad_left = std::min(static_cast(conv_info.pad_left()), filter_half_width); + const int pad_top = std::min(static_cast(conv_info.pad_top()), filter_half_height); + const int pad_right = std::min(static_cast(conv_info.pad_right()), filter_half_width); + const int pad_bottom = std::min(static_cast(conv_info.pad_bottom()), filter_half_height); + + const int minimum_x = -pad_left + filter_half_width; + const int minimum_y = -pad_top + filter_half_height; + const int maximum_x = input_width + pad_left - filter_half_width + pad_right - filter_half_width; + const int maximum_y = input_height + pad_top - filter_half_height + pad_bottom - filter_half_height; + + int out_pos = 0; + for(int r = 0; r < num_batches; ++r) + { + for(int z = 0; z < input_depth; ++z) + { + for(int y = minimum_y; y < minimum_y + maximum_y; y += conv_info.stride().second) + { + for(int x = minimum_x; x < minimum_x + maximum_x; x += conv_info.stride().first) + { + Coordinates coords(static_cast(x), static_cast(y), static_cast(z), static_cast(r)); + size_t filter_offset = filter_plane * z; + + T val = 0; + for(int j = y - filter_half_height; j <= static_cast(y + filter_half_height); ++j) + { + for(int i = x - filter_half_width; i <= static_cast(x + filter_half_width); ++i) + { + coords.set(0, i); + coords.set(1, j); + val += *(weights.data() + filter_offset) * tensor_elem_at(src, coords, BorderMode::CONSTANT, 0.f); + ++filter_offset; + } + } + coords.set(0, x); + coords.set(1, y); + dst[out_pos++] = saturate_cast(val + *static_cast(biases(Coordinates(z)))); + } + } + } + } + + return dst; +} + +template <> +SimpleTensor depthwise_convolution(const SimpleTensor &src, const SimpleTensor &weights, const SimpleTensor &biases, const TensorShape &dst_shape, + const PadStrideInfo &conv_info) +{ + // Create reference + SimpleTensor dst{ dst_shape, src.data_type(), 1, src.fixed_point_position(), src.quantization_info() }; + + const int input_offset = -src.quantization_info().offset; + const float input_scale = src.quantization_info().scale; + const int weights_offset = -weights.quantization_info().offset; + const float weights_scale = weights.quantization_info().scale; + const int output_offset = dst.quantization_info().offset; + const float output_scale = dst.quantization_info().scale; + + int output_multiplier; + int output_shift; + const float multiplier = input_scale * weights_scale / output_scale; + arm_compute::quantization::calculate_quantized_multiplier_less_than_one(multiplier, &output_multiplier, &output_shift); + + // Compute reference + const int filter_width = weights.shape().x(); + const int filter_height = weights.shape().y(); + const int filter_plane = filter_width * filter_height; + const int input_width = src.shape().x(); + const int input_height = src.shape().y(); + const int input_depth = src.shape().z(); + const int num_batches = src.shape().total_size() / (input_width * input_height * input_depth); + + const int filter_half_size = filter_width / 2; + const int pad_x = std::min(filter_half_size, static_cast(conv_info.pad().first)); + const int pad_y = std::min(filter_half_size, static_cast(conv_info.pad().second)); + const int minimum_x = -pad_x + filter_half_size; + const int minimum_y = -pad_y + filter_half_size; + + int out_pos = 0; + for(int r = 0; r < num_batches; ++r) + { + for(int z = 0; z < input_depth; ++z) + { + int32_t bias_val = *static_cast(biases(Coordinates(z))); + for(int y = minimum_y; y < input_height + pad_y - filter_half_size; y += conv_info.stride().second) + { + for(int x = minimum_x; x < input_width + pad_x - filter_half_size; x += conv_info.stride().first) + { + Coordinates coords(x, y, z); + int filter_offset = filter_plane * z; + + uint32_t val = 0; + for(int j = y - filter_half_size; j <= (y + filter_half_size); ++j) + { + for(int i = x - filter_half_size; i <= (x + filter_half_size); ++i) + { + coords.set(0, i); + coords.set(1, j); + auto in_val = tensor_elem_at(src, coords, BorderMode::CONSTANT, 0); + uint8_t w_val = *(weights.data() + filter_offset); + val += (in_val + input_offset) * (w_val + weights_offset); + ++filter_offset; + } + } + val += bias_val; + val = asymm_rounding_divide_by_pow2(asymm_int_mult(val, output_multiplier), output_shift); + val += output_offset; + val = std::max(val, 0); + val = std::min(val, 255); + + // Store the result + dst[out_pos++] = val; + } + } + } + } + + return dst; +} + +template SimpleTensor depthwise_convolution(const SimpleTensor &src, const SimpleTensor &weights, const SimpleTensor &biases, const TensorShape &dst_shape, + const PadStrideInfo &conv_info); +} // namespace reference +} // namespace validation +} // namespace test +} // namespace arm_compute diff --git a/tests/validation/CPP/DepthwiseConvolutionLayer.h b/tests/validation/CPP/DepthwiseConvolutionLayer.h new file mode 100644 index 0000000000..df743a5b8e --- /dev/null +++ b/tests/validation/CPP/DepthwiseConvolutionLayer.h @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2017 ARM Limited. + * + * SPDX-License-Identifier: MIT + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#ifndef __ARM_COMPUTE_TEST_DEPTHWISE_CONVOLUTION_H__ +#define __ARM_COMPUTE_TEST_DEPTHWISE_CONVOLUTION_H__ + +#include "tests/SimpleTensor.h" +#include "tests/validation/Helpers.h" + +namespace arm_compute +{ +namespace test +{ +namespace validation +{ +namespace reference +{ +template +SimpleTensor depthwise_convolution(const SimpleTensor &src, const SimpleTensor &weights, const SimpleTensor &biases, const TensorShape &dst_shape, const PadStrideInfo &conv_info); +} // namespace reference +} // namespace validation +} // namespace test +} // namespace arm_compute +#endif /* __ARM_COMPUTE_TEST_DEPTHWISE_SEPARABLE_CONVOLUTION_LAYER_H__ */ diff --git a/tests/validation/CPP/DepthwiseSeparableConvolutionLayer.cpp b/tests/validation/CPP/DepthwiseSeparableConvolutionLayer.cpp index 8c8e50d349..ca6c168114 100644 --- a/tests/validation/CPP/DepthwiseSeparableConvolutionLayer.cpp +++ b/tests/validation/CPP/DepthwiseSeparableConvolutionLayer.cpp @@ -21,7 +21,7 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ -#include "DepthwiseConvolution.h" +#include "DepthwiseConvolutionLayer.h" #include "DepthwiseSeparableConvolutionLayer.h" diff --git a/tests/validation/CPP/L2Normalize.cpp b/tests/validation/CPP/L2Normalize.cpp deleted file mode 100644 index 4fb4d57eb4..0000000000 --- a/tests/validation/CPP/L2Normalize.cpp +++ /dev/null @@ -1,88 +0,0 @@ -/* - * Copyright (c) 2017 ARM Limited. - * - * SPDX-License-Identifier: MIT - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -#include "L2Normalize.h" -#include "ReductionOperation.h" - -#include "tests/validation/Helpers.h" - -#include -#include - -namespace arm_compute -{ -namespace test -{ -namespace validation -{ -namespace reference -{ -namespace -{ -TensorShape get_output_shape(TensorShape shape, unsigned int axis) -{ - TensorShape output_shape(shape); - output_shape.set(axis, 1); - return output_shape; -} -} // namespace - -template -SimpleTensor l2_normalize(const SimpleTensor &src, unsigned int axis, float epsilon) -{ - // Create reference - SimpleTensor dst{ src.shape(), src.data_type() }; - - // Reduce across given axis - SimpleTensor sum = reduction_operation(src, get_output_shape(src.shape(), axis), axis, ReductionOperation::SUM_SQUARE); - - // Compute reference - const int elems = src.shape()[axis]; - const int upper_dims = src.shape().total_size_upper(axis + 1); - - for(int du = 0; du < upper_dims; ++du) - { - if(axis == 0) - { - const T *src_row_ptr = src.data() + du * elems; - T *dst_row_ptr = dst.data() + du * elems; - const T normalization_value = std::sqrt(std::max(sum[du], epsilon)); - std::transform(src_row_ptr, src_row_ptr + elems, dst_row_ptr, [normalization_value](T val) - { - return val / normalization_value; - }); - } - else - { - ARM_COMPUTE_ERROR("Unsupported normalization axis"); - } - } - - return dst; -} - -template SimpleTensor l2_normalize(const SimpleTensor &src, unsigned int axis, float epsilon); -} // namespace reference -} // namespace validation -} // namespace test -} // namespace arm_compute diff --git a/tests/validation/CPP/L2Normalize.h b/tests/validation/CPP/L2Normalize.h deleted file mode 100644 index 1db3ae6174..0000000000 --- a/tests/validation/CPP/L2Normalize.h +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright (c) 2017 ARM Limited. - * - * SPDX-License-Identifier: MIT - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -#ifndef __ARM_COMPUTE_TEST_L2NORMALIZE_H__ -#define __ARM_COMPUTE_TEST_L2NORMALIZE_H__ - -#include "tests/SimpleTensor.h" -#include "tests/validation/Helpers.h" - -namespace arm_compute -{ -namespace test -{ -namespace validation -{ -namespace reference -{ -template -SimpleTensor l2_normalize(const SimpleTensor &src, unsigned int axis, float epsilon); -} // namespace reference -} // namespace validation -} // namespace test -} // namespace arm_compute -#endif /* __ARM_COMPUTE_TEST_L2NORMALIZE_H__ */ diff --git a/tests/validation/CPP/L2NormalizeLayer.cpp b/tests/validation/CPP/L2NormalizeLayer.cpp new file mode 100644 index 0000000000..99f4e8a6e6 --- /dev/null +++ b/tests/validation/CPP/L2NormalizeLayer.cpp @@ -0,0 +1,88 @@ +/* + * Copyright (c) 2017 ARM Limited. + * + * SPDX-License-Identifier: MIT + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#include "L2NormalizeLayer.h" +#include "ReductionOperation.h" + +#include "tests/validation/Helpers.h" + +#include +#include + +namespace arm_compute +{ +namespace test +{ +namespace validation +{ +namespace reference +{ +namespace +{ +TensorShape get_output_shape(TensorShape shape, unsigned int axis) +{ + TensorShape output_shape(shape); + output_shape.set(axis, 1); + return output_shape; +} +} // namespace + +template +SimpleTensor l2_normalize(const SimpleTensor &src, unsigned int axis, float epsilon) +{ + // Create reference + SimpleTensor dst{ src.shape(), src.data_type() }; + + // Reduce across given axis + SimpleTensor sum = reduction_operation(src, get_output_shape(src.shape(), axis), axis, ReductionOperation::SUM_SQUARE); + + // Compute reference + const int elems = src.shape()[axis]; + const int upper_dims = src.shape().total_size_upper(axis + 1); + + for(int du = 0; du < upper_dims; ++du) + { + if(axis == 0) + { + const T *src_row_ptr = src.data() + du * elems; + T *dst_row_ptr = dst.data() + du * elems; + const T normalization_value = std::sqrt(std::max(sum[du], epsilon)); + std::transform(src_row_ptr, src_row_ptr + elems, dst_row_ptr, [normalization_value](T val) + { + return val / normalization_value; + }); + } + else + { + ARM_COMPUTE_ERROR("Unsupported normalization axis"); + } + } + + return dst; +} + +template SimpleTensor l2_normalize(const SimpleTensor &src, unsigned int axis, float epsilon); +} // namespace reference +} // namespace validation +} // namespace test +} // namespace arm_compute diff --git a/tests/validation/CPP/L2NormalizeLayer.h b/tests/validation/CPP/L2NormalizeLayer.h new file mode 100644 index 0000000000..1db3ae6174 --- /dev/null +++ b/tests/validation/CPP/L2NormalizeLayer.h @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2017 ARM Limited. + * + * SPDX-License-Identifier: MIT + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#ifndef __ARM_COMPUTE_TEST_L2NORMALIZE_H__ +#define __ARM_COMPUTE_TEST_L2NORMALIZE_H__ + +#include "tests/SimpleTensor.h" +#include "tests/validation/Helpers.h" + +namespace arm_compute +{ +namespace test +{ +namespace validation +{ +namespace reference +{ +template +SimpleTensor l2_normalize(const SimpleTensor &src, unsigned int axis, float epsilon); +} // namespace reference +} // namespace validation +} // namespace test +} // namespace arm_compute +#endif /* __ARM_COMPUTE_TEST_L2NORMALIZE_H__ */ -- cgit v1.2.1