blob: a796b6e4daf92de5c60f5edc08426c0b1f09c879 [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<uint8_t> tolerance_qasymm8(1); /**< Tolerance for quantized tests */
Michalis Spyroudef665a2017-08-14 11:26:37 +010052
Moritz Pflanzerb3d25792017-07-26 11:49:37 +010053/** Direct convolution data set. */
54const auto data = combine(datasets::SmallDirectConvolutionShapes(),
55 combine(framework::dataset::make("StrideX", 1, 3),
56 combine(framework::dataset::make("StrideY", 1, 3),
Georgios Pinitas15997872018-02-19 13:58:22 +000057 combine(concat(combine(framework::dataset::make("PadX", 0, 1),
58 combine(framework::dataset::make("PadY", 0, 1),
Moritz Pflanzerb3d25792017-07-26 11:49:37 +010059 framework::dataset::make("KernelSize", 1))),
60 combine(framework::dataset::make("PadX", 0, 2),
61 combine(framework::dataset::make("PadY", 0, 2),
steniu01db006682017-08-09 16:26:22 +010062 framework::dataset::make("KernelSize", { 3, 5 })))),
Moritz Pflanzerb3d25792017-07-26 11:49:37 +010063 framework::dataset::make("NumKernels", { 1, 4, 8, 16 })))));
Anthony Barbier1c0d0ff2018-01-31 13:05:09 +000064const auto data_fixed_point = combine(datasets::TinyDirectConvolutionShapes(),
Chunosovd621bca2017-11-03 17:33:15 +070065 combine(framework::dataset::make("StrideX", 1, 3),
66 combine(framework::dataset::make("StrideY", 1, 3),
67 combine(concat(combine(framework::dataset::make("PadX", 0),
68 combine(framework::dataset::make("PadY", 0),
69 framework::dataset::make("KernelSize", 1))),
70 combine(framework::dataset::make("PadX", 0, 2),
71 combine(framework::dataset::make("PadY", 0, 2),
72 framework::dataset::make("KernelSize", { 3 })))),
73 framework::dataset::make("NumKernels", { 1, 4, 8, 16 })))));
Isabella Gottardi3f217ec2018-02-12 14:59:19 +000074/** Activation function Dataset*/
75const auto ActivationFunctionsDataset = framework::dataset::make("ActivationInfo",
76{
77 ActivationLayerInfo(),
78 ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU),
79 ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::BOUNDED_RELU, 0.5f),
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(DirectConvolutionLayer)
86
87//TODO(COMPMID-415): Configuration tests?
88
Georgios Pinitas30902ed2017-11-14 15:32:57 +000089// *INDENT-OFF*
90// clang-format off
Isabella Gottardi3f217ec2018-02-12 14:59:19 +000091DATA_TEST_CASE(Validate, framework::DatasetMode::ALL, zip(zip(zip(zip(zip(zip(
Georgios Pinitas30902ed2017-11-14 15:32:57 +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
Giorgio Arena59486342017-12-01 10:42:47 +0000101 TensorInfo(TensorShape(27U, 13U, 2U), 1, DataType::F32, 0), // Window shrink
102 TensorInfo(TensorShape(32U, 16U, 2U), 1, DataType::F32, 0),
Georgios Pinitas30902ed2017-11-14 15:32:57 +0000103 }),
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),
Giorgio Arena59486342017-12-01 10:42:47 +0000114 TensorInfo(TensorShape(1U, 1U, 2U, 4U), 1, DataType::F32, 0),
Georgios Pinitas30902ed2017-11-14 15:32:57 +0000115 })),
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),
Giorgio Arena59486342017-12-01 10:42:47 +0000126 TensorInfo(TensorShape(4U), 1, DataType::F32, 0),
Georgios Pinitas30902ed2017-11-14 15:32:57 +0000127 })),
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),
Giorgio Arena59486342017-12-01 10:42:47 +0000138 TensorInfo(TensorShape(32U, 16U, 4U), 1, DataType::F32, 0),
Georgios Pinitas30902ed2017-11-14 15:32:57 +0000139 })),
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),
Giorgio Arena59486342017-12-01 10:42:47 +0000150 PadStrideInfo(1, 1, 0, 0),
Georgios Pinitas30902ed2017-11-14 15:32:57 +0000151 })),
Isabella Gottardi3f217ec2018-02-12 14:59:19 +0000152 framework::dataset::make("ActivationInfo",
Georgios Pinitas30902ed2017-11-14 15:32:57 +0000153{
Isabella Gottardi3f217ec2018-02-12 14:59:19 +0000154 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));
Georgios Pinitas631c41a2017-12-06 11:53:03 +0000160 ARM_COMPUTE_EXPECT(is_valid == expected, framework::LogLevel::ERRORS);
Georgios Pinitas30902ed2017-11-14 15:32:57 +0000161}
162// clang-format on
163// *INDENT-ON*
164
Moritz Pflanzerb3d25792017-07-26 11:49:37 +0100165template <typename T>
166using CLDirectConvolutionLayerFixture = DirectConvolutionValidationFixture<CLTensor, CLAccessor, CLDirectConvolutionLayer, T>;
Jaroslaw Rzepecki2ecbada2017-11-29 13:51:34 +0000167template <typename T>
168using CLDirectConvolutionValidationWithTensorShapesFixture = DirectConvolutionValidationWithTensorShapesFixture<CLTensor, CLAccessor, CLDirectConvolutionLayer, T>;
Moritz Pflanzerb3d25792017-07-26 11:49:37 +0100169
170TEST_SUITE(Float)
171TEST_SUITE(FP16)
Giorgio Arenac0f54432018-03-16 14:02:34 +0000172FIXTURE_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)))
Moritz Pflanzerb3d25792017-07-26 11:49:37 +0100175{
176 // Validate output
steniu013e05e4e2017-08-25 17:18:01 +0100177 validate(CLAccessor(_target), _reference, tolerance_fp16, tolerance_num);
Moritz Pflanzerb3d25792017-07-26 11:49:37 +0100178}
179TEST_SUITE_END()
180
181TEST_SUITE(FP32)
Giorgio Arenac0f54432018-03-16 14:02:34 +0000182FIXTURE_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)))
Moritz Pflanzerb3d25792017-07-26 11:49:37 +0100185{
186 // Validate output
187 validate(CLAccessor(_target), _reference, tolerance_fp32);
188}
189TEST_SUITE_END()
Jaroslaw Rzepecki2ecbada2017-11-29 13:51:34 +0000190
191TEST_SUITE(FP32_CustomDataset)
Isabella Gottardi3f217ec2018-02-12 14:59:19 +0000192FIXTURE_DATA_TEST_CASE(Run, CLDirectConvolutionValidationWithTensorShapesFixture<float>, framework::DatasetMode::ALL, combine(combine(datasets::DirectConvolutionLayerDataset(),
193 framework::dataset::make("DataType", DataType::F32)),
194 ActivationFunctionsDataset))
Jaroslaw Rzepecki2ecbada2017-11-29 13:51:34 +0000195{
196 // Validate output
197 validate(CLAccessor(_target), _reference, tolerance_fp32);
198}
199TEST_SUITE_END()
Moritz Pflanzerb3d25792017-07-26 11:49:37 +0100200TEST_SUITE_END()
201
Michalis Spyroudef665a2017-08-14 11:26:37 +0100202template <typename T>
Chunosovd621bca2017-11-03 17:33:15 +0700203using CLDirectConvolutionLayerQuantizedFixture = DirectConvolutionValidationQuantizedFixture<CLTensor, CLAccessor, CLDirectConvolutionLayer, T>;
Jaroslaw Rzepecki2ecbada2017-11-29 13:51:34 +0000204template <typename T>
205using CLDirectConvolutionValidationWithTensorShapesQuantizedFixture = DirectConvolutionValidationWithTensorShapesQuantizedFixture<CLTensor, CLAccessor, CLDirectConvolutionLayer, T>;
Chunosovd621bca2017-11-03 17:33:15 +0700206
Isabella Gottardi3f217ec2018-02-12 14:59:19 +0000207const auto QuantizedActivationFunctionsDataset = framework::dataset::make("ActivationInfo",
208{
209 ActivationLayerInfo(),
210 ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU),
211 ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::LU_BOUNDED_RELU, 6.f)
212});
Chunosovd621bca2017-11-03 17:33:15 +0700213TEST_SUITE(Quantized)
214TEST_SUITE(QASYMM8)
Isabella Gottardi3f217ec2018-02-12 14:59:19 +0000215FIXTURE_DATA_TEST_CASE(Run, CLDirectConvolutionLayerQuantizedFixture<uint8_t>, framework::DatasetMode::ALL, combine(combine(combine(data, framework::dataset::make("DataType", DataType::QASYMM8)),
216 framework::dataset::make("QuantizationInfo", { QuantizationInfo(2.f / 255, 10) })),
217 QuantizedActivationFunctionsDataset))
Chunosovd621bca2017-11-03 17:33:15 +0700218{
219 // Validate output
220 validate(CLAccessor(_target), _reference, tolerance_qasymm8);
221}
222TEST_SUITE_END()
Jaroslaw Rzepecki2ecbada2017-11-29 13:51:34 +0000223
224TEST_SUITE(QASYMM8_CustomDataset)
Isabella Gottardi3f217ec2018-02-12 14:59:19 +0000225FIXTURE_DATA_TEST_CASE(Run, CLDirectConvolutionValidationWithTensorShapesQuantizedFixture<uint8_t>, framework::DatasetMode::ALL, combine(combine(combine(datasets::DirectConvolutionLayerDataset(),
Jaroslaw Rzepecki2ecbada2017-11-29 13:51:34 +0000226 framework::dataset::make("DataType", DataType::QASYMM8)),
Isabella Gottardi3f217ec2018-02-12 14:59:19 +0000227 framework::dataset::make("QuantizationInfo", { QuantizationInfo(2.f / 255, 127) })),
228 QuantizedActivationFunctionsDataset))
Jaroslaw Rzepecki2ecbada2017-11-29 13:51:34 +0000229{
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