blob: 437d5bac8c129c549f047fdfe612cb984c49449a [file] [log] [blame]
Moritz Pflanzerb3d25792017-07-26 11:49:37 +01001/*
Michalis Spyrou80943252019-01-10 17:19:50 +00002 * Copyright (c) 2017-2019 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,
21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 * 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/CLDirectConvolutionLayer.h"
Moritz Pflanzerb3d25792017-07-26 11:49:37 +010028#include "tests/CL/CLAccessor.h"
29#include "tests/PaddingCalculator.h"
Jaroslaw Rzepecki2ecbada2017-11-29 13:51:34 +000030#include "tests/datasets/DirectConvolutionLayerDataset.h"
Moritz Pflanzera09de0c2017-09-01 20:41:12 +010031#include "tests/datasets/ShapeDatasets.h"
32#include "tests/framework/Asserts.h"
33#include "tests/framework/Macros.h"
34#include "tests/framework/datasets/Datasets.h"
35#include "tests/validation/Validation.h"
36#include "tests/validation/fixtures/DirectConvolutionLayerFixture.h"
Moritz Pflanzerb3d25792017-07-26 11:49:37 +010037
38namespace arm_compute
39{
40namespace test
41{
42namespace validation
43{
44namespace
45{
Michalis Spyrou064add62018-11-01 18:14:27 +000046// COMPMID-517 Investigate the mismatch to see whether it is a real bug
Pablo Tellod041a832018-10-03 17:11:09 +010047RelativeTolerance<half> tolerance_fp16(half(0.2)); /**< Tolerance for floating point tests */
48RelativeTolerance<float> tolerance_fp32(0.02f); /**< Tolerance for floating point tests */
49constexpr float tolerance_num = 0.07f; /**< Tolerance number */
50constexpr AbsoluteTolerance<uint8_t> tolerance_qasymm8(1); /**< Tolerance for quantized tests */
Moritz Pflanzerb3d25792017-07-26 11:49:37 +010051
Michalis Spyrou80943252019-01-10 17:19:50 +000052const auto data_strides = combine(framework::dataset::make("StrideX", 1, 3), framework::dataset::make("StrideY", 1, 3));
53const auto data_strides_small = combine(framework::dataset::make("StrideX", 1), framework::dataset::make("StrideY", 1));
54const auto data_ksize_one = combine(framework::dataset::make("PadX", 0, 1), combine(framework::dataset::make("PadY", 0, 1), framework::dataset::make("KernelSize", 1)));
55const auto data_ksize_one_small = combine(framework::dataset::make("PadX", 0), combine(framework::dataset::make("PadY", 0), framework::dataset::make("KernelSize", 1)));
56const auto data_ksize_three = combine(framework::dataset::make("PadX", 0, 2), combine(framework::dataset::make("PadY", 0, 2), framework::dataset::make("KernelSize", 3)));
57const auto data_ksize_five = combine(framework::dataset::make("PadX", 0, 3), combine(framework::dataset::make("PadY", 0, 3), framework::dataset::make("KernelSize", 5)));
58const auto data_all_kernels = concat(concat(data_ksize_one, data_ksize_three), data_ksize_five);
Michalis Spyroudef665a2017-08-14 11:26:37 +010059
Michalis Spyrou80943252019-01-10 17:19:50 +000060const auto data = combine(datasets::SmallDirectConvolutionShapes(), combine(data_strides, data_all_kernels));
61const auto data_small = combine(datasets::SmallDirectConvolutionShapes(), combine(data_strides_small, data_ksize_one_small));
Michalis Spyrou064add62018-11-01 18:14:27 +000062
63/** Direct convolution nightly data set. */
Michalis Spyrou5ce99a22019-01-25 14:17:49 +000064const auto data_nightly = combine(data, framework::dataset::make("NumKernels", { 1, 4 }));
Michalis Spyrou064add62018-11-01 18:14:27 +000065/** Direct convolution precommit data set. */
Michalis Spyrou80943252019-01-10 17:19:50 +000066const auto data_precommit = combine(data_small, framework::dataset::make("NumKernels", { 1 }));
Vidhya Sudhan Loganathan7485d5a2018-07-04 09:34:00 +010067
Isabella Gottardi3f217ec2018-02-12 14:59:19 +000068/** Activation function Dataset*/
69const auto ActivationFunctionsDataset = framework::dataset::make("ActivationInfo",
Michalis Spyrou5ce99a22019-01-25 14:17:49 +000070{ ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::LU_BOUNDED_RELU, 0.5f) });
Moritz Pflanzerb3d25792017-07-26 11:49:37 +010071} // namespace
72
73TEST_SUITE(CL)
74TEST_SUITE(DirectConvolutionLayer)
75
76//TODO(COMPMID-415): Configuration tests?
77
Georgios Pinitas30902ed2017-11-14 15:32:57 +000078// *INDENT-OFF*
79// clang-format off
Isabella Gottardi3f217ec2018-02-12 14:59:19 +000080DATA_TEST_CASE(Validate, framework::DatasetMode::ALL, zip(zip(zip(zip(zip(zip(
Vidhya Sudhan Loganathan7485d5a2018-07-04 09:34:00 +010081 framework::dataset::make("InputInfo", { TensorInfo(TensorShape(27U, 13U, 2U), 1, DataType::F32), // Mismatching data type input/weights
82 TensorInfo(TensorShape(27U, 13U, 2U), 1, DataType::F32), // Mismatching input feature maps
83 TensorInfo(TensorShape(27U, 13U, 2U), 1, DataType::F32), // Unsupported kernel width
84 TensorInfo(TensorShape(27U, 13U, 2U), 1, DataType::F32), // Non-rectangular weights dimensions
85 TensorInfo(TensorShape(27U, 13U, 2U), 1, DataType::F32), // Invalid weights dimensions
86 TensorInfo(TensorShape(27U, 13U, 2U), 1, DataType::F32), // Invalid stride
87 TensorInfo(TensorShape(27U, 13U, 2U), 1, DataType::F32), // Invalid biases size
88 TensorInfo(TensorShape(27U, 13U, 2U), 1, DataType::F32), // Invalid biases dimensions
89 TensorInfo(TensorShape(27U, 13U, 2U), 1, DataType::F32), // Invalid output size
90 TensorInfo(TensorShape(27U, 13U, 2U), 1, DataType::F32), // Window shrink
91 TensorInfo(TensorShape(32U, 16U, 2U), 1, DataType::F32),
Georgios Pinitas30902ed2017-11-14 15:32:57 +000092 }),
Vidhya Sudhan Loganathan7485d5a2018-07-04 09:34:00 +010093 framework::dataset::make("WeightsInfo",{ TensorInfo(TensorShape(3U, 3U, 2U, 4U), 1, DataType::F16),
94 TensorInfo(TensorShape(3U, 3U, 3U, 4U), 1, DataType::F32),
95 TensorInfo(TensorShape(9U, 9U, 2U, 4U), 1, DataType::F32),
96 TensorInfo(TensorShape(5U, 3U, 2U, 4U), 1, DataType::F32),
97 TensorInfo(TensorShape(3U, 3U, 2U, 4U, 3U), 1, DataType::F32),
98 TensorInfo(TensorShape(3U, 3U, 2U, 4U), 1, DataType::F32),
99 TensorInfo(TensorShape(3U, 3U, 2U, 4U), 1, DataType::F32),
100 TensorInfo(TensorShape(3U, 3U, 2U, 4U), 1, DataType::F32),
101 TensorInfo(TensorShape(3U, 3U, 2U, 4U), 1, DataType::F32),
102 TensorInfo(TensorShape(3U, 3U, 2U, 4U), 1, DataType::F32),
103 TensorInfo(TensorShape(1U, 1U, 2U, 4U), 1, DataType::F32),
Georgios Pinitas30902ed2017-11-14 15:32:57 +0000104 })),
Vidhya Sudhan Loganathan7485d5a2018-07-04 09:34:00 +0100105 framework::dataset::make("BiasesInfo",{ TensorInfo(TensorShape(4U), 1, DataType::F32),
106 TensorInfo(TensorShape(4U), 1, DataType::F32),
107 TensorInfo(TensorShape(4U), 1, DataType::F32),
108 TensorInfo(TensorShape(4U), 1, DataType::F32),
109 TensorInfo(TensorShape(4U), 1, DataType::F32),
110 TensorInfo(TensorShape(4U), 1, DataType::F32),
111 TensorInfo(TensorShape(3U), 1, DataType::F32),
112 TensorInfo(TensorShape(4U, 2U), 1, DataType::F32),
113 TensorInfo(TensorShape(4U), 1, DataType::F32),
114 TensorInfo(TensorShape(4U), 1, DataType::F32),
115 TensorInfo(TensorShape(4U), 1, DataType::F32),
Georgios Pinitas30902ed2017-11-14 15:32:57 +0000116 })),
Vidhya Sudhan Loganathan7485d5a2018-07-04 09:34:00 +0100117 framework::dataset::make("OutputInfo",{ TensorInfo(TensorShape(25U, 11U, 4U), 1, DataType::F32),
118 TensorInfo(TensorShape(25U, 11U, 4U), 1, DataType::F32),
119 TensorInfo(TensorShape(25U, 11U, 4U), 1, DataType::F32),
120 TensorInfo(TensorShape(25U, 11U, 4U), 1, DataType::F32),
121 TensorInfo(TensorShape(25U, 11U, 4U), 1, DataType::F32),
122 TensorInfo(TensorShape(25U, 11U, 4U), 1, DataType::F32),
123 TensorInfo(TensorShape(25U, 11U, 4U), 1, DataType::F32),
124 TensorInfo(TensorShape(25U, 11U, 4U), 1, DataType::F32),
125 TensorInfo(TensorShape(26U, 11U, 4U), 1, DataType::F32),
126 TensorInfo(TensorShape(25U, 11U, 4U), 1, DataType::F32),
127 TensorInfo(TensorShape(32U, 16U, 4U), 1, DataType::F32),
Georgios Pinitas30902ed2017-11-14 15:32:57 +0000128 })),
129 framework::dataset::make("ConvInfo", { PadStrideInfo(1, 1, 0, 0),
130 PadStrideInfo(1, 1, 0, 0),
131 PadStrideInfo(1, 1, 0, 0),
132 PadStrideInfo(1, 1, 0, 0),
133 PadStrideInfo(1, 1, 0, 0),
134 PadStrideInfo(3, 3, 0, 0),
135 PadStrideInfo(1, 1, 0, 0),
136 PadStrideInfo(1, 1, 0, 0),
137 PadStrideInfo(1, 1, 0, 0),
138 PadStrideInfo(1, 1, 0, 0),
Giorgio Arena59486342017-12-01 10:42:47 +0000139 PadStrideInfo(1, 1, 0, 0),
Georgios Pinitas30902ed2017-11-14 15:32:57 +0000140 })),
Isabella Gottardi3f217ec2018-02-12 14:59:19 +0000141 framework::dataset::make("ActivationInfo",
Georgios Pinitas30902ed2017-11-14 15:32:57 +0000142{
Isabella Gottardi3f217ec2018-02-12 14:59:19 +0000143 ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU)
144})),
145 framework::dataset::make("Expected", { false, false, false, false, false, false, false, false, false, false, true })),
146 input_info, weights_info, biases_info, output_info, conv_info, act_info, expected)
147{
148 bool is_valid = bool(CLDirectConvolutionLayer::validate(&input_info.clone()->set_is_resizable(false), &weights_info.clone()->set_is_resizable(false), &biases_info.clone()->set_is_resizable(false), &output_info.clone()->set_is_resizable(false), conv_info, act_info));
Georgios Pinitas631c41a2017-12-06 11:53:03 +0000149 ARM_COMPUTE_EXPECT(is_valid == expected, framework::LogLevel::ERRORS);
Georgios Pinitas30902ed2017-11-14 15:32:57 +0000150}
151// clang-format on
152// *INDENT-ON*
153
Moritz Pflanzerb3d25792017-07-26 11:49:37 +0100154template <typename T>
155using CLDirectConvolutionLayerFixture = DirectConvolutionValidationFixture<CLTensor, CLAccessor, CLDirectConvolutionLayer, T>;
Jaroslaw Rzepecki2ecbada2017-11-29 13:51:34 +0000156template <typename T>
157using CLDirectConvolutionValidationWithTensorShapesFixture = DirectConvolutionValidationWithTensorShapesFixture<CLTensor, CLAccessor, CLDirectConvolutionLayer, T>;
Moritz Pflanzerb3d25792017-07-26 11:49:37 +0100158
159TEST_SUITE(Float)
160TEST_SUITE(FP16)
Michalis Spyrou064add62018-11-01 18:14:27 +0000161FIXTURE_DATA_TEST_CASE(RunSmall, CLDirectConvolutionLayerFixture<half>, framework::DatasetMode::PRECOMMIT, combine(combine(combine(data_precommit, framework::dataset::make("DataType", DataType::F16)),
162 ActivationFunctionsDataset),
163 framework::dataset::make("DataLayout", DataLayout::NCHW)))
Moritz Pflanzerb3d25792017-07-26 11:49:37 +0100164{
165 // Validate output
steniu013e05e4e2017-08-25 17:18:01 +0100166 validate(CLAccessor(_target), _reference, tolerance_fp16, tolerance_num);
Moritz Pflanzerb3d25792017-07-26 11:49:37 +0100167}
Michalis Spyrou064add62018-11-01 18:14:27 +0000168FIXTURE_DATA_TEST_CASE(RunLarge, CLDirectConvolutionLayerFixture<half>, framework::DatasetMode::NIGHTLY, combine(combine(combine(data_nightly, framework::dataset::make("DataType", DataType::F16)),
169 ActivationFunctionsDataset),
170 framework::dataset::make("DataLayout", DataLayout::NCHW)))
171{
172 // Validate output
173 validate(CLAccessor(_target), _reference, tolerance_fp16, tolerance_num);
174}
175TEST_SUITE_END() // FP16
Moritz Pflanzerb3d25792017-07-26 11:49:37 +0100176
177TEST_SUITE(FP32)
Michalis Spyrou064add62018-11-01 18:14:27 +0000178FIXTURE_DATA_TEST_CASE(RunSmall, CLDirectConvolutionLayerFixture<float>, framework::DatasetMode::PRECOMMIT, combine(combine(combine(data_precommit, framework::dataset::make("DataType",
179 DataType::F32)),
180 ActivationFunctionsDataset),
181 framework::dataset::make("DataLayout", { DataLayout::NCHW, DataLayout::NHWC })))
Moritz Pflanzerb3d25792017-07-26 11:49:37 +0100182{
Moritz Pflanzerb3d25792017-07-26 11:49:37 +0100183 validate(CLAccessor(_target), _reference, tolerance_fp32);
184}
Michalis Spyrou064add62018-11-01 18:14:27 +0000185FIXTURE_DATA_TEST_CASE(RunLarge, CLDirectConvolutionLayerFixture<float>, framework::DatasetMode::NIGHTLY, combine(combine(combine(data_nightly, framework::dataset::make("DataType", DataType::F32)),
186 ActivationFunctionsDataset),
187 framework::dataset::make("DataLayout", { DataLayout::NCHW, DataLayout::NHWC })))
188{
189 validate(CLAccessor(_target), _reference, tolerance_fp32);
190}
191TEST_SUITE_END() // FP32
Jaroslaw Rzepecki2ecbada2017-11-29 13:51:34 +0000192
193TEST_SUITE(FP32_CustomDataset)
Michalis Spyrou80943252019-01-10 17:19:50 +0000194FIXTURE_DATA_TEST_CASE(Run, CLDirectConvolutionValidationWithTensorShapesFixture<float>, framework::DatasetMode::NIGHTLY, combine(combine(datasets::DirectConvolutionLayerDataset(),
Isabella Gottardi3f217ec2018-02-12 14:59:19 +0000195 framework::dataset::make("DataType", DataType::F32)),
196 ActivationFunctionsDataset))
Jaroslaw Rzepecki2ecbada2017-11-29 13:51:34 +0000197{
198 // Validate output
199 validate(CLAccessor(_target), _reference, tolerance_fp32);
200}
Michalis Spyrou064add62018-11-01 18:14:27 +0000201TEST_SUITE_END() // FP32_CustomDataset
202TEST_SUITE_END() // Float
Moritz Pflanzerb3d25792017-07-26 11:49:37 +0100203
Michalis Spyroudef665a2017-08-14 11:26:37 +0100204template <typename T>
Chunosovd621bca2017-11-03 17:33:15 +0700205using CLDirectConvolutionLayerQuantizedFixture = DirectConvolutionValidationQuantizedFixture<CLTensor, CLAccessor, CLDirectConvolutionLayer, T>;
Jaroslaw Rzepecki2ecbada2017-11-29 13:51:34 +0000206template <typename T>
207using CLDirectConvolutionValidationWithTensorShapesQuantizedFixture = DirectConvolutionValidationWithTensorShapesQuantizedFixture<CLTensor, CLAccessor, CLDirectConvolutionLayer, T>;
Chunosovd621bca2017-11-03 17:33:15 +0700208
Isabella Gottardi3f217ec2018-02-12 14:59:19 +0000209const auto QuantizedActivationFunctionsDataset = framework::dataset::make("ActivationInfo",
210{
211 ActivationLayerInfo(),
212 ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU),
213 ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::LU_BOUNDED_RELU, 6.f)
214});
Chunosovd621bca2017-11-03 17:33:15 +0700215TEST_SUITE(Quantized)
216TEST_SUITE(QASYMM8)
Michalis Spyrou064add62018-11-01 18:14:27 +0000217FIXTURE_DATA_TEST_CASE(RunSmall, CLDirectConvolutionLayerQuantizedFixture<uint8_t>, framework::DatasetMode::PRECOMMIT, combine(combine(combine(data_precommit, framework::dataset::make("DataType",
218 DataType::QASYMM8)),
219 framework::dataset::make("QuantizationInfo", { QuantizationInfo(2.f / 255, 10) })),
220 QuantizedActivationFunctionsDataset))
Chunosovd621bca2017-11-03 17:33:15 +0700221{
222 // Validate output
223 validate(CLAccessor(_target), _reference, tolerance_qasymm8);
224}
Michalis Spyrou064add62018-11-01 18:14:27 +0000225FIXTURE_DATA_TEST_CASE(RunLarge, CLDirectConvolutionLayerQuantizedFixture<uint8_t>, framework::DatasetMode::NIGHTLY, combine(combine(combine(data_nightly, framework::dataset::make("DataType",
226 DataType::QASYMM8)),
227 framework::dataset::make("QuantizationInfo", { QuantizationInfo(2.f / 255, 10) })),
228 QuantizedActivationFunctionsDataset))
229{
230 // Validate output
231 validate(CLAccessor(_target), _reference, tolerance_qasymm8);
232}
233TEST_SUITE_END() // QASYMM8
Jaroslaw Rzepecki2ecbada2017-11-29 13:51:34 +0000234
235TEST_SUITE(QASYMM8_CustomDataset)
Michalis Spyrou80943252019-01-10 17:19:50 +0000236FIXTURE_DATA_TEST_CASE(Run, CLDirectConvolutionValidationWithTensorShapesQuantizedFixture<uint8_t>, framework::DatasetMode::NIGHTLY, combine(combine(combine(datasets::DirectConvolutionLayerDataset(),
Jaroslaw Rzepecki2ecbada2017-11-29 13:51:34 +0000237 framework::dataset::make("DataType", DataType::QASYMM8)),
Isabella Gottardi3f217ec2018-02-12 14:59:19 +0000238 framework::dataset::make("QuantizationInfo", { QuantizationInfo(2.f / 255, 127) })),
239 QuantizedActivationFunctionsDataset))
Jaroslaw Rzepecki2ecbada2017-11-29 13:51:34 +0000240{
241 // Validate output
242 validate(CLAccessor(_target), _reference, tolerance_qasymm8);
243}
Michalis Spyrou064add62018-11-01 18:14:27 +0000244TEST_SUITE_END() // QASYMM8_CustomDataset
245TEST_SUITE_END() // Quantized
Chunosovd621bca2017-11-03 17:33:15 +0700246
Michalis Spyrou064add62018-11-01 18:14:27 +0000247TEST_SUITE_END() // DirectConvolutionLayer
248TEST_SUITE_END() // Float
Moritz Pflanzerb3d25792017-07-26 11:49:37 +0100249} // namespace validation
250} // namespace test
Anthony Barbier1c0d0ff2018-01-31 13:05:09 +0000251} // namespace arm_compute