blob: 86d89d71f7f01860c6d4abfd28789cb279fb7e00 [file] [log] [blame]
Isabella Gottardi1fab09f2017-07-13 15:55:57 +01001/*
Matthew Bentham945b8da2023-07-12 11:54:59 +00002 * Copyright (c) 2017-2023 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 */
Jakub Sujak8f4b3df2023-10-30 16:04:51 +000024#ifndef ACL_TESTS_VALIDATION_FIXTURES_SCALEFIXTURE_H
25#define ACL_TESTS_VALIDATION_FIXTURES_SCALEFIXTURE_H
Isabella Gottardi1fab09f2017-07-13 15:55:57 +010026
Jakub Sujak8f4b3df2023-10-30 16:04:51 +000027#include "tests/framework/Asserts.h" // Required for ARM_COMPUTE_ASSERT
Moritz Pflanzera09de0c2017-09-01 20:41:12 +010028#include "tests/framework/Fixture.h"
Michalis Spyrou46da23f2018-04-10 13:41:30 +010029#include "tests/validation/reference/Permute.h"
Georgios Pinitas5a7e7762017-12-01 16:27:29 +000030#include "tests/validation/reference/Scale.h"
Isabella Gottardi1fab09f2017-07-13 15:55:57 +010031
32namespace arm_compute
33{
34namespace test
35{
36namespace validation
37{
38template <typename TensorType, typename AccessorType, typename FunctionType, typename T>
Michalis Spyrou17220e22018-09-12 13:35:38 +010039class ScaleValidationGenericFixture : public framework::Fixture
Isabella Gottardi1fab09f2017-07-13 15:55:57 +010040{
41public:
Sang-Hoon Parkbb123bd2020-01-03 10:57:30 +000042 void setup(TensorShape shape, DataType data_type, QuantizationInfo quantization_info, DataLayout data_layout, InterpolationPolicy policy, BorderMode border_mode, SamplingPolicy sampling_policy,
Gunes Bayirc4f27432022-09-11 15:59:19 +010043 bool align_corners, bool mixed_layout, QuantizationInfo output_quantization_info)
Isabella Gottardi1fab09f2017-07-13 15:55:57 +010044 {
Gunes Bayirc4f27432022-09-11 15:59:19 +010045 _shape = shape;
46 _policy = policy;
47 _border_mode = border_mode;
48 _sampling_policy = sampling_policy;
49 _data_type = data_type;
50 _input_quantization_info = quantization_info;
51 _output_quantization_info = output_quantization_info;
52 _align_corners = align_corners;
53 _mixed_layout = mixed_layout;
Isabella Gottardi1fab09f2017-07-13 15:55:57 +010054
Sang-Hoon Parkc72dabc2020-05-27 13:03:18 +010055 generate_scale(shape);
Gian Marco Iodiceb11e2692017-09-25 11:31:42 +010056
Pablo Tello29cab362022-03-10 17:05:34 +000057 std::mt19937 generator(library->seed());
58 std::uniform_int_distribution<uint32_t> distribution_u8(0, 255);
Sang-Hoon Parkc72dabc2020-05-27 13:03:18 +010059 _constant_border_value = static_cast<T>(distribution_u8(generator));
Isabella Gottardi1fab09f2017-07-13 15:55:57 +010060
Sang-Hoon Parkc72dabc2020-05-27 13:03:18 +010061 _target = compute_target(shape, data_layout);
62 _reference = compute_reference(shape);
Isabella Gottardi1fab09f2017-07-13 15:55:57 +010063 }
64
65protected:
Manuel Bottinica62c6f2021-03-23 11:50:34 +000066 void mix_layout(FunctionType &layer, TensorType &src, TensorType &dst)
67 {
68 const DataLayout data_layout = src.info()->data_layout();
69 // Test Multi DataLayout graph cases, when the data layout changes after configure
70 src.info()->set_data_layout(data_layout == DataLayout::NCHW ? DataLayout::NHWC : DataLayout::NCHW);
71 dst.info()->set_data_layout(data_layout == DataLayout::NCHW ? DataLayout::NHWC : DataLayout::NCHW);
72
73 // Compute Convolution function
74 layer.run();
75
76 // Reinstating original data layout for the test suite to properly check the values
77 src.info()->set_data_layout(data_layout);
78 dst.info()->set_data_layout(data_layout);
79 }
80
Sang-Hoon Parkc72dabc2020-05-27 13:03:18 +010081 void generate_scale(const TensorShape &shape)
82 {
83 static constexpr float _min_scale{ 0.25f };
84 static constexpr float _max_scale{ 3.f };
85
86 constexpr float max_width{ 8192.0f };
87 constexpr float max_height{ 6384.0f };
Sang-Hoon Park3687ee12020-06-24 13:34:04 +010088 const float min_width{ 1.f };
89 const float min_height{ 1.f };
Sang-Hoon Parkc72dabc2020-05-27 13:03:18 +010090
91 std::mt19937 generator(library->seed());
92 std::uniform_real_distribution<float> distribution_float(_min_scale, _max_scale);
93
94 auto generate = [&](size_t input_size, float min_output, float max_output) -> float
95 {
96 const float generated_scale = distribution_float(generator);
97 const float output_size = utility::clamp(static_cast<float>(input_size) * generated_scale, min_output, max_output);
98 return output_size / input_size;
99 };
100
101 // Input shape is always given in NCHW layout. NHWC is dealt by permute in compute_target()
102 const int idx_width = get_data_layout_dimension_index(DataLayout::NCHW, DataLayoutDimension::WIDTH);
103 const int idx_height = get_data_layout_dimension_index(DataLayout::NCHW, DataLayoutDimension::HEIGHT);
104
105 _scale_x = generate(shape[idx_width], min_width, max_width);
106 _scale_y = generate(shape[idx_height], min_height, max_height);
107 }
108
Isabella Gottardi1fab09f2017-07-13 15:55:57 +0100109 template <typename U>
110 void fill(U &&tensor)
111 {
Giorgio Arena4bdd1772020-12-17 16:47:07 +0000112 if(tensor.data_type() == DataType::F32)
Diego Lopez Recas00854292018-02-22 13:08:01 +0000113 {
Giorgio Arena4bdd1772020-12-17 16:47:07 +0000114 std::uniform_real_distribution<float> distribution(-5.0f, 5.0f);
115 library->fill(tensor, distribution, 0);
116 }
117 else if(tensor.data_type() == DataType::F16)
118 {
Giorgio Arena33b103b2021-01-08 10:37:15 +0000119 arm_compute::utils::uniform_real_distribution_16bit<half> distribution{ -5.0f, 5.0f };
Giorgio Arena4bdd1772020-12-17 16:47:07 +0000120 library->fill(tensor, distribution, 0);
Diego Lopez Recas00854292018-02-22 13:08:01 +0000121 }
Michalis Spyrou17220e22018-09-12 13:35:38 +0100122 else if(is_data_type_quantized(tensor.data_type()))
123 {
124 std::uniform_int_distribution<> distribution(0, 100);
125 library->fill(tensor, distribution, 0);
126 }
Diego Lopez Recas00854292018-02-22 13:08:01 +0000127 else
128 {
Giorgio Arena4bdd1772020-12-17 16:47:07 +0000129 library->fill_tensor_uniform(tensor, 0);
Diego Lopez Recas00854292018-02-22 13:08:01 +0000130 }
Isabella Gottardi1fab09f2017-07-13 15:55:57 +0100131 }
132
Sang-Hoon Parkc72dabc2020-05-27 13:03:18 +0100133 TensorType compute_target(TensorShape shape, DataLayout data_layout)
Isabella Gottardi1fab09f2017-07-13 15:55:57 +0100134 {
Georgios Pinitas393fa4c2018-05-08 15:54:53 +0100135 // Change shape in case of NHWC.
136 if(data_layout == DataLayout::NHWC)
137 {
138 permute(shape, PermutationVector(2U, 0U, 1U));
139 }
140
Isabella Gottardi1fab09f2017-07-13 15:55:57 +0100141 // Create tensors
Gunes Bayirc4f27432022-09-11 15:59:19 +0100142 TensorType src = create_tensor<TensorType>(shape, _data_type, 1, _input_quantization_info, data_layout);
Georgios Pinitas393fa4c2018-05-08 15:54:53 +0100143
144 const int idx_width = get_data_layout_dimension_index(data_layout, DataLayoutDimension::WIDTH);
145 const int idx_height = get_data_layout_dimension_index(data_layout, DataLayoutDimension::HEIGHT);
146
Isabella Gottardi1fab09f2017-07-13 15:55:57 +0100147 TensorShape shape_scaled(shape);
Sang-Hoon Park9e4b8992020-06-22 13:48:56 +0100148 shape_scaled.set(idx_width, shape[idx_width] * _scale_x, /* apply_dim_correction = */ false);
149 shape_scaled.set(idx_height, shape[idx_height] * _scale_y, /* apply_dim_correction = */ false);
Gunes Bayirc4f27432022-09-11 15:59:19 +0100150 TensorType dst = create_tensor<TensorType>(shape_scaled, _data_type, 1, _output_quantization_info, data_layout);
Isabella Gottardi1fab09f2017-07-13 15:55:57 +0100151
152 // Create and configure function
153 FunctionType scale;
154
Manuel Bottinifc2f6d02020-08-26 16:28:38 +0100155 scale.configure(&src, &dst, ScaleKernelInfo{ _policy, _border_mode, _constant_border_value, _sampling_policy, /* use_padding */ false, _align_corners });
Isabella Gottardi1fab09f2017-07-13 15:55:57 +0100156
Michele Di Giorgio4fc10b32021-04-30 18:30:41 +0100157 ARM_COMPUTE_ASSERT(src.info()->is_resizable());
158 ARM_COMPUTE_ASSERT(dst.info()->is_resizable());
Isabella Gottardi1fab09f2017-07-13 15:55:57 +0100159
Giorgio Arena63825e82021-03-25 14:54:50 +0000160 add_padding_x({ &src, &dst }, data_layout);
161
Isabella Gottardi1fab09f2017-07-13 15:55:57 +0100162 // Allocate tensors
163 src.allocator()->allocate();
164 dst.allocator()->allocate();
Michele Di Giorgio4fc10b32021-04-30 18:30:41 +0100165 ARM_COMPUTE_ASSERT(!src.info()->is_resizable());
166 ARM_COMPUTE_ASSERT(!dst.info()->is_resizable());
Isabella Gottardi1fab09f2017-07-13 15:55:57 +0100167
168 // Fill tensors
169 fill(AccessorType(src));
170
Manuel Bottinica62c6f2021-03-23 11:50:34 +0000171 if(_mixed_layout)
172 {
173 mix_layout(scale, src, dst);
174 }
175 else
176 {
177 // Compute function
178 scale.run();
179 }
Isabella Gottardi1fab09f2017-07-13 15:55:57 +0100180 return dst;
181 }
182
Sang-Hoon Parkc72dabc2020-05-27 13:03:18 +0100183 SimpleTensor<T> compute_reference(const TensorShape &shape)
Isabella Gottardi1fab09f2017-07-13 15:55:57 +0100184 {
185 // Create reference
Gunes Bayirc4f27432022-09-11 15:59:19 +0100186 SimpleTensor<T> src{ shape, _data_type, 1, _input_quantization_info };
Isabella Gottardi1fab09f2017-07-13 15:55:57 +0100187
188 // Fill reference
189 fill(src);
190
Gunes Bayirc4f27432022-09-11 15:59:19 +0100191 return reference::scale<T>(src, _scale_x, _scale_y, _policy, _border_mode, _constant_border_value, _sampling_policy, /* ceil_policy_scale */ false, _align_corners, _output_quantization_info);
Isabella Gottardi1fab09f2017-07-13 15:55:57 +0100192 }
193
194 TensorType _target{};
195 SimpleTensor<T> _reference{};
196 TensorShape _shape{};
197 InterpolationPolicy _policy{};
198 BorderMode _border_mode{};
Sang-Hoon Parkc72dabc2020-05-27 13:03:18 +0100199 T _constant_border_value{};
Daniil Efremov02bf80d2017-11-22 00:26:51 +0700200 SamplingPolicy _sampling_policy{};
Isabella Gottardi1fab09f2017-07-13 15:55:57 +0100201 DataType _data_type{};
Gunes Bayirc4f27432022-09-11 15:59:19 +0100202 QuantizationInfo _input_quantization_info{};
203 QuantizationInfo _output_quantization_info{};
Sang-Hoon Parkbb123bd2020-01-03 10:57:30 +0000204 bool _align_corners{ false };
Manuel Bottinica62c6f2021-03-23 11:50:34 +0000205 bool _mixed_layout{ false };
Sang-Hoon Parkc72dabc2020-05-27 13:03:18 +0100206 float _scale_x{ 1.f };
207 float _scale_y{ 1.f };
Michalis Spyrou17220e22018-09-12 13:35:38 +0100208};
209
Manuel Bottinica62c6f2021-03-23 11:50:34 +0000210template <typename TensorType, typename AccessorType, typename FunctionType, typename T, bool mixed_layout = false>
Michalis Spyrou17220e22018-09-12 13:35:38 +0100211class ScaleValidationQuantizedFixture : public ScaleValidationGenericFixture<TensorType, AccessorType, FunctionType, T>
212{
213public:
Sang-Hoon Parkbb123bd2020-01-03 10:57:30 +0000214 void setup(TensorShape shape, DataType data_type, QuantizationInfo quantization_info, DataLayout data_layout, InterpolationPolicy policy, BorderMode border_mode, SamplingPolicy sampling_policy,
215 bool align_corners)
Michalis Spyrou17220e22018-09-12 13:35:38 +0100216 {
217 ScaleValidationGenericFixture<TensorType, AccessorType, FunctionType, T>::setup(shape,
218 data_type,
219 quantization_info,
220 data_layout,
221 policy,
222 border_mode,
Sang-Hoon Parkbb123bd2020-01-03 10:57:30 +0000223 sampling_policy,
Manuel Bottinica62c6f2021-03-23 11:50:34 +0000224 align_corners,
Gunes Bayirc4f27432022-09-11 15:59:19 +0100225 mixed_layout,
226 quantization_info);
227 }
228};
229template <typename TensorType, typename AccessorType, typename FunctionType, typename T, bool mixed_layout = false>
230class ScaleValidationDifferentOutputQuantizedFixture : public ScaleValidationGenericFixture<TensorType, AccessorType, FunctionType, T>
231{
232public:
Gunes Bayirc4f27432022-09-11 15:59:19 +0100233 void setup(TensorShape shape, DataType data_type, QuantizationInfo input_quantization_info, QuantizationInfo output_quantization_info, DataLayout data_layout, InterpolationPolicy policy,
234 BorderMode border_mode, SamplingPolicy sampling_policy,
235 bool align_corners)
236 {
237 ScaleValidationGenericFixture<TensorType, AccessorType, FunctionType, T>::setup(shape,
238 data_type,
239 input_quantization_info,
240 data_layout,
241 policy,
242 border_mode,
243 sampling_policy,
244 align_corners,
245 mixed_layout,
246 output_quantization_info);
Michalis Spyrou17220e22018-09-12 13:35:38 +0100247 }
248};
Manuel Bottinica62c6f2021-03-23 11:50:34 +0000249template <typename TensorType, typename AccessorType, typename FunctionType, typename T, bool mixed_layout = false>
Michalis Spyrou17220e22018-09-12 13:35:38 +0100250class ScaleValidationFixture : public ScaleValidationGenericFixture<TensorType, AccessorType, FunctionType, T>
251{
252public:
Sang-Hoon Parkbb123bd2020-01-03 10:57:30 +0000253 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 +0100254 {
255 ScaleValidationGenericFixture<TensorType, AccessorType, FunctionType, T>::setup(shape,
256 data_type,
257 QuantizationInfo(),
258 data_layout,
259 policy,
260 border_mode,
Sang-Hoon Parkbb123bd2020-01-03 10:57:30 +0000261 sampling_policy,
Manuel Bottinica62c6f2021-03-23 11:50:34 +0000262 align_corners,
Gunes Bayirc4f27432022-09-11 15:59:19 +0100263 mixed_layout,
264 QuantizationInfo());
Michalis Spyrou17220e22018-09-12 13:35:38 +0100265 }
Isabella Gottardi1fab09f2017-07-13 15:55:57 +0100266};
267} // namespace validation
268} // namespace test
269} // namespace arm_compute
Jakub Sujak8f4b3df2023-10-30 16:04:51 +0000270#endif // ACL_TESTS_VALIDATION_FIXTURES_SCALEFIXTURE_H