blob: 12f3d3da328569d40ac3e738f5ff7020c0edf2be [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{
Kaizen8938bd32017-09-28 14:38:23 +010046RelativeTolerance<half> tolerance_fp16(half(0.2)); /**< Tolerance for floating point tests */
47RelativeTolerance<float> tolerance_fp32(0.02f); /**< Tolerance for floating point tests */
48constexpr float tolerance_num = 0.07f; /**< Tolerance number */
49
Anthony Barbier8140e1e2017-12-14 23:48:46 +000050constexpr AbsoluteTolerance<int8_t> tolerance_qs8(0); /**< Tolerance for fixed point tests */
51constexpr AbsoluteTolerance<int16_t> tolerance_qs16(0); /**< Tolerance for fixed point tests */
52constexpr AbsoluteTolerance<uint8_t> tolerance_qasymm8(1); /**< Tolerance for quantized tests */
Kaizen8938bd32017-09-28 14:38:23 +010053
54/** Direct convolution data set. */
Kaizen8938bd32017-09-28 14:38:23 +010055const auto data = combine(datasets::SmallDirectConvolutionShapes(),
56 combine(framework::dataset::make("StrideX", 1, 3),
57 combine(framework::dataset::make("StrideY", 1, 3),
Anthony Barbier06ea0482018-02-22 15:45:35 +000058 combine(concat(combine(framework::dataset::make("PadX", 0, 1),
59 combine(framework::dataset::make("PadY", 0, 1),
Kaizen8938bd32017-09-28 14:38:23 +010060 framework::dataset::make("KernelSize", 1))),
61 combine(framework::dataset::make("PadX", 0, 2),
62 combine(framework::dataset::make("PadY", 0, 2),
63 framework::dataset::make("KernelSize", { 3, 5 })))),
64 framework::dataset::make("NumKernels", { 1, 4, 8, 16 })))));
Anthony Barbier06ea0482018-02-22 15:45:35 +000065const auto data_fixed_point = combine(datasets::TinyDirectConvolutionShapes(),
Anthony Barbier8140e1e2017-12-14 23:48:46 +000066 combine(framework::dataset::make("StrideX", 1, 3),
67 combine(framework::dataset::make("StrideY", 1, 3),
68 combine(concat(combine(framework::dataset::make("PadX", 0),
69 combine(framework::dataset::make("PadY", 0),
70 framework::dataset::make("KernelSize", 1))),
71 combine(framework::dataset::make("PadX", 0, 2),
72 combine(framework::dataset::make("PadY", 0, 2),
73 framework::dataset::make("KernelSize", { 3 })))),
74 framework::dataset::make("NumKernels", { 1, 4, 8, 16 })))));
Kaizen8938bd32017-09-28 14:38:23 +010075} // namespace
76
77TEST_SUITE(CL)
78TEST_SUITE(DirectConvolutionLayer)
79
Anthony Barbier8140e1e2017-12-14 23:48:46 +000080// *INDENT-OFF*
81// clang-format off
82DATA_TEST_CASE(Validate, framework::DatasetMode::ALL, zip(zip(zip(zip(zip(
83 framework::dataset::make("InputInfo", { TensorInfo(TensorShape(27U, 13U, 2U), 1, DataType::F32, 0), // Mismatching data type input/weights
84 TensorInfo(TensorShape(27U, 13U, 2U), 1, DataType::F32, 0), // Mismatching input feature maps
85 TensorInfo(TensorShape(27U, 13U, 2U), 1, DataType::F32, 0), // Unsupported kernel width
86 TensorInfo(TensorShape(27U, 13U, 2U), 1, DataType::F32, 0), // Non-rectangular weights dimensions
87 TensorInfo(TensorShape(27U, 13U, 2U), 1, DataType::F32, 0), // Invalid weights dimensions
88 TensorInfo(TensorShape(27U, 13U, 2U), 1, DataType::F32, 0), // Invalid stride
89 TensorInfo(TensorShape(27U, 13U, 2U), 1, DataType::F32, 0), // Invalid biases size
90 TensorInfo(TensorShape(27U, 13U, 2U), 1, DataType::F32, 0), // Invalid biases dimensions
91 TensorInfo(TensorShape(27U, 13U, 2U), 1, DataType::F32, 0), // Invalid output size
92 TensorInfo(TensorShape(27U, 13U, 2U), 1, DataType::F32, 0), // Window shrink
93 TensorInfo(TensorShape(32U, 16U, 2U), 1, DataType::F32, 0),
94 }),
95 framework::dataset::make("WeightsInfo",{ TensorInfo(TensorShape(3U, 3U, 2U, 4U), 1, DataType::F16, 0),
96 TensorInfo(TensorShape(3U, 3U, 3U, 4U), 1, DataType::F32, 0),
97 TensorInfo(TensorShape(9U, 9U, 2U, 4U), 1, DataType::F32, 0),
98 TensorInfo(TensorShape(5U, 3U, 2U, 4U), 1, DataType::F32, 0),
99 TensorInfo(TensorShape(3U, 3U, 2U, 4U, 3U), 1, DataType::F32, 0),
100 TensorInfo(TensorShape(3U, 3U, 2U, 4U), 1, DataType::F32, 0),
101 TensorInfo(TensorShape(3U, 3U, 2U, 4U), 1, DataType::F32, 0),
102 TensorInfo(TensorShape(3U, 3U, 2U, 4U), 1, DataType::F32, 0),
103 TensorInfo(TensorShape(3U, 3U, 2U, 4U), 1, DataType::F32, 0),
104 TensorInfo(TensorShape(3U, 3U, 2U, 4U), 1, DataType::F32, 0),
105 TensorInfo(TensorShape(1U, 1U, 2U, 4U), 1, DataType::F32, 0),
106 })),
107 framework::dataset::make("BiasesInfo",{ TensorInfo(TensorShape(4U), 1, DataType::F32, 0),
108 TensorInfo(TensorShape(4U), 1, DataType::F32, 0),
109 TensorInfo(TensorShape(4U), 1, DataType::F32, 0),
110 TensorInfo(TensorShape(4U), 1, DataType::F32, 0),
111 TensorInfo(TensorShape(4U), 1, DataType::F32, 0),
112 TensorInfo(TensorShape(4U), 1, DataType::F32, 0),
113 TensorInfo(TensorShape(3U), 1, DataType::F32, 0),
114 TensorInfo(TensorShape(4U, 2U), 1, DataType::F32, 0),
115 TensorInfo(TensorShape(4U), 1, DataType::F32, 0),
116 TensorInfo(TensorShape(4U), 1, DataType::F32, 0),
117 TensorInfo(TensorShape(4U), 1, DataType::F32, 0),
118 })),
119 framework::dataset::make("OutputInfo",{ TensorInfo(TensorShape(25U, 11U, 4U), 1, DataType::F32, 0),
120 TensorInfo(TensorShape(25U, 11U, 4U), 1, DataType::F32, 0),
121 TensorInfo(TensorShape(25U, 11U, 4U), 1, DataType::F32, 0),
122 TensorInfo(TensorShape(25U, 11U, 4U), 1, DataType::F32, 0),
123 TensorInfo(TensorShape(25U, 11U, 4U), 1, DataType::F32, 0),
124 TensorInfo(TensorShape(25U, 11U, 4U), 1, DataType::F32, 0),
125 TensorInfo(TensorShape(25U, 11U, 4U), 1, DataType::F32, 0),
126 TensorInfo(TensorShape(25U, 11U, 4U), 1, DataType::F32, 0),
127 TensorInfo(TensorShape(26U, 11U, 4U), 1, DataType::F32, 0),
128 TensorInfo(TensorShape(25U, 11U, 4U), 1, DataType::F32, 0),
129 TensorInfo(TensorShape(32U, 16U, 4U), 1, DataType::F32, 0),
130 })),
131 framework::dataset::make("ConvInfo", { PadStrideInfo(1, 1, 0, 0),
132 PadStrideInfo(1, 1, 0, 0),
133 PadStrideInfo(1, 1, 0, 0),
134 PadStrideInfo(1, 1, 0, 0),
135 PadStrideInfo(1, 1, 0, 0),
136 PadStrideInfo(3, 3, 0, 0),
137 PadStrideInfo(1, 1, 0, 0),
138 PadStrideInfo(1, 1, 0, 0),
139 PadStrideInfo(1, 1, 0, 0),
140 PadStrideInfo(1, 1, 0, 0),
141 PadStrideInfo(1, 1, 0, 0),
142 })),
143 framework::dataset::make("Expected", { false, false, false, false, false, false, false, false, false, false, true })),
144 input_info, weights_info, biases_info, output_info, conv_info, expected)
145{
146 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));
147 ARM_COMPUTE_EXPECT(is_valid == expected, framework::LogLevel::ERRORS);
148}
149// clang-format on
150// *INDENT-ON*
151
Kaizen8938bd32017-09-28 14:38:23 +0100152template <typename T>
153using CLDirectConvolutionLayerFixture = DirectConvolutionValidationFixture<CLTensor, CLAccessor, CLDirectConvolutionLayer, T>;
Anthony Barbier8140e1e2017-12-14 23:48:46 +0000154template <typename T>
155using CLDirectConvolutionValidationWithTensorShapesFixture = DirectConvolutionValidationWithTensorShapesFixture<CLTensor, CLAccessor, CLDirectConvolutionLayer, T>;
Kaizen8938bd32017-09-28 14:38:23 +0100156
157TEST_SUITE(Float)
158TEST_SUITE(FP16)
159FIXTURE_DATA_TEST_CASE(Run, CLDirectConvolutionLayerFixture<half>, framework::DatasetMode::ALL, combine(data, framework::dataset::make("DataType", DataType::F16)))
160{
161 // Validate output
162 validate(CLAccessor(_target), _reference, tolerance_fp16, tolerance_num);
163}
164TEST_SUITE_END()
165
166TEST_SUITE(FP32)
167FIXTURE_DATA_TEST_CASE(Run, CLDirectConvolutionLayerFixture<float>, framework::DatasetMode::ALL, combine(data, framework::dataset::make("DataType", DataType::F32)))
168{
169 // Validate output
170 validate(CLAccessor(_target), _reference, tolerance_fp32);
171}
172TEST_SUITE_END()
Anthony Barbier8140e1e2017-12-14 23:48:46 +0000173
174TEST_SUITE(FP32_CustomDataset)
175FIXTURE_DATA_TEST_CASE(Run, CLDirectConvolutionValidationWithTensorShapesFixture<float>, framework::DatasetMode::ALL, combine(datasets::DirectConvolutionLayerDataset(),
176 framework::dataset::make("DataType", DataType::F32)))
177{
178 // Validate output
179 validate(CLAccessor(_target), _reference, tolerance_fp32);
180}
181TEST_SUITE_END()
Kaizen8938bd32017-09-28 14:38:23 +0100182TEST_SUITE_END()
183
184template <typename T>
185using CLDirectConvolutionLayerFixedPointFixture = DirectConvolutionValidationFixedPointFixture<CLTensor, CLAccessor, CLDirectConvolutionLayer, T>;
186
Anthony Barbier8140e1e2017-12-14 23:48:46 +0000187TEST_SUITE(FixedPoint)
Kaizen8938bd32017-09-28 14:38:23 +0100188TEST_SUITE(QS8)
Anthony Barbier8140e1e2017-12-14 23:48:46 +0000189FIXTURE_DATA_TEST_CASE(Run, CLDirectConvolutionLayerFixedPointFixture<int8_t>, framework::DatasetMode::ALL, combine(combine(data_fixed_point, framework::dataset::make("DataType", DataType::QS8)),
Kaizen8938bd32017-09-28 14:38:23 +0100190 framework::dataset::make("FractionalBits", 2, 7)))
191{
192 // Validate output
193 validate(CLAccessor(_target), _reference, tolerance_qs8);
194}
195TEST_SUITE_END()
196
197TEST_SUITE(QS16)
Anthony Barbier8140e1e2017-12-14 23:48:46 +0000198FIXTURE_DATA_TEST_CASE(Run, CLDirectConvolutionLayerFixedPointFixture<int16_t>, framework::DatasetMode::ALL, combine(combine(data_fixed_point, framework::dataset::make("DataType", DataType::QS16)),
Kaizen8938bd32017-09-28 14:38:23 +0100199 framework::dataset::make("FractionalBits", 2, 15)))
200{
201 // Validate output
202 validate(CLAccessor(_target), _reference, tolerance_qs16);
203}
204TEST_SUITE_END()
205TEST_SUITE_END()
206
Anthony Barbier8140e1e2017-12-14 23:48:46 +0000207template <typename T>
208using CLDirectConvolutionLayerQuantizedFixture = DirectConvolutionValidationQuantizedFixture<CLTensor, CLAccessor, CLDirectConvolutionLayer, T>;
209template <typename T>
210using CLDirectConvolutionValidationWithTensorShapesQuantizedFixture = DirectConvolutionValidationWithTensorShapesQuantizedFixture<CLTensor, CLAccessor, CLDirectConvolutionLayer, T>;
211
212TEST_SUITE(Quantized)
213TEST_SUITE(QASYMM8)
214FIXTURE_DATA_TEST_CASE(Run, CLDirectConvolutionLayerQuantizedFixture<uint8_t>, framework::DatasetMode::ALL, combine(combine(data, framework::dataset::make("DataType", DataType::QASYMM8)),
215 framework::dataset::make("QuantizationInfo", { QuantizationInfo(2.f / 255, 10) })))
216{
217 // Validate output
218 validate(CLAccessor(_target), _reference, tolerance_qasymm8);
219}
220TEST_SUITE_END()
221
222TEST_SUITE(QASYMM8_CustomDataset)
223FIXTURE_DATA_TEST_CASE(Run, CLDirectConvolutionValidationWithTensorShapesQuantizedFixture<uint8_t>, framework::DatasetMode::ALL, combine(combine(datasets::DirectConvolutionLayerDataset(),
224 framework::dataset::make("DataType", DataType::QASYMM8)),
225 framework::dataset::make("QuantizationInfo", { QuantizationInfo(2.f / 255, 127) })))
226{
227 // Validate output
228 validate(CLAccessor(_target), _reference, tolerance_qasymm8);
229}
230TEST_SUITE_END()
231TEST_SUITE_END()
232
Kaizen8938bd32017-09-28 14:38:23 +0100233TEST_SUITE_END()
234TEST_SUITE_END()
235} // namespace validation
236} // namespace test
237} // namespace arm_compute