blob: 2c943735ca79868980ba6c80243e3516892a7fa4 [file] [log] [blame]
Giorgio Arena93a690e2017-08-01 16:09:33 +01001/*
Giorgio Arenab309fc22021-01-05 09:46:16 +00002 * Copyright (c) 2017-2021 Arm Limited.
Giorgio Arena93a690e2017-08-01 16:09:33 +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_DEPTHWISE_CONVOLUTION_FIXTURE
25#define ARM_COMPUTE_TEST_DEPTHWISE_CONVOLUTION_FIXTURE
26
27#include "arm_compute/core/TensorShape.h"
28#include "arm_compute/core/Types.h"
Giorgio Arena76572242018-04-04 17:44:26 +010029#include "arm_compute/core/utils/misc/ShapeCalculator.h"
Giorgio Arena93a690e2017-08-01 16:09:33 +010030#include "tests/AssetsLibrary.h"
31#include "tests/Globals.h"
32#include "tests/IAccessor.h"
Moritz Pflanzera09de0c2017-09-01 20:41:12 +010033#include "tests/framework/Asserts.h"
34#include "tests/framework/Fixture.h"
Moritz Pflanzera09de0c2017-09-01 20:41:12 +010035#include "tests/validation/Helpers.h"
Manuel Bottinia788c2f2019-04-08 13:18:00 +010036#include "tests/validation/reference/ActivationLayer.h"
Georgios Pinitas5a7e7762017-12-01 16:27:29 +000037#include "tests/validation/reference/DepthwiseConvolutionLayer.h"
Giorgio Arena93a690e2017-08-01 16:09:33 +010038
Georgios Pinitasf72f9362018-01-12 16:29:45 +000039#include "utils/Utils.h"
40
Giorgio Arena93a690e2017-08-01 16:09:33 +010041#include <random>
42
43namespace arm_compute
44{
45namespace test
46{
47namespace validation
48{
Giorgio Arena76572242018-04-04 17:44:26 +010049using namespace arm_compute::misc::shape_calculator;
50
Michele Di Giorgio633d30b2019-10-08 17:17:18 +010051template <typename TensorType, typename AccessorType, typename FunctionType, typename T, typename TW>
Giorgio Arena04a8f8c2017-11-23 11:45:24 +000052class DepthwiseConvolutionLayerValidationGenericFixture : public framework::Fixture
Giorgio Arena93a690e2017-08-01 16:09:33 +010053{
54public:
Michele Di Giorgio633d30b2019-10-08 17:17:18 +010055 using TBias = typename std::conditional < std::is_same<T, uint8_t>::value || std::is_same<T, int8_t>::value, int32_t, T >::type;
Dmitry Savenkod7295b72017-11-20 22:00:08 +070056
57public:
Giorgio Arena93a690e2017-08-01 16:09:33 +010058 template <typename...>
Michele Di Giorgio633d30b2019-10-08 17:17:18 +010059 void setup(TensorShape in_shape, Size2D kernel_size, PadStrideInfo pad_stride_info, Size2D dilation,
60 unsigned int depth_multiplier, DataType input_data_type, DataType weights_data_type,
61 QuantizationInfo input_quantization_info, QuantizationInfo weights_quantization_info, QuantizationInfo output_quantization_info,
Manuel Bottinica62c6f2021-03-23 11:50:34 +000062 DataLayout data_layout, ActivationLayerInfo act_info, bool mixed_layout = false)
Giorgio Arena93a690e2017-08-01 16:09:33 +010063 {
Manuel Bottinica62c6f2021-03-23 11:50:34 +000064 _mixed_layout = mixed_layout;
Giorgio Arena68e29da2021-02-08 16:31:10 +000065 _input_shape = in_shape;
66 _input_data_type = input_data_type;
67 _weights_data_type = weights_data_type;
68 _input_quantization_info = input_quantization_info;
69 _weights_quantization_info = weights_quantization_info;
70 _output_quantization_info = output_quantization_info;
71 _data_layout = data_layout;
72 _pad_stride_info = pad_stride_info;
73 _act_info = act_info;
74 _depth_multiplier = depth_multiplier;
75 _dilation = dilation;
Giorgio Arena76572242018-04-04 17:44:26 +010076
Giorgio Arena68e29da2021-02-08 16:31:10 +000077 _bias_data_type = is_data_type_quantized(_input_data_type) ? DataType::S32 : _input_data_type;
Giorgio Arena76572242018-04-04 17:44:26 +010078
Giorgio Arena68e29da2021-02-08 16:31:10 +000079 _weights_shape = TensorShape(kernel_size.width, kernel_size.height);
Giorgio Arena76572242018-04-04 17:44:26 +010080
Michalis Spyrou60c3b0e2021-04-08 12:02:58 +010081 const TensorInfo in_info(_input_shape, 1, _input_data_type);
82 const TensorInfo we_info(_weights_shape, 1, _weights_data_type);
83 const ConvolutionInfo info{ _pad_stride_info, _depth_multiplier, _act_info, _dilation };
84 _output_shape = compute_depthwise_convolution_shape(in_info, we_info, info);
Dmitry Savenkod7295b72017-11-20 22:00:08 +070085
Giorgio Arena68e29da2021-02-08 16:31:10 +000086 _weights_shape.set(2, _output_shape.z());
87 _biases_shape = TensorShape(_weights_shape[2]);
88 }
89
90 void configure_target()
91 {
92 TensorShape input_shape = _input_shape;
93 TensorShape weights_shape = _weights_shape;
94 TensorShape output_shape = _output_shape;
95
96 if(_data_layout == DataLayout::NHWC)
97 {
98 permute(input_shape, PermutationVector(2U, 0U, 1U));
99 permute(weights_shape, PermutationVector(2U, 0U, 1U));
100 permute(output_shape, PermutationVector(2U, 0U, 1U));
101 }
102
103 // Create tensors
104 _src = create_tensor<TensorType>(input_shape, _input_data_type, 1, _input_quantization_info, _data_layout);
105 _weights = create_tensor<TensorType>(weights_shape, _weights_data_type, 1, _weights_quantization_info, _data_layout);
106 _biases = create_tensor<TensorType>(_biases_shape, _bias_data_type, 1, _input_quantization_info, _data_layout);
107 _target = create_tensor<TensorType>(output_shape, _input_data_type, 1, _output_quantization_info, _data_layout);
108
109 // Create Depthwise Convolution configure function
110 _dwc.configure(&_src, &_weights, &_biases, &_target, _pad_stride_info, _depth_multiplier, _act_info, _dilation);
111
Michele Di Giorgio4fc10b32021-04-30 18:30:41 +0100112 ARM_COMPUTE_ASSERT(_src.info()->is_resizable());
113 ARM_COMPUTE_ASSERT(_weights.info()->is_resizable());
114 ARM_COMPUTE_ASSERT(_biases.info()->is_resizable());
115 ARM_COMPUTE_ASSERT(_target.info()->is_resizable());
Giorgio Arena68e29da2021-02-08 16:31:10 +0000116 }
117
118 void allocate_and_run_target()
119 {
Giorgio Arena63825e82021-03-25 14:54:50 +0000120 // TODO: uncomment after COMPMID-4361
121 // add_padding_x({ &_src, &_weights, &_biases, &_target }, _data_layout);
122
Giorgio Arena68e29da2021-02-08 16:31:10 +0000123 // Allocate tensors
124 _src.allocator()->allocate();
125 _weights.allocator()->allocate();
126 _biases.allocator()->allocate();
127 _target.allocator()->allocate();
128
Michele Di Giorgio4fc10b32021-04-30 18:30:41 +0100129 ARM_COMPUTE_ASSERT(!_src.info()->is_resizable());
130 ARM_COMPUTE_ASSERT(!_weights.info()->is_resizable());
131 ARM_COMPUTE_ASSERT(!_biases.info()->is_resizable());
132 ARM_COMPUTE_ASSERT(!_target.info()->is_resizable());
Giorgio Arena68e29da2021-02-08 16:31:10 +0000133
134 // Fill tensors
135 fill(AccessorType(_src), 0);
136 fill(AccessorType(_weights), 1);
137 fill(AccessorType(_biases), 2);
Giorgio Arena63825e82021-03-25 14:54:50 +0000138
Manuel Bottinica62c6f2021-03-23 11:50:34 +0000139 if(_mixed_layout)
140 {
141 mix_layout(_dwc, _src, _target);
142 }
143 else
144 {
145 // Compute function
146 _dwc.run();
147 }
Giorgio Arena68e29da2021-02-08 16:31:10 +0000148 }
149
150 void compute_reference()
151 {
152 SimpleTensor<T> src{ _input_shape, _input_data_type, 1, _input_quantization_info };
153 SimpleTensor<TW> weights{ _weights_shape, _weights_data_type, 1, _weights_quantization_info };
154 SimpleTensor<TBias> biases{ _biases_shape, _bias_data_type, 1, _input_quantization_info };
155
156 fill(src, 0);
157 fill(weights, 1);
158 fill(biases, 2);
159
160 SimpleTensor<T> depth_out = reference::depthwise_convolution(src, weights, biases, _output_shape, _pad_stride_info, _depth_multiplier, _dilation, _output_quantization_info);
161 _reference = (_act_info.enabled()) ? reference::activation_layer<T>(depth_out, _act_info) : depth_out;
Giorgio Arena93a690e2017-08-01 16:09:33 +0100162 }
163
164protected:
Manuel Bottinica62c6f2021-03-23 11:50:34 +0000165 void mix_layout(FunctionType &layer, TensorType &src, TensorType &dst)
166 {
167 // Test Multi DataLayout graph cases, when the data layout changes after configure
168 src.info()->set_data_layout(_data_layout == DataLayout::NCHW ? DataLayout::NHWC : DataLayout::NCHW);
169 dst.info()->set_data_layout(_data_layout == DataLayout::NCHW ? DataLayout::NHWC : DataLayout::NCHW);
170
171 // Compute Convolution function
172 layer.run();
173
174 // Reinstating original data layout for the test suite to properly check the values
175 src.info()->set_data_layout(_data_layout);
176 dst.info()->set_data_layout(_data_layout);
177 }
178
Giorgio Arena93a690e2017-08-01 16:09:33 +0100179 template <typename U>
180 void fill(U &&tensor, int i)
181 {
182 switch(tensor.data_type())
183 {
Dmitry Savenkod7295b72017-11-20 22:00:08 +0700184 case DataType::QASYMM8:
185 {
186 std::uniform_int_distribution<uint8_t> distribution(0, 10);
187 library->fill(tensor, distribution, i);
188 break;
189 }
Michele Di Giorgio4cd4cde2020-01-06 14:07:44 +0000190 case DataType::QASYMM8_SIGNED:
Michele Di Giorgio633d30b2019-10-08 17:17:18 +0100191 case DataType::QSYMM8_PER_CHANNEL:
192 {
193 std::uniform_int_distribution<int8_t> distribution(-10, 10);
194 library->fill(tensor, distribution, i);
195 break;
196 }
Frank Lei8cdfdb82018-01-02 16:49:33 +0800197 case DataType::F16:
Giorgio Arena93a690e2017-08-01 16:09:33 +0100198 {
Giorgio Arenaa8e2aeb2021-01-06 11:34:57 +0000199 arm_compute::utils::uniform_real_distribution_16bit<half> distribution{ -1.0f, 1.0f };
Giorgio Arena6aeb2172020-12-15 15:45:43 +0000200 library->fill(tensor, distribution, i);
201 break;
202 }
203 case DataType::F32:
204 {
205 std::uniform_real_distribution<float> distribution(-1.0f, 1.0f);
Giorgio Arena93a690e2017-08-01 16:09:33 +0100206 library->fill(tensor, distribution, i);
207 break;
208 }
Dmitry Savenkod7295b72017-11-20 22:00:08 +0700209 case DataType::S32:
210 {
Georgios Pinitasf72f9362018-01-12 16:29:45 +0000211 std::uniform_int_distribution<int32_t> distribution(-100, 100);
Dmitry Savenkod7295b72017-11-20 22:00:08 +0700212 library->fill(tensor, distribution, i);
213 break;
214 }
Giorgio Arena93a690e2017-08-01 16:09:33 +0100215 default:
216 library->fill_tensor_uniform(tensor, i);
217 }
218 }
219
Georgios Pinitasddec4d62019-07-10 19:23:02 +0100220 TensorType _target{};
221 SimpleTensor<T> _reference{};
Giorgio Arena68e29da2021-02-08 16:31:10 +0000222
223 TensorType _src{};
224 TensorType _weights{};
225 TensorType _biases{};
226 FunctionType _dwc{};
227
228 TensorShape _input_shape{};
229 TensorShape _weights_shape{};
230 TensorShape _biases_shape{};
231 TensorShape _output_shape{};
232 DataType _input_data_type{};
233 DataType _weights_data_type{};
234 DataType _bias_data_type{};
235 QuantizationInfo _input_quantization_info{};
236 QuantizationInfo _weights_quantization_info{};
237 QuantizationInfo _output_quantization_info{};
238 DataLayout _data_layout{};
239 PadStrideInfo _pad_stride_info{};
240 ActivationLayerInfo _act_info{};
241 unsigned int _depth_multiplier{};
242 Size2D _dilation{};
Giorgio Arena63825e82021-03-25 14:54:50 +0000243 bool _mixed_layout{ false };
Dmitry Savenkod7295b72017-11-20 22:00:08 +0700244};
245
Manuel Bottinica62c6f2021-03-23 11:50:34 +0000246template <typename TensorType, typename AccessorType, typename FunctionType, typename T, bool mixed_layout = false>
Michele Di Giorgio633d30b2019-10-08 17:17:18 +0100247class DepthwiseConvolutionLayerValidationFixture : public DepthwiseConvolutionLayerValidationGenericFixture<TensorType, AccessorType, FunctionType, T, T>
Dmitry Savenkod7295b72017-11-20 22:00:08 +0700248{
249public:
250 template <typename...>
Manuel Bottinia788c2f2019-04-08 13:18:00 +0100251 void setup(TensorShape in_shape, Size2D kernel_size, PadStrideInfo pad_stride_info, Size2D dilation, unsigned int depth_multiplier, DataType data_type, DataLayout data_layout,
252 ActivationLayerInfo act_info)
Dmitry Savenkod7295b72017-11-20 22:00:08 +0700253 {
Michele Di Giorgio633d30b2019-10-08 17:17:18 +0100254 DepthwiseConvolutionLayerValidationGenericFixture<TensorType, AccessorType, FunctionType, T, T>::setup(in_shape, kernel_size, pad_stride_info, dilation, depth_multiplier,
255 data_type, data_type, QuantizationInfo(), QuantizationInfo(), QuantizationInfo(),
Manuel Bottinica62c6f2021-03-23 11:50:34 +0000256 data_layout, act_info, mixed_layout);
Dmitry Savenkod7295b72017-11-20 22:00:08 +0700257 }
258};
259
260template <typename TensorType, typename AccessorType, typename FunctionType, typename T>
Michele Di Giorgio633d30b2019-10-08 17:17:18 +0100261class DepthwiseConvolutionLayerNativeValidationFixture : public DepthwiseConvolutionLayerValidationGenericFixture<TensorType, AccessorType, FunctionType, T, T>
Giorgio Arena44f55722019-07-12 14:49:49 +0100262{
263public:
264 template <typename...>
265 void setup(size_t width, size_t height, size_t channel, size_t batch, Size2D kernel_size, size_t depth_multiplier, Size2D dilation, Size2D stride, bool padding_valid, DataType data_type,
266 DataLayout data_layout)
267 {
Giorgio Arena68e29da2021-02-08 16:31:10 +0000268 _dilation = dilation;
269 _depth_multiplier = depth_multiplier;
270 _data_type = data_type;
271 _data_layout = data_layout;
Giorgio Arena44f55722019-07-12 14:49:49 +0100272
Giorgio Arena68e29da2021-02-08 16:31:10 +0000273 _input_shape = TensorShape(width, height, channel, batch);
274 _weights_shape = TensorShape(kernel_size.width, kernel_size.height, channel * _depth_multiplier);
275 _biases_shape = TensorShape(_weights_shape.z());
276
Giorgio Arena44f55722019-07-12 14:49:49 +0100277 if(padding_valid)
278 {
Giorgio Arena68e29da2021-02-08 16:31:10 +0000279 _conv_info = PadStrideInfo();
Giorgio Arena44f55722019-07-12 14:49:49 +0100280 }
281 else
282 {
Giorgio Arena68e29da2021-02-08 16:31:10 +0000283 _conv_info = calculate_same_pad(_input_shape, _weights_shape, PadStrideInfo(stride.width, stride.height), DataLayout::NCHW, _dilation);
284 }
285 }
286
287 void configure_target()
288 {
289 TensorShape input_shape = _input_shape;
290 TensorShape weights_shape = _weights_shape;
291
292 if(_data_layout == DataLayout::NHWC)
293 {
294 permute(input_shape, PermutationVector(2U, 0U, 1U));
295 permute(weights_shape, PermutationVector(2U, 0U, 1U));
Giorgio Arena44f55722019-07-12 14:49:49 +0100296 }
297
Giorgio Arena68e29da2021-02-08 16:31:10 +0000298 // Create tensors
299 _src = create_tensor<TensorType>(input_shape, _data_type, 1, QuantizationInfo(), _data_layout);
300 _weights = create_tensor<TensorType>(weights_shape, _data_type, 1, QuantizationInfo(), _data_layout);
301 _biases = create_tensor<TensorType>(_biases_shape, _data_type, 1, QuantizationInfo(), _data_layout);
302 _target = create_tensor<TensorType>(TensorShape(), _data_type, 1, QuantizationInfo(), _data_layout);
303
304 // Create Depthwise Convolution configure function
Michalis Spyrou60c3b0e2021-04-08 12:02:58 +0100305 const ConvolutionInfo info
306 {
307 _conv_info, _depth_multiplier, ActivationLayerInfo(), _dilation
308 };
309 _dwc.configure(_src.info(), _weights.info(), _biases.info(), _target.info(), info);
Giorgio Arena68e29da2021-02-08 16:31:10 +0000310
Michele Di Giorgio4fc10b32021-04-30 18:30:41 +0100311 ARM_COMPUTE_ASSERT(_src.info()->is_resizable());
312 ARM_COMPUTE_ASSERT(_weights.info()->is_resizable());
313 ARM_COMPUTE_ASSERT(_biases.info()->is_resizable());
314 ARM_COMPUTE_ASSERT(_target.info()->is_resizable());
Giorgio Arena68e29da2021-02-08 16:31:10 +0000315 }
316
317 void allocate_and_run_target()
318 {
Giorgio Arena63825e82021-03-25 14:54:50 +0000319 add_padding_x({ &_src, &_weights, &_biases, &_target }, _data_layout);
320
Giorgio Arena68e29da2021-02-08 16:31:10 +0000321 // Allocate tensors
322 _src.allocator()->allocate();
323 _weights.allocator()->allocate();
324 _biases.allocator()->allocate();
325 _target.allocator()->allocate();
326
Michele Di Giorgio4fc10b32021-04-30 18:30:41 +0100327 ARM_COMPUTE_ASSERT(!_src.info()->is_resizable());
328 ARM_COMPUTE_ASSERT(!_weights.info()->is_resizable());
329 ARM_COMPUTE_ASSERT(!_biases.info()->is_resizable());
330 ARM_COMPUTE_ASSERT(!_target.info()->is_resizable());
Giorgio Arena68e29da2021-02-08 16:31:10 +0000331
332 // Fill tensors
333 fill(AccessorType(_src), 0);
334 fill(AccessorType(_weights), 1);
335 fill(AccessorType(_biases), 2);
336
Michalis Spyrou60c3b0e2021-04-08 12:02:58 +0100337 arm_compute::ITensorPack pack;
338 pack.add_const_tensor(arm_compute::TensorType::ACL_SRC_0, &_src);
339 pack.add_const_tensor(arm_compute::TensorType::ACL_SRC_1, &_weights);
340 pack.add_const_tensor(arm_compute::TensorType::ACL_SRC_2, &_biases);
341 pack.add_tensor(arm_compute::TensorType::ACL_DST, &_target);
342
Giorgio Arena68e29da2021-02-08 16:31:10 +0000343 // Compute function
Michalis Spyrou60c3b0e2021-04-08 12:02:58 +0100344 _dwc.run(pack);
Giorgio Arena68e29da2021-02-08 16:31:10 +0000345 }
346
347 void compute_reference()
348 {
349 SimpleTensor<T> src{ _input_shape, _data_type };
350 SimpleTensor<T> weights{ _weights_shape, _data_type };
351 SimpleTensor<T> biases{ _biases_shape, _data_type };
352
353 fill(src, 0);
354 fill(weights, 1);
355 fill(biases, 2);
356
Michalis Spyrou60c3b0e2021-04-08 12:02:58 +0100357 const ConvolutionInfo info{ _conv_info, _depth_multiplier, ActivationLayerInfo(), _dilation };
358 const TensorShape dst_shape = compute_depthwise_convolution_shape(TensorInfo(_input_shape, 1, _data_type), TensorInfo(_weights_shape, 1, _data_type), info);
359 _reference = reference::depthwise_convolution(src, weights, biases, dst_shape, _conv_info, _depth_multiplier, _dilation);
Giorgio Arena44f55722019-07-12 14:49:49 +0100360 }
361
362protected:
363 template <typename U>
364 void fill(U &&tensor, int i)
365 {
366 switch(tensor.data_type())
367 {
368 case DataType::F32:
369 {
Giorgio Arena4bdd1772020-12-17 16:47:07 +0000370 std::uniform_real_distribution<float> distribution(-1.0f, 1.0f);
Giorgio Arena44f55722019-07-12 14:49:49 +0100371 library->fill(tensor, distribution, i);
372 break;
373 }
374 default:
375 library->fill_tensor_uniform(tensor, i);
376 }
377 }
378
Giorgio Arena44f55722019-07-12 14:49:49 +0100379 TensorType _target{};
380 SimpleTensor<T> _reference{};
Giorgio Arena68e29da2021-02-08 16:31:10 +0000381
382 TensorType _src{};
383 TensorType _weights{};
384 TensorType _biases{};
385 FunctionType _dwc{};
386
387 TensorShape _input_shape{};
388 TensorShape _weights_shape{};
389 TensorShape _biases_shape{};
390 DataType _data_type{};
391 DataLayout _data_layout{};
392 PadStrideInfo _conv_info{};
393 Size2D _dilation{};
394 unsigned int _depth_multiplier{};
Giorgio Arena44f55722019-07-12 14:49:49 +0100395};
396
397template <typename TensorType, typename AccessorType, typename FunctionType, typename T>
Michele Di Giorgio633d30b2019-10-08 17:17:18 +0100398class DepthwiseConvolutionLayerNativeConfigurableValidationFixture : public DepthwiseConvolutionLayerValidationGenericFixture<TensorType, AccessorType, FunctionType, T, T>
Gian Marco Iodice9285adb2019-09-05 16:10:27 +0100399{
400public:
401 template <typename...>
402 void setup(size_t width, size_t height, size_t channel, size_t batch, Size2D kernel_size, size_t depth_multiplier, Size2D dilation, Size2D stride, bool padding_valid, DataType data_type,
403 DataLayout data_layout, const ActivationLayerInfo &act_info, unsigned int n0)
404 {
Giorgio Arena68e29da2021-02-08 16:31:10 +0000405 _dilation = dilation;
406 _depth_multiplier = depth_multiplier;
407 _data_type = data_type;
408 _data_layout = data_layout;
409 _act_info = act_info;
410 _n0 = n0;
Gian Marco Iodice9285adb2019-09-05 16:10:27 +0100411
Giorgio Arena68e29da2021-02-08 16:31:10 +0000412 _input_shape = TensorShape(width, height, channel, batch);
413 _weights_shape = TensorShape(kernel_size.width, kernel_size.height, channel * _depth_multiplier);
414 _biases_shape = TensorShape(_weights_shape.z());
415
Gian Marco Iodice9285adb2019-09-05 16:10:27 +0100416 if(padding_valid)
417 {
Giorgio Arena68e29da2021-02-08 16:31:10 +0000418 _conv_info = PadStrideInfo();
Gian Marco Iodice9285adb2019-09-05 16:10:27 +0100419 }
420 else
421 {
Giorgio Arena68e29da2021-02-08 16:31:10 +0000422 _conv_info = calculate_same_pad(_input_shape, _weights_shape, PadStrideInfo(stride.width, stride.height), DataLayout::NCHW, _dilation);
423 }
424 }
425
426 void configure_target()
427 {
428 TensorShape input_shape = _input_shape;
429 TensorShape weights_shape = _weights_shape;
430
431 if(_data_layout == DataLayout::NHWC)
432 {
433 permute(input_shape, PermutationVector(2U, 0U, 1U));
434 permute(weights_shape, PermutationVector(2U, 0U, 1U));
Gian Marco Iodice9285adb2019-09-05 16:10:27 +0100435 }
436
Giorgio Arena68e29da2021-02-08 16:31:10 +0000437 // Create tensors
438 _src = create_tensor<TensorType>(input_shape, _data_type, 1, QuantizationInfo(), _data_layout);
439 _weights = create_tensor<TensorType>(weights_shape, _data_type, 1, QuantizationInfo(), _data_layout);
440 _biases = create_tensor<TensorType>(_biases_shape, _data_type, 1, QuantizationInfo(), _data_layout);
441 _target = create_tensor<TensorType>(TensorShape(), _data_type, 1, QuantizationInfo(), _data_layout);
442
443 DWCWeightsKernelInfo dwc_weights_info;
444 dwc_weights_info.n0 = _n0;
445
446 DWCKernelInfo dwc_info;
447 dwc_info.activation_info = _act_info;
448
449 // Create Depthwise Convolution configure function
450 _dwc.configure(&_src, &_weights, &_biases, &_target, dwc_weights_info, dwc_info, _conv_info, _depth_multiplier, _dilation);
451
Michele Di Giorgio4fc10b32021-04-30 18:30:41 +0100452 ARM_COMPUTE_ASSERT(_src.info()->is_resizable());
453 ARM_COMPUTE_ASSERT(_weights.info()->is_resizable());
454 ARM_COMPUTE_ASSERT(_biases.info()->is_resizable());
455 ARM_COMPUTE_ASSERT(_target.info()->is_resizable());
Giorgio Arena68e29da2021-02-08 16:31:10 +0000456 }
457
458 void allocate_and_run_target()
459 {
Giorgio Arena63825e82021-03-25 14:54:50 +0000460 add_padding_x({ &_src, &_weights, &_biases, &_target }, _data_layout);
461
Giorgio Arena68e29da2021-02-08 16:31:10 +0000462 // Allocate tensors
463 _src.allocator()->allocate();
464 _weights.allocator()->allocate();
465 _biases.allocator()->allocate();
466 _target.allocator()->allocate();
467
Michele Di Giorgio4fc10b32021-04-30 18:30:41 +0100468 ARM_COMPUTE_ASSERT(!_src.info()->is_resizable());
469 ARM_COMPUTE_ASSERT(!_weights.info()->is_resizable());
470 ARM_COMPUTE_ASSERT(!_biases.info()->is_resizable());
471 ARM_COMPUTE_ASSERT(!_target.info()->is_resizable());
Giorgio Arena68e29da2021-02-08 16:31:10 +0000472
473 // Fill tensors
474 fill(AccessorType(_src), 0);
475 fill(AccessorType(_weights), 1);
476 fill(AccessorType(_biases), 2);
477
Manuel Bottinica62c6f2021-03-23 11:50:34 +0000478 // Test Multi DataLayout graph cases, when the data layout changes after configure
479 _src.info()->set_data_layout(_data_layout == DataLayout::NCHW ? DataLayout::NHWC : DataLayout::NCHW);
480 _target.info()->set_data_layout(_data_layout == DataLayout::NCHW ? DataLayout::NHWC : DataLayout::NCHW);
481
Giorgio Arena68e29da2021-02-08 16:31:10 +0000482 // Compute function
483 _dwc.run();
Manuel Bottinica62c6f2021-03-23 11:50:34 +0000484
485 // Reinstating original data layout for the test suite to properly check the values
486 _target.info()->set_data_layout(_data_layout);
Giorgio Arena68e29da2021-02-08 16:31:10 +0000487 }
488
489 void compute_reference()
490 {
491 SimpleTensor<T> src{ _input_shape, _data_type };
492 SimpleTensor<T> weights{ _weights_shape, _data_type };
493 SimpleTensor<T> biases{ _biases_shape, _data_type };
494
495 fill(src, 0);
496 fill(weights, 1);
497 fill(biases, 2);
498
Michalis Spyrou60c3b0e2021-04-08 12:02:58 +0100499 const ConvolutionInfo info{ _conv_info, _depth_multiplier, _act_info, _dilation };
500 const TensorShape dst_shape = compute_depthwise_convolution_shape(TensorInfo(_input_shape, 1, _data_type), TensorInfo(_weights_shape, 1, _data_type), info);
501 _reference = reference::activation_layer(reference::depthwise_convolution(src, weights, biases, dst_shape, _conv_info, _depth_multiplier, _dilation), _act_info);
Gian Marco Iodice9285adb2019-09-05 16:10:27 +0100502 }
503
504protected:
505 template <typename U>
506 void fill(U &&tensor, int i)
507 {
508 switch(tensor.data_type())
509 {
510 case DataType::F32:
511 {
Giorgio Arena6aeb2172020-12-15 15:45:43 +0000512 std::uniform_real_distribution<float> distribution(-1.0f, 1.0f);
Gian Marco Iodice9285adb2019-09-05 16:10:27 +0100513 library->fill(tensor, distribution, i);
514 break;
515 }
516 case DataType::F16:
517 {
Giorgio Arenaa8e2aeb2021-01-06 11:34:57 +0000518 arm_compute::utils::uniform_real_distribution_16bit<half> distribution{ -1.0f, 1.0f };
Gian Marco Iodice9285adb2019-09-05 16:10:27 +0100519 library->fill(tensor, distribution, i);
520 break;
521 }
522 default:
523 library->fill_tensor_uniform(tensor, i);
524 }
525 }
526
Gian Marco Iodice9285adb2019-09-05 16:10:27 +0100527 TensorType _target{};
528 SimpleTensor<T> _reference{};
Giorgio Arena68e29da2021-02-08 16:31:10 +0000529
530 TensorType _src{};
531 TensorType _weights{};
532 TensorType _biases{};
533 FunctionType _dwc{};
534
535 TensorShape _input_shape{};
536 TensorShape _weights_shape{};
537 TensorShape _biases_shape{};
538 DataType _data_type{};
539 DataLayout _data_layout{};
540 PadStrideInfo _conv_info{};
541 ActivationLayerInfo _act_info{};
542 Size2D _dilation{};
543 unsigned int _depth_multiplier{};
544 unsigned int _n0{};
Gian Marco Iodice9285adb2019-09-05 16:10:27 +0100545};
546
Manuel Bottinica62c6f2021-03-23 11:50:34 +0000547template <typename TensorType, typename AccessorType, typename FunctionType, typename T, bool mixed_layout = false>
Michele Di Giorgio633d30b2019-10-08 17:17:18 +0100548class DepthwiseConvolutionLayerValidationQuantizedFixture : public DepthwiseConvolutionLayerValidationGenericFixture<TensorType, AccessorType, FunctionType, T, T>
Dmitry Savenkod7295b72017-11-20 22:00:08 +0700549{
550public:
551 template <typename...>
Pablo Telloa28aebc2019-06-03 14:59:48 +0100552 void setup(TensorShape in_shape, Size2D kernel_size, PadStrideInfo pad_stride_info, Size2D dilation, unsigned int depth_multiplier, DataType data_type,
553 QuantizationInfo input_quantization_info, QuantizationInfo output_quantization_info, DataLayout data_layout, ActivationLayerInfo act_info)
Dmitry Savenkod7295b72017-11-20 22:00:08 +0700554 {
Michele Di Giorgio633d30b2019-10-08 17:17:18 +0100555 DepthwiseConvolutionLayerValidationGenericFixture<TensorType, AccessorType, FunctionType, T, T>::setup(in_shape, kernel_size, pad_stride_info, dilation, depth_multiplier, data_type,
556 data_type, input_quantization_info, input_quantization_info, output_quantization_info,
Manuel Bottinica62c6f2021-03-23 11:50:34 +0000557 data_layout, act_info, mixed_layout);
Michele Di Giorgio633d30b2019-10-08 17:17:18 +0100558 }
559};
560
561template <typename TensorType, typename AccessorType, typename FunctionType, typename T, typename TW>
562class DepthwiseConvolutionLayerValidationQuantizedPerChannelFixture : public DepthwiseConvolutionLayerValidationGenericFixture<TensorType, AccessorType, FunctionType, T, TW>
563{
564public:
565 template <typename...>
566 void setup(TensorShape in_shape, Size2D kernel_size, PadStrideInfo pad_stride_info, Size2D dilation, unsigned int depth_multiplier, DataType input_data_type, DataType weights_data_type,
Giorgio Arenad93e2632019-10-15 11:09:33 +0100567 QuantizationInfo input_quantization_info, QuantizationInfo output_quantization_info, DataLayout data_layout, ActivationLayerInfo act_info)
Michele Di Giorgio633d30b2019-10-08 17:17:18 +0100568 {
Giorgio Arenad93e2632019-10-15 11:09:33 +0100569 const float out_scale = output_quantization_info.uniform().scale;
570 const float in_scale = input_quantization_info.uniform().scale;
571
Giorgio Arena4bdd1772020-12-17 16:47:07 +0000572 std::vector<float> weights_scales{};
573 std::mt19937 gen(library->seed());
574 std::uniform_real_distribution<float> dis(0.01f, out_scale / in_scale);
Giorgio Arenad93e2632019-10-15 11:09:33 +0100575 for(size_t i = 0; i < in_shape.z() * depth_multiplier; ++i)
576 {
577 weights_scales.push_back(dis(gen));
578 }
579
Michele Di Giorgio633d30b2019-10-08 17:17:18 +0100580 DepthwiseConvolutionLayerValidationGenericFixture<TensorType, AccessorType, FunctionType, T, TW>::setup(in_shape, kernel_size, pad_stride_info, dilation, depth_multiplier,
581 input_data_type, weights_data_type,
Giorgio Arenad93e2632019-10-15 11:09:33 +0100582 input_quantization_info, QuantizationInfo(weights_scales), output_quantization_info,
Michele Di Giorgio633d30b2019-10-08 17:17:18 +0100583 data_layout, act_info);
Dmitry Savenkod7295b72017-11-20 22:00:08 +0700584 }
Giorgio Arena93a690e2017-08-01 16:09:33 +0100585};
586} // namespace validation
587} // namespace test
588} // namespace arm_compute
589#endif /* ARM_COMPUTE_TEST_DEPTHWISE_CONVOLUTION_FIXTURE */