blob: 00a01b048ee8332fd64dfcb4bf34fa10603407c8 [file] [log] [blame]
Kaizen8938bd32017-09-28 14:38:23 +01001/*
Anthony Barbier06ea0482018-02-22 15:45:35 +00002 * Copyright (c) 2017-2018 ARM Limited.
Kaizen8938bd32017-09-28 14:38:23 +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"
28#include "tests/CL/CLAccessor.h"
29#include "tests/PaddingCalculator.h"
Anthony Barbier8140e1e2017-12-14 23:48:46 +000030#include "tests/datasets/DirectConvolutionLayerDataset.h"
Kaizen8938bd32017-09-28 14:38:23 +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"
37
38namespace arm_compute
39{
40namespace test
41{
42namespace validation
43{
44namespace
45{
Jenkinsb3a371b2018-05-23 11:36:53 +010046// COMPMID-517 Invesitgate the mismatch to see whether it is a real bug
Kaizen8938bd32017-09-28 14:38:23 +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 */
50
Anthony Barbier8140e1e2017-12-14 23:48:46 +000051constexpr AbsoluteTolerance<int8_t> tolerance_qs8(0); /**< Tolerance for fixed point tests */
52constexpr AbsoluteTolerance<int16_t> tolerance_qs16(0); /**< Tolerance for fixed point tests */
53constexpr AbsoluteTolerance<uint8_t> tolerance_qasymm8(1); /**< Tolerance for quantized tests */
Kaizen8938bd32017-09-28 14:38:23 +010054
55/** Direct convolution data set. */
Kaizen8938bd32017-09-28 14:38:23 +010056const auto data = combine(datasets::SmallDirectConvolutionShapes(),
57 combine(framework::dataset::make("StrideX", 1, 3),
58 combine(framework::dataset::make("StrideY", 1, 3),
Anthony Barbier06ea0482018-02-22 15:45:35 +000059 combine(concat(combine(framework::dataset::make("PadX", 0, 1),
60 combine(framework::dataset::make("PadY", 0, 1),
Kaizen8938bd32017-09-28 14:38:23 +010061 framework::dataset::make("KernelSize", 1))),
62 combine(framework::dataset::make("PadX", 0, 2),
63 combine(framework::dataset::make("PadY", 0, 2),
64 framework::dataset::make("KernelSize", { 3, 5 })))),
65 framework::dataset::make("NumKernels", { 1, 4, 8, 16 })))));
Anthony Barbier06ea0482018-02-22 15:45:35 +000066const auto data_fixed_point = combine(datasets::TinyDirectConvolutionShapes(),
Anthony Barbier8140e1e2017-12-14 23:48:46 +000067 combine(framework::dataset::make("StrideX", 1, 3),
68 combine(framework::dataset::make("StrideY", 1, 3),
69 combine(concat(combine(framework::dataset::make("PadX", 0),
70 combine(framework::dataset::make("PadY", 0),
71 framework::dataset::make("KernelSize", 1))),
72 combine(framework::dataset::make("PadX", 0, 2),
73 combine(framework::dataset::make("PadY", 0, 2),
74 framework::dataset::make("KernelSize", { 3 })))),
75 framework::dataset::make("NumKernels", { 1, 4, 8, 16 })))));
Jenkinsb3a371b2018-05-23 11:36:53 +010076/** Activation function Dataset*/
77const auto ActivationFunctionsDataset = framework::dataset::make("ActivationInfo",
78{
79 ActivationLayerInfo(),
80 ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU),
81 ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::BOUNDED_RELU, 0.5f),
82 ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::LU_BOUNDED_RELU, 0.5f)
83});
Kaizen8938bd32017-09-28 14:38:23 +010084} // namespace
85
86TEST_SUITE(CL)
87TEST_SUITE(DirectConvolutionLayer)
88
Anthony Barbier8140e1e2017-12-14 23:48:46 +000089// *INDENT-OFF*
90// clang-format off
Jenkinsb3a371b2018-05-23 11:36:53 +010091DATA_TEST_CASE(Validate, framework::DatasetMode::ALL, zip(zip(zip(zip(zip(zip(
Anthony Barbier8140e1e2017-12-14 23:48:46 +000092 framework::dataset::make("InputInfo", { TensorInfo(TensorShape(27U, 13U, 2U), 1, DataType::F32, 0), // Mismatching data type input/weights
93 TensorInfo(TensorShape(27U, 13U, 2U), 1, DataType::F32, 0), // Mismatching input feature maps
94 TensorInfo(TensorShape(27U, 13U, 2U), 1, DataType::F32, 0), // Unsupported kernel width
95 TensorInfo(TensorShape(27U, 13U, 2U), 1, DataType::F32, 0), // Non-rectangular weights dimensions
96 TensorInfo(TensorShape(27U, 13U, 2U), 1, DataType::F32, 0), // Invalid weights dimensions
97 TensorInfo(TensorShape(27U, 13U, 2U), 1, DataType::F32, 0), // Invalid stride
98 TensorInfo(TensorShape(27U, 13U, 2U), 1, DataType::F32, 0), // Invalid biases size
99 TensorInfo(TensorShape(27U, 13U, 2U), 1, DataType::F32, 0), // Invalid biases dimensions
100 TensorInfo(TensorShape(27U, 13U, 2U), 1, DataType::F32, 0), // Invalid output size
101 TensorInfo(TensorShape(27U, 13U, 2U), 1, DataType::F32, 0), // Window shrink
102 TensorInfo(TensorShape(32U, 16U, 2U), 1, DataType::F32, 0),
103 }),
104 framework::dataset::make("WeightsInfo",{ TensorInfo(TensorShape(3U, 3U, 2U, 4U), 1, DataType::F16, 0),
105 TensorInfo(TensorShape(3U, 3U, 3U, 4U), 1, DataType::F32, 0),
106 TensorInfo(TensorShape(9U, 9U, 2U, 4U), 1, DataType::F32, 0),
107 TensorInfo(TensorShape(5U, 3U, 2U, 4U), 1, DataType::F32, 0),
108 TensorInfo(TensorShape(3U, 3U, 2U, 4U, 3U), 1, DataType::F32, 0),
109 TensorInfo(TensorShape(3U, 3U, 2U, 4U), 1, DataType::F32, 0),
110 TensorInfo(TensorShape(3U, 3U, 2U, 4U), 1, DataType::F32, 0),
111 TensorInfo(TensorShape(3U, 3U, 2U, 4U), 1, DataType::F32, 0),
112 TensorInfo(TensorShape(3U, 3U, 2U, 4U), 1, DataType::F32, 0),
113 TensorInfo(TensorShape(3U, 3U, 2U, 4U), 1, DataType::F32, 0),
114 TensorInfo(TensorShape(1U, 1U, 2U, 4U), 1, DataType::F32, 0),
115 })),
116 framework::dataset::make("BiasesInfo",{ TensorInfo(TensorShape(4U), 1, DataType::F32, 0),
117 TensorInfo(TensorShape(4U), 1, DataType::F32, 0),
118 TensorInfo(TensorShape(4U), 1, DataType::F32, 0),
119 TensorInfo(TensorShape(4U), 1, DataType::F32, 0),
120 TensorInfo(TensorShape(4U), 1, DataType::F32, 0),
121 TensorInfo(TensorShape(4U), 1, DataType::F32, 0),
122 TensorInfo(TensorShape(3U), 1, DataType::F32, 0),
123 TensorInfo(TensorShape(4U, 2U), 1, DataType::F32, 0),
124 TensorInfo(TensorShape(4U), 1, DataType::F32, 0),
125 TensorInfo(TensorShape(4U), 1, DataType::F32, 0),
126 TensorInfo(TensorShape(4U), 1, DataType::F32, 0),
127 })),
128 framework::dataset::make("OutputInfo",{ TensorInfo(TensorShape(25U, 11U, 4U), 1, DataType::F32, 0),
129 TensorInfo(TensorShape(25U, 11U, 4U), 1, DataType::F32, 0),
130 TensorInfo(TensorShape(25U, 11U, 4U), 1, DataType::F32, 0),
131 TensorInfo(TensorShape(25U, 11U, 4U), 1, DataType::F32, 0),
132 TensorInfo(TensorShape(25U, 11U, 4U), 1, DataType::F32, 0),
133 TensorInfo(TensorShape(25U, 11U, 4U), 1, DataType::F32, 0),
134 TensorInfo(TensorShape(25U, 11U, 4U), 1, DataType::F32, 0),
135 TensorInfo(TensorShape(25U, 11U, 4U), 1, DataType::F32, 0),
136 TensorInfo(TensorShape(26U, 11U, 4U), 1, DataType::F32, 0),
137 TensorInfo(TensorShape(25U, 11U, 4U), 1, DataType::F32, 0),
138 TensorInfo(TensorShape(32U, 16U, 4U), 1, DataType::F32, 0),
139 })),
140 framework::dataset::make("ConvInfo", { PadStrideInfo(1, 1, 0, 0),
141 PadStrideInfo(1, 1, 0, 0),
142 PadStrideInfo(1, 1, 0, 0),
143 PadStrideInfo(1, 1, 0, 0),
144 PadStrideInfo(1, 1, 0, 0),
145 PadStrideInfo(3, 3, 0, 0),
146 PadStrideInfo(1, 1, 0, 0),
147 PadStrideInfo(1, 1, 0, 0),
148 PadStrideInfo(1, 1, 0, 0),
149 PadStrideInfo(1, 1, 0, 0),
150 PadStrideInfo(1, 1, 0, 0),
151 })),
Jenkinsb3a371b2018-05-23 11:36:53 +0100152 framework::dataset::make("ActivationInfo",
Anthony Barbier8140e1e2017-12-14 23:48:46 +0000153{
Jenkinsb3a371b2018-05-23 11:36:53 +0100154 ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU)
155})),
156 framework::dataset::make("Expected", { false, false, false, false, false, false, false, false, false, false, true })),
157 input_info, weights_info, biases_info, output_info, conv_info, act_info, expected)
158{
159 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));
Anthony Barbier8140e1e2017-12-14 23:48:46 +0000160 ARM_COMPUTE_EXPECT(is_valid == expected, framework::LogLevel::ERRORS);
161}
162// clang-format on
163// *INDENT-ON*
164
Kaizen8938bd32017-09-28 14:38:23 +0100165template <typename T>
166using CLDirectConvolutionLayerFixture = DirectConvolutionValidationFixture<CLTensor, CLAccessor, CLDirectConvolutionLayer, T>;
Anthony Barbier8140e1e2017-12-14 23:48:46 +0000167template <typename T>
168using CLDirectConvolutionValidationWithTensorShapesFixture = DirectConvolutionValidationWithTensorShapesFixture<CLTensor, CLAccessor, CLDirectConvolutionLayer, T>;
Kaizen8938bd32017-09-28 14:38:23 +0100169
170TEST_SUITE(Float)
171TEST_SUITE(FP16)
Jenkinsb3a371b2018-05-23 11:36:53 +0100172FIXTURE_DATA_TEST_CASE(Run, CLDirectConvolutionLayerFixture<half>, framework::DatasetMode::ALL, combine(combine(combine(data, framework::dataset::make("DataType", DataType::F16)),
173 ActivationFunctionsDataset),
174 framework::dataset::make("DataLayout", DataLayout::NCHW)))
Kaizen8938bd32017-09-28 14:38:23 +0100175{
176 // Validate output
177 validate(CLAccessor(_target), _reference, tolerance_fp16, tolerance_num);
178}
179TEST_SUITE_END()
180
181TEST_SUITE(FP32)
Jenkinsb3a371b2018-05-23 11:36:53 +0100182FIXTURE_DATA_TEST_CASE(Run, CLDirectConvolutionLayerFixture<float>, framework::DatasetMode::ALL, combine(combine(combine(data, framework::dataset::make("DataType", DataType::F32)),
183 ActivationFunctionsDataset),
184 framework::dataset::make("DataLayout", DataLayout::NCHW)))
Kaizen8938bd32017-09-28 14:38:23 +0100185{
186 // Validate output
187 validate(CLAccessor(_target), _reference, tolerance_fp32);
188}
189TEST_SUITE_END()
Anthony Barbier8140e1e2017-12-14 23:48:46 +0000190
191TEST_SUITE(FP32_CustomDataset)
Jenkinsb3a371b2018-05-23 11:36:53 +0100192FIXTURE_DATA_TEST_CASE(Run, CLDirectConvolutionValidationWithTensorShapesFixture<float>, framework::DatasetMode::ALL, combine(combine(datasets::DirectConvolutionLayerDataset(),
193 framework::dataset::make("DataType", DataType::F32)),
194 ActivationFunctionsDataset))
Anthony Barbier8140e1e2017-12-14 23:48:46 +0000195{
196 // Validate output
197 validate(CLAccessor(_target), _reference, tolerance_fp32);
198}
199TEST_SUITE_END()
Kaizen8938bd32017-09-28 14:38:23 +0100200TEST_SUITE_END()
201
202template <typename T>
203using CLDirectConvolutionLayerFixedPointFixture = DirectConvolutionValidationFixedPointFixture<CLTensor, CLAccessor, CLDirectConvolutionLayer, T>;
204
Anthony Barbier8140e1e2017-12-14 23:48:46 +0000205TEST_SUITE(FixedPoint)
Kaizen8938bd32017-09-28 14:38:23 +0100206TEST_SUITE(QS8)
Jenkinsb3a371b2018-05-23 11:36:53 +0100207FIXTURE_DATA_TEST_CASE(Run, CLDirectConvolutionLayerFixedPointFixture<int8_t>, framework::DatasetMode::ALL, combine(combine(combine(data_fixed_point, framework::dataset::make("DataType",
208 DataType::QS8)),
209 framework::dataset::make("FractionalBits", 2, 7)),
210 ActivationFunctionsDataset))
Kaizen8938bd32017-09-28 14:38:23 +0100211{
212 // Validate output
213 validate(CLAccessor(_target), _reference, tolerance_qs8);
214}
215TEST_SUITE_END()
216
217TEST_SUITE(QS16)
Jenkinsb3a371b2018-05-23 11:36:53 +0100218FIXTURE_DATA_TEST_CASE(Run, CLDirectConvolutionLayerFixedPointFixture<int16_t>, framework::DatasetMode::ALL, combine(combine(combine(data_fixed_point, framework::dataset::make("DataType",
219 DataType::QS16)),
220 framework::dataset::make("FractionalBits", 2, 15)),
221 ActivationFunctionsDataset))
Kaizen8938bd32017-09-28 14:38:23 +0100222{
223 // Validate output
224 validate(CLAccessor(_target), _reference, tolerance_qs16);
225}
226TEST_SUITE_END()
227TEST_SUITE_END()
228
Anthony Barbier8140e1e2017-12-14 23:48:46 +0000229template <typename T>
230using CLDirectConvolutionLayerQuantizedFixture = DirectConvolutionValidationQuantizedFixture<CLTensor, CLAccessor, CLDirectConvolutionLayer, T>;
231template <typename T>
232using CLDirectConvolutionValidationWithTensorShapesQuantizedFixture = DirectConvolutionValidationWithTensorShapesQuantizedFixture<CLTensor, CLAccessor, CLDirectConvolutionLayer, T>;
233
Jenkinsb3a371b2018-05-23 11:36:53 +0100234const auto QuantizedActivationFunctionsDataset = framework::dataset::make("ActivationInfo",
235{
236 ActivationLayerInfo(),
237 ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU),
238 ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::LU_BOUNDED_RELU, 6.f)
239});
Anthony Barbier8140e1e2017-12-14 23:48:46 +0000240TEST_SUITE(Quantized)
241TEST_SUITE(QASYMM8)
Jenkinsb3a371b2018-05-23 11:36:53 +0100242FIXTURE_DATA_TEST_CASE(Run, CLDirectConvolutionLayerQuantizedFixture<uint8_t>, framework::DatasetMode::ALL, combine(combine(combine(data, framework::dataset::make("DataType", DataType::QASYMM8)),
243 framework::dataset::make("QuantizationInfo", { QuantizationInfo(2.f / 255, 10) })),
244 QuantizedActivationFunctionsDataset))
Anthony Barbier8140e1e2017-12-14 23:48:46 +0000245{
246 // Validate output
247 validate(CLAccessor(_target), _reference, tolerance_qasymm8);
248}
249TEST_SUITE_END()
250
251TEST_SUITE(QASYMM8_CustomDataset)
Jenkinsb3a371b2018-05-23 11:36:53 +0100252FIXTURE_DATA_TEST_CASE(Run, CLDirectConvolutionValidationWithTensorShapesQuantizedFixture<uint8_t>, framework::DatasetMode::ALL, combine(combine(combine(datasets::DirectConvolutionLayerDataset(),
Anthony Barbier8140e1e2017-12-14 23:48:46 +0000253 framework::dataset::make("DataType", DataType::QASYMM8)),
Jenkinsb3a371b2018-05-23 11:36:53 +0100254 framework::dataset::make("QuantizationInfo", { QuantizationInfo(2.f / 255, 127) })),
255 QuantizedActivationFunctionsDataset))
Anthony Barbier8140e1e2017-12-14 23:48:46 +0000256{
257 // Validate output
258 validate(CLAccessor(_target), _reference, tolerance_qasymm8);
259}
260TEST_SUITE_END()
261TEST_SUITE_END()
262
Kaizen8938bd32017-09-28 14:38:23 +0100263TEST_SUITE_END()
264TEST_SUITE_END()
265} // namespace validation
266} // namespace test
267} // namespace arm_compute