blob: 12d9012ece799516b77c19ea3b066e033ee10315 [file] [log] [blame]
Isabella Gottardi1fab09f2017-07-13 15:55:57 +01001/*
Sang-Hoon Parkbb123bd2020-01-03 10:57:30 +00002 * Copyright (c) 2017-2020 ARM Limited.
Isabella Gottardi1fab09f2017-07-13 15:55:57 +01003 *
4 * SPDX-License-Identifier: MIT
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a copy
7 * of this software and associated documentation files (the "Software"), to
8 * deal in the Software without restriction, including without limitation the
9 * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
10 * sell copies of the Software, and to permit persons to whom the Software is
11 * furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be included in all
14 * copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 * SOFTWARE.
23 */
24#ifndef ARM_COMPUTE_TEST_SCALE_FIXTURE
25#define ARM_COMPUTE_TEST_SCALE_FIXTURE
26
27#include "arm_compute/core/TensorShape.h"
28#include "arm_compute/core/Types.h"
Isabella Gottardi1fab09f2017-07-13 15:55:57 +010029#include "tests/AssetsLibrary.h"
30#include "tests/Globals.h"
31#include "tests/IAccessor.h"
Moritz Pflanzera09de0c2017-09-01 20:41:12 +010032#include "tests/framework/Asserts.h"
33#include "tests/framework/Fixture.h"
Michalis Spyrou46da23f2018-04-10 13:41:30 +010034#include "tests/validation/reference/Permute.h"
Georgios Pinitas5a7e7762017-12-01 16:27:29 +000035#include "tests/validation/reference/Scale.h"
Isabella Gottardi1fab09f2017-07-13 15:55:57 +010036
37namespace arm_compute
38{
39namespace test
40{
41namespace validation
42{
43template <typename TensorType, typename AccessorType, typename FunctionType, typename T>
Michalis Spyrou17220e22018-09-12 13:35:38 +010044class ScaleValidationGenericFixture : public framework::Fixture
Isabella Gottardi1fab09f2017-07-13 15:55:57 +010045{
46public:
47 template <typename...>
Sang-Hoon Parkbb123bd2020-01-03 10:57:30 +000048 void setup(TensorShape shape, DataType data_type, QuantizationInfo quantization_info, DataLayout data_layout, InterpolationPolicy policy, BorderMode border_mode, SamplingPolicy sampling_policy,
49 bool align_corners)
Isabella Gottardi1fab09f2017-07-13 15:55:57 +010050 {
Michalis Spyrou17220e22018-09-12 13:35:38 +010051 _shape = shape;
52 _policy = policy;
53 _border_mode = border_mode;
54 _sampling_policy = sampling_policy;
55 _data_type = data_type;
56 _quantization_info = quantization_info;
Sang-Hoon Parkf025a772020-05-26 11:11:32 +010057 _align_corners = align_corners;
Isabella Gottardi1fab09f2017-07-13 15:55:57 +010058
Sang-Hoon Parkc72dabc2020-05-27 13:03:18 +010059 generate_scale(shape);
Gian Marco Iodiceb11e2692017-09-25 11:31:42 +010060
Sang-Hoon Parkc72dabc2020-05-27 13:03:18 +010061 std::mt19937 generator(library->seed());
Isabella Gottardi1fab09f2017-07-13 15:55:57 +010062 std::uniform_int_distribution<uint8_t> distribution_u8(0, 255);
Sang-Hoon Parkc72dabc2020-05-27 13:03:18 +010063 _constant_border_value = static_cast<T>(distribution_u8(generator));
Isabella Gottardi1fab09f2017-07-13 15:55:57 +010064
Sang-Hoon Parkc72dabc2020-05-27 13:03:18 +010065 _target = compute_target(shape, data_layout);
66 _reference = compute_reference(shape);
Isabella Gottardi1fab09f2017-07-13 15:55:57 +010067 }
68
69protected:
Sang-Hoon Parkc72dabc2020-05-27 13:03:18 +010070 void generate_scale(const TensorShape &shape)
71 {
72 static constexpr float _min_scale{ 0.25f };
73 static constexpr float _max_scale{ 3.f };
74
75 constexpr float max_width{ 8192.0f };
76 constexpr float max_height{ 6384.0f };
77
Sang-Hoon Parkf025a772020-05-26 11:11:32 +010078 const bool is_align_corners_used = _align_corners && arm_compute::is_align_corners_allowed(_sampling_policy);
79
80 const float min_width = is_align_corners_used ? 2.f : 1.f;
81 const float min_height = is_align_corners_used ? 2.f : 1.f;
Sang-Hoon Parkc72dabc2020-05-27 13:03:18 +010082
83 std::mt19937 generator(library->seed());
84 std::uniform_real_distribution<float> distribution_float(_min_scale, _max_scale);
85
86 auto generate = [&](size_t input_size, float min_output, float max_output) -> float
87 {
88 const float generated_scale = distribution_float(generator);
89 const float output_size = utility::clamp(static_cast<float>(input_size) * generated_scale, min_output, max_output);
90 return output_size / input_size;
91 };
92
93 // Input shape is always given in NCHW layout. NHWC is dealt by permute in compute_target()
94 const int idx_width = get_data_layout_dimension_index(DataLayout::NCHW, DataLayoutDimension::WIDTH);
95 const int idx_height = get_data_layout_dimension_index(DataLayout::NCHW, DataLayoutDimension::HEIGHT);
96
97 _scale_x = generate(shape[idx_width], min_width, max_width);
98 _scale_y = generate(shape[idx_height], min_height, max_height);
99 }
100
Isabella Gottardi1fab09f2017-07-13 15:55:57 +0100101 template <typename U>
102 void fill(U &&tensor)
103 {
Diego Lopez Recas00854292018-02-22 13:08:01 +0000104 if(is_data_type_float(_data_type))
105 {
106 library->fill_tensor_uniform(tensor, 0);
107 }
Michalis Spyrou17220e22018-09-12 13:35:38 +0100108 else if(is_data_type_quantized(tensor.data_type()))
109 {
110 std::uniform_int_distribution<> distribution(0, 100);
111 library->fill(tensor, distribution, 0);
112 }
Diego Lopez Recas00854292018-02-22 13:08:01 +0000113 else
114 {
115 // Restrict range for float to avoid any floating point issues
116 std::uniform_real_distribution<> distribution(-5.0f, 5.0f);
117 library->fill(tensor, distribution, 0);
118 }
Isabella Gottardi1fab09f2017-07-13 15:55:57 +0100119 }
120
Sang-Hoon Parkc72dabc2020-05-27 13:03:18 +0100121 TensorType compute_target(TensorShape shape, DataLayout data_layout)
Isabella Gottardi1fab09f2017-07-13 15:55:57 +0100122 {
Georgios Pinitas393fa4c2018-05-08 15:54:53 +0100123 // Change shape in case of NHWC.
124 if(data_layout == DataLayout::NHWC)
125 {
126 permute(shape, PermutationVector(2U, 0U, 1U));
127 }
128
Isabella Gottardi1fab09f2017-07-13 15:55:57 +0100129 // Create tensors
Sang-Hoon Parkc72dabc2020-05-27 13:03:18 +0100130 TensorType src = create_tensor<TensorType>(shape, _data_type, 1, _quantization_info, data_layout);
Georgios Pinitas393fa4c2018-05-08 15:54:53 +0100131
132 const int idx_width = get_data_layout_dimension_index(data_layout, DataLayoutDimension::WIDTH);
133 const int idx_height = get_data_layout_dimension_index(data_layout, DataLayoutDimension::HEIGHT);
134
Isabella Gottardi1fab09f2017-07-13 15:55:57 +0100135 TensorShape shape_scaled(shape);
Sang-Hoon Park9e4b8992020-06-22 13:48:56 +0100136 shape_scaled.set(idx_width, shape[idx_width] * _scale_x, /* apply_dim_correction = */ false);
137 shape_scaled.set(idx_height, shape[idx_height] * _scale_y, /* apply_dim_correction = */ false);
Sang-Hoon Parkc72dabc2020-05-27 13:03:18 +0100138 TensorType dst = create_tensor<TensorType>(shape_scaled, _data_type, 1, _quantization_info, data_layout);
Isabella Gottardi1fab09f2017-07-13 15:55:57 +0100139
140 // Create and configure function
141 FunctionType scale;
142
Sang-Hoon Parkccd94962020-06-09 12:09:24 +0100143 scale.configure(&src, &dst, ScaleKernelInfo{ _policy, _border_mode, _constant_border_value, _sampling_policy, /* use_padding */ true, _align_corners });
Isabella Gottardi1fab09f2017-07-13 15:55:57 +0100144
145 ARM_COMPUTE_EXPECT(src.info()->is_resizable(), framework::LogLevel::ERRORS);
146 ARM_COMPUTE_EXPECT(dst.info()->is_resizable(), framework::LogLevel::ERRORS);
147
148 // Allocate tensors
149 src.allocator()->allocate();
150 dst.allocator()->allocate();
151 ARM_COMPUTE_EXPECT(!src.info()->is_resizable(), framework::LogLevel::ERRORS);
152 ARM_COMPUTE_EXPECT(!dst.info()->is_resizable(), framework::LogLevel::ERRORS);
153
154 // Fill tensors
155 fill(AccessorType(src));
156
157 // Compute function
158 scale.run();
159
160 return dst;
161 }
162
Sang-Hoon Parkc72dabc2020-05-27 13:03:18 +0100163 SimpleTensor<T> compute_reference(const TensorShape &shape)
Isabella Gottardi1fab09f2017-07-13 15:55:57 +0100164 {
165 // Create reference
Sang-Hoon Parkc72dabc2020-05-27 13:03:18 +0100166 SimpleTensor<T> src{ shape, _data_type, 1, _quantization_info };
Isabella Gottardi1fab09f2017-07-13 15:55:57 +0100167
168 // Fill reference
169 fill(src);
170
Sang-Hoon Parkc72dabc2020-05-27 13:03:18 +0100171 return reference::scale<T>(src, _scale_x, _scale_y, _policy, _border_mode, _constant_border_value, _sampling_policy, /* ceil_policy_scale */ false, _align_corners);
Isabella Gottardi1fab09f2017-07-13 15:55:57 +0100172 }
173
174 TensorType _target{};
175 SimpleTensor<T> _reference{};
176 TensorShape _shape{};
177 InterpolationPolicy _policy{};
178 BorderMode _border_mode{};
Sang-Hoon Parkc72dabc2020-05-27 13:03:18 +0100179 T _constant_border_value{};
Daniil Efremov02bf80d2017-11-22 00:26:51 +0700180 SamplingPolicy _sampling_policy{};
Isabella Gottardi1fab09f2017-07-13 15:55:57 +0100181 DataType _data_type{};
Michalis Spyrou17220e22018-09-12 13:35:38 +0100182 QuantizationInfo _quantization_info{};
Sang-Hoon Parkbb123bd2020-01-03 10:57:30 +0000183 bool _align_corners{ false };
Sang-Hoon Parkc72dabc2020-05-27 13:03:18 +0100184 float _scale_x{ 1.f };
185 float _scale_y{ 1.f };
Michalis Spyrou17220e22018-09-12 13:35:38 +0100186};
187
188template <typename TensorType, typename AccessorType, typename FunctionType, typename T>
189class ScaleValidationQuantizedFixture : public ScaleValidationGenericFixture<TensorType, AccessorType, FunctionType, T>
190{
191public:
192 template <typename...>
Sang-Hoon Parkbb123bd2020-01-03 10:57:30 +0000193 void setup(TensorShape shape, DataType data_type, QuantizationInfo quantization_info, DataLayout data_layout, InterpolationPolicy policy, BorderMode border_mode, SamplingPolicy sampling_policy,
194 bool align_corners)
Michalis Spyrou17220e22018-09-12 13:35:38 +0100195 {
196 ScaleValidationGenericFixture<TensorType, AccessorType, FunctionType, T>::setup(shape,
197 data_type,
198 quantization_info,
199 data_layout,
200 policy,
201 border_mode,
Sang-Hoon Parkbb123bd2020-01-03 10:57:30 +0000202 sampling_policy,
203 align_corners);
Michalis Spyrou17220e22018-09-12 13:35:38 +0100204 }
205};
206template <typename TensorType, typename AccessorType, typename FunctionType, typename T>
207class ScaleValidationFixture : public ScaleValidationGenericFixture<TensorType, AccessorType, FunctionType, T>
208{
209public:
210 template <typename...>
Sang-Hoon Parkbb123bd2020-01-03 10:57:30 +0000211 void setup(TensorShape shape, DataType data_type, DataLayout data_layout, InterpolationPolicy policy, BorderMode border_mode, SamplingPolicy sampling_policy, bool align_corners)
Michalis Spyrou17220e22018-09-12 13:35:38 +0100212 {
213 ScaleValidationGenericFixture<TensorType, AccessorType, FunctionType, T>::setup(shape,
214 data_type,
215 QuantizationInfo(),
216 data_layout,
217 policy,
218 border_mode,
Sang-Hoon Parkbb123bd2020-01-03 10:57:30 +0000219 sampling_policy,
220 align_corners);
Michalis Spyrou17220e22018-09-12 13:35:38 +0100221 }
Isabella Gottardi1fab09f2017-07-13 15:55:57 +0100222};
223} // namespace validation
224} // namespace test
225} // namespace arm_compute
steniu01f81652d2017-09-11 15:29:12 +0100226#endif /* ARM_COMPUTE_TEST_SCALE_FIXTURE */