blob: 5545b7f574fd9d6ebcc50a420046f80f04db662a [file] [log] [blame]
Sanghoon Leec8a85ba2017-11-29 11:23:14 +00001/*
Sanghoon Leec8d23162018-01-12 16:19:10 +00002 * Copyright (c) 2017-2018 ARM Limited.
Sanghoon Leec8a85ba2017-11-29 11:23:14 +00003 *
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/NEON/functions/NEConvolution.h"
26#include "arm_compute/runtime/Tensor.h"
27#include "arm_compute/runtime/TensorAllocator.h"
28#include "tests/NEON/Accessor.h"
29#include "tests/PaddingCalculator.h"
30#include "tests/datasets/BorderModeDataset.h"
31#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/ConvolutionFixture.h"
37
38namespace arm_compute
39{
40namespace test
41{
42namespace validation
43{
44namespace
45{
Georgios Pinitasacacc322017-12-13 12:48:44 +000046/** Tolerance value for comparing reference's output against implementation
47 *
48 * This is due to the fact that NEON target performs multiplication with reciprocal of scale,
49 * while reference performs direct division with scale.
50 */
51constexpr AbsoluteTolerance<uint8_t> tolerance_u8(1);
Sanghoon Leec8d23162018-01-12 16:19:10 +000052constexpr AbsoluteTolerance<int16_t> tolerance_s16(1);
Sanghoon Leec8a85ba2017-11-29 11:23:14 +000053} // namespace
54
55TEST_SUITE(NEON)
56TEST_SUITE(CustomConvolution)
Sanghoon Leec0079e92018-01-29 17:28:49 +000057TEST_SUITE(Square3x3)
Sanghoon Leec8a85ba2017-11-29 11:23:14 +000058
Sanghoon Leec8d23162018-01-12 16:19:10 +000059DATA_TEST_CASE(Configuration, framework::DatasetMode::ALL, combine(combine(combine(concat(datasets::SmallShapes(), datasets::LargeShapes()), framework::dataset::make("DataType", { DataType::U8, DataType::S16 })),
Sanghoon Leed7ba5392017-12-13 11:28:50 +000060 datasets::BorderModes()),
61 framework::dataset::make("filter_size", { 3 })),
Sanghoon Leec8d23162018-01-12 16:19:10 +000062 shape, output_data_type, border_mode, filter_size)
Sanghoon Leec8a85ba2017-11-29 11:23:14 +000063{
64 // Create tensors
Sanghoon Leec8d23162018-01-12 16:19:10 +000065 Tensor src = create_tensor<Tensor>(shape, DataType::U8);
66 Tensor dst = create_tensor<Tensor>(shape, output_data_type);
Sanghoon Leec8a85ba2017-11-29 11:23:14 +000067
68 // Create conv matrix
Michalis Spyrou5ae9b692018-02-05 14:59:54 +000069 int16_t conv[9] = {};
Sanghoon Leec8a85ba2017-11-29 11:23:14 +000070
71 ARM_COMPUTE_EXPECT(src.info()->is_resizable(), framework::LogLevel::ERRORS);
72 ARM_COMPUTE_EXPECT(dst.info()->is_resizable(), framework::LogLevel::ERRORS);
73
74 // Create and configure function
75 NEConvolution3x3 convolution;
Sanghoon Leed7ba5392017-12-13 11:28:50 +000076 convolution.configure(&src, &dst, conv, 0, border_mode);
Sanghoon Leec8a85ba2017-11-29 11:23:14 +000077
78 // Validate valid region
Sanghoon Leed7ba5392017-12-13 11:28:50 +000079 const ValidRegion dst_valid_region = shape_to_valid_region(shape, (border_mode == BorderMode::UNDEFINED), BorderSize(filter_size / 2));
Sanghoon Leec8a85ba2017-11-29 11:23:14 +000080 validate(dst.info()->valid_region(), dst_valid_region);
81
82 // Validate padding
83 PaddingCalculator calculator(shape.x(), 8);
84 calculator.set_border_size(1);
85 calculator.set_border_mode(border_mode);
86
87 const PaddingSize dst_padding = calculator.required_padding();
88
89 calculator.set_accessed_elements(16);
90 calculator.set_access_offset(-1);
91
92 const PaddingSize src_padding = calculator.required_padding();
93
94 validate(src.info()->padding(), src_padding);
95 validate(dst.info()->padding(), dst_padding);
96}
97
98template <typename T>
Sanghoon Leed7ba5392017-12-13 11:28:50 +000099using NEConvolutionFixture = ConvolutionSquareValidationFixture<Tensor, Accessor, NEConvolution3x3, T>;
Sanghoon Leec8a85ba2017-11-29 11:23:14 +0000100
Sanghoon Leec0079e92018-01-29 17:28:49 +0000101TEST_SUITE(U8)
Sanghoon Leed7ba5392017-12-13 11:28:50 +0000102FIXTURE_DATA_TEST_CASE(RunSmall, NEConvolutionFixture<uint8_t>, framework::DatasetMode::PRECOMMIT, combine(combine(combine(datasets::SmallShapes(), framework::dataset::make("DataType",
Sanghoon Leec8a85ba2017-11-29 11:23:14 +0000103 DataType::U8)),
Sanghoon Leed7ba5392017-12-13 11:28:50 +0000104 datasets::BorderModes()),
105 framework::dataset::make("filter_size", { 3 })))
Sanghoon Leec8a85ba2017-11-29 11:23:14 +0000106{
107 // Validate output
Sanghoon Leed7ba5392017-12-13 11:28:50 +0000108 validate(Accessor(_target), _reference, shape_to_valid_region(_reference.shape(), (_border_mode == BorderMode::UNDEFINED), BorderSize(_height / 2, _width / 2)), tolerance_u8);
Sanghoon Leec8a85ba2017-11-29 11:23:14 +0000109}
110
Sanghoon Leed7ba5392017-12-13 11:28:50 +0000111FIXTURE_DATA_TEST_CASE(RunLarge, NEConvolutionFixture<uint8_t>, framework::DatasetMode::NIGHTLY, combine(combine(combine(datasets::LargeShapes(), framework::dataset::make("DataType",
Sanghoon Leec8a85ba2017-11-29 11:23:14 +0000112 DataType::U8)),
Sanghoon Leed7ba5392017-12-13 11:28:50 +0000113 datasets::BorderModes()),
114 framework::dataset::make("filter_size", { 3 })))
Sanghoon Leec8a85ba2017-11-29 11:23:14 +0000115{
116 // Validate output
Sanghoon Leed7ba5392017-12-13 11:28:50 +0000117 validate(Accessor(_target), _reference, shape_to_valid_region(_reference.shape(), (_border_mode == BorderMode::UNDEFINED), BorderSize(_height / 2, _width / 2)), tolerance_u8);
Sanghoon Leec8a85ba2017-11-29 11:23:14 +0000118}
Sanghoon Leec8d23162018-01-12 16:19:10 +0000119TEST_SUITE_END()
120
Sanghoon Leec0079e92018-01-29 17:28:49 +0000121TEST_SUITE(S16)
Sanghoon Leec8d23162018-01-12 16:19:10 +0000122FIXTURE_DATA_TEST_CASE(RunSmall, NEConvolutionFixture<int16_t>, framework::DatasetMode::PRECOMMIT, combine(combine(combine(datasets::SmallShapes(), framework::dataset::make("DataType",
123 DataType::S16)),
124 datasets::BorderModes()),
125 framework::dataset::make("filter_size", { 3 })))
126{
127 // Validate output
128 validate(Accessor(_target), _reference, shape_to_valid_region(_reference.shape(), (_border_mode == BorderMode::UNDEFINED), BorderSize(_height / 2, _width / 2)), tolerance_s16);
129}
130
131FIXTURE_DATA_TEST_CASE(RunLarge, NEConvolutionFixture<int16_t>, framework::DatasetMode::NIGHTLY, combine(combine(combine(datasets::LargeShapes(), framework::dataset::make("DataType",
132 DataType::S16)),
133 datasets::BorderModes()),
134 framework::dataset::make("filter_size", { 3 })))
135{
136 // Validate output
137 validate(Accessor(_target), _reference, shape_to_valid_region(_reference.shape(), (_border_mode == BorderMode::UNDEFINED), BorderSize(_height / 2, _width / 2)), tolerance_s16);
138}
139TEST_SUITE_END()
Sanghoon Leec0079e92018-01-29 17:28:49 +0000140TEST_SUITE_END() /* Square3x3 */
Sanghoon Leec8a85ba2017-11-29 11:23:14 +0000141
Sanghoon Leec0079e92018-01-29 17:28:49 +0000142TEST_SUITE(Square5x5)
Sanghoon Leec8d23162018-01-12 16:19:10 +0000143DATA_TEST_CASE(Configuration, framework::DatasetMode::ALL, combine(combine(combine(concat(datasets::SmallShapes(), datasets::LargeShapes()), framework::dataset::make("DataType", { DataType::U8, DataType::S16 })),
Sanghoon Leed7ba5392017-12-13 11:28:50 +0000144 datasets::BorderModes()),
145 framework::dataset::make("filter_size", { 5 })),
Sanghoon Leec8d23162018-01-12 16:19:10 +0000146 shape, output_data_type, border_mode, filter_size)
Sanghoon Leec8a85ba2017-11-29 11:23:14 +0000147{
148 // Create tensors
Sanghoon Leec8d23162018-01-12 16:19:10 +0000149 Tensor src = create_tensor<Tensor>(shape, DataType::U8);
150 Tensor dst = create_tensor<Tensor>(shape, output_data_type);
Sanghoon Leec8a85ba2017-11-29 11:23:14 +0000151
152 // Create conv matrix
Michalis Spyrou5ae9b692018-02-05 14:59:54 +0000153 int16_t conv[25] = {};
Sanghoon Leec8a85ba2017-11-29 11:23:14 +0000154
155 ARM_COMPUTE_EXPECT(src.info()->is_resizable(), framework::LogLevel::ERRORS);
156 ARM_COMPUTE_EXPECT(dst.info()->is_resizable(), framework::LogLevel::ERRORS);
157
158 // Create and configure function
159 NEConvolution5x5 convolution;
Sanghoon Leed7ba5392017-12-13 11:28:50 +0000160 convolution.configure(&src, &dst, conv, 0, border_mode);
Sanghoon Leec8a85ba2017-11-29 11:23:14 +0000161
162 // Validate valid region
Sanghoon Leed7ba5392017-12-13 11:28:50 +0000163 const ValidRegion dst_valid_region = shape_to_valid_region(shape, (border_mode == BorderMode::UNDEFINED), BorderSize(filter_size / 2));
Sanghoon Leec8a85ba2017-11-29 11:23:14 +0000164 validate(dst.info()->valid_region(), dst_valid_region);
165
166 // Validate padding
167 PaddingCalculator calculator(shape.x(), 8);
168 calculator.set_border_size(2);
169 calculator.set_border_mode(border_mode);
170
171 const PaddingSize dst_padding = calculator.required_padding();
172
173 calculator.set_accessed_elements(16);
174 calculator.set_access_offset(-2);
175
176 const PaddingSize src_padding = calculator.required_padding();
177
178 validate(src.info()->padding(), src_padding);
179 validate(dst.info()->padding(), dst_padding);
180}
181
182template <typename T>
Sanghoon Leed7ba5392017-12-13 11:28:50 +0000183using NEConvolutionFixture = ConvolutionSquareValidationFixture<Tensor, Accessor, NEConvolution5x5, T>;
Sanghoon Leec8a85ba2017-11-29 11:23:14 +0000184
Sanghoon Leec0079e92018-01-29 17:28:49 +0000185TEST_SUITE(U8)
Sanghoon Leed7ba5392017-12-13 11:28:50 +0000186FIXTURE_DATA_TEST_CASE(RunSmall, NEConvolutionFixture<uint8_t>, framework::DatasetMode::PRECOMMIT, combine(combine(combine(datasets::SmallShapes(), framework::dataset::make("DataType",
Sanghoon Leec8a85ba2017-11-29 11:23:14 +0000187 DataType::U8)),
Sanghoon Leed7ba5392017-12-13 11:28:50 +0000188 datasets::BorderModes()),
189 framework::dataset::make("filter_size", { 5 })))
Sanghoon Leec8a85ba2017-11-29 11:23:14 +0000190{
191 // Validate output
Sanghoon Leed7ba5392017-12-13 11:28:50 +0000192 validate(Accessor(_target), _reference, shape_to_valid_region(_reference.shape(), (_border_mode == BorderMode::UNDEFINED), BorderSize(_height / 2, _width / 2)), tolerance_u8);
Sanghoon Leec8a85ba2017-11-29 11:23:14 +0000193}
194
Sanghoon Leed7ba5392017-12-13 11:28:50 +0000195FIXTURE_DATA_TEST_CASE(RunLarge, NEConvolutionFixture<uint8_t>, framework::DatasetMode::NIGHTLY, combine(combine(combine(datasets::LargeShapes(), framework::dataset::make("DataType",
Sanghoon Leec8a85ba2017-11-29 11:23:14 +0000196 DataType::U8)),
Sanghoon Leed7ba5392017-12-13 11:28:50 +0000197 datasets::BorderModes()),
198 framework::dataset::make("filter_size", { 5 })))
Sanghoon Leec8a85ba2017-11-29 11:23:14 +0000199{
200 // Validate output
Sanghoon Leed7ba5392017-12-13 11:28:50 +0000201 validate(Accessor(_target), _reference, shape_to_valid_region(_reference.shape(), (_border_mode == BorderMode::UNDEFINED), BorderSize(_height / 2, _width / 2)), tolerance_u8);
Sanghoon Leec8a85ba2017-11-29 11:23:14 +0000202}
Sanghoon Leec8d23162018-01-12 16:19:10 +0000203TEST_SUITE_END()
204
Sanghoon Leec0079e92018-01-29 17:28:49 +0000205TEST_SUITE(S16)
Sanghoon Leec8d23162018-01-12 16:19:10 +0000206FIXTURE_DATA_TEST_CASE(RunSmall, NEConvolutionFixture<int16_t>, framework::DatasetMode::PRECOMMIT, combine(combine(combine(datasets::SmallShapes(), framework::dataset::make("DataType",
207 DataType::S16)),
208 datasets::BorderModes()),
209 framework::dataset::make("filter_size", { 5 })))
210{
211 // Validate output
212 validate(Accessor(_target), _reference, shape_to_valid_region(_reference.shape(), (_border_mode == BorderMode::UNDEFINED), BorderSize(_height / 2, _width / 2)), tolerance_s16);
213}
214
215FIXTURE_DATA_TEST_CASE(RunLarge, NEConvolutionFixture<int16_t>, framework::DatasetMode::NIGHTLY, combine(combine(combine(datasets::LargeShapes(), framework::dataset::make("DataType",
216 DataType::S16)),
217 datasets::BorderModes()),
218 framework::dataset::make("filter_size", { 5 })))
219{
220 // Validate output
221 validate(Accessor(_target), _reference, shape_to_valid_region(_reference.shape(), (_border_mode == BorderMode::UNDEFINED), BorderSize(_height / 2, _width / 2)), tolerance_s16);
222}
223TEST_SUITE_END()
Sanghoon Leec0079e92018-01-29 17:28:49 +0000224TEST_SUITE_END() /* Square5x5 */
Sanghoon Leec8a85ba2017-11-29 11:23:14 +0000225
Sanghoon Leec0079e92018-01-29 17:28:49 +0000226TEST_SUITE(Square7x7)
Sanghoon Leec8d23162018-01-12 16:19:10 +0000227DATA_TEST_CASE(Configuration, framework::DatasetMode::ALL, combine(combine(combine(concat(datasets::SmallShapes(), datasets::LargeShapes()), framework::dataset::make("DataType", { DataType::U8, DataType::S16 })),
Sanghoon Leed7ba5392017-12-13 11:28:50 +0000228 datasets::BorderModes()),
229 framework::dataset::make("filter_size", { 7 })),
Sanghoon Leec8d23162018-01-12 16:19:10 +0000230 shape, output_data_type, border_mode, filter_size)
Sanghoon Leec8a85ba2017-11-29 11:23:14 +0000231{
232 // Create tensors
Sanghoon Leec8d23162018-01-12 16:19:10 +0000233 Tensor src = create_tensor<Tensor>(shape, DataType::U8);
234 Tensor dst = create_tensor<Tensor>(shape, output_data_type);
Sanghoon Leec8a85ba2017-11-29 11:23:14 +0000235
236 // Create conv matrix
Michalis Spyrou5ae9b692018-02-05 14:59:54 +0000237 int16_t conv[49] = {};
Sanghoon Leec8a85ba2017-11-29 11:23:14 +0000238
239 ARM_COMPUTE_EXPECT(src.info()->is_resizable(), framework::LogLevel::ERRORS);
240 ARM_COMPUTE_EXPECT(dst.info()->is_resizable(), framework::LogLevel::ERRORS);
241
242 // Create and configure function
243 NEConvolution7x7 convolution;
Sanghoon Leed7ba5392017-12-13 11:28:50 +0000244 convolution.configure(&src, &dst, conv, 0, border_mode);
Sanghoon Leec8a85ba2017-11-29 11:23:14 +0000245
246 // Validate valid region
Sanghoon Leed7ba5392017-12-13 11:28:50 +0000247 const ValidRegion dst_valid_region = shape_to_valid_region(shape, (border_mode == BorderMode::UNDEFINED), BorderSize(filter_size / 2));
Sanghoon Leec8a85ba2017-11-29 11:23:14 +0000248 validate(dst.info()->valid_region(), dst_valid_region);
249
250 // Validate padding
251 PaddingCalculator calculator(shape.x(), 8);
252 calculator.set_border_size(3);
253 calculator.set_border_mode(border_mode);
254
255 const PaddingSize dst_padding = calculator.required_padding();
256
257 calculator.set_accessed_elements(16);
258 calculator.set_access_offset(-3);
259
260 const PaddingSize src_padding = calculator.required_padding();
261
262 validate(src.info()->padding(), src_padding);
263 validate(dst.info()->padding(), dst_padding);
264}
265
266template <typename T>
Sanghoon Leed7ba5392017-12-13 11:28:50 +0000267using NEConvolutionFixture = ConvolutionSquareValidationFixture<Tensor, Accessor, NEConvolution7x7, T>;
Sanghoon Leec8a85ba2017-11-29 11:23:14 +0000268
Sanghoon Leec0079e92018-01-29 17:28:49 +0000269TEST_SUITE(U8)
Sanghoon Leed7ba5392017-12-13 11:28:50 +0000270FIXTURE_DATA_TEST_CASE(RunSmall, NEConvolutionFixture<uint8_t>, framework::DatasetMode::PRECOMMIT, combine(combine(combine(datasets::SmallShapes(), framework::dataset::make("DataType",
Sanghoon Leec8a85ba2017-11-29 11:23:14 +0000271 DataType::U8)),
Sanghoon Leed7ba5392017-12-13 11:28:50 +0000272 datasets::BorderModes()),
273 framework::dataset::make("filter_size", { 7 })))
Sanghoon Leec8a85ba2017-11-29 11:23:14 +0000274{
275 // Validate output
Sanghoon Leed7ba5392017-12-13 11:28:50 +0000276 validate(Accessor(_target), _reference, shape_to_valid_region(_reference.shape(), (_border_mode == BorderMode::UNDEFINED), BorderSize(_height / 2, _width / 2)), tolerance_u8);
Sanghoon Leec8a85ba2017-11-29 11:23:14 +0000277}
278
Sanghoon Leed7ba5392017-12-13 11:28:50 +0000279FIXTURE_DATA_TEST_CASE(RunLarge, NEConvolutionFixture<uint8_t>, framework::DatasetMode::NIGHTLY, combine(combine(combine(datasets::LargeShapes(), framework::dataset::make("DataType",
Sanghoon Leec8a85ba2017-11-29 11:23:14 +0000280 DataType::U8)),
Sanghoon Leed7ba5392017-12-13 11:28:50 +0000281 datasets::BorderModes()),
282 framework::dataset::make("filter_size", { 7 })))
Sanghoon Leec8a85ba2017-11-29 11:23:14 +0000283{
284 // Validate output
Sanghoon Leed7ba5392017-12-13 11:28:50 +0000285 validate(Accessor(_target), _reference, shape_to_valid_region(_reference.shape(), (_border_mode == BorderMode::UNDEFINED), BorderSize(_height / 2, _width / 2)), tolerance_u8);
Sanghoon Leec8a85ba2017-11-29 11:23:14 +0000286}
Sanghoon Leec8d23162018-01-12 16:19:10 +0000287TEST_SUITE_END()
288
Sanghoon Leec0079e92018-01-29 17:28:49 +0000289TEST_SUITE(S16)
Sanghoon Leec8d23162018-01-12 16:19:10 +0000290FIXTURE_DATA_TEST_CASE(RunSmall, NEConvolutionFixture<int16_t>, framework::DatasetMode::PRECOMMIT, combine(combine(combine(datasets::SmallShapes(), framework::dataset::make("DataType",
291 DataType::S16)),
292 datasets::BorderModes()),
293 framework::dataset::make("filter_size", { 7 })))
294{
295 // Validate output
296 validate(Accessor(_target), _reference, shape_to_valid_region(_reference.shape(), (_border_mode == BorderMode::UNDEFINED), BorderSize(_height / 2, _width / 2)), tolerance_s16);
297}
298
299FIXTURE_DATA_TEST_CASE(RunLarge, NEConvolutionFixture<int16_t>, framework::DatasetMode::NIGHTLY, combine(combine(combine(datasets::LargeShapes(), framework::dataset::make("DataType",
300 DataType::S16)),
301 datasets::BorderModes()),
302 framework::dataset::make("filter_size", { 7 })))
303{
304 // Validate output
305 validate(Accessor(_target), _reference, shape_to_valid_region(_reference.shape(), (_border_mode == BorderMode::UNDEFINED), BorderSize(_height / 2, _width / 2)), tolerance_s16);
306}
307TEST_SUITE_END()
Sanghoon Leec0079e92018-01-29 17:28:49 +0000308TEST_SUITE_END() /* Square7x7 */
Sanghoon Leec8a85ba2017-11-29 11:23:14 +0000309
Sanghoon Leec0079e92018-01-29 17:28:49 +0000310TEST_SUITE(Square9x9)
Sanghoon Leec8d23162018-01-12 16:19:10 +0000311DATA_TEST_CASE(Configuration, framework::DatasetMode::ALL, combine(combine(combine(concat(datasets::SmallShapes(), datasets::LargeShapes()), framework::dataset::make("DataType", { DataType::U8, DataType::S16 })),
Sanghoon Leed7ba5392017-12-13 11:28:50 +0000312 datasets::BorderModes()),
313 framework::dataset::make("filter_size", { 9 })),
Sanghoon Leec8d23162018-01-12 16:19:10 +0000314 shape, output_data_type, border_mode, filter_size)
Sanghoon Leec8a85ba2017-11-29 11:23:14 +0000315{
316 // Create tensors
Sanghoon Leec8d23162018-01-12 16:19:10 +0000317 Tensor src = create_tensor<Tensor>(shape, DataType::U8);
318 Tensor dst = create_tensor<Tensor>(shape, output_data_type);
Sanghoon Leec8a85ba2017-11-29 11:23:14 +0000319
320 // Create conv matrix
Michalis Spyrou5ae9b692018-02-05 14:59:54 +0000321 int16_t conv[81] = {};
Sanghoon Leec8a85ba2017-11-29 11:23:14 +0000322
323 ARM_COMPUTE_EXPECT(src.info()->is_resizable(), framework::LogLevel::ERRORS);
324 ARM_COMPUTE_EXPECT(dst.info()->is_resizable(), framework::LogLevel::ERRORS);
325
326 // Create and configure function
327 NEConvolution9x9 convolution;
Sanghoon Leed7ba5392017-12-13 11:28:50 +0000328 convolution.configure(&src, &dst, conv, 0, border_mode);
Sanghoon Leec8a85ba2017-11-29 11:23:14 +0000329
330 // Validate valid region
Sanghoon Leed7ba5392017-12-13 11:28:50 +0000331 const ValidRegion dst_valid_region = shape_to_valid_region(shape, (border_mode == BorderMode::UNDEFINED), BorderSize(filter_size / 2));
Sanghoon Leec8a85ba2017-11-29 11:23:14 +0000332 validate(dst.info()->valid_region(), dst_valid_region);
333
334 // Validate padding
335 PaddingCalculator calculator(shape.x(), 8);
336 calculator.set_border_size(4);
337 calculator.set_border_mode(border_mode);
338
339 const PaddingSize dst_padding = calculator.required_padding();
340
341 calculator.set_accessed_elements(16);
342 calculator.set_access_offset(-4);
343
344 const PaddingSize src_padding = calculator.required_padding();
345
346 validate(src.info()->padding(), src_padding);
347 validate(dst.info()->padding(), dst_padding);
348}
349
350template <typename T>
Sanghoon Leed7ba5392017-12-13 11:28:50 +0000351using NEConvolutionFixture = ConvolutionSquareValidationFixture<Tensor, Accessor, NEConvolution9x9, T>;
Sanghoon Leec8a85ba2017-11-29 11:23:14 +0000352
Sanghoon Leec0079e92018-01-29 17:28:49 +0000353TEST_SUITE(U8)
Sanghoon Leed7ba5392017-12-13 11:28:50 +0000354FIXTURE_DATA_TEST_CASE(RunSmall, NEConvolutionFixture<uint8_t>, framework::DatasetMode::PRECOMMIT, combine(combine(combine(datasets::SmallShapes(), framework::dataset::make("DataType",
Sanghoon Leec8a85ba2017-11-29 11:23:14 +0000355 DataType::U8)),
Sanghoon Leed7ba5392017-12-13 11:28:50 +0000356 datasets::BorderModes()),
357 framework::dataset::make("filter_size", { 9 })))
Sanghoon Leec8a85ba2017-11-29 11:23:14 +0000358{
359 // Validate output
Sanghoon Leed7ba5392017-12-13 11:28:50 +0000360 validate(Accessor(_target), _reference, shape_to_valid_region(_reference.shape(), (_border_mode == BorderMode::UNDEFINED), BorderSize(_height / 2, _width / 2)), tolerance_u8);
Sanghoon Leec8a85ba2017-11-29 11:23:14 +0000361}
362
Sanghoon Leed7ba5392017-12-13 11:28:50 +0000363FIXTURE_DATA_TEST_CASE(RunLarge, NEConvolutionFixture<uint8_t>, framework::DatasetMode::NIGHTLY, combine(combine(combine(datasets::LargeShapes(), framework::dataset::make("DataType",
Sanghoon Leec8a85ba2017-11-29 11:23:14 +0000364 DataType::U8)),
Sanghoon Leed7ba5392017-12-13 11:28:50 +0000365 datasets::BorderModes()),
366 framework::dataset::make("filter_size", { 9 })))
Sanghoon Leec8a85ba2017-11-29 11:23:14 +0000367{
368 // Validate output
Sanghoon Leed7ba5392017-12-13 11:28:50 +0000369 validate(Accessor(_target), _reference, shape_to_valid_region(_reference.shape(), (_border_mode == BorderMode::UNDEFINED), BorderSize(_height / 2, _width / 2)), tolerance_u8);
Sanghoon Leec8a85ba2017-11-29 11:23:14 +0000370}
Sanghoon Leec8d23162018-01-12 16:19:10 +0000371TEST_SUITE_END()
372
Sanghoon Leec0079e92018-01-29 17:28:49 +0000373TEST_SUITE(S16)
Sanghoon Leec8d23162018-01-12 16:19:10 +0000374FIXTURE_DATA_TEST_CASE(RunSmall, NEConvolutionFixture<int16_t>, framework::DatasetMode::PRECOMMIT, combine(combine(combine(datasets::SmallShapes(), framework::dataset::make("DataType",
375 DataType::S16)),
376 datasets::BorderModes()),
377 framework::dataset::make("filter_size", { 9 })))
378{
379 // Validate output
380 validate(Accessor(_target), _reference, shape_to_valid_region(_reference.shape(), (_border_mode == BorderMode::UNDEFINED), BorderSize(_height / 2, _width / 2)), tolerance_s16);
381}
382
383FIXTURE_DATA_TEST_CASE(RunLarge, NEConvolutionFixture<int16_t>, framework::DatasetMode::NIGHTLY, combine(combine(combine(datasets::LargeShapes(), framework::dataset::make("DataType",
384 DataType::S16)),
385 datasets::BorderModes()),
386 framework::dataset::make("filter_size", { 9 })))
387{
388 // Validate output
389 validate(Accessor(_target), _reference, shape_to_valid_region(_reference.shape(), (_border_mode == BorderMode::UNDEFINED), BorderSize(_height / 2, _width / 2)), tolerance_s16);
390}
391TEST_SUITE_END()
Sanghoon Leec0079e92018-01-29 17:28:49 +0000392TEST_SUITE_END() /* Square9x9 */
Sanghoon Leed7ba5392017-12-13 11:28:50 +0000393
Sanghoon Leec0079e92018-01-29 17:28:49 +0000394TEST_SUITE(Rectangle)
Sanghoon Leed7ba5392017-12-13 11:28:50 +0000395DATA_TEST_CASE(Configuration, framework::DatasetMode::ALL, combine(combine(combine(combine(concat(datasets::SmallShapes(), datasets::LargeShapes()), framework::dataset::make("DataType",
Sanghoon Leec8d23162018-01-12 16:19:10 +0000396{ DataType::U8, DataType::S16 })),
397datasets::BorderModes()),
398framework::dataset::make("filter_width", { 3, 5, 7, 9 })),
399framework::dataset::make("filter_height", { 3, 5, 7, 9 })),
400shape, output_data_type, border_mode, filter_width, filter_height)
Sanghoon Leed7ba5392017-12-13 11:28:50 +0000401{
402 // Create tensors
Sanghoon Leec8d23162018-01-12 16:19:10 +0000403 Tensor src = create_tensor<Tensor>(shape, DataType::U8);
404 Tensor dst = create_tensor<Tensor>(shape, output_data_type);
Sanghoon Leed7ba5392017-12-13 11:28:50 +0000405
406 // Create conv matrix
Michalis Spyrou5ae9b692018-02-05 14:59:54 +0000407 std::vector<int16_t> conv(filter_height * filter_width);
Sanghoon Leed7ba5392017-12-13 11:28:50 +0000408
409 ARM_COMPUTE_EXPECT(src.info()->is_resizable(), framework::LogLevel::ERRORS);
410 ARM_COMPUTE_EXPECT(dst.info()->is_resizable(), framework::LogLevel::ERRORS);
411
412 // Create and configure function
413 NEConvolutionRectangle convolution;
Michalis Spyrou5ae9b692018-02-05 14:59:54 +0000414 convolution.configure(&src, &dst, conv.data(), filter_width, filter_height, 1, border_mode);
Sanghoon Leed7ba5392017-12-13 11:28:50 +0000415
416 // Validate valid region
417 const ValidRegion dst_valid_region = shape_to_valid_region(shape, (border_mode == BorderMode::UNDEFINED), BorderSize(filter_height / 2, filter_width / 2));
418 validate(dst.info()->valid_region(), dst_valid_region);
419
420 // Validate padding
421 PaddingCalculator calculator(shape.x(), 8);
422 calculator.set_border_size(filter_width / 2);
423 calculator.set_border_mode(border_mode);
424
425 const PaddingSize dst_padding = calculator.required_padding();
426
427 calculator.set_accessed_elements(16);
428 calculator.set_access_offset(-(filter_width / 2));
429
430 const PaddingSize width_padding = calculator.required_padding();
431
432 calculator.set_border_size(filter_height / 2);
433 calculator.set_access_offset(-(filter_height / 2));
434 const PaddingSize height_padding = calculator.required_padding();
435
436 validate(src.info()->padding(), width_padding, height_padding);
437 validate(dst.info()->padding(), dst_padding);
438}
439
440template <typename T>
441using NEConvolutionFixture = ConvolutionRectangleValidationFixture<Tensor, Accessor, NEConvolutionRectangle, T>;
442
Sanghoon Leec0079e92018-01-29 17:28:49 +0000443TEST_SUITE(U8)
Sanghoon Leed7ba5392017-12-13 11:28:50 +0000444FIXTURE_DATA_TEST_CASE(RunSmall, NEConvolutionFixture<uint8_t>, framework::DatasetMode::PRECOMMIT, combine(combine(combine(combine(datasets::SmallShapes(), framework::dataset::make("DataType",
445 DataType::U8)),
446 datasets::BorderModes()),
447 framework::dataset::make("filter_width", { 3, 5, 7, 9 })),
448 framework::dataset::make("filter_height", { 3, 5, 7, 9 })))
449{
450 // Validate output
451 validate(Accessor(_target), _reference, shape_to_valid_region(_reference.shape(), (_border_mode == BorderMode::UNDEFINED), BorderSize(_height / 2, _width / 2)), tolerance_u8);
452}
453
454FIXTURE_DATA_TEST_CASE(RunLarge, NEConvolutionFixture<uint8_t>, framework::DatasetMode::NIGHTLY, combine(combine(combine(combine(datasets::LargeShapes(), framework::dataset::make("DataType",
455 DataType::U8)),
456 datasets::BorderModes()),
457 framework::dataset::make("filter_width", { 3, 5, 7, 9 })),
458 framework::dataset::make("filter_height", { 3, 5, 7, 9 })))
459{
460 // Validate output
461 validate(Accessor(_target), _reference, shape_to_valid_region(_reference.shape(), (_border_mode == BorderMode::UNDEFINED), BorderSize(_height / 2, _width / 2)), tolerance_u8);
462}
463TEST_SUITE_END()
Sanghoon Leec8d23162018-01-12 16:19:10 +0000464
Sanghoon Leec0079e92018-01-29 17:28:49 +0000465TEST_SUITE(S16)
Sanghoon Leec8d23162018-01-12 16:19:10 +0000466FIXTURE_DATA_TEST_CASE(RunSmall, NEConvolutionFixture<int16_t>, framework::DatasetMode::PRECOMMIT, combine(combine(combine(combine(datasets::SmallShapes(), framework::dataset::make("DataType",
467 DataType::S16)),
468 datasets::BorderModes()),
469 framework::dataset::make("filter_width", { 3, 5, 7, 9 })),
470 framework::dataset::make("filter_height", { 3, 5, 7, 9 })))
471{
472 // Validate output
473 validate(Accessor(_target), _reference, shape_to_valid_region(_reference.shape(), (_border_mode == BorderMode::UNDEFINED), BorderSize(_height / 2, _width / 2)), tolerance_s16);
474}
475
476FIXTURE_DATA_TEST_CASE(RunLarge, NEConvolutionFixture<int16_t>, framework::DatasetMode::NIGHTLY, combine(combine(combine(combine(datasets::LargeShapes(), framework::dataset::make("DataType",
477 DataType::S16)),
478 datasets::BorderModes()),
479 framework::dataset::make("filter_width", { 3, 5, 7, 9 })),
480 framework::dataset::make("filter_height", { 3, 5, 7, 9 })))
481{
482 // Validate output
483 validate(Accessor(_target), _reference, shape_to_valid_region(_reference.shape(), (_border_mode == BorderMode::UNDEFINED), BorderSize(_height / 2, _width / 2)), tolerance_s16);
484}
Sanghoon Leec8a85ba2017-11-29 11:23:14 +0000485TEST_SUITE_END()
Sanghoon Leec0079e92018-01-29 17:28:49 +0000486TEST_SUITE_END() /* Rectangle */
Sanghoon Leec8d23162018-01-12 16:19:10 +0000487
Sanghoon Leec0079e92018-01-29 17:28:49 +0000488TEST_SUITE(Separable5x5)
Sanghoon Leec8d23162018-01-12 16:19:10 +0000489template <typename T>
490using NEConvolutionFixture = ConvolutionSeparableValidationFixture<Tensor, Accessor, NEConvolution5x5, T>;
491
Sanghoon Leec0079e92018-01-29 17:28:49 +0000492TEST_SUITE(U8)
Sanghoon Leec8d23162018-01-12 16:19:10 +0000493FIXTURE_DATA_TEST_CASE(RunSmall, NEConvolutionFixture<uint8_t>, framework::DatasetMode::PRECOMMIT, combine(combine(combine(datasets::SmallShapes(), framework::dataset::make("DataType",
494 DataType::U8)),
495 datasets::BorderModes()),
496 framework::dataset::make("filter_size", { 5 })))
497{
498 // Validate output
499 validate(Accessor(_target), _reference, shape_to_valid_region(_reference.shape(), (_border_mode == BorderMode::UNDEFINED), BorderSize(_height / 2, _width / 2)), tolerance_u8);
500}
501
502FIXTURE_DATA_TEST_CASE(RunLarge, NEConvolutionFixture<uint8_t>, framework::DatasetMode::NIGHTLY, combine(combine(combine(datasets::LargeShapes(), framework::dataset::make("DataType",
503 DataType::U8)),
504 datasets::BorderModes()),
505 framework::dataset::make("filter_size", { 5 })))
506{
507 // Validate output
508 validate(Accessor(_target), _reference, shape_to_valid_region(_reference.shape(), (_border_mode == BorderMode::UNDEFINED), BorderSize(_height / 2, _width / 2)), tolerance_u8);
509}
510TEST_SUITE_END()
511
Sanghoon Leec0079e92018-01-29 17:28:49 +0000512TEST_SUITE(S16)
Sanghoon Leec8d23162018-01-12 16:19:10 +0000513FIXTURE_DATA_TEST_CASE(RunSmall, NEConvolutionFixture<int16_t>, framework::DatasetMode::PRECOMMIT, combine(combine(combine(datasets::SmallShapes(), framework::dataset::make("DataType",
514 DataType::S16)),
515 datasets::BorderModes()),
516 framework::dataset::make("filter_size", { 5 })))
517{
518 // Validate output
519 validate(Accessor(_target), _reference, shape_to_valid_region(_reference.shape(), (_border_mode == BorderMode::UNDEFINED), BorderSize(_height / 2, _width / 2)), tolerance_s16);
520}
521
522FIXTURE_DATA_TEST_CASE(RunLarge, NEConvolutionFixture<int16_t>, framework::DatasetMode::NIGHTLY, combine(combine(combine(datasets::LargeShapes(), framework::dataset::make("DataType",
523 DataType::S16)),
524 datasets::BorderModes()),
525 framework::dataset::make("filter_size", { 5 })))
526{
527 // Validate output
528 validate(Accessor(_target), _reference, shape_to_valid_region(_reference.shape(), (_border_mode == BorderMode::UNDEFINED), BorderSize(_height / 2, _width / 2)), tolerance_s16);
529}
530TEST_SUITE_END()
Sanghoon Leec0079e92018-01-29 17:28:49 +0000531TEST_SUITE_END() /* Separable5x5 */
Sanghoon Leec8d23162018-01-12 16:19:10 +0000532
Sanghoon Leec0079e92018-01-29 17:28:49 +0000533TEST_SUITE(Separable7x7)
Sanghoon Leec8d23162018-01-12 16:19:10 +0000534template <typename T>
535using NEConvolutionFixture = ConvolutionSeparableValidationFixture<Tensor, Accessor, NEConvolution7x7, T>;
536
Sanghoon Leec0079e92018-01-29 17:28:49 +0000537TEST_SUITE(U8)
Sanghoon Leec8d23162018-01-12 16:19:10 +0000538FIXTURE_DATA_TEST_CASE(RunSmall, NEConvolutionFixture<uint8_t>, framework::DatasetMode::PRECOMMIT, combine(combine(combine(datasets::SmallShapes(), framework::dataset::make("DataType",
539 DataType::U8)),
540 datasets::BorderModes()),
541 framework::dataset::make("filter_size", { 7 })))
542{
543 // Validate output
544 validate(Accessor(_target), _reference, shape_to_valid_region(_reference.shape(), (_border_mode == BorderMode::UNDEFINED), BorderSize(_height / 2, _width / 2)), tolerance_u8);
545}
546
547FIXTURE_DATA_TEST_CASE(RunLarge, NEConvolutionFixture<uint8_t>, framework::DatasetMode::NIGHTLY, combine(combine(combine(datasets::LargeShapes(), framework::dataset::make("DataType",
548 DataType::U8)),
549 datasets::BorderModes()),
550 framework::dataset::make("filter_size", { 7 })))
551{
552 // Validate output
553 validate(Accessor(_target), _reference, shape_to_valid_region(_reference.shape(), (_border_mode == BorderMode::UNDEFINED), BorderSize(_height / 2, _width / 2)), tolerance_u8);
554}
555TEST_SUITE_END()
556
Sanghoon Leec0079e92018-01-29 17:28:49 +0000557TEST_SUITE(S16)
Sanghoon Leec8d23162018-01-12 16:19:10 +0000558FIXTURE_DATA_TEST_CASE(RunSmall, NEConvolutionFixture<int16_t>, framework::DatasetMode::PRECOMMIT, combine(combine(combine(datasets::SmallShapes(), framework::dataset::make("DataType",
559 DataType::S16)),
560 datasets::BorderModes()),
561 framework::dataset::make("filter_size", { 7 })))
562{
563 // Validate output
564 validate(Accessor(_target), _reference, shape_to_valid_region(_reference.shape(), (_border_mode == BorderMode::UNDEFINED), BorderSize(_height / 2, _width / 2)), tolerance_s16);
565}
566
567FIXTURE_DATA_TEST_CASE(RunLarge, NEConvolutionFixture<int16_t>, framework::DatasetMode::NIGHTLY, combine(combine(combine(datasets::LargeShapes(), framework::dataset::make("DataType",
568 DataType::S16)),
569 datasets::BorderModes()),
570 framework::dataset::make("filter_size", { 7 })))
571{
572 // Validate output
573 validate(Accessor(_target), _reference, shape_to_valid_region(_reference.shape(), (_border_mode == BorderMode::UNDEFINED), BorderSize(_height / 2, _width / 2)), tolerance_s16);
574}
575TEST_SUITE_END()
Sanghoon Leec0079e92018-01-29 17:28:49 +0000576TEST_SUITE_END() /* Separable7x7 */
Sanghoon Leec8d23162018-01-12 16:19:10 +0000577
Sanghoon Leec0079e92018-01-29 17:28:49 +0000578TEST_SUITE(Separable9x9)
Sanghoon Leec8d23162018-01-12 16:19:10 +0000579template <typename T>
580using NEConvolutionFixture = ConvolutionSeparableValidationFixture<Tensor, Accessor, NEConvolution9x9, T>;
581
Sanghoon Leec0079e92018-01-29 17:28:49 +0000582TEST_SUITE(U8)
Sanghoon Leec8d23162018-01-12 16:19:10 +0000583FIXTURE_DATA_TEST_CASE(RunSmall, NEConvolutionFixture<uint8_t>, framework::DatasetMode::PRECOMMIT, combine(combine(combine(datasets::SmallShapes(), framework::dataset::make("DataType",
584 DataType::U8)),
585 datasets::BorderModes()),
586 framework::dataset::make("filter_size", { 9 })))
587{
588 // Validate output
589 validate(Accessor(_target), _reference, shape_to_valid_region(_reference.shape(), (_border_mode == BorderMode::UNDEFINED), BorderSize(_height / 2, _width / 2)), tolerance_u8);
590}
591
592FIXTURE_DATA_TEST_CASE(RunLarge, NEConvolutionFixture<uint8_t>, framework::DatasetMode::NIGHTLY, combine(combine(combine(datasets::LargeShapes(), framework::dataset::make("DataType",
593 DataType::U8)),
594 datasets::BorderModes()),
595 framework::dataset::make("filter_size", { 9 })))
596{
597 // Validate output
598 validate(Accessor(_target), _reference, shape_to_valid_region(_reference.shape(), (_border_mode == BorderMode::UNDEFINED), BorderSize(_height / 2, _width / 2)), tolerance_u8);
599}
600TEST_SUITE_END()
601
Sanghoon Leec0079e92018-01-29 17:28:49 +0000602TEST_SUITE(S16)
Sanghoon Leec8d23162018-01-12 16:19:10 +0000603FIXTURE_DATA_TEST_CASE(RunSmall, NEConvolutionFixture<int16_t>, framework::DatasetMode::PRECOMMIT, combine(combine(combine(datasets::SmallShapes(), framework::dataset::make("DataType",
604 DataType::S16)),
605 datasets::BorderModes()),
606 framework::dataset::make("filter_size", { 9 })))
607{
608 // Validate output
609 validate(Accessor(_target), _reference, shape_to_valid_region(_reference.shape(), (_border_mode == BorderMode::UNDEFINED), BorderSize(_height / 2, _width / 2)), tolerance_s16);
610}
611
612FIXTURE_DATA_TEST_CASE(RunLarge, NEConvolutionFixture<int16_t>, framework::DatasetMode::NIGHTLY, combine(combine(combine(datasets::LargeShapes(), framework::dataset::make("DataType",
613 DataType::S16)),
614 datasets::BorderModes()),
615 framework::dataset::make("filter_size", { 9 })))
616{
617 // Validate output
618 validate(Accessor(_target), _reference, shape_to_valid_region(_reference.shape(), (_border_mode == BorderMode::UNDEFINED), BorderSize(_height / 2, _width / 2)), tolerance_s16);
619}
620TEST_SUITE_END()
Sanghoon Leec0079e92018-01-29 17:28:49 +0000621TEST_SUITE_END() /* Separable9x9 */
622
Sanghoon Leec8d23162018-01-12 16:19:10 +0000623TEST_SUITE_END() /* Custom Convolution */
Sanghoon Leec8a85ba2017-11-29 11:23:14 +0000624TEST_SUITE_END()
625} // namespace validation
626} // namespace test
627} // namespace arm_compute