blob: 130af572ffa4e94fd908764779b6275d3b743dd1 [file] [log] [blame]
Moritz Pflanzerb3d25792017-07-26 11:49:37 +01001/*
Sang-Hoon Park4715cf92020-01-08 16:02:47 +00002 * Copyright (c) 2017-2020 ARM Limited.
Moritz Pflanzerb3d25792017-07-26 11:49:37 +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,
Michalis Spyrou80943252019-01-10 17:19:50 +000021 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
Moritz Pflanzerb3d25792017-07-26 11:49:37 +010022 * SOFTWARE.
23 */
24#include "arm_compute/core/Types.h"
25#include "arm_compute/runtime/CL/CLTensor.h"
26#include "arm_compute/runtime/CL/CLTensorAllocator.h"
27#include "arm_compute/runtime/CL/functions/CLConvolutionLayer.h"
Isabella Gottardif07d28d2018-02-06 14:52:43 +000028#include "arm_compute/runtime/CL/functions/CLGEMMConvolutionLayer.h"
Moritz Pflanzerb3d25792017-07-26 11:49:37 +010029#include "tests/CL/CLAccessor.h"
30#include "tests/PaddingCalculator.h"
Moritz Pflanzera09de0c2017-09-01 20:41:12 +010031#include "tests/datasets/LargeConvolutionLayerDataset.h"
32#include "tests/datasets/SmallConvolutionLayerDataset.h"
Anthony Barbier1c0d0ff2018-01-31 13:05:09 +000033#include "tests/datasets/TinyConvolutionLayerDataset.h"
Moritz Pflanzera09de0c2017-09-01 20:41:12 +010034#include "tests/framework/Asserts.h"
35#include "tests/framework/Macros.h"
36#include "tests/framework/datasets/Datasets.h"
37#include "tests/validation/Validation.h"
38#include "tests/validation/fixtures/ConvolutionLayerFixture.h"
Moritz Pflanzerb3d25792017-07-26 11:49:37 +010039
40namespace arm_compute
41{
42namespace test
43{
44namespace validation
45{
46namespace
47{
Georgios Pinitas5e207532018-04-27 14:38:16 +010048constexpr AbsoluteTolerance<float> absolute_tolerance_float(0.0001f); /**< Absolute Tolerance value for comparing reference's output against implementation's output for DataType::F32 */
Georgios Pinitas8be91482019-03-26 17:23:28 +000049RelativeTolerance<float> tolerance_f32(0.1f); /**< Tolerance value for comparing reference's output against implementation's output for DataType::F32 */
steniu01f81652d2017-09-11 15:29:12 +010050RelativeTolerance<half_float::half> tolerance_f16(half_float::half(0.2)); /**< Tolerance value for comparing reference's output against implementation's output for DataType::F16 */
Georgios Pinitas51e53a32018-10-22 13:49:08 +010051constexpr AbsoluteTolerance<float> tolerance_qasymm8(1); /**< Tolerance value for comparing reference's output against implementation's output for quantized data types */
steniu01f81652d2017-09-11 15:29:12 +010052constexpr float tolerance_num = 0.07f; /**< Tolerance number */
Moritz Pflanzerb3d25792017-07-26 11:49:37 +010053
54/** CNN data types */
55const auto CNNDataTypes = framework::dataset::make("DataType",
56{
57 DataType::F16,
58 DataType::F32,
Chunosov5124be52017-11-22 20:42:13 +070059 DataType::QASYMM8,
Sang-Hoon Park4715cf92020-01-08 16:02:47 +000060 DataType::QASYMM8_SIGNED,
Moritz Pflanzerb3d25792017-07-26 11:49:37 +010061});
Gian Marco Iodice916d1bc2018-08-13 11:20:41 +010062
63/** Grouped CNN data types */
64const auto GroupedCNNDataTypes = framework::dataset::make("DataType",
65{
66 DataType::F16,
67 DataType::F32
68});
69
Isabella Gottardi3f217ec2018-02-12 14:59:19 +000070const auto ActivationFunctionsDataset = framework::dataset::make("ActivationInfo",
71{
72 ActivationLayerInfo(),
73 ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU),
74 ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::BOUNDED_RELU, 0.5f),
75 ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::LU_BOUNDED_RELU, 0.5f)
76});
Michalis Spyrou80943252019-01-10 17:19:50 +000077const auto ActivationFunctionsSmallDataset = framework::dataset::make("ActivationInfo",
78{
79 ActivationLayerInfo(),
80 ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::LU_BOUNDED_RELU, 0.5f)
81});
Moritz Pflanzerb3d25792017-07-26 11:49:37 +010082} // namespace
83
84TEST_SUITE(CL)
85TEST_SUITE(ConvolutionLayer)
86
Michalis Spyrou80943252019-01-10 17:19:50 +000087// *INDENT-OFF*
88// clang-format off
Gian Marco Iodice2213d4b2018-04-27 10:39:06 +010089DATA_TEST_CASE(ValidateConvolutionMethod, framework::DatasetMode::ALL, zip(zip(zip(zip(zip(zip(zip(
Michalis Spyrou80943252019-01-10 17:19:50 +000090 framework::dataset::make("InputInfo", { TensorInfo(TensorShape(17U, 31U, 2U), 1, DataType::F32), // Select GEMM
91 TensorInfo(TensorShape(17U, 31U, 2U), 1, DataType::F32), // Select GEMM
92 TensorInfo(TensorShape(23U, 27U, 5U, 4U), 1, DataType::F32), // Select GEMM
93 TensorInfo(TensorShape(23U, 27U, 31U, 4U), 1, DataType::F32), // Select WINOGRAD
94 TensorInfo(TensorShape(3U, 3U, 2U, 1U), 1, DataType::F32), // Select GEMM
95 TensorInfo(TensorShape(33U, 27U, 7U, 4U), 1, DataType::F32), // Select GEMM
96 TensorInfo(TensorShape(17U, 31U, 32U), 1, DataType::F32), // Select WINOGRAD
97 TensorInfo(TensorShape(17U, 31U, 2U), 1, DataType::F32) // Select GEMM
98 }),
99 framework::dataset::make("WeightsInfo", { TensorInfo(TensorShape(5U, 5U, 2U, 19U), 1, DataType::F32),
100 TensorInfo(TensorShape(5U, 5U, 2U, 19U), 1, DataType::F32),
101 TensorInfo(TensorShape(3U, 3U, 5U, 21U), 1, DataType::F32),
102 TensorInfo(TensorShape(3U, 3U, 31U, 21U), 1, DataType::F32),
103 TensorInfo(TensorShape(3U, 3U, 5U, 21U), 1, DataType::F32),
104 TensorInfo(TensorShape(5U, 5U, 7U, 16U), 1, DataType::F16),
105 TensorInfo(TensorShape(5U, 5U, 32U, 19U), 1, DataType::F32),
106 TensorInfo(TensorShape(5U, 5U, 2U, 19U), 1, DataType::F32)
107 })),
108 framework::dataset::make("OutputInfo", { TensorInfo(TensorShape(15U, 15U, 19U), 1, DataType::F32),
109 TensorInfo(TensorShape(15U, 15U, 19U), 1, DataType::F32),
110 TensorInfo(TensorShape(21U, 25U, 21U, 4U), 1, DataType::F32),
111 TensorInfo(TensorShape(21U, 25U, 21U, 4U), 1, DataType::F32),
112 TensorInfo(TensorShape(11U, 25U, 21U), 1, DataType::F32),
113 TensorInfo(TensorShape(11U, 12U, 16U, 4U), 1, DataType::F32),
114 TensorInfo(TensorShape(17U, 31U, 19U), 1, DataType::F32),
115 TensorInfo(TensorShape(17U, 31U, 19U), 1, DataType::F32)
116 })),
117 framework::dataset::make("ConvInfo", { PadStrideInfo(1, 2, 1, 1),
118 PadStrideInfo(1, 2, 1, 1),
119 PadStrideInfo(1, 1, 0, 0),
120 PadStrideInfo(1, 1, 0, 0),
121 PadStrideInfo(2, 1, 0, 0),
122 PadStrideInfo(3, 2, 1, 0),
123 PadStrideInfo(1, 1, 2, 2),
124 PadStrideInfo(1, 1, 2, 2)
125 })),
126 framework::dataset::make("GpuTarget", { GPUTarget::BIFROST,
127 GPUTarget::MIDGARD,
128 GPUTarget::G71,
129 GPUTarget::G71,
130 GPUTarget::MIDGARD,
131 GPUTarget::BIFROST,
132 GPUTarget::BIFROST,
133 GPUTarget::BIFROST
134 })),
135 framework::dataset::make("Dilation", { Size2D(1U, 1U),
136 Size2D(1U, 1U),
137 Size2D(1U, 1U),
138 Size2D(1U, 1U),
139 Size2D(1U, 1U),
140 Size2D(1U, 1U),
141 Size2D(1U, 1U),
142 Size2D(2U, 1U),
143 })),
144 framework::dataset::make("EnableFastMath", { false, false, false, false, false, false, true, true })),
145 framework::dataset::make("Expected",{ ConvolutionMethod::GEMM,
146 ConvolutionMethod::GEMM,
147 ConvolutionMethod::GEMM,
148 ConvolutionMethod::WINOGRAD,
149 ConvolutionMethod::GEMM,
150 ConvolutionMethod::GEMM,
151 ConvolutionMethod::WINOGRAD,
152 ConvolutionMethod::GEMM,
153 })),
154 input_info, weights_info, output_info, conv_info, gpu_target, dilation, enable_fast_math, expected)
Gian Marco Iodice2213d4b2018-04-27 10:39:06 +0100155{
156 ConvolutionMethod is_valid = CLConvolutionLayer::get_convolution_method(&input_info.clone()->set_is_resizable(true),
157 &weights_info.clone()->set_is_resizable(true),
158 &output_info.clone()->set_is_resizable(true), conv_info,
159 WeightsInfo(),
160 ActivationLayerInfo(),
161 gpu_target,
162 dilation,
163 enable_fast_math);
Isabella Gottardif07d28d2018-02-06 14:52:43 +0000164 ARM_COMPUTE_EXPECT(is_valid == expected, framework::LogLevel::ERRORS);
165}
Michalis Spyrou80943252019-01-10 17:19:50 +0000166// clang-format on
167// *INDENT-ON*
168TEST_SUITE_END() // ConvolutionLayer
Isabella Gottardif07d28d2018-02-06 14:52:43 +0000169
170TEST_SUITE(GEMMConvolutionLayer)
171
Michalis Spyrou80943252019-01-10 17:19:50 +0000172DATA_TEST_CASE(Configuration, framework::DatasetMode::ALL, combine(combine(datasets::SmallConvolutionLayerDataset(),
Isabella Gottardi3f217ec2018-02-12 14:59:19 +0000173 CNNDataTypes),
174 ActivationFunctionsDataset),
175 input_shape, weights_shape, bias_shape, output_shape, info, dilation, data_type, act_info)
Moritz Pflanzerb3d25792017-07-26 11:49:37 +0100176{
Chunosov5124be52017-11-22 20:42:13 +0700177 auto bias_data_type = is_data_type_quantized_asymmetric(data_type) ? DataType::S32 : data_type;
178
Moritz Pflanzerb3d25792017-07-26 11:49:37 +0100179 // Create tensors
Vidhya Sudhan Loganathan014333d2018-07-02 09:13:49 +0100180 CLTensor src = create_tensor<CLTensor>(input_shape, data_type, 1, QuantizationInfo(2.f / 255.f, 127));
181 CLTensor weights = create_tensor<CLTensor>(weights_shape, data_type, 1, QuantizationInfo(2.f / 255.f, 127));
182 CLTensor bias = create_tensor<CLTensor>(bias_shape, bias_data_type, 1, QuantizationInfo(2.f / 255.f, 127));
183 CLTensor dst = create_tensor<CLTensor>(output_shape, data_type, 1, QuantizationInfo(2.f / 255.f, 127));
Moritz Pflanzerb3d25792017-07-26 11:49:37 +0100184
185 ARM_COMPUTE_EXPECT(src.info()->is_resizable(), framework::LogLevel::ERRORS);
186 ARM_COMPUTE_EXPECT(weights.info()->is_resizable(), framework::LogLevel::ERRORS);
187 ARM_COMPUTE_EXPECT(bias.info()->is_resizable(), framework::LogLevel::ERRORS);
188 ARM_COMPUTE_EXPECT(dst.info()->is_resizable(), framework::LogLevel::ERRORS);
189
Chunosov5124be52017-11-22 20:42:13 +0700190 const QuantizationInfo src_quantization_info = src.info()->quantization_info();
191 const QuantizationInfo weights_quantization_info = weights.info()->quantization_info();
192
Moritz Pflanzerb3d25792017-07-26 11:49:37 +0100193 // Create and configure function
Isabella Gottardif07d28d2018-02-06 14:52:43 +0000194 CLGEMMConvolutionLayer conv;
Isabella Gottardi3f217ec2018-02-12 14:59:19 +0000195 conv.configure(&src, &weights, &bias, &dst, info, WeightsInfo(), dilation, act_info);
Moritz Pflanzerb3d25792017-07-26 11:49:37 +0100196
197 // Validate valid region
198 const ValidRegion src_valid_region = shape_to_valid_region(input_shape);
199 const ValidRegion weights_valid_region = shape_to_valid_region(weights_shape);
200 const ValidRegion bias_valid_region = shape_to_valid_region(bias_shape);
201 const ValidRegion dst_valid_region = shape_to_valid_region(output_shape);
202
203 validate(src.info()->valid_region(), src_valid_region);
204 validate(weights.info()->valid_region(), weights_valid_region);
205 validate(bias.info()->valid_region(), bias_valid_region);
206 validate(dst.info()->valid_region(), dst_valid_region);
207
Chunosov5124be52017-11-22 20:42:13 +0700208 // Validate QuantizationInfo
209 ARM_COMPUTE_EXPECT(src.info()->quantization_info() == src_quantization_info, framework::LogLevel::ERRORS);
210 ARM_COMPUTE_EXPECT(weights.info()->quantization_info() == weights_quantization_info, framework::LogLevel::ERRORS);
211
Moritz Pflanzerb3d25792017-07-26 11:49:37 +0100212 // Validate padding
213 //TODO(COMPMID-415) Need to validate padding?
214}
215
216template <typename T>
Isabella Gottardif07d28d2018-02-06 14:52:43 +0000217using CLGEMMConvolutionLayerFixture = ConvolutionValidationFixture<CLTensor, CLAccessor, CLGEMMConvolutionLayer, T>;
Moritz Pflanzerb3d25792017-07-26 11:49:37 +0100218
219TEST_SUITE(Float)
220TEST_SUITE(FP16)
Isabella Gottardi3f217ec2018-02-12 14:59:19 +0000221
Michalis Spyrou80943252019-01-10 17:19:50 +0000222FIXTURE_DATA_TEST_CASE(RunSmall, CLGEMMConvolutionLayerFixture<half>, framework::DatasetMode::PRECOMMIT, combine(combine(combine(combine(datasets::SmallConvolutionLayerReducedDataset(),
Isabella Gottardif07d28d2018-02-06 14:52:43 +0000223 framework::dataset::make("ReshapeWeights", { true })),
224 framework::dataset::make("DataType",
Isabella Gottardi3f217ec2018-02-12 14:59:19 +0000225 DataType::F16)),
Georgios Pinitas19ea4192018-06-19 13:09:53 +0100226 framework::dataset::make("DataLayout", { DataLayout::NCHW, DataLayout::NHWC })),
Michalis Spyrou80943252019-01-10 17:19:50 +0000227 ActivationFunctionsSmallDataset))
Moritz Pflanzerb3d25792017-07-26 11:49:37 +0100228{
229 // Validate output
steniu013e05e4e2017-08-25 17:18:01 +0100230 validate(CLAccessor(_target), _reference, tolerance_f16, tolerance_num);
Moritz Pflanzerb3d25792017-07-26 11:49:37 +0100231}
Isabella Gottardi3f217ec2018-02-12 14:59:19 +0000232
Michalis Spyrou80943252019-01-10 17:19:50 +0000233FIXTURE_DATA_TEST_CASE(RunLarge, CLGEMMConvolutionLayerFixture<half>, framework::DatasetMode::NIGHTLY,
Michalis Spyrou618451d2019-01-18 16:32:25 +0000234 combine(combine(combine(combine(framework::dataset::concat(datasets::SmallConvolutionLayerDataset(), datasets::LargeConvolutionLayerDataset()),
Michalis Spyrou80943252019-01-10 17:19:50 +0000235 framework::dataset::make("ReshapeWeights", { true })),
236 framework::dataset::make("DataType",
237 DataType::F16)),
238 framework::dataset::make("DataLayout", { DataLayout::NCHW, DataLayout::NHWC })),
239 ActivationFunctionsDataset))
Moritz Pflanzerb3d25792017-07-26 11:49:37 +0100240{
241 // Validate output
steniu013e05e4e2017-08-25 17:18:01 +0100242 validate(CLAccessor(_target), _reference, tolerance_f16, tolerance_num);
Moritz Pflanzerb3d25792017-07-26 11:49:37 +0100243}
Gian Marco Iodice916d1bc2018-08-13 11:20:41 +0100244TEST_SUITE_END() // FP16
Moritz Pflanzerb3d25792017-07-26 11:49:37 +0100245
246TEST_SUITE(FP32)
Isabella Gottardi3f217ec2018-02-12 14:59:19 +0000247
Michalis Spyrou80943252019-01-10 17:19:50 +0000248FIXTURE_DATA_TEST_CASE(RunSmall, CLGEMMConvolutionLayerFixture<float>, framework::DatasetMode::PRECOMMIT, combine(combine(combine(combine(datasets::SmallConvolutionLayerReducedDataset(),
Isabella Gottardif07d28d2018-02-06 14:52:43 +0000249 framework::dataset::make("ReshapeWeights", { true })),
250 framework::dataset::make("DataType",
Isabella Gottardi3f217ec2018-02-12 14:59:19 +0000251 DataType::F32)),
Georgios Pinitas19ea4192018-06-19 13:09:53 +0100252 framework::dataset::make("DataLayout", { DataLayout::NCHW, DataLayout::NHWC })),
Michalis Spyrou80943252019-01-10 17:19:50 +0000253 ActivationFunctionsSmallDataset))
Moritz Pflanzerb3d25792017-07-26 11:49:37 +0100254{
255 // Validate output
256 validate(CLAccessor(_target), _reference, tolerance_f32);
257}
Isabella Gottardi3f217ec2018-02-12 14:59:19 +0000258
Michalis Spyrou80943252019-01-10 17:19:50 +0000259FIXTURE_DATA_TEST_CASE(RunLarge, CLGEMMConvolutionLayerFixture<float>, framework::DatasetMode::NIGHTLY,
Michalis Spyrou618451d2019-01-18 16:32:25 +0000260 combine(combine(combine(combine(framework::dataset::concat(datasets::SmallConvolutionLayerDataset(), datasets::LargeConvolutionLayerDataset()),
Michalis Spyrou80943252019-01-10 17:19:50 +0000261 framework::dataset::make("ReshapeWeights", { true })),
262 framework::dataset::make("DataType",
263 DataType::F32)),
264 framework::dataset::make("DataLayout", { DataLayout::NCHW, DataLayout::NHWC })),
265 ActivationFunctionsDataset))
Moritz Pflanzerb3d25792017-07-26 11:49:37 +0100266{
267 // Validate output
Georgios Pinitas5e207532018-04-27 14:38:16 +0100268 validate(CLAccessor(_target), _reference, tolerance_f32, 0.f, absolute_tolerance_float);
Moritz Pflanzerb3d25792017-07-26 11:49:37 +0100269}
Gian Marco Iodice916d1bc2018-08-13 11:20:41 +0100270TEST_SUITE_END() // FP32
271TEST_SUITE_END() // Float
Moritz Pflanzerb3d25792017-07-26 11:49:37 +0100272
273template <typename T>
Isabella Gottardif07d28d2018-02-06 14:52:43 +0000274using CLGEMMConvolutionLayerQuantizedFixture = ConvolutionValidationQuantizedFixture<CLTensor, CLAccessor, CLGEMMConvolutionLayer, T>;
Vidhya Sudhan Loganathan951b8a42019-11-04 14:42:08 +0000275template <typename T>
276using CLGEMMConvolutionLayerQuantizedPerChannelFixture = ConvolutionValidationQuantizedPerChannelFixture<CLTensor, CLAccessor, CLGEMMConvolutionLayer, T, int8_t>;
Chunosov5124be52017-11-22 20:42:13 +0700277
Isabella Gottardi3f217ec2018-02-12 14:59:19 +0000278const auto QuantizedActivationFunctionsDataset = framework::dataset::make("ActivationInfo",
279{
280 ActivationLayerInfo(),
281 ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU),
282 ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::LU_BOUNDED_RELU, 6.f)
283});
Michalis Spyrou80943252019-01-10 17:19:50 +0000284const auto QuantizedActivationFunctionsSmallDataset = framework::dataset::make("ActivationInfo",
285{
286 ActivationLayerInfo(),
287 ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::LU_BOUNDED_RELU, 6.f)
288});
Isabella Gottardi3f217ec2018-02-12 14:59:19 +0000289
Chunosov5124be52017-11-22 20:42:13 +0700290TEST_SUITE(Quantized)
Isabella Gottardi3f217ec2018-02-12 14:59:19 +0000291
Gian Marco Iodice3139f032018-11-05 14:26:32 +0000292const auto QuantizationData = framework::dataset::make("QuantizationInfo",
293{
294 QuantizationInfo(0.5f, 10),
295 QuantizationInfo(0.3f, 3),
Michele Di Giorgio14cbfb22019-10-23 10:53:10 +0100296 QuantizationInfo(1.1f, 10),
Gian Marco Iodice3139f032018-11-05 14:26:32 +0000297});
Vidhya Sudhan Loganathan951b8a42019-11-04 14:42:08 +0000298TEST_SUITE(QASYMM8)
Gian Marco Iodice3139f032018-11-05 14:26:32 +0000299
Michalis Spyrou80943252019-01-10 17:19:50 +0000300FIXTURE_DATA_TEST_CASE(RunSmall, CLGEMMConvolutionLayerQuantizedFixture<uint8_t>, framework::DatasetMode::PRECOMMIT,
301 combine(combine(combine(combine(combine(datasets::SmallConvolutionLayerReducedDataset(),
302 framework::dataset::make("ReshapeWeights", { true })),
303 framework::dataset::make("DataType", DataType::QASYMM8)),
304 framework::dataset::make("DataLayout", { DataLayout::NCHW, DataLayout::NHWC })),
305 QuantizationData),
306 QuantizedActivationFunctionsSmallDataset))
Chunosov5124be52017-11-22 20:42:13 +0700307{
308 // Validate output
309 validate(CLAccessor(_target), _reference, tolerance_qasymm8);
310}
Michalis Spyrou80943252019-01-10 17:19:50 +0000311FIXTURE_DATA_TEST_CASE(RunLarge, CLGEMMConvolutionLayerQuantizedFixture<uint8_t>, framework::DatasetMode::NIGHTLY,
Michalis Spyrou618451d2019-01-18 16:32:25 +0000312 combine(combine(combine(combine(combine(framework::dataset::concat(datasets::SmallConvolutionLayerDataset(), datasets::LargeConvolutionLayerDataset()),
Michalis Spyrou80943252019-01-10 17:19:50 +0000313 framework::dataset::make("ReshapeWeights", { true })),
314 framework::dataset::make("DataType", DataType::QASYMM8)),
315 framework::dataset::make("DataLayout", { DataLayout::NCHW, DataLayout::NHWC })),
316 QuantizationData),
317 QuantizedActivationFunctionsDataset))
Chunosov5124be52017-11-22 20:42:13 +0700318{
319 // Validate output
320 validate(CLAccessor(_target), _reference, tolerance_qasymm8);
Moritz Pflanzerb3d25792017-07-26 11:49:37 +0100321}
Gian Marco Iodice916d1bc2018-08-13 11:20:41 +0100322TEST_SUITE_END() // QASYMM8
Sang-Hoon Park4715cf92020-01-08 16:02:47 +0000323TEST_SUITE(QASYMM8_SIGNED)
324
325FIXTURE_DATA_TEST_CASE(RunSmall, CLGEMMConvolutionLayerQuantizedFixture<int8_t>, framework::DatasetMode::PRECOMMIT,
326 combine(combine(combine(combine(combine(datasets::SmallConvolutionLayerReducedDataset(),
327 framework::dataset::make("ReshapeWeights", { true })),
328 framework::dataset::make("DataType", DataType::QASYMM8_SIGNED)),
329 framework::dataset::make("DataLayout", { DataLayout::NCHW, DataLayout::NHWC })),
330 QuantizationData),
331 QuantizedActivationFunctionsSmallDataset))
332{
333 // Validate output
334 validate(CLAccessor(_target), _reference, tolerance_qasymm8);
335}
336TEST_SUITE_END() // QASYMM8_SIGNED
Vidhya Sudhan Loganathan951b8a42019-11-04 14:42:08 +0000337TEST_SUITE(QSYMM8_PER_CHANNEL)
338
339FIXTURE_DATA_TEST_CASE(RunSmall, CLGEMMConvolutionLayerQuantizedPerChannelFixture<uint8_t>, framework::DatasetMode::PRECOMMIT,
340 combine(combine(combine(combine(combine(combine(datasets::SmallConvolutionLayerReducedDataset(),
341 framework::dataset::make("ReshapeWeights", { true })),
342 framework::dataset::make("DataType", { DataType::QASYMM8 })),
343 framework::dataset::make("DataLayout", { DataLayout::NCHW, DataLayout::NHWC })),
344 QuantizationData),
345 QuantizedActivationFunctionsSmallDataset),
346 framework::dataset::make("WeightsDataType", { DataType::QSYMM8_PER_CHANNEL })))
347{
348 // Validate output
349 validate(CLAccessor(_target), _reference, tolerance_qasymm8);
350}
351FIXTURE_DATA_TEST_CASE(RunLarge, CLGEMMConvolutionLayerQuantizedPerChannelFixture<uint8_t>, framework::DatasetMode::NIGHTLY,
352 combine(combine(combine(combine(combine(combine(datasets::SmallConvolutionLayerDataset(),
353 framework::dataset::make("ReshapeWeights", { true })),
354 framework::dataset::make("DataType", { DataType::QASYMM8 })),
355 framework::dataset::make("DataLayout", { DataLayout::NCHW, DataLayout::NHWC })),
356 QuantizationData),
357 QuantizedActivationFunctionsDataset),
358 framework::dataset::make("WeightsDataType", { DataType::QSYMM8_PER_CHANNEL })))
359{
360 // Validate output
361 validate(CLAccessor(_target), _reference, tolerance_qasymm8);
362}
363TEST_SUITE_END() // QSYMM8_PER_CHANNEL
Gian Marco Iodice916d1bc2018-08-13 11:20:41 +0100364TEST_SUITE_END() // Quantized
Moritz Pflanzerb3d25792017-07-26 11:49:37 +0100365
Gian Marco Iodice916d1bc2018-08-13 11:20:41 +0100366TEST_SUITE_END() // GEMMConvolutionLayer
367
368template <typename T>
369using CLGEMMGroupedConvolutionLayerFixture = ConvolutionValidationFixture<CLTensor, CLAccessor, CLGEMMConvolutionLayer, T>;
370
371TEST_SUITE(GroupedGEMMConvolutionLayer)
372
Michalis Spyrou618451d2019-01-18 16:32:25 +0000373DATA_TEST_CASE(Configuration, framework::DatasetMode::ALL, combine(combine(datasets::SmallGroupedConvolutionLayerDataset(),
Gian Marco Iodice916d1bc2018-08-13 11:20:41 +0100374 GroupedCNNDataTypes),
375 ActivationFunctionsDataset),
376 input_shape, weights_shape, bias_shape, output_shape, info, dilation, data_type, act_info)
377{
378 ARM_COMPUTE_ERROR_ON((input_shape[2] % weights_shape[2]) != 0);
379
380 // The number of groups is calculated dividing the number of input channels of the input tensor by the number of input channels of the weights shape
381 const int num_groups = input_shape[2] / weights_shape[2];
382
383 // Create tensors
384 CLTensor src = create_tensor<CLTensor>(input_shape, data_type);
385 CLTensor weights = create_tensor<CLTensor>(weights_shape, data_type, 1);
386 CLTensor bias = create_tensor<CLTensor>(bias_shape, data_type, 1);
387 CLTensor dst = create_tensor<CLTensor>(output_shape, data_type, 1);
388
389 ARM_COMPUTE_EXPECT(src.info()->is_resizable(), framework::LogLevel::ERRORS);
390 ARM_COMPUTE_EXPECT(weights.info()->is_resizable(), framework::LogLevel::ERRORS);
391 ARM_COMPUTE_EXPECT(bias.info()->is_resizable(), framework::LogLevel::ERRORS);
392 ARM_COMPUTE_EXPECT(dst.info()->is_resizable(), framework::LogLevel::ERRORS);
393
394 // Create and configure function
395 CLGEMMConvolutionLayer conv;
396 conv.configure(&src, &weights, &bias, &dst, info, WeightsInfo(), dilation, act_info, num_groups);
397
398 // Validate valid region
399 const ValidRegion src_valid_region = shape_to_valid_region(input_shape);
400 const ValidRegion weights_valid_region = shape_to_valid_region(weights_shape);
401 const ValidRegion bias_valid_region = shape_to_valid_region(bias_shape);
402 const ValidRegion dst_valid_region = shape_to_valid_region(output_shape);
403
404 validate(src.info()->valid_region(), src_valid_region);
405 validate(weights.info()->valid_region(), weights_valid_region);
406 validate(bias.info()->valid_region(), bias_valid_region);
407 validate(dst.info()->valid_region(), dst_valid_region);
408
409 // Validate padding
410 //TODO(COMPMID-415) Need to validate padding?
411}
412
413TEST_SUITE(Float)
414TEST_SUITE(FP32)
415
Michalis Spyrou618451d2019-01-18 16:32:25 +0000416FIXTURE_DATA_TEST_CASE(RunSmall, CLGEMMGroupedConvolutionLayerFixture<float>, framework::DatasetMode::PRECOMMIT, combine(combine(combine(combine(datasets::SmallGroupedConvolutionLayerDataset(),
Gian Marco Iodice916d1bc2018-08-13 11:20:41 +0100417 framework::dataset::make("ReshapeWeights", { true })),
418 framework::dataset::make("DataType", DataType::F32)),
419 framework::dataset::make("DataLayout", { DataLayout::NCHW })),
Michalis Spyrou80943252019-01-10 17:19:50 +0000420 ActivationFunctionsSmallDataset))
Gian Marco Iodice916d1bc2018-08-13 11:20:41 +0100421{
422 // Validate output
423 validate(CLAccessor(_target), _reference, tolerance_f32, tolerance_num);
424}
425
Michalis Spyrou80943252019-01-10 17:19:50 +0000426FIXTURE_DATA_TEST_CASE(RunLarge, CLGEMMGroupedConvolutionLayerFixture<float>, framework::DatasetMode::NIGHTLY,
427 combine(combine(combine(combine(framework::dataset::concat(datasets::SmallGroupedConvolutionLayerDataset(), datasets::LargeGroupedConvolutionLayerDataset()),
428 framework::dataset::make("ReshapeWeights", { true })),
429 framework::dataset::make("DataType", DataType::F32)),
430 framework::dataset::make("DataLayout", { DataLayout::NCHW })),
431 ActivationFunctionsDataset))
Gian Marco Iodice916d1bc2018-08-13 11:20:41 +0100432{
433 // Validate output
434 validate(CLAccessor(_target), _reference, tolerance_f32, tolerance_num);
435}
436TEST_SUITE_END() // FP32
437
438TEST_SUITE(FP16)
439
Michalis Spyrou618451d2019-01-18 16:32:25 +0000440FIXTURE_DATA_TEST_CASE(RunSmall, CLGEMMGroupedConvolutionLayerFixture<half>, framework::DatasetMode::PRECOMMIT, combine(combine(combine(combine(datasets::SmallGroupedConvolutionLayerDataset(),
Gian Marco Iodice916d1bc2018-08-13 11:20:41 +0100441 framework::dataset::make("ReshapeWeights", { true })),
442 framework::dataset::make("DataType", DataType::F16)),
443 framework::dataset::make("DataLayout", { DataLayout::NCHW })),
Michalis Spyrou80943252019-01-10 17:19:50 +0000444 ActivationFunctionsSmallDataset))
Gian Marco Iodice916d1bc2018-08-13 11:20:41 +0100445{
446 // Validate output
447 validate(CLAccessor(_target), _reference, tolerance_f32, tolerance_num);
448}
449
Michalis Spyrou80943252019-01-10 17:19:50 +0000450FIXTURE_DATA_TEST_CASE(RunLarge, CLGEMMGroupedConvolutionLayerFixture<half>, framework::DatasetMode::NIGHTLY,
451 combine(combine(combine(combine(framework::dataset::concat(datasets::SmallGroupedConvolutionLayerDataset(), datasets::LargeGroupedConvolutionLayerDataset()),
452 framework::dataset::make("ReshapeWeights", { true })),
453 framework::dataset::make("DataType", DataType::F16)),
454 framework::dataset::make("DataLayout", { DataLayout::NCHW })),
455 ActivationFunctionsDataset))
Gian Marco Iodice916d1bc2018-08-13 11:20:41 +0100456{
457 // Validate output
458 validate(CLAccessor(_target), _reference, tolerance_f32, tolerance_num);
459}
460TEST_SUITE_END() // FP16
461TEST_SUITE_END() // Float
462
463TEST_SUITE_END() // GroupedGEMMConvolutionLayer
464TEST_SUITE_END() // CL
Moritz Pflanzerb3d25792017-07-26 11:49:37 +0100465} // namespace validation
466} // namespace test
467} // namespace arm_compute