Compute Library
 23.08
Scale.cpp
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2017-2023 Arm Limited.
3  *
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  */
26 #include "tests/NEON/Accessor.h"
27 #include "tests/datasets/ScaleValidationDataset.h"
28 #include "tests/framework/Macros.h"
30 #include "tests/validation/fixtures/ScaleFixture.h"
31 
32 namespace arm_compute
33 {
34 namespace test
35 {
36 namespace validation
37 {
38 namespace
39 {
40 using datasets::ScaleShapesBaseDataSet;
41 using datasets::ScaleInterpolationPolicySet;
42 using datasets::ScaleDataLayouts;
43 using datasets::ScaleSamplingPolicySet;
44 using datasets::ScaleAlignCornersSamplingPolicySet;
45 
46 /** We consider vector size in byte 64 since the maximum size of
47  * a vector used by the kernel is currently 64-byte (float32x4x4).
48  * There is possibility to reduce test time further by using
49  * smaller vector sizes for different data types where applicable.
50  */
51 constexpr uint32_t vector_byte = 64;
52 
53 template <typename T>
54 constexpr uint32_t num_elements_per_vector()
55 {
56  return vector_byte / sizeof(T);
57 }
58 
59 /** Quantization information data set */
60 const auto QuantizationInfoSet = framework::dataset::make("QuantizationInfo",
61 {
62  QuantizationInfo(0.5f, -10),
63 });
64 
65 /** Quantization information data set */
66 const auto InputQuantizationInfoSet = framework::dataset::make("InputQuantizationInfo",
67 {
68  QuantizationInfo(0.5f, -10),
69 });
70 
71 /** Quantization information data set */
72 const auto OutputQuantizationInfoSet = framework::dataset::make("OutputQuantizationInfo",
73 {
74  QuantizationInfo(0.2f, 20),
75 });
76 
77 /** Tolerance */
78 constexpr AbsoluteTolerance<uint8_t> tolerance_u8(1);
79 constexpr AbsoluteTolerance<int8_t> tolerance_s8(1);
80 constexpr AbsoluteTolerance<int16_t> tolerance_s16(1);
81 RelativeTolerance<float> tolerance_f32(0.05);
82 #ifdef __ARM_FEATURE_FP16_VECTOR_ARITHMETIC
83 constexpr float abs_tolerance_f16(0.01f);
84 RelativeTolerance<half> tolerance_f16(half(0.1));
85 #endif /* __ARM_FEATURE_FP16_VECTOR_ARITHMETIC */
86 
87 constexpr float tolerance_num_s16 = 0.01f;
88 constexpr float tolerance_num_f32 = 0.01f;
89 } // namespace
90 
91 TEST_SUITE(NEON)
92 TEST_SUITE(Scale)
93 TEST_SUITE(Validate)
94 
95 /** Validate test suite is to test ARM_COMPUTE_RETURN_ON_* macros
96  * we use to check the validity of given arguments in @ref NEScale
97  * Since this is using validate() of @ref NEScale, which pre-adjust
98  * arguments for the kernel, the following conditions in
99  * the kernel are not currently tested.
100  * - The same input and output
101  * - Data type of offset, dx and dy
102  * This suite also tests two different validate() APIs - one is
103  * using @ref ScaleKernelInfo and the other one is more verbose
104  * one calls the other one - in the same test case. Even though
105  * there are possibility that it makes debugging for regression
106  * harder, belows are reasons of this test case implementation.
107  * - The more verbose one is just a wrapper function calls
108  * the other one without any additional logic. So we are
109  * safe to merge two tests into one.
110  * - A large amount of code duplication is test suite can be prevented.
111  */
112 
113 const auto input_shape = TensorShape{ 2, 3, 3, 2 };
114 const auto output_shape = TensorShape{ 4, 6, 3, 2 };
115 
116 constexpr auto default_data_type = DataType::U8;
117 constexpr auto default_data_layout = DataLayout::NHWC;
121 
123 {
125  const auto output = TensorInfo{ output_shape, 1, default_data_type, default_data_layout };
126  Status result{};
127 
128  // nullptr is given as input
130  ARM_COMPUTE_EXPECT(bool(result) == false, framework::LogLevel::ERRORS);
131 
132  // nullptr is given as output
134  ARM_COMPUTE_EXPECT(bool(result) == false, framework::LogLevel::ERRORS);
135 }
136 
137 TEST_CASE(SupportDataType, framework::DatasetMode::ALL)
138 {
139  const std::map<DataType, bool> supported_data_types =
140  {
141  { DataType::U8, true },
142  { DataType::S8, false },
143  { DataType::QSYMM8, false },
144  { DataType::QASYMM8, true },
145  { DataType::QASYMM8_SIGNED, true },
146  { DataType::QSYMM8_PER_CHANNEL, false },
147  { DataType::U16, false },
148  { DataType::S16, true },
149  { DataType::QSYMM16, false },
150  { DataType::QASYMM16, false },
151  { DataType::U32, false },
152  { DataType::S32, false },
153  { DataType::U64, false },
154  { DataType::S64, false },
155  { DataType::BFLOAT16, false },
156 #ifdef __ARM_FEATURE_FP16_VECTOR_ARITHMETIC
157  { DataType::F16, true },
158 #endif // __ARM_FEATURE_FP16_VECTOR_ARITHMETIC
159  { DataType::F32, true },
160  { DataType::F64, false },
161  { DataType::SIZET, false },
162  };
163  Status result{};
164  for(auto &kv : supported_data_types)
165  {
166  const auto input = TensorInfo{ input_shape, 1, kv.first, default_data_layout };
167  const auto output = TensorInfo{ output_shape, 1, kv.first, default_data_layout };
168 
169  result = NEScale::validate(&input, &output, ScaleKernelInfo{ default_interpolation_policy, default_border_mode, PixelValue(), SamplingPolicy::CENTER, false });
170  ARM_COMPUTE_EXPECT(bool(result) == kv.second, framework::LogLevel::ERRORS);
171  }
172 }
173 
174 TEST_CASE(MissmatchingDataType, framework::DatasetMode::ALL)
175 {
176  constexpr auto non_default_data_type = DataType::F32;
177 
178  const auto input = TensorInfo{ input_shape, 1, default_data_type, default_data_layout };
179  const auto output = TensorInfo{ output_shape, 1, non_default_data_type, default_data_layout };
180  Status result{};
181 
182  result = NEScale::validate(&input, &output, ScaleKernelInfo{ default_interpolation_policy, default_border_mode, PixelValue(), SamplingPolicy::CENTER, false });
183  ARM_COMPUTE_EXPECT(bool(result) == false, framework::LogLevel::ERRORS);
184 }
185 
187 {
189  const auto output = TensorInfo{ output_shape, 1, default_data_type, default_data_layout };
190  Status result{};
191 
192  // Padding is not supported anymore
193  constexpr auto border_mode = BorderMode::CONSTANT;
194  constexpr bool use_padding = true;
195 
196  result = NEScale::validate(&input, &output, ScaleKernelInfo{ default_interpolation_policy, border_mode, PixelValue(), default_sampling_policy, use_padding });
197  ARM_COMPUTE_EXPECT(bool(result) == false, framework::LogLevel::ERRORS);
198 }
199 
201 {
202  // InterpolationPolicy::AREA is not supported for NHWC
204  constexpr auto data_layout = DataLayout::NHWC;
205 
207  const auto output = TensorInfo{ output_shape, 1, default_data_type, data_layout };
208  Status result{};
209 
211  ARM_COMPUTE_EXPECT(bool(result) == false, framework::LogLevel::ERRORS);
212 }
213 
215 {
216  // InterpolationPolicy::AREA only supports U8
218  constexpr auto data_type = DataType::F32;
219  constexpr auto data_layout = DataLayout::NCHW;
220 
221  const auto input = TensorInfo{ input_shape, 1, data_type, data_layout };
222  const auto output = TensorInfo{ output_shape, 1, data_type, data_layout };
223  Status result{};
224 
226  ARM_COMPUTE_EXPECT(bool(result) == false, framework::LogLevel::ERRORS);
227 }
228 
229 TEST_CASE(AlignedCornerNotSupported, framework::DatasetMode::ALL)
230 {
231  // Aligned corners require sampling policy to be TOP_LEFT.
233  constexpr bool align_corners = true;
234  constexpr auto sampling_policy = SamplingPolicy::CENTER;
235 
237  const auto output = TensorInfo{ output_shape, 1, default_data_type, default_data_layout };
238  Status result{};
239 
240  result = NEScale::validate(&input, &output, ScaleKernelInfo{ interpolation_policy, default_border_mode, PixelValue(), sampling_policy, false, align_corners });
241  ARM_COMPUTE_EXPECT(bool(result) == false, framework::LogLevel::ERRORS);
242 }
243 TEST_SUITE_END() // Validate
244 
245 DATA_TEST_CASE(CheckNoPadding, framework::DatasetMode::ALL, combine(combine(combine(combine(datasets::Medium4DShapes(),
246  framework::dataset::make("DataType", { DataType::F32, DataType::QASYMM8 })),
251 {
252  constexpr auto default_border_mode = BorderMode::CONSTANT;
254 
255  // Create tensors
256  Tensor src = create_tensor<Tensor>(shape, data_type);
257  src.info()->set_data_layout(data_layout);
258 
259  const float scale_x = 0.5f;
260  const float scale_y = 0.5f;
264  shape_scaled.set(idx_width, shape[idx_width] * scale_x, /* apply_dim_correction = */ false);
265  shape_scaled.set(idx_height, shape[idx_height] * scale_y, /* apply_dim_correction = */ false);
266  Tensor dst = create_tensor<Tensor>(shape_scaled, data_type);
267 
268  ARM_COMPUTE_EXPECT(src.info()->is_resizable(), framework::LogLevel::ERRORS);
269  ARM_COMPUTE_EXPECT(dst.info()->is_resizable(), framework::LogLevel::ERRORS);
270 
271  // Create and configure function
273  scale.configure(&src, &dst, info);
274 
275  validate(src.info()->padding(), PaddingSize(0, 0, 0, 0));
276  validate(dst.info()->padding(), PaddingSize(0, 0, 0, 0));
277 }
278 
279 DATA_TEST_CASE(CheckNoPaddingInterpAREA, framework::DatasetMode::ALL, combine(combine(combine(combine(datasets::Medium4DShapes(),
280  framework::dataset::make("DataType", { DataType::U8 })),
281  framework::dataset::make("InterpolationPolicy", { InterpolationPolicy::AREA })),
283  framework::dataset::make("DataLayout", { DataLayout::NCHW })),
285 {
286  constexpr auto default_border_mode = BorderMode::CONSTANT;
287  ScaleKernelInfo info(interpolation_policy, default_border_mode, PixelValue(), sampling_policy, false);
288 
289  // Create tensors
290  Tensor src = create_tensor<Tensor>(shape, data_type);
291  src.info()->set_data_layout(data_layout);
292 
293  const float scale_x = 0.5f;
294  const float scale_y = 0.5f;
295  TensorShape shape_scaled(shape);
298  shape_scaled.set(idx_width, shape[idx_width] * scale_x, /* apply_dim_correction = */ false);
299  shape_scaled.set(idx_height, shape[idx_height] * scale_y, /* apply_dim_correction = */ false);
300 
301  Tensor dst = create_tensor<Tensor>(shape, data_type);
302 
303  ARM_COMPUTE_EXPECT(src.info()->is_resizable(), framework::LogLevel::ERRORS);
304  ARM_COMPUTE_EXPECT(dst.info()->is_resizable(), framework::LogLevel::ERRORS);
305 
306  // Create and configure function
307  NEScale scale;
308  scale.configure(&src, &dst, info);
309 
310  validate(src.info()->padding(), PaddingSize(0, 0, 0, 0));
311  validate(dst.info()->padding(), PaddingSize(0, 0, 0, 0));
312 }
313 
314 template <typename T>
315 using NEScaleFixture = ScaleValidationFixture<Tensor, Accessor, NEScale, T>;
316 template <typename T>
317 using NEScaleMixedDataLayoutFixture = ScaleValidationFixture<Tensor, Accessor, NEScale, T, true>;
318 template <typename T>
319 using NEScaleQuantizedFixture = ScaleValidationQuantizedFixture<Tensor, Accessor, NEScale, T>;
320 template <typename T>
321 using NEScaleDifferentOutputQuantizedFixture = ScaleValidationDifferentOutputQuantizedFixture<Tensor, Accessor, NEScale, T>;
322 template <typename T>
323 using NEScaleQuantizedMixedDataLayoutFixture = ScaleValidationQuantizedFixture<Tensor, Accessor, NEScale, T, true>;
324 
325 TEST_SUITE(Float)
326 TEST_SUITE(FP32)
327 const auto f32_shape = combine((SCALE_SHAPE_DATASET(num_elements_per_vector<float>())), framework::dataset::make("DataType", DataType::F32));
328 const auto f32_shape_nhwc = combine(datasets::Small3DShapes(), framework::dataset::make("DataType", DataType::F32));
329 FIXTURE_DATA_TEST_CASE(RunSmall, NEScaleFixture<float>, framework::DatasetMode::ALL, ASSEMBLE_DATASET(f32_shape, ScaleSamplingPolicySet))
330 {
331  //Create valid region
332  TensorInfo src_info(_shape, 1, _data_type);
333  ValidRegion valid_region = calculate_valid_region_scale(src_info, _reference.shape(), _policy, _sampling_policy, (_border_mode == BorderMode::UNDEFINED));
334 
335  // Validate output
336  validate(Accessor(_target), _reference, valid_region, tolerance_f32, tolerance_num_f32);
337 }
338 FIXTURE_DATA_TEST_CASE(RunMixedDataLayout, NEScaleMixedDataLayoutFixture<float>, framework::DatasetMode::PRECOMMIT, ASSEMBLE_DATASET(f32_shape, ScaleSamplingPolicySet))
339 {
340  //Create valid region
341  TensorInfo src_info(_shape, 1, _data_type);
342  ValidRegion valid_region = calculate_valid_region_scale(src_info, _reference.shape(), _policy, _sampling_policy, (_border_mode == BorderMode::UNDEFINED));
343 
344  // Validate output
345  validate(Accessor(_target), _reference, valid_region, tolerance_f32, tolerance_num_f32);
346 }
347 FIXTURE_DATA_TEST_CASE(RunSmallAlignCorners, NEScaleFixture<float>, framework::DatasetMode::ALL, ASSEMBLE_DATASET(f32_shape, ScaleAlignCornersSamplingPolicySet))
348 {
349  //Create valid region
350  TensorInfo src_info(_shape, 1, _data_type);
351  ValidRegion valid_region = calculate_valid_region_scale(src_info, _reference.shape(), _policy, _sampling_policy, (_border_mode == BorderMode::UNDEFINED));
352 
353  // Validate output
354  validate(Accessor(_target), _reference, valid_region, tolerance_f32, tolerance_num_f32);
355 }
356 FIXTURE_DATA_TEST_CASE(RunMediumNHWC, NEScaleFixture<float>, framework::DatasetMode::ALL, ASSEMBLE_NHWC_DATASET(f32_shape_nhwc, ScaleSamplingPolicySet))
357 {
358  //Create valid region
359  TensorInfo src_info(_shape, 1, _data_type);
360  ValidRegion valid_region = calculate_valid_region_scale(src_info, _reference.shape(), _policy, _sampling_policy, (_border_mode == BorderMode::UNDEFINED));
361 
362  // Validate output
363  validate(Accessor(_target), _reference, valid_region, tolerance_f32, tolerance_num_f32);
364 }
365 FIXTURE_DATA_TEST_CASE(RunMediumMixedDataLayoutNHWC, NEScaleMixedDataLayoutFixture<float>, framework::DatasetMode::PRECOMMIT, ASSEMBLE_NHWC_DATASET(f32_shape_nhwc, ScaleSamplingPolicySet))
366 {
367  //Create valid region
368  TensorInfo src_info(_shape, 1, _data_type);
369  ValidRegion valid_region = calculate_valid_region_scale(src_info, _reference.shape(), _policy, _sampling_policy, (_border_mode == BorderMode::UNDEFINED));
370 
371  // Validate output
372  validate(Accessor(_target), _reference, valid_region, tolerance_f32, tolerance_num_f32);
373 }
374 FIXTURE_DATA_TEST_CASE(RunMediumAlignCornersNHWC, NEScaleFixture<float>, framework::DatasetMode::ALL, ASSEMBLE_NHWC_DATASET(f32_shape_nhwc, ScaleAlignCornersSamplingPolicySet))
375 {
376  //Create valid region
377  TensorInfo src_info(_shape, 1, _data_type);
378  ValidRegion valid_region = calculate_valid_region_scale(src_info, _reference.shape(), _policy, _sampling_policy, (_border_mode == BorderMode::UNDEFINED));
379 
380  // Validate output
381  validate(Accessor(_target), _reference, valid_region, tolerance_f32, tolerance_num_f32);
382 }
383 TEST_SUITE_END() // FP32
384 #ifdef __ARM_FEATURE_FP16_VECTOR_ARITHMETIC
385 TEST_SUITE(FP16)
386 const auto f16_shape = combine((SCALE_SHAPE_DATASET(num_elements_per_vector<half>())), framework::dataset::make("DataType", DataType::F16));
387 const auto f16_shape_nhwc = combine(datasets::Small3DShapes(), framework::dataset::make("DataType", DataType::F16));
388 FIXTURE_DATA_TEST_CASE(RunSmall, NEScaleFixture<half>, framework::DatasetMode::ALL, ASSEMBLE_DATASET(f16_shape, ScaleSamplingPolicySet))
389 {
390  //Create valid region
391  TensorInfo src_info(_shape, 1, _data_type);
392  const ValidRegion valid_region = calculate_valid_region_scale(src_info, _reference.shape(), _policy, _sampling_policy, (_border_mode == BorderMode::UNDEFINED));
393 
394  // Validate output
395  validate(Accessor(_target), _reference, valid_region, tolerance_f16, 0.0f, abs_tolerance_f16);
396 }
397 FIXTURE_DATA_TEST_CASE(RunSmallAlignCorners, NEScaleFixture<half>, framework::DatasetMode::ALL, ASSEMBLE_DATASET(f16_shape, ScaleAlignCornersSamplingPolicySet))
398 {
399  //Create valid region
400  TensorInfo src_info(_shape, 1, _data_type);
401  const ValidRegion valid_region = calculate_valid_region_scale(src_info, _reference.shape(), _policy, _sampling_policy, (_border_mode == BorderMode::UNDEFINED));
402 
403  // Validate output
404  validate(Accessor(_target), _reference, valid_region, tolerance_f16, 0.0f, abs_tolerance_f16);
405 }
406 FIXTURE_DATA_TEST_CASE(RunMediumNHWC, NEScaleFixture<half>, framework::DatasetMode::ALL, ASSEMBLE_NHWC_DATASET(f16_shape_nhwc, ScaleSamplingPolicySet))
407 {
408  //Create valid region
409  TensorInfo src_info(_shape, 1, _data_type);
410  ValidRegion valid_region = calculate_valid_region_scale(src_info, _reference.shape(), _policy, _sampling_policy, (_border_mode == BorderMode::UNDEFINED));
411 
412  // Validate output
413  validate(Accessor(_target), _reference, valid_region, tolerance_f16, 0.0f, abs_tolerance_f16);
414 }
415 FIXTURE_DATA_TEST_CASE(RunMediumMixedDataLayoutNHWC, NEScaleMixedDataLayoutFixture<half>, framework::DatasetMode::PRECOMMIT, ASSEMBLE_NHWC_DATASET(f16_shape_nhwc, ScaleSamplingPolicySet))
416 {
417  //Create valid region
418  TensorInfo src_info(_shape, 1, _data_type);
419  ValidRegion valid_region = calculate_valid_region_scale(src_info, _reference.shape(), _policy, _sampling_policy, (_border_mode == BorderMode::UNDEFINED));
420 
421  // Validate output
422  validate(Accessor(_target), _reference, valid_region, tolerance_f16, 0.0f, abs_tolerance_f16);
423 }
424 FIXTURE_DATA_TEST_CASE(RunMediumAlignCornersNHWC, NEScaleFixture<half>, framework::DatasetMode::ALL, ASSEMBLE_NHWC_DATASET(f16_shape_nhwc, ScaleAlignCornersSamplingPolicySet))
425 {
426  //Create valid region
427  TensorInfo src_info(_shape, 1, _data_type);
428  ValidRegion valid_region = calculate_valid_region_scale(src_info, _reference.shape(), _policy, _sampling_policy, (_border_mode == BorderMode::UNDEFINED));
429 
430  // Validate output
431  validate(Accessor(_target), _reference, valid_region, tolerance_f16, 0.0f, abs_tolerance_f16);
432 }
433 TEST_SUITE_END() // FP16
434 #endif /* __ARM_FEATURE_FP16_VECTOR_ARITHMETIC */
435 TEST_SUITE_END() // Float
436 
437 TEST_SUITE(Integer)
438 TEST_SUITE(U8)
439 const auto u8_shape = combine((SCALE_SHAPE_DATASET(num_elements_per_vector<uint8_t>())), framework::dataset::make("DataType", DataType::U8));
440 FIXTURE_DATA_TEST_CASE(RunSmall, NEScaleFixture<uint8_t>, framework::DatasetMode::ALL, ASSEMBLE_DATASET(u8_shape, ScaleSamplingPolicySet))
441 {
442  //Create valid region
443  TensorInfo src_info(_shape, 1, _data_type);
444  ValidRegion valid_region = calculate_valid_region_scale(src_info, _reference.shape(), _policy, _sampling_policy, (_border_mode == BorderMode::UNDEFINED));
445 
446  // Validate output
447  validate(Accessor(_target), _reference, valid_region, tolerance_u8);
448 }
449 FIXTURE_DATA_TEST_CASE(RunSmallAlignCorners, NEScaleFixture<uint8_t>, framework::DatasetMode::ALL, ASSEMBLE_DATASET(u8_shape, ScaleAlignCornersSamplingPolicySet))
450 {
451  //Create valid region
452  TensorInfo src_info(_shape, 1, _data_type);
453  ValidRegion valid_region = calculate_valid_region_scale(src_info, _reference.shape(), _policy, _sampling_policy, (_border_mode == BorderMode::UNDEFINED));
454 
455  // Validate output
456  validate(Accessor(_target), _reference, valid_region, tolerance_u8);
457 }
458 TEST_SUITE_END() // U8
459 TEST_SUITE(S8)
460 const auto s8_shape = combine((SCALE_SHAPE_DATASET(num_elements_per_vector<int8_t>())), framework::dataset::make("DataType", DataType::S8));
461 FIXTURE_DATA_TEST_CASE(RunSmall, NEScaleFixture<int8_t>, framework::DatasetMode::ALL, ASSEMBLE_S8_DATASET(s8_shape, ScaleSamplingPolicySet))
462 {
463  //Create valid region
464  TensorInfo src_info(_shape, 1, _data_type);
465  ValidRegion valid_region = calculate_valid_region_scale(src_info, _reference.shape(), _policy, _sampling_policy, (_border_mode == BorderMode::UNDEFINED));
466 
467  // Validate output
468  validate(Accessor(_target), _reference, valid_region, tolerance_s8);
469 }
470 FIXTURE_DATA_TEST_CASE(RunSmallAlignCorners, NEScaleFixture<int8_t>, framework::DatasetMode::ALL, ASSEMBLE_S8_DATASET(s8_shape, ScaleAlignCornersSamplingPolicySet))
471 {
472  //Create valid region
473  TensorInfo src_info(_shape, 1, _data_type);
474  ValidRegion valid_region = calculate_valid_region_scale(src_info, _reference.shape(), _policy, _sampling_policy, (_border_mode == BorderMode::UNDEFINED));
475 
476  // Validate output
477  validate(Accessor(_target), _reference, valid_region, tolerance_s8);
478 }
479 TEST_SUITE_END() // S8
480 TEST_SUITE(S16)
481 const auto s16_shape = combine((SCALE_SHAPE_DATASET(num_elements_per_vector<int16_t>())), framework::dataset::make("DataType", DataType::S16));
482 FIXTURE_DATA_TEST_CASE(RunSmall, NEScaleFixture<int16_t>, framework::DatasetMode::ALL, ASSEMBLE_DATASET(s16_shape, ScaleSamplingPolicySet))
483 {
484  //Create valid region
485  TensorInfo src_info(_shape, 1, _data_type);
486  ValidRegion valid_region = calculate_valid_region_scale(src_info, _reference.shape(), _policy, _sampling_policy, (_border_mode == BorderMode::UNDEFINED));
487 
488  // Validate output
489  validate(Accessor(_target), _reference, valid_region, tolerance_s16, tolerance_num_s16);
490 }
491 FIXTURE_DATA_TEST_CASE(RunSmallAlignCorners, NEScaleFixture<int16_t>, framework::DatasetMode::ALL, ASSEMBLE_DATASET(s16_shape, ScaleAlignCornersSamplingPolicySet))
492 {
493  //Create valid region
494  TensorInfo src_info(_shape, 1, _data_type);
495  ValidRegion valid_region = calculate_valid_region_scale(src_info, _reference.shape(), _policy, _sampling_policy, (_border_mode == BorderMode::UNDEFINED));
496 
497  // Validate output
498  validate(Accessor(_target), _reference, valid_region, tolerance_s16, tolerance_num_s16);
499 }
500 TEST_SUITE_END() // S16
501 TEST_SUITE_END() // Integer
502 
503 TEST_SUITE(Quantized)
504 TEST_SUITE(QASYMM8)
505 const auto qasymm8_shape = combine((SCALE_SHAPE_DATASET(num_elements_per_vector<uint8_t>())), framework::dataset::make("DataType", DataType::QASYMM8));
506 FIXTURE_DATA_TEST_CASE(RunSmall, NEScaleQuantizedFixture<uint8_t>, framework::DatasetMode::ALL, ASSEMBLE_QUANTIZED_DATASET(qasymm8_shape, ScaleSamplingPolicySet, QuantizationInfoSet))
507 {
508  //Create valid region
509  TensorInfo src_info(_shape, 1, _data_type);
510  ValidRegion valid_region = calculate_valid_region_scale(src_info, _reference.shape(), _policy, _sampling_policy, (_border_mode == BorderMode::UNDEFINED));
511 
512  // Validate output
513  validate(Accessor(_target), _reference, valid_region, tolerance_u8);
514 }
516  ASSEMBLE_DIFFERENTLY_QUANTIZED_DATASET(qasymm8_shape, ScaleSamplingPolicySet, InputQuantizationInfoSet, OutputQuantizationInfoSet))
517 {
518  //Create valid region
519  TensorInfo src_info(_shape, 1, _data_type);
520  ValidRegion valid_region = calculate_valid_region_scale(src_info, _reference.shape(), _policy, _sampling_policy, (_border_mode == BorderMode::UNDEFINED));
521 
522  // Validate output
523  validate(Accessor(_target), _reference, valid_region, tolerance_u8);
524 }
525 FIXTURE_DATA_TEST_CASE(RunMixedDataLayout, NEScaleQuantizedMixedDataLayoutFixture<uint8_t>, framework::DatasetMode::ALL, ASSEMBLE_QUANTIZED_DATASET(qasymm8_shape, ScaleSamplingPolicySet,
526  QuantizationInfoSet))
527 {
528  //Create valid region
529  TensorInfo src_info(_shape, 1, _data_type);
530  ValidRegion valid_region = calculate_valid_region_scale(src_info, _reference.shape(), _policy, _sampling_policy, (_border_mode == BorderMode::UNDEFINED));
531 
532  // Validate output
533  validate(Accessor(_target), _reference, valid_region, tolerance_u8);
534 }
535 FIXTURE_DATA_TEST_CASE(RunSmallAlignCorners, NEScaleQuantizedFixture<uint8_t>, framework::DatasetMode::ALL, ASSEMBLE_QUANTIZED_DATASET(qasymm8_shape, ScaleAlignCornersSamplingPolicySet,
536  QuantizationInfoSet))
537 {
538  //Create valid region
539  TensorInfo src_info(_shape, 1, _data_type);
540  ValidRegion valid_region = calculate_valid_region_scale(src_info, _reference.shape(), _policy, _sampling_policy, (_border_mode == BorderMode::UNDEFINED));
541 
542  // Validate output
543  validate(Accessor(_target), _reference, valid_region, tolerance_u8);
544 }
545 TEST_SUITE_END() // QASYMM8
546 TEST_SUITE(QASYMM8_SIGNED)
547 const auto qasymm8_signed_shape = combine((SCALE_SHAPE_DATASET(num_elements_per_vector<int8_t>())), framework::dataset::make("DataType", DataType::QASYMM8_SIGNED));
549 FIXTURE_DATA_TEST_CASE(RunSmall, NEScaleQuantizedFixture<int8_t>, framework::DatasetMode::ALL, ASSEMBLE_QUANTIZED_DATASET(qasymm8_signed_shape, ScaleSamplingPolicySet, QuantizationInfoSet))
550 {
551  //Create valid region
552  TensorInfo src_info(_shape, 1, _data_type);
553  ValidRegion valid_region = calculate_valid_region_scale(src_info, _reference.shape(), _policy, _sampling_policy, (_border_mode == BorderMode::UNDEFINED));
554 
555  // Validate output
556  validate(Accessor(_target), _reference, valid_region, tolerance_qasymm8_signed);
557 }
559  ASSEMBLE_DIFFERENTLY_QUANTIZED_DATASET(qasymm8_signed_shape, ScaleSamplingPolicySet, InputQuantizationInfoSet, OutputQuantizationInfoSet))
560 {
561  //Create valid region
562  TensorInfo src_info(_shape, 1, _data_type);
563  ValidRegion valid_region = calculate_valid_region_scale(src_info, _reference.shape(), _policy, _sampling_policy, (_border_mode == BorderMode::UNDEFINED));
564 
565  // Validate output
566  validate(Accessor(_target), _reference, valid_region, tolerance_qasymm8_signed);
567 }
568 FIXTURE_DATA_TEST_CASE(RunSmallAlignCorners, NEScaleQuantizedFixture<int8_t>, framework::DatasetMode::ALL, ASSEMBLE_QUANTIZED_DATASET(qasymm8_signed_shape, ScaleAlignCornersSamplingPolicySet,
569  QuantizationInfoSet))
570 {
571  //Create valid region
572  TensorInfo src_info(_shape, 1, _data_type);
573  ValidRegion valid_region = calculate_valid_region_scale(src_info, _reference.shape(), _policy, _sampling_policy, (_border_mode == BorderMode::UNDEFINED));
574 
575  // Validate output
576  validate(Accessor(_target), _reference, valid_region, tolerance_qasymm8_signed);
577 }
578 TEST_SUITE_END() // QASYMM8_SIGNED
579 TEST_SUITE_END() // Quantized
580 
581 TEST_SUITE_END() // Scale
582 TEST_SUITE_END() // Neon
583 } // namespace validation
584 } // namespace test
585 } // namespace arm_compute
arm_compute::DataLayout::NCHW
@ NCHW
Num samples, channels, height, width.
arm_compute::test::validation::TEST_SUITE_END
TEST_SUITE_END() FIXTURE_DATA_TEST_CASE(RunSmall
[CLActivationLayer Test snippet]
Definition: DequantizationLayer.cpp:111
arm_compute::DataType::QSYMM8_PER_CHANNEL
@ QSYMM8_PER_CHANNEL
quantized, symmetric per channel fixed-point 8-bit number
arm_compute::DataType::QASYMM16
@ QASYMM16
quantized, asymmetric fixed-point 16-bit number
arm_compute::BorderMode::CONSTANT
@ CONSTANT
Pixels outside the image are assumed to have a constant value.
arm_compute::DataType::U64
@ U64
unsigned 64-bit number
arm_compute::test::validation::TEST_CASE
TEST_CASE(FusedActivation, framework::DatasetMode::ALL)
Validate fused activation expecting the following behaviours:
Definition: ArithmeticAddition.cpp:93
arm_compute::test::validation::src
SimpleTensor< float > src
Definition: DFT.cpp:155
arm_compute::test::validation::FIXTURE_DATA_TEST_CASE
FIXTURE_DATA_TEST_CASE(RunSmall, CLAbsLayerFixture< half >, framework::DatasetMode::PRECOMMIT, combine(datasets::SmallShapes(), framework::dataset::make("DataType", DataType::F16)))
Definition: AbsLayer.cpp:50
arm_compute::DataType::BFLOAT16
@ BFLOAT16
16-bit brain floating-point number
arm_compute::test::validation::DATA_TEST_CASE
DATA_TEST_CASE(Validate, framework::DatasetMode::ALL, zip(zip(zip(framework::dataset::make("InputInfo", { TensorInfo(TensorShape(27U, 13U, 2U), 1, DataType::F32), TensorInfo(TensorShape(27U, 13U, 2U), 1, DataType::F32), TensorInfo(TensorShape(32U, 13U, 2U), 1, DataType::F32), TensorInfo(TensorShape(32U, 13U, 2U), 1, DataType::QASYMM8), TensorInfo(TensorShape(27U, 13U, 2U), 1, DataType::QASYMM8), TensorInfo(TensorShape(27U, 13U, 2U), 1, DataType::F32), TensorInfo(TensorShape(32U, 13U, 2U), 1, DataType::QSYMM16), TensorInfo(TensorShape(32U, 13U, 2U), 1, DataType::QSYMM16), TensorInfo(TensorShape(32U, 13U, 2U), 1, DataType::QSYMM16), }), framework::dataset::make("OutputInfo",{ TensorInfo(TensorShape(27U, 13U, 2U), 1, DataType::F16), TensorInfo(TensorShape(27U, 13U, 2U), 1, DataType::F32), TensorInfo(TensorShape(32U, 13U, 2U), 1, DataType::F32), TensorInfo(TensorShape(32U, 13U, 2U), 1, DataType::QASYMM8), TensorInfo(TensorShape(27U, 13U, 2U), 1, DataType::QASYMM8), TensorInfo(TensorShape(30U, 11U, 2U), 1, DataType::F32), TensorInfo(TensorShape(32U, 13U, 2U), 1, DataType::QSYMM16, QuantizationInfo(1.f/32768.f, 0)), TensorInfo(TensorShape(32U, 13U, 2U), 1, DataType::QSYMM16, QuantizationInfo(1.f/32768.f, 0)), TensorInfo(TensorShape(32U, 13U, 2U), 1, DataType::QSYMM16, QuantizationInfo(1.f/32768.f, 0)), })), framework::dataset::make("ActivationInfo", { ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU), ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU), ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU), ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::LU_BOUNDED_RELU), ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::TANH), ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU), ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::TANH), ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::LOGISTIC), ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::SQRT), })), framework::dataset::make("Expected", { false, true, true, true, false, false, true, true, false })), input_info, output_info, act_info, expected)
Definition: ActivationLayer.cpp:100
arm_compute::test::validation::qasymm8_shape
const auto qasymm8_shape
Definition: Scale.cpp:386
arm_compute::PixelValue
Class describing the value of a pixel for any image format.
Definition: PixelValue.h:35
arm_compute::test::validation::idx_height
const int idx_height
Definition: Scale.cpp:263
arm_compute::test::validation::NEScaleDifferentOutputQuantizedFixture
ScaleValidationDifferentOutputQuantizedFixture< Tensor, Accessor, NEScale, T > NEScaleDifferentOutputQuantizedFixture
Definition: Scale.cpp:321
Helpers.h
arm_compute::test::validation::combine
combine(datasets::SmallShapes(), framework::dataset::make("DataType", DataType::F32)))
Definition: AbsLayer.cpp:65
arm_compute::DataType::F64
@ F64
64-bit floating-point number
arm_compute::test::validation::f32_shape
const auto f32_shape
Definition: Scale.cpp:209
arm_compute::test::validation::output_shape
const auto output_shape
Definition: ConvolutionLayer.cpp:411
arm_compute::BorderSize
Container for 2D border size.
Definition: Types.h:242
arm_compute::DataLayout::NHWC
@ NHWC
Num samples, height, width, channels.
arm_compute::BorderMode::UNDEFINED
@ UNDEFINED
Borders are left undefined.
arm_compute::SamplingPolicy::TOP_LEFT
@ TOP_LEFT
Samples are taken at pixel top left corner.
arm_compute::InterpolationPolicy::AREA
@ AREA
Output values are determined by averaging the source pixels whose areas fall under the area of the de...
arm_compute::DataType::QASYMM8
@ QASYMM8
quantized, asymmetric fixed-point 8-bit number unsigned
arm_compute::DataType::U16
@ U16
unsigned 16-bit number
arm_compute::TensorShape
Shape of a tensor.
Definition: TensorShape.h:39
arm_compute::test::validation::dst
auto dst
Definition: DFT.cpp:170
arm_compute::test::validation::tolerance_f16
RelativeTolerance< half_float::half > tolerance_f16(half_float::half(0.1))
Tolerance value for comparing reference's output against implementation's output for DataType::F16.
arm_compute::DataType::QSYMM8
@ QSYMM8
quantized, symmetric fixed-point 8-bit number
arm_compute::test::validation::sampling_policy
sampling_policy
Definition: Scale.cpp:250
arm_compute::test::validation::NEScaleQuantizedFixture
ScaleValidationQuantizedFixture< Tensor, Accessor, NEScale, T > NEScaleQuantizedFixture
Definition: Scale.cpp:319
arm_compute::test::validation::idx_width
const int idx_width
Definition: Scale.cpp:262
arm_compute::test::Accessor
Accessor implementation for Tensor objects.
Definition: Accessor.h:35
arm_compute::test::validation::NEScaleQuantizedMixedDataLayoutFixture
ScaleValidationQuantizedFixture< Tensor, Accessor, NEScale, T, true > NEScaleQuantizedMixedDataLayoutFixture
Definition: Scale.cpp:323
arm_compute::DataType::S8
@ S8
signed 8-bit number
arm_compute::test::validation::default_data_type
constexpr auto default_data_type
Definition: Scale.cpp:98
arm_compute::DataLayoutDimension::WIDTH
@ WIDTH
width
arm_compute::DataType::QSYMM16
@ QSYMM16
quantized, symmetric fixed-point 16-bit number
arm_compute::test::validation::data_layout
const auto data_layout
Definition: ConvolutionLayer.cpp:406
arm_compute::test::validation::valid_region
const ValidRegion valid_region
Definition: Scale.cpp:214
arm_compute::test::validation::default_sampling_policy
constexpr auto default_sampling_policy
Definition: Scale.cpp:120
arm_compute::test::validation::validate
validate(CLAccessor(output_state), expected_output)
arm_compute::test::validation::default_interpolation_policy
constexpr auto default_interpolation_policy
Definition: Scale.cpp:100
arm_compute::half
half_float::half half
16-bit floating point type
Definition: CoreTypes.h:35
arm_compute::test::validation::shape
shape
Definition: DFT.cpp:115
arm_compute::test::validation::NEScaleFixture
ScaleValidationFixture< Tensor, Accessor, NEScale, T > NEScaleFixture
Definition: Scale.cpp:315
arm_compute::test::framework::DatasetMode::ALL
@ ALL
arm_compute::DataType::U32
@ U32
unsigned 32-bit number
arm_compute::NEScale::configure
void configure(ITensor *input, ITensor *output, const ScaleKernelInfo &info)
Initialize the function's source, destination, interpolation type and border_mode.
Definition: NEScale.cpp:49
arm_compute::NEScale::validate
static Status validate(const ITensorInfo *input, const ITensorInfo *output, const ScaleKernelInfo &info)
Static function to check if given info will lead to a valid configuration of NEScale.
Definition: NEScale.cpp:119
arm_compute::test::validation::ARM_COMPUTE_EXPECT
ARM_COMPUTE_EXPECT(has_error==expected, framework::LogLevel::ERRORS)
arm_compute::DataLayoutDimension::HEIGHT
@ HEIGHT
height
arm_compute::DataType::U8
@ U8
unsigned 8-bit number
Accessor.h
arm_compute::NEScale
Basic function to compute Scale.
Definition: NEScale.h:40
arm_compute::DataType::S16
@ S16
signed 16-bit number
arm_compute::ValidRegion
Container for valid region of a window.
Definition: Types.h:144
arm_compute::Status
Status class.
Definition: Error.h:52
arm_compute::DataType::QASYMM8_SIGNED
@ QASYMM8_SIGNED
quantized, asymmetric fixed-point 8-bit number signed
arm_compute::test::validation::scale_y
const float scale_y
Definition: Scale.cpp:260
arm_compute::detail::ObjectType::Tensor
@ Tensor
arm_compute::test::validation::shape_scaled
TensorShape shape_scaled(shape)
Macros.h
arm_compute::test::validation::interpolation_policy
interpolation_policy
Definition: Scale.cpp:250
arm_compute::test::framework::DatasetMode::PRECOMMIT
@ PRECOMMIT
arm_compute::test::validation::scale_x
const float scale_x
Definition: Scale.cpp:259
arm_compute::test::framework::dataset::make
std::enable_if< is_container< T >::value, ContainerDataset< T > >::type make(std::string name, T &&values)
Helper function to create a ContainerDataset.
Definition: ContainerDataset.h:160
arm_compute::InterpolationPolicy::BILINEAR
@ BILINEAR
Output values are defined by bilinear interpolation between the pixels.
arm_compute::test::validation::data_type
data_type
Definition: Cast.cpp:223
Validation.h
arm_compute::test::validation::input_shape
const auto input_shape
Validate test suite is to test ARM_COMPUTE_RETURN_ON_* macros we use to check the validity of given a...
Definition: ConvolutionLayer.cpp:408
arm_compute::test::validation::NEScaleMixedDataLayoutFixture
ScaleValidationFixture< Tensor, Accessor, NEScale, T, true > NEScaleMixedDataLayoutFixture
Definition: Scale.cpp:317
arm_compute::test::validation::tolerance_f32
RelativeTolerance< float > tolerance_f32(0.01f)
Tolerance value for comparing reference's output against implementation's output for DataType::F32.
arm_compute::get_data_layout_dimension_index
size_t get_data_layout_dimension_index(const DataLayout &data_layout, const DataLayoutDimension &data_layout_dimension)
Get the index of the given dimension.
Definition: Helpers.inl:203
arm_compute::TensorInfo
Store the tensor's metadata.
Definition: TensorInfo.h:42
NEScale.h
arm_compute::PaddingSize
BorderSize PaddingSize
Container for 2D padding size.
Definition: Types.h:357
arm_compute::calculate_valid_region_scale
ValidRegion calculate_valid_region_scale(const ITensorInfo &src_info, const TensorShape &dst_shape, InterpolationPolicy interpolate_policy, SamplingPolicy sampling_policy, bool border_undefined)
Helper function to calculate the Valid Region for Scale.
Definition: Helpers.cpp:28
arm_compute::DataType::S64
@ S64
signed 64-bit number
arm_compute::test::validation::f32_shape_nhwc
const auto f32_shape_nhwc
Definition: Scale.cpp:328
arm_compute::test::validation::scale
NEScale scale
Definition: Scale.cpp:272
arm_compute
Copyright (c) 2017-2023 Arm Limited.
Definition: introduction.dox:24
arm_compute::ScaleKernelInfo
Definition: KernelDescriptors.h:190
arm_compute::test::validation::TEST_SUITE
TEST_SUITE(QASYMM8_to_F32) FIXTURE_DATA_TEST_CASE(RunSmall
arm_compute::DataType::F16
@ F16
16-bit floating-point number
arm_compute::test::validation::default_data_layout
constexpr auto default_data_layout
Definition: Scale.cpp:99
arm_compute::DataType::SIZET
@ SIZET
size_t
arm_compute::DataType::S32
@ S32
signed 32-bit number
arm_compute::test::validation::src_info
TensorInfo src_info(src_shape, 1, data_type)
arm_compute::test::validation::default_border_mode
constexpr auto default_border_mode
Definition: Scale.cpp:101
arm_compute::InterpolationPolicy::NEAREST_NEIGHBOR
@ NEAREST_NEIGHBOR
Output values are defined to match the source pixel whose center is nearest to the sample position.
arm_compute::SamplingPolicy::CENTER
@ CENTER
Samples are taken at pixel center.
arm_compute::test::validation::tolerance_qasymm8_signed
constexpr AbsoluteTolerance< int8_t > tolerance_qasymm8_signed
Definition: Scale.cpp:548
arm_compute::DataType::F32
@ F32
32-bit floating-point number
arm_compute::Tensor
Basic implementation of the tensor interface.
Definition: Tensor.h:37
arm_compute::test::validation::info
ScaleKernelInfo info(interpolation_policy, default_border_mode, PixelValue(), sampling_policy, false)
arm_compute::TensorShape::set
TensorShape & set(size_t dimension, size_t value, bool apply_dim_correction=true, bool increase_dim_unit=true)
Accessor to set the value of one of the dimensions.
Definition: TensorShape.h:79
arm_compute::test::validation::AbsoluteTolerance
Class reprensenting an absolute tolerance value.
Definition: Validation.h:61
arm_compute::test::framework::DatasetMode
DatasetMode
Possible dataset modes.
Definition: DatasetModes.h:40
arm_compute::DataType
DataType
Available data types.
Definition: CoreTypes.h:82
arm_compute::test::validation::input
auto input
Definition: LSTMLayerQuantized.cpp:486
arm_compute::test::framework::LogLevel::ERRORS
@ ERRORS