blob: fe7bba365a76b8cad6279d1d2360582c8bbb9c8e [file] [log] [blame]
Michalis Spyrou7362f0d2017-10-18 17:58:22 +01001/*
Georgios Pinitasf72f9362018-01-12 16:29:45 +00002 * Copyright (c) 2017-2018 ARM Limited.
Michalis Spyrou7362f0d2017-10-18 17:58:22 +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 CONCLCTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 * SOFTWARE.
23 */
24#include "arm_compute/core/Types.h"
Giorgio Arena76572242018-04-04 17:44:26 +010025#include "arm_compute/core/utils/misc/ShapeCalculator.h"
Giorgio Arena04a8f8c2017-11-23 11:45:24 +000026#include "arm_compute/runtime/NEON/functions/NEDepthwiseConvolutionLayer.h"
Michalis Spyrou7362f0d2017-10-18 17:58:22 +010027#include "arm_compute/runtime/Tensor.h"
28#include "arm_compute/runtime/TensorAllocator.h"
29#include "tests/NEON/Accessor.h"
30#include "tests/PaddingCalculator.h"
Giorgio Arena04a8f8c2017-11-23 11:45:24 +000031#include "tests/datasets/DepthwiseConvolutionLayerDataset.h"
Michalis Spyrou7362f0d2017-10-18 17:58:22 +010032#include "tests/framework/Asserts.h"
33#include "tests/framework/Macros.h"
34#include "tests/framework/datasets/Datasets.h"
35#include "tests/validation/Validation.h"
Giorgio Arena04a8f8c2017-11-23 11:45:24 +000036#include "tests/validation/fixtures/DepthwiseConvolutionLayerFixture.h"
Michalis Spyrou7362f0d2017-10-18 17:58:22 +010037
38namespace arm_compute
39{
40namespace test
41{
42namespace validation
43{
Giorgio Arena76572242018-04-04 17:44:26 +010044using namespace arm_compute::misc::shape_calculator;
45
Michalis Spyrou7362f0d2017-10-18 17:58:22 +010046namespace
47{
Georgios Pinitasf72f9362018-01-12 16:29:45 +000048constexpr RelativeTolerance<float> tolerance_f32(0.01f); /**< Tolerance value for comparing reference's output against implementation's output for DataType::F32 */
49constexpr AbsoluteTolerance<uint8_t> tolerance_qasymm8(1); /**< Tolerance value for comparing reference's output against implementation's output for DataType::QASYMM8 */
Giorgio Arena76572242018-04-04 17:44:26 +010050
51const auto depth_multipliers = framework::dataset::make("DepthMultiplier", { 1, 2, 3 });
Michalis Spyrou7362f0d2017-10-18 17:58:22 +010052} // namespace
53
54TEST_SUITE(NEON)
Pablo Tello941cd702017-12-12 14:35:00 +000055TEST_SUITE(DepthwiseConvLayer)
Michalis Spyrou7362f0d2017-10-18 17:58:22 +010056
Abe Mbise7784c832018-05-31 16:48:41 +010057// *INDENT-OFF*
58// clang-format off
59DATA_TEST_CASE(Validate3x3, framework::DatasetMode::ALL, zip(zip(zip(zip(zip(zip(
60 framework::dataset::make("InputInfo", { TensorInfo(TensorShape(32U, 18U, 2U), 1, DataType::F32), // Mismatching data type input/weights
61 TensorInfo(TensorShape(32U, 18U, 3U), 1, DataType::F32), // Mismatching input feature maps
62 TensorInfo(TensorShape(32U, 18U, 2U), 1, DataType::F32), // Unsupported weights dimensions
63 TensorInfo(TensorShape(32U, 18U, 2U), 1, DataType::F32), // Mismatching depth multiplier
Giorgio Arena66cbafb2018-08-23 14:51:00 +010064 TensorInfo(TensorShape(32U, 18U, 2U), 1, DataType::QASYMM8), // Invalid stride
Abe Mbise7784c832018-05-31 16:48:41 +010065 TensorInfo(TensorShape(32U, 18U, 2U), 1, DataType::F32), // Invalid biases size
66 TensorInfo(TensorShape(32U, 18U, 2U), 1, DataType::F32), // Invalid biases dimensions
67 TensorInfo(TensorShape(32U, 18U, 2U), 1, DataType::F32), // Invalid output size
Giorgio Arena66cbafb2018-08-23 14:51:00 +010068 TensorInfo(TensorShape(27U, 13U, 2U), 1, DataType::F32),
Abe Mbise7784c832018-05-31 16:48:41 +010069 }),
Giorgio Arena66cbafb2018-08-23 14:51:00 +010070 framework::dataset::make("WeightsInfo", { TensorInfo(TensorShape(3U, 3U, 2U, 2U), 1, DataType::F16),
71 TensorInfo(TensorShape(3U, 3U, 2U, 2U), 1, DataType::F32),
72 TensorInfo(TensorShape(5U, 5U, 2U, 2U), 1, DataType::F32),
73 TensorInfo(TensorShape(3U, 3U, 2U, 2U), 1, DataType::F32),
74 TensorInfo(TensorShape(3U, 3U, 2U, 2U), 1, DataType::QASYMM8),
75 TensorInfo(TensorShape(3U, 3U, 2U, 2U), 1, DataType::F32),
76 TensorInfo(TensorShape(3U, 3U, 2U, 2U), 1, DataType::F32),
77 TensorInfo(TensorShape(3U, 3U, 2U, 2U), 1, DataType::F32),
78 TensorInfo(TensorShape(3U, 3U, 2U, 2U), 1, DataType::F32),
Abe Mbise7784c832018-05-31 16:48:41 +010079 })),
80 framework::dataset::make("BiasesInfo", { TensorInfo(TensorShape(2U), 1, DataType::F32),
81 TensorInfo(TensorShape(2U), 1, DataType::F32),
82 TensorInfo(TensorShape(2U), 1, DataType::F32),
83 TensorInfo(TensorShape(2U), 1, DataType::F32),
Giorgio Arena66cbafb2018-08-23 14:51:00 +010084 TensorInfo(TensorShape(2U), 1, DataType::S32),
Abe Mbise7784c832018-05-31 16:48:41 +010085 TensorInfo(TensorShape(4U), 1, DataType::F32),
86 TensorInfo(TensorShape(2U, 2U), 1, DataType::F32),
87 TensorInfo(TensorShape(2U), 1, DataType::F32),
88 TensorInfo(TensorShape(2U), 1, DataType::F32),
89 })),
90 framework::dataset::make("OutputInfo", { TensorInfo(TensorShape(30U, 16U, 2U), 1, DataType::F32),
91 TensorInfo(TensorShape(30U, 16U, 2U), 1, DataType::F32),
92 TensorInfo(TensorShape(30U, 16U, 2U), 1, DataType::F32),
93 TensorInfo(TensorShape(30U, 16U, 2U), 1, DataType::F32),
Giorgio Arena66cbafb2018-08-23 14:51:00 +010094 TensorInfo(TensorShape(30U, 16U, 2U), 1, DataType::QASYMM8),
Abe Mbise7784c832018-05-31 16:48:41 +010095 TensorInfo(TensorShape(30U, 16U, 2U), 1, DataType::F32),
96 TensorInfo(TensorShape(30U, 16U, 2U), 1, DataType::F32),
97 TensorInfo(TensorShape(32U, 18U, 2U), 1, DataType::F32),
98 TensorInfo(TensorShape(25U, 11U, 2U), 1, DataType::F32),
99 })),
100 framework::dataset::make("ConvInfo", { PadStrideInfo(1, 1, 0, 0),
101 PadStrideInfo(1, 1, 0, 0),
102 PadStrideInfo(1, 1, 0, 0),
103 PadStrideInfo(1, 1, 0, 0),
104 PadStrideInfo(4, 1, 0, 0),
105 PadStrideInfo(1, 1, 0, 0),
106 PadStrideInfo(1, 1, 0, 0),
107 PadStrideInfo(1, 1, 0, 0),
108 PadStrideInfo(1, 1, 0, 0),
109 })),
110 framework::dataset::make("DepthMultiplier", { 1,
111 1,
112 1,
113 3,
114 1,
115 1,
116 1,
117 1,
118 1,
119 })),
Giorgio Arena66cbafb2018-08-23 14:51:00 +0100120 framework::dataset::make("Expected", { false, false, false, false, false, false, false, false, true })),
Abe Mbise7784c832018-05-31 16:48:41 +0100121 input_info, weights_info, biases_info, output_info, conv_info, depth_multiplier, expected)
Michalis Spyrou7362f0d2017-10-18 17:58:22 +0100122{
Abe Mbise7784c832018-05-31 16:48:41 +0100123 bool is_valid = bool(NEDepthwiseConvolutionLayer3x3::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, depth_multiplier));
124 ARM_COMPUTE_EXPECT(is_valid == expected, framework::LogLevel::ERRORS);
Michalis Spyrou7362f0d2017-10-18 17:58:22 +0100125}
126
Abe Mbise7784c832018-05-31 16:48:41 +0100127DATA_TEST_CASE(ValidateGeneric, framework::DatasetMode::ALL, zip(zip(zip(zip(zip(zip(
128 framework::dataset::make("InputInfo", { TensorInfo(TensorShape(27U, 13U, 2U), 1, DataType::F32), // Mismatching data type input/weights
129 TensorInfo(TensorShape(27U, 13U, 3U), 1, DataType::F32), // Mismatching input feature maps
130 TensorInfo(TensorShape(27U, 13U, 2U), 1, DataType::F32), // Mismatching depth multiplier
131 TensorInfo(TensorShape(27U, 13U, 2U), 1, DataType::F32), // Invalid biases size
132 TensorInfo(TensorShape(27U, 13U, 2U), 1, DataType::F32), // Invalid biases dimensions
133 TensorInfo(TensorShape(27U, 13U, 2U), 1, DataType::F32), // Invalid output size
134 TensorInfo(TensorShape(27U, 13U, 8U), 1, DataType::F32),
135 TensorInfo(TensorShape(32U, 13U, 8U), 1, DataType::QASYMM8),
136 }),
137 framework::dataset::make("WeightsInfo", { TensorInfo(TensorShape(3U, 3U, 2U), 1, DataType::F16),
138 TensorInfo(TensorShape(3U, 3U, 2U), 1, DataType::F32),
139 TensorInfo(TensorShape(3U, 3U, 2U), 1, DataType::F32),
140 TensorInfo(TensorShape(3U, 3U, 2U), 1, DataType::F32),
141 TensorInfo(TensorShape(3U, 3U, 2U), 1, DataType::F32),
142 TensorInfo(TensorShape(3U, 3U, 2U), 1, DataType::F32),
143 TensorInfo(TensorShape(3U, 3U, 16U), 1, DataType::F32),
144 TensorInfo(TensorShape(3U, 3U, 24U), 1, DataType::QASYMM8),
145 })),
146 framework::dataset::make("BiasesInfo", { TensorInfo(TensorShape(2U), 1, DataType::F32),
147 TensorInfo(TensorShape(2U), 1, DataType::F32),
148 TensorInfo(TensorShape(2U), 1, DataType::F32),
149 TensorInfo(TensorShape(4U), 1, DataType::F32),
150 TensorInfo(TensorShape(2U, 2U), 1, DataType::F32),
151 TensorInfo(TensorShape(2U), 1, DataType::F32),
152 TensorInfo(TensorShape(16U), 1, DataType::F32),
153 TensorInfo(TensorShape(24U), 1, DataType::S32),
154 })),
155 framework::dataset::make("OutputInfo", { TensorInfo(TensorShape(25U, 11U, 2U), 1, DataType::F32),
156 TensorInfo(TensorShape(25U, 11U, 2U), 1, DataType::F32),
157 TensorInfo(TensorShape(25U, 11U, 2U), 1, DataType::F32),
158 TensorInfo(TensorShape(25U, 11U, 2U), 1, DataType::F32),
159 TensorInfo(TensorShape(25U, 11U, 2U), 1, DataType::F32),
160 TensorInfo(TensorShape(27U, 13U, 2U), 1, DataType::F32),
161 TensorInfo(TensorShape(25U, 11U, 16U), 1, DataType::F32),
162 TensorInfo(TensorShape(32U, 11U, 24U), 1, DataType::QASYMM8),
163 })),
164 framework::dataset::make("ConvInfo", { PadStrideInfo(1, 1, 0, 0),
165 PadStrideInfo(1, 1, 0, 0),
166 PadStrideInfo(1, 1, 0, 0),
167 PadStrideInfo(1, 1, 0, 0),
168 PadStrideInfo(1, 1, 0, 0),
169 PadStrideInfo(1, 1, 0, 0),
170 PadStrideInfo(1, 1, 0, 0),
171 PadStrideInfo(1, 1, 1, 0),
172 })),
173 framework::dataset::make("DepthMultiplier", { 1,
174 1,
175 3,
176 1,
177 1,
178 1,
179 2,
180 3,
181 })),
182 framework::dataset::make("Expected", { false, false, false, false, false, false, true, true })),
183 input_info, weights_info, biases_info, output_info, conv_info, depth_multiplier, expected)
184{
185 bool is_valid = bool(NEDepthwiseConvolutionLayer::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, depth_multiplier));
186 ARM_COMPUTE_EXPECT(is_valid == expected, framework::LogLevel::ERRORS);
187}
188// clang-format on
189// *INDENT-ON*
190
Dmitry Savenkod7295b72017-11-20 22:00:08 +0700191TEST_SUITE(Float)
Michalis Spyrou7362f0d2017-10-18 17:58:22 +0100192TEST_SUITE(F32)
Michalis Spyroub7b31532017-11-23 12:10:21 +0000193TEST_SUITE(Generic)
194template <typename T>
Giorgio Arena04a8f8c2017-11-23 11:45:24 +0000195using NEDepthwiseConvolutionLayerFixture = DepthwiseConvolutionLayerValidationFixture<Tensor, Accessor, NEDepthwiseConvolutionLayer, T>;
Giorgio Arena76572242018-04-04 17:44:26 +0100196FIXTURE_DATA_TEST_CASE(RunSmall, NEDepthwiseConvolutionLayerFixture<float>, framework::DatasetMode::PRECOMMIT, combine(combine(combine(datasets::SmallDepthwiseConvolutionLayerDataset(),
197 depth_multipliers),
Giorgio Arena04a8f8c2017-11-23 11:45:24 +0000198 framework::dataset::make("DataType",
Giorgio Arena1ed1fc62018-03-26 16:20:05 +0100199 DataType::F32)),
Giorgio Arena26b22162018-08-13 15:49:49 +0100200 framework::dataset::make("DataLayout", { DataLayout::NCHW, DataLayout::NHWC })))
Michalis Spyroub7b31532017-11-23 12:10:21 +0000201{
202 validate(Accessor(_target), _reference, tolerance_f32);
203}
Giorgio Arena76572242018-04-04 17:44:26 +0100204FIXTURE_DATA_TEST_CASE(RunLarge, NEDepthwiseConvolutionLayerFixture<float>, framework::DatasetMode::NIGHTLY, combine(combine(combine(datasets::LargeDepthwiseConvolutionLayerDataset(),
205 depth_multipliers),
Giorgio Arena04a8f8c2017-11-23 11:45:24 +0000206 framework::dataset::make("DataType",
Giorgio Arena1ed1fc62018-03-26 16:20:05 +0100207 DataType::F32)),
Giorgio Arena26b22162018-08-13 15:49:49 +0100208 framework::dataset::make("DataLayout", { DataLayout::NCHW, DataLayout::NHWC })))
Michalis Spyroub7b31532017-11-23 12:10:21 +0000209{
210 validate(Accessor(_target), _reference, tolerance_f32);
211}
212TEST_SUITE_END()
213
Michalis Spyrou7362f0d2017-10-18 17:58:22 +0100214TEST_SUITE(W3x3)
Michalis Spyroub7b31532017-11-23 12:10:21 +0000215template <typename T>
Giorgio Arena04a8f8c2017-11-23 11:45:24 +0000216using NEDepthwiseConvolutionLayerFixture3x3 = DepthwiseConvolutionLayerValidationFixture<Tensor, Accessor, NEDepthwiseConvolutionLayer3x3, T>;
Giorgio Arena76572242018-04-04 17:44:26 +0100217FIXTURE_DATA_TEST_CASE(RunSmall, NEDepthwiseConvolutionLayerFixture3x3<float>, framework::DatasetMode::ALL, combine(combine(combine(datasets::SmallDepthwiseConvolutionLayerDataset3x3(),
218 depth_multipliers),
Giorgio Arena04a8f8c2017-11-23 11:45:24 +0000219 framework::dataset::make("DataType",
Giorgio Arena1ed1fc62018-03-26 16:20:05 +0100220 DataType::F32)),
Giorgio Arena26b22162018-08-13 15:49:49 +0100221 framework::dataset::make("DataLayout", { DataLayout::NCHW, DataLayout::NHWC })))
Michalis Spyrou7362f0d2017-10-18 17:58:22 +0100222{
223 validate(Accessor(_target), _reference, tolerance_f32);
224}
Giorgio Arena76572242018-04-04 17:44:26 +0100225FIXTURE_DATA_TEST_CASE(RunLarge, NEDepthwiseConvolutionLayerFixture3x3<float>, framework::DatasetMode::NIGHTLY, combine(combine(combine(datasets::LargeDepthwiseConvolutionLayerDataset3x3(),
226 depth_multipliers),
Giorgio Arena04a8f8c2017-11-23 11:45:24 +0000227 framework::dataset::make("DataType",
Giorgio Arena1ed1fc62018-03-26 16:20:05 +0100228 DataType::F32)),
Giorgio Arena26b22162018-08-13 15:49:49 +0100229 framework::dataset::make("DataLayout", { DataLayout::NCHW, DataLayout::NHWC })))
Michalis Spyrou7362f0d2017-10-18 17:58:22 +0100230{
231 validate(Accessor(_target), _reference, tolerance_f32);
232}
Giorgio Arena76572242018-04-04 17:44:26 +0100233FIXTURE_DATA_TEST_CASE(RunOptimized, NEDepthwiseConvolutionLayerFixture3x3<float>, framework::DatasetMode::ALL, combine(combine(combine(datasets::OptimizedDepthwiseConvolutionLayerDataset3x3(),
234 framework::dataset::make("DepthMultiplier", 1)),
Georgios Pinitas4074c992018-01-30 18:13:46 +0000235 framework::dataset::make("DataType",
Giorgio Arena1ed1fc62018-03-26 16:20:05 +0100236 DataType::F32)),
237 framework::dataset::make("DataLayout", { DataLayout::NCHW, DataLayout::NHWC })))
Georgios Pinitas4074c992018-01-30 18:13:46 +0000238{
239 validate(Accessor(_target), _reference, tolerance_f32);
240}
Michalis Spyrou7362f0d2017-10-18 17:58:22 +0100241TEST_SUITE_END()
242TEST_SUITE_END()
Pablo Tello941cd702017-12-12 14:35:00 +0000243
Dmitry Savenkod7295b72017-11-20 22:00:08 +0700244TEST_SUITE_END()
Michalis Spyrou7362f0d2017-10-18 17:58:22 +0100245
Georgios Pinitasf72f9362018-01-12 16:29:45 +0000246template <typename T>
247using NEDepthwiseConvolutionLayerQuantizedFixture3x3 = DepthwiseConvolutionLayerValidationQuantizedFixture<Tensor, Accessor, NEDepthwiseConvolutionLayer3x3, T>;
Georgios Pinitasd05dce42018-01-22 16:29:17 +0000248template <typename T>
249using NEDepthwiseConvolutionLayerQuantizedFixture = DepthwiseConvolutionLayerValidationQuantizedFixture<Tensor, Accessor, NEDepthwiseConvolutionLayer, T>;
Georgios Pinitasf72f9362018-01-12 16:29:45 +0000250
251TEST_SUITE(Quantized)
252TEST_SUITE(QASYMM8)
Georgios Pinitasd05dce42018-01-22 16:29:17 +0000253TEST_SUITE(Generic)
Giorgio Arena76572242018-04-04 17:44:26 +0100254FIXTURE_DATA_TEST_CASE(RunSmall, NEDepthwiseConvolutionLayerQuantizedFixture<uint8_t>, framework::DatasetMode::PRECOMMIT,
255 combine(combine(combine(combine(datasets::SmallDepthwiseConvolutionLayerDataset(),
256 depth_multipliers),
Giorgio Arenadfca60b2018-01-31 10:30:59 +0000257 framework::dataset::make("DataType", DataType::QASYMM8)),
258 framework::dataset::make("QuantizationInfo", { QuantizationInfo(0.5f, 10) })),
Giorgio Arena26b22162018-08-13 15:49:49 +0100259 framework::dataset::make("DataLayout", { DataLayout::NCHW, DataLayout::NHWC })))
Georgios Pinitasf72f9362018-01-12 16:29:45 +0000260{
261 validate(Accessor(_target), _reference, tolerance_qasymm8);
262}
Giorgio Arena76572242018-04-04 17:44:26 +0100263TEST_SUITE_END()
264TEST_SUITE(W3x3)
265FIXTURE_DATA_TEST_CASE(RunSmall, NEDepthwiseConvolutionLayerQuantizedFixture3x3<uint8_t>, framework::DatasetMode::PRECOMMIT,
266 combine(combine(combine(combine(datasets::SmallDepthwiseConvolutionLayerDataset3x3(), depth_multipliers),
267 framework::dataset::make("DataType", DataType::QASYMM8)),
268 framework::dataset::make("QuantizationInfo", { QuantizationInfo(0.5f, 10) })),
Giorgio Arena26b22162018-08-13 15:49:49 +0100269 framework::dataset::make("DataLayout", { DataLayout::NCHW, DataLayout::NHWC })))
Giorgio Arena76572242018-04-04 17:44:26 +0100270{
271 validate(Accessor(_target), _reference, tolerance_qasymm8);
272}
273FIXTURE_DATA_TEST_CASE(RunLarge, NEDepthwiseConvolutionLayerQuantizedFixture3x3<uint8_t>, framework::DatasetMode::NIGHTLY,
274 combine(combine(combine(combine(datasets::LargeDepthwiseConvolutionLayerDataset3x3(),
275 depth_multipliers),
276 framework::dataset::make("DataType", DataType::QASYMM8)),
277 framework::dataset::make("QuantizationInfo", { QuantizationInfo(0.5f, 10) })),
Giorgio Arena26b22162018-08-13 15:49:49 +0100278 framework::dataset::make("DataLayout", { DataLayout::NCHW, DataLayout::NHWC })))
Georgios Pinitasf72f9362018-01-12 16:29:45 +0000279{
280 validate(Accessor(_target), _reference, tolerance_qasymm8);
281}
282TEST_SUITE_END()
283TEST_SUITE_END()
284TEST_SUITE_END()
285
Michalis Spyrou7362f0d2017-10-18 17:58:22 +0100286TEST_SUITE_END()
287TEST_SUITE_END()
288} // namespace validation
289} // namespace test
290} // namespace arm_compute