• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2017-2020 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 "arm_compute/core/TensorShape.h"
28 #include "arm_compute/core/Types.h"
29 #include "tests/AssetsLibrary.h"
30 #include "tests/Globals.h"
31 #include "tests/IAccessor.h"
32 #include "tests/framework/Asserts.h"
33 #include "tests/framework/Fixture.h"
34 #include "tests/validation/reference/Permute.h"
35 #include "tests/validation/reference/Scale.h"
36 
37 namespace arm_compute
38 {
39 namespace test
40 {
41 namespace validation
42 {
43 template <typename TensorType, typename AccessorType, typename FunctionType, typename T>
44 class ScaleValidationGenericFixture : public framework::Fixture
45 {
46 public:
47     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)48     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)
50     {
51         _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;
57         _align_corners     = align_corners;
58 
59         generate_scale(shape);
60 
61         std::mt19937                           generator(library->seed());
62         std::uniform_int_distribution<uint8_t> distribution_u8(0, 255);
63         _constant_border_value = static_cast<T>(distribution_u8(generator));
64 
65         _target    = compute_target(shape, data_layout);
66         _reference = compute_reference(shape);
67     }
68 
69 protected:
generate_scale(const TensorShape & shape)70     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         const float     min_width{ 1.f };
78         const float     min_height{ 1.f };
79 
80         std::mt19937                          generator(library->seed());
81         std::uniform_real_distribution<float> distribution_float(_min_scale, _max_scale);
82 
83         auto generate = [&](size_t input_size, float min_output, float max_output) -> float
84         {
85             const float generated_scale = distribution_float(generator);
86             const float output_size     = utility::clamp(static_cast<float>(input_size) * generated_scale, min_output, max_output);
87             return output_size / input_size;
88         };
89 
90         // Input shape is always given in NCHW layout. NHWC is dealt by permute in compute_target()
91         const int idx_width  = get_data_layout_dimension_index(DataLayout::NCHW, DataLayoutDimension::WIDTH);
92         const int idx_height = get_data_layout_dimension_index(DataLayout::NCHW, DataLayoutDimension::HEIGHT);
93 
94         _scale_x = generate(shape[idx_width], min_width, max_width);
95         _scale_y = generate(shape[idx_height], min_height, max_height);
96     }
97 
98     template <typename U>
fill(U && tensor)99     void fill(U &&tensor)
100     {
101         if(is_data_type_float(_data_type))
102         {
103             library->fill_tensor_uniform(tensor, 0);
104         }
105         else if(is_data_type_quantized(tensor.data_type()))
106         {
107             std::uniform_int_distribution<> distribution(0, 100);
108             library->fill(tensor, distribution, 0);
109         }
110         else
111         {
112             // Restrict range for float to avoid any floating point issues
113             std::uniform_real_distribution<> distribution(-5.0f, 5.0f);
114             library->fill(tensor, distribution, 0);
115         }
116     }
117 
compute_target(TensorShape shape,DataLayout data_layout)118     TensorType compute_target(TensorShape shape, DataLayout data_layout)
119     {
120         // Change shape in case of NHWC.
121         if(data_layout == DataLayout::NHWC)
122         {
123             permute(shape, PermutationVector(2U, 0U, 1U));
124         }
125 
126         // Create tensors
127         TensorType src = create_tensor<TensorType>(shape, _data_type, 1, _quantization_info, data_layout);
128 
129         const int idx_width  = get_data_layout_dimension_index(data_layout, DataLayoutDimension::WIDTH);
130         const int idx_height = get_data_layout_dimension_index(data_layout, DataLayoutDimension::HEIGHT);
131 
132         TensorShape shape_scaled(shape);
133         shape_scaled.set(idx_width, shape[idx_width] * _scale_x, /* apply_dim_correction = */ false);
134         shape_scaled.set(idx_height, shape[idx_height] * _scale_y, /* apply_dim_correction = */ false);
135         TensorType dst = create_tensor<TensorType>(shape_scaled, _data_type, 1, _quantization_info, data_layout);
136 
137         // Create and configure function
138         FunctionType scale;
139 
140         scale.configure(&src, &dst, ScaleKernelInfo{ _policy, _border_mode, _constant_border_value, _sampling_policy, /* use_padding */ false, _align_corners });
141 
142         ARM_COMPUTE_EXPECT(src.info()->is_resizable(), framework::LogLevel::ERRORS);
143         ARM_COMPUTE_EXPECT(dst.info()->is_resizable(), framework::LogLevel::ERRORS);
144 
145         // Allocate tensors
146         src.allocator()->allocate();
147         dst.allocator()->allocate();
148         ARM_COMPUTE_EXPECT(!src.info()->is_resizable(), framework::LogLevel::ERRORS);
149         ARM_COMPUTE_EXPECT(!dst.info()->is_resizable(), framework::LogLevel::ERRORS);
150 
151         // Fill tensors
152         fill(AccessorType(src));
153 
154         // Compute function
155         scale.run();
156 
157         return dst;
158     }
159 
compute_reference(const TensorShape & shape)160     SimpleTensor<T> compute_reference(const TensorShape &shape)
161     {
162         // Create reference
163         SimpleTensor<T> src{ shape, _data_type, 1, _quantization_info };
164 
165         // Fill reference
166         fill(src);
167 
168         return reference::scale<T>(src, _scale_x, _scale_y, _policy, _border_mode, _constant_border_value, _sampling_policy, /* ceil_policy_scale */ false, _align_corners);
169     }
170 
171     TensorType          _target{};
172     SimpleTensor<T>     _reference{};
173     TensorShape         _shape{};
174     InterpolationPolicy _policy{};
175     BorderMode          _border_mode{};
176     T                   _constant_border_value{};
177     SamplingPolicy      _sampling_policy{};
178     DataType            _data_type{};
179     QuantizationInfo    _quantization_info{};
180     bool                _align_corners{ false };
181     float               _scale_x{ 1.f };
182     float               _scale_y{ 1.f };
183 };
184 
185 template <typename TensorType, typename AccessorType, typename FunctionType, typename T>
186 class ScaleValidationQuantizedFixture : public ScaleValidationGenericFixture<TensorType, AccessorType, FunctionType, T>
187 {
188 public:
189     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)190     void setup(TensorShape shape, DataType data_type, QuantizationInfo quantization_info, DataLayout data_layout, InterpolationPolicy policy, BorderMode border_mode, SamplingPolicy sampling_policy,
191                bool align_corners)
192     {
193         ScaleValidationGenericFixture<TensorType, AccessorType, FunctionType, T>::setup(shape,
194                                                                                         data_type,
195                                                                                         quantization_info,
196                                                                                         data_layout,
197                                                                                         policy,
198                                                                                         border_mode,
199                                                                                         sampling_policy,
200                                                                                         align_corners);
201     }
202 };
203 template <typename TensorType, typename AccessorType, typename FunctionType, typename T>
204 class ScaleValidationFixture : public ScaleValidationGenericFixture<TensorType, AccessorType, FunctionType, T>
205 {
206 public:
207     template <typename...>
setup(TensorShape shape,DataType data_type,DataLayout data_layout,InterpolationPolicy policy,BorderMode border_mode,SamplingPolicy sampling_policy,bool align_corners)208     void setup(TensorShape shape, DataType data_type, DataLayout data_layout, InterpolationPolicy policy, BorderMode border_mode, SamplingPolicy sampling_policy, bool align_corners)
209     {
210         ScaleValidationGenericFixture<TensorType, AccessorType, FunctionType, T>::setup(shape,
211                                                                                         data_type,
212                                                                                         QuantizationInfo(),
213                                                                                         data_layout,
214                                                                                         policy,
215                                                                                         border_mode,
216                                                                                         sampling_policy,
217                                                                                         align_corners);
218     }
219 };
220 } // namespace validation
221 } // namespace test
222 } // namespace arm_compute
223 #endif /* ARM_COMPUTE_TEST_SCALE_FIXTURE */
224