blob: 4af825e526bdcfced8c6f760c7e3aa785bb189a8 [file] [log] [blame]
Moritz Pflanzerb3d25792017-07-26 11:49:37 +01001/*
Anthony Barbier1c0d0ff2018-01-31 13:05:09 +00002 * Copyright (c) 2017-2018 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{
steniu013e05e4e2017-08-25 17:18:01 +010046// COMPMID-517 Invesitgate the mismatch to see whether it is a real bug
Georgios Pinitas583137c2017-08-31 18:12:42 +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 */
Moritz Pflanzerb3d25792017-07-26 11:49:37 +010050
Chunosovd621bca2017-11-03 17:33:15 +070051constexpr 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 */
Michalis Spyroudef665a2017-08-14 11:26:37 +010054
Moritz Pflanzerb3d25792017-07-26 11:49:37 +010055/** Direct convolution data set. */
56const auto data = combine(datasets::SmallDirectConvolutionShapes(),
57 combine(framework::dataset::make("StrideX", 1, 3),
58 combine(framework::dataset::make("StrideY", 1, 3),
59 combine(concat(combine(framework::dataset::make("PadX", 0),
60 combine(framework::dataset::make("PadY", 0),
61 framework::dataset::make("KernelSize", 1))),
62 combine(framework::dataset::make("PadX", 0, 2),
63 combine(framework::dataset::make("PadY", 0, 2),
steniu01db006682017-08-09 16:26:22 +010064 framework::dataset::make("KernelSize", { 3, 5 })))),
Moritz Pflanzerb3d25792017-07-26 11:49:37 +010065 framework::dataset::make("NumKernels", { 1, 4, 8, 16 })))));
Anthony Barbier1c0d0ff2018-01-31 13:05:09 +000066const auto data_fixed_point = combine(datasets::TinyDirectConvolutionShapes(),
Chunosovd621bca2017-11-03 17:33:15 +070067 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 })))));
Moritz Pflanzerb3d25792017-07-26 11:49:37 +010076} // namespace
77
78TEST_SUITE(CL)
79TEST_SUITE(DirectConvolutionLayer)
80
81//TODO(COMPMID-415): Configuration tests?
82
Georgios Pinitas30902ed2017-11-14 15:32:57 +000083// *INDENT-OFF*
84// clang-format off
85DATA_TEST_CASE(Validate, framework::DatasetMode::ALL, zip(zip(zip(zip(zip(
86 framework::dataset::make("InputInfo", { TensorInfo(TensorShape(27U, 13U, 2U), 1, DataType::F32, 0), // Mismatching data type input/weights
87 TensorInfo(TensorShape(27U, 13U, 2U), 1, DataType::F32, 0), // Mismatching input feature maps
88 TensorInfo(TensorShape(27U, 13U, 2U), 1, DataType::F32, 0), // Unsupported kernel width
89 TensorInfo(TensorShape(27U, 13U, 2U), 1, DataType::F32, 0), // Non-rectangular weights dimensions
90 TensorInfo(TensorShape(27U, 13U, 2U), 1, DataType::F32, 0), // Invalid weights dimensions
91 TensorInfo(TensorShape(27U, 13U, 2U), 1, DataType::F32, 0), // Invalid stride
92 TensorInfo(TensorShape(27U, 13U, 2U), 1, DataType::F32, 0), // Invalid biases size
93 TensorInfo(TensorShape(27U, 13U, 2U), 1, DataType::F32, 0), // Invalid biases dimensions
94 TensorInfo(TensorShape(27U, 13U, 2U), 1, DataType::F32, 0), // Invalid output size
Giorgio Arena59486342017-12-01 10:42:47 +000095 TensorInfo(TensorShape(27U, 13U, 2U), 1, DataType::F32, 0), // Window shrink
96 TensorInfo(TensorShape(32U, 16U, 2U), 1, DataType::F32, 0),
Georgios Pinitas30902ed2017-11-14 15:32:57 +000097 }),
98 framework::dataset::make("WeightsInfo",{ TensorInfo(TensorShape(3U, 3U, 2U, 4U), 1, DataType::F16, 0),
99 TensorInfo(TensorShape(3U, 3U, 3U, 4U), 1, DataType::F32, 0),
100 TensorInfo(TensorShape(9U, 9U, 2U, 4U), 1, DataType::F32, 0),
101 TensorInfo(TensorShape(5U, 3U, 2U, 4U), 1, DataType::F32, 0),
102 TensorInfo(TensorShape(3U, 3U, 2U, 4U, 3U), 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(3U, 3U, 2U, 4U), 1, DataType::F32, 0),
106 TensorInfo(TensorShape(3U, 3U, 2U, 4U), 1, DataType::F32, 0),
107 TensorInfo(TensorShape(3U, 3U, 2U, 4U), 1, DataType::F32, 0),
Giorgio Arena59486342017-12-01 10:42:47 +0000108 TensorInfo(TensorShape(1U, 1U, 2U, 4U), 1, DataType::F32, 0),
Georgios Pinitas30902ed2017-11-14 15:32:57 +0000109 })),
110 framework::dataset::make("BiasesInfo",{ 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(4U), 1, DataType::F32, 0),
114 TensorInfo(TensorShape(4U), 1, DataType::F32, 0),
115 TensorInfo(TensorShape(4U), 1, DataType::F32, 0),
116 TensorInfo(TensorShape(3U), 1, DataType::F32, 0),
117 TensorInfo(TensorShape(4U, 2U), 1, DataType::F32, 0),
118 TensorInfo(TensorShape(4U), 1, DataType::F32, 0),
119 TensorInfo(TensorShape(4U), 1, DataType::F32, 0),
Giorgio Arena59486342017-12-01 10:42:47 +0000120 TensorInfo(TensorShape(4U), 1, DataType::F32, 0),
Georgios Pinitas30902ed2017-11-14 15:32:57 +0000121 })),
122 framework::dataset::make("OutputInfo",{ 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(25U, 11U, 4U), 1, DataType::F32, 0),
128 TensorInfo(TensorShape(25U, 11U, 4U), 1, DataType::F32, 0),
129 TensorInfo(TensorShape(25U, 11U, 4U), 1, DataType::F32, 0),
130 TensorInfo(TensorShape(26U, 11U, 4U), 1, DataType::F32, 0),
131 TensorInfo(TensorShape(25U, 11U, 4U), 1, DataType::F32, 0),
Giorgio Arena59486342017-12-01 10:42:47 +0000132 TensorInfo(TensorShape(32U, 16U, 4U), 1, DataType::F32, 0),
Georgios Pinitas30902ed2017-11-14 15:32:57 +0000133 })),
134 framework::dataset::make("ConvInfo", { PadStrideInfo(1, 1, 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),
139 PadStrideInfo(3, 3, 0, 0),
140 PadStrideInfo(1, 1, 0, 0),
141 PadStrideInfo(1, 1, 0, 0),
142 PadStrideInfo(1, 1, 0, 0),
143 PadStrideInfo(1, 1, 0, 0),
Giorgio Arena59486342017-12-01 10:42:47 +0000144 PadStrideInfo(1, 1, 0, 0),
Georgios Pinitas30902ed2017-11-14 15:32:57 +0000145 })),
Georgios Pinitas631c41a2017-12-06 11:53:03 +0000146 framework::dataset::make("Expected", { false, false, false, false, false, false, false, false, false, false, true })),
Georgios Pinitas30902ed2017-11-14 15:32:57 +0000147 input_info, weights_info, biases_info, output_info, conv_info, expected)
148{
Georgios Pinitas631c41a2017-12-06 11:53:03 +0000149 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));
150 ARM_COMPUTE_EXPECT(is_valid == expected, framework::LogLevel::ERRORS);
Georgios Pinitas30902ed2017-11-14 15:32:57 +0000151}
152// clang-format on
153// *INDENT-ON*
154
Moritz Pflanzerb3d25792017-07-26 11:49:37 +0100155template <typename T>
156using CLDirectConvolutionLayerFixture = DirectConvolutionValidationFixture<CLTensor, CLAccessor, CLDirectConvolutionLayer, T>;
Jaroslaw Rzepecki2ecbada2017-11-29 13:51:34 +0000157template <typename T>
158using CLDirectConvolutionValidationWithTensorShapesFixture = DirectConvolutionValidationWithTensorShapesFixture<CLTensor, CLAccessor, CLDirectConvolutionLayer, T>;
Moritz Pflanzerb3d25792017-07-26 11:49:37 +0100159
160TEST_SUITE(Float)
161TEST_SUITE(FP16)
Georgios Pinitas583137c2017-08-31 18:12:42 +0100162FIXTURE_DATA_TEST_CASE(Run, CLDirectConvolutionLayerFixture<half>, framework::DatasetMode::ALL, combine(data, framework::dataset::make("DataType", DataType::F16)))
Moritz Pflanzerb3d25792017-07-26 11:49:37 +0100163{
164 // Validate output
steniu013e05e4e2017-08-25 17:18:01 +0100165 validate(CLAccessor(_target), _reference, tolerance_fp16, tolerance_num);
Moritz Pflanzerb3d25792017-07-26 11:49:37 +0100166}
167TEST_SUITE_END()
168
169TEST_SUITE(FP32)
170FIXTURE_DATA_TEST_CASE(Run, CLDirectConvolutionLayerFixture<float>, framework::DatasetMode::ALL, combine(data, framework::dataset::make("DataType", DataType::F32)))
171{
172 // Validate output
173 validate(CLAccessor(_target), _reference, tolerance_fp32);
174}
175TEST_SUITE_END()
Jaroslaw Rzepecki2ecbada2017-11-29 13:51:34 +0000176
177TEST_SUITE(FP32_CustomDataset)
178FIXTURE_DATA_TEST_CASE(Run, CLDirectConvolutionValidationWithTensorShapesFixture<float>, framework::DatasetMode::ALL, combine(datasets::DirectConvolutionLayerDataset(),
179 framework::dataset::make("DataType", DataType::F32)))
180{
181 // Validate output
182 validate(CLAccessor(_target), _reference, tolerance_fp32);
183}
184TEST_SUITE_END()
Moritz Pflanzerb3d25792017-07-26 11:49:37 +0100185TEST_SUITE_END()
186
Michalis Spyroudef665a2017-08-14 11:26:37 +0100187template <typename T>
188using CLDirectConvolutionLayerFixedPointFixture = DirectConvolutionValidationFixedPointFixture<CLTensor, CLAccessor, CLDirectConvolutionLayer, T>;
189
Chunosovd621bca2017-11-03 17:33:15 +0700190TEST_SUITE(FixedPoint)
Michalis Spyroudef665a2017-08-14 11:26:37 +0100191TEST_SUITE(QS8)
Chunosovd621bca2017-11-03 17:33:15 +0700192FIXTURE_DATA_TEST_CASE(Run, CLDirectConvolutionLayerFixedPointFixture<int8_t>, framework::DatasetMode::ALL, combine(combine(data_fixed_point, framework::dataset::make("DataType", DataType::QS8)),
Michalis Spyroudef665a2017-08-14 11:26:37 +0100193 framework::dataset::make("FractionalBits", 2, 7)))
194{
195 // Validate output
196 validate(CLAccessor(_target), _reference, tolerance_qs8);
197}
198TEST_SUITE_END()
199
200TEST_SUITE(QS16)
Chunosovd621bca2017-11-03 17:33:15 +0700201FIXTURE_DATA_TEST_CASE(Run, CLDirectConvolutionLayerFixedPointFixture<int16_t>, framework::DatasetMode::ALL, combine(combine(data_fixed_point, framework::dataset::make("DataType", DataType::QS16)),
Michalis Spyroudef665a2017-08-14 11:26:37 +0100202 framework::dataset::make("FractionalBits", 2, 15)))
203{
204 // Validate output
205 validate(CLAccessor(_target), _reference, tolerance_qs16);
206}
207TEST_SUITE_END()
208TEST_SUITE_END()
209
Chunosovd621bca2017-11-03 17:33:15 +0700210template <typename T>
211using CLDirectConvolutionLayerQuantizedFixture = DirectConvolutionValidationQuantizedFixture<CLTensor, CLAccessor, CLDirectConvolutionLayer, T>;
Jaroslaw Rzepecki2ecbada2017-11-29 13:51:34 +0000212template <typename T>
213using CLDirectConvolutionValidationWithTensorShapesQuantizedFixture = DirectConvolutionValidationWithTensorShapesQuantizedFixture<CLTensor, CLAccessor, CLDirectConvolutionLayer, T>;
Chunosovd621bca2017-11-03 17:33:15 +0700214
215TEST_SUITE(Quantized)
216TEST_SUITE(QASYMM8)
217FIXTURE_DATA_TEST_CASE(Run, CLDirectConvolutionLayerQuantizedFixture<uint8_t>, framework::DatasetMode::ALL, combine(combine(data, framework::dataset::make("DataType", DataType::QASYMM8)),
Georgios Pinitas6fdfaa82017-11-29 14:27:24 +0000218 framework::dataset::make("QuantizationInfo", { QuantizationInfo(2.f / 255, 10) })))
Chunosovd621bca2017-11-03 17:33:15 +0700219{
220 // Validate output
221 validate(CLAccessor(_target), _reference, tolerance_qasymm8);
222}
223TEST_SUITE_END()
Jaroslaw Rzepecki2ecbada2017-11-29 13:51:34 +0000224
225TEST_SUITE(QASYMM8_CustomDataset)
226FIXTURE_DATA_TEST_CASE(Run, CLDirectConvolutionValidationWithTensorShapesQuantizedFixture<uint8_t>, framework::DatasetMode::ALL, combine(combine(datasets::DirectConvolutionLayerDataset(),
227 framework::dataset::make("DataType", DataType::QASYMM8)),
228 framework::dataset::make("QuantizationInfo", { QuantizationInfo(2.f / 255, 127) })))
229{
230 // Validate output
231 validate(CLAccessor(_target), _reference, tolerance_qasymm8);
232}
233TEST_SUITE_END()
Chunosovd621bca2017-11-03 17:33:15 +0700234TEST_SUITE_END()
235
Moritz Pflanzerb3d25792017-07-26 11:49:37 +0100236TEST_SUITE_END()
237TEST_SUITE_END()
238} // namespace validation
239} // namespace test
Anthony Barbier1c0d0ff2018-01-31 13:05:09 +0000240} // namespace arm_compute