• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2017-2022 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  */
24 #ifndef ARM_COMPUTE_TEST_SCALE_FIXTURE
25 #define ARM_COMPUTE_TEST_SCALE_FIXTURE
26 
27 #include "tests/framework/Fixture.h"
28 #include "tests/validation/reference/Permute.h"
29 #include "tests/validation/reference/Scale.h"
30 
31 namespace arm_compute
32 {
33 namespace test
34 {
35 namespace validation
36 {
37 template <typename TensorType, typename AccessorType, typename FunctionType, typename T>
38 class ScaleValidationGenericFixture : public framework::Fixture
39 {
40 public:
41     template <typename...>
setup(TensorShape shape,DataType data_type,QuantizationInfo quantization_info,DataLayout data_layout,InterpolationPolicy policy,BorderMode border_mode,SamplingPolicy sampling_policy,bool align_corners,bool mixed_layout,QuantizationInfo output_quantization_info)42     void setup(TensorShape shape, DataType data_type, QuantizationInfo quantization_info, DataLayout data_layout, InterpolationPolicy policy, BorderMode border_mode, SamplingPolicy sampling_policy,
43                bool align_corners, bool mixed_layout, QuantizationInfo output_quantization_info)
44     {
45         _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;
54 
55         generate_scale(shape);
56 
57         std::mt19937                            generator(library->seed());
58         std::uniform_int_distribution<uint32_t> distribution_u8(0, 255);
59         _constant_border_value = static_cast<T>(distribution_u8(generator));
60 
61         _target    = compute_target(shape, data_layout);
62         _reference = compute_reference(shape);
63     }
64 
65 protected:
mix_layout(FunctionType & layer,TensorType & src,TensorType & dst)66     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 
generate_scale(const TensorShape & shape)81     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 };
88         const float     min_width{ 1.f };
89         const float     min_height{ 1.f };
90 
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 
109     template <typename U>
fill(U && tensor)110     void fill(U &&tensor)
111     {
112         if(tensor.data_type() == DataType::F32)
113         {
114             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         {
119             arm_compute::utils::uniform_real_distribution_16bit<half> distribution{ -5.0f, 5.0f };
120             library->fill(tensor, distribution, 0);
121         }
122         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         }
127         else
128         {
129             library->fill_tensor_uniform(tensor, 0);
130         }
131     }
132 
compute_target(TensorShape shape,DataLayout data_layout)133     TensorType compute_target(TensorShape shape, DataLayout data_layout)
134     {
135         // Change shape in case of NHWC.
136         if(data_layout == DataLayout::NHWC)
137         {
138             permute(shape, PermutationVector(2U, 0U, 1U));
139         }
140 
141         // Create tensors
142         TensorType src = create_tensor<TensorType>(shape, _data_type, 1, _input_quantization_info, data_layout);
143 
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 
147         TensorShape shape_scaled(shape);
148         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);
150         TensorType dst = create_tensor<TensorType>(shape_scaled, _data_type, 1, _output_quantization_info, data_layout);
151 
152         // Create and configure function
153         FunctionType scale;
154 
155         scale.configure(&src, &dst, ScaleKernelInfo{ _policy, _border_mode, _constant_border_value, _sampling_policy, /* use_padding */ false, _align_corners });
156 
157         ARM_COMPUTE_ASSERT(src.info()->is_resizable());
158         ARM_COMPUTE_ASSERT(dst.info()->is_resizable());
159 
160         add_padding_x({ &src, &dst }, data_layout);
161 
162         // Allocate tensors
163         src.allocator()->allocate();
164         dst.allocator()->allocate();
165         ARM_COMPUTE_ASSERT(!src.info()->is_resizable());
166         ARM_COMPUTE_ASSERT(!dst.info()->is_resizable());
167 
168         // Fill tensors
169         fill(AccessorType(src));
170 
171         if(_mixed_layout)
172         {
173             mix_layout(scale, src, dst);
174         }
175         else
176         {
177             // Compute function
178             scale.run();
179         }
180         return dst;
181     }
182 
compute_reference(const TensorShape & shape)183     SimpleTensor<T> compute_reference(const TensorShape &shape)
184     {
185         // Create reference
186         SimpleTensor<T> src{ shape, _data_type, 1, _input_quantization_info };
187 
188         // Fill reference
189         fill(src);
190 
191         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);
192     }
193 
194     TensorType          _target{};
195     SimpleTensor<T>     _reference{};
196     TensorShape         _shape{};
197     InterpolationPolicy _policy{};
198     BorderMode          _border_mode{};
199     T                   _constant_border_value{};
200     SamplingPolicy      _sampling_policy{};
201     DataType            _data_type{};
202     QuantizationInfo    _input_quantization_info{};
203     QuantizationInfo    _output_quantization_info{};
204     bool                _align_corners{ false };
205     bool                _mixed_layout{ false };
206     float               _scale_x{ 1.f };
207     float               _scale_y{ 1.f };
208 };
209 
210 template <typename TensorType, typename AccessorType, typename FunctionType, typename T, bool mixed_layout = false>
211 class ScaleValidationQuantizedFixture : public ScaleValidationGenericFixture<TensorType, AccessorType, FunctionType, T>
212 {
213 public:
214     template <typename...>
setup(TensorShape shape,DataType data_type,QuantizationInfo quantization_info,DataLayout data_layout,InterpolationPolicy policy,BorderMode border_mode,SamplingPolicy sampling_policy,bool align_corners)215     void setup(TensorShape shape, DataType data_type, QuantizationInfo quantization_info, DataLayout data_layout, InterpolationPolicy policy, BorderMode border_mode, SamplingPolicy sampling_policy,
216                bool align_corners)
217     {
218         ScaleValidationGenericFixture<TensorType, AccessorType, FunctionType, T>::setup(shape,
219                                                                                         data_type,
220                                                                                         quantization_info,
221                                                                                         data_layout,
222                                                                                         policy,
223                                                                                         border_mode,
224                                                                                         sampling_policy,
225                                                                                         align_corners,
226                                                                                         mixed_layout,
227                                                                                         quantization_info);
228     }
229 };
230 template <typename TensorType, typename AccessorType, typename FunctionType, typename T, bool mixed_layout = false>
231 class ScaleValidationDifferentOutputQuantizedFixture : public ScaleValidationGenericFixture<TensorType, AccessorType, FunctionType, T>
232 {
233 public:
234     template <typename...>
setup(TensorShape shape,DataType data_type,QuantizationInfo input_quantization_info,QuantizationInfo output_quantization_info,DataLayout data_layout,InterpolationPolicy policy,BorderMode border_mode,SamplingPolicy sampling_policy,bool align_corners)235     void setup(TensorShape shape, DataType data_type, QuantizationInfo input_quantization_info, QuantizationInfo output_quantization_info, DataLayout data_layout, InterpolationPolicy policy,
236                BorderMode border_mode, SamplingPolicy sampling_policy,
237                bool align_corners)
238     {
239         ScaleValidationGenericFixture<TensorType, AccessorType, FunctionType, T>::setup(shape,
240                                                                                         data_type,
241                                                                                         input_quantization_info,
242                                                                                         data_layout,
243                                                                                         policy,
244                                                                                         border_mode,
245                                                                                         sampling_policy,
246                                                                                         align_corners,
247                                                                                         mixed_layout,
248                                                                                         output_quantization_info);
249     }
250 };
251 template <typename TensorType, typename AccessorType, typename FunctionType, typename T, bool mixed_layout = false>
252 class ScaleValidationFixture : public ScaleValidationGenericFixture<TensorType, AccessorType, FunctionType, T>
253 {
254 public:
255     template <typename...>
setup(TensorShape shape,DataType data_type,DataLayout data_layout,InterpolationPolicy policy,BorderMode border_mode,SamplingPolicy sampling_policy,bool align_corners)256     void setup(TensorShape shape, DataType data_type, DataLayout data_layout, InterpolationPolicy policy, BorderMode border_mode, SamplingPolicy sampling_policy, bool align_corners)
257     {
258         ScaleValidationGenericFixture<TensorType, AccessorType, FunctionType, T>::setup(shape,
259                                                                                         data_type,
260                                                                                         QuantizationInfo(),
261                                                                                         data_layout,
262                                                                                         policy,
263                                                                                         border_mode,
264                                                                                         sampling_policy,
265                                                                                         align_corners,
266                                                                                         mixed_layout,
267                                                                                         QuantizationInfo());
268     }
269 };
270 } // namespace validation
271 } // namespace test
272 } // namespace arm_compute
273 #endif /* ARM_COMPUTE_TEST_SCALE_FIXTURE */
274