blob: 68a3bace50854062174f55b74e96eb6cf3676bc2 [file] [log] [blame]
Sanghoon Lee70f82912017-08-24 14:21:24 +01001/*
Georgios Pinitas5a594532018-12-03 14:30:05 +00002 * Copyright (c) 2017-2019 ARM Limited.
Sanghoon Lee70f82912017-08-24 14:21:24 +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,
Georgios Pinitas5a594532018-12-03 14:30:05 +000021 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
Sanghoon Lee70f82912017-08-24 14:21:24 +010022 * SOFTWARE.
23 */
24#include "arm_compute/core/Types.h"
25#include "arm_compute/runtime/NEON/functions/NEArithmeticAddition.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/ConvertPolicyDataset.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"
Georgios Pinitascbf39c62018-09-10 15:07:45 +010036#include "tests/validation/fixtures/ArithmeticOperationsFixture.h"
Sanghoon Lee70f82912017-08-24 14:21:24 +010037
38namespace arm_compute
39{
40namespace test
41{
42namespace validation
43{
44namespace
45{
Vidhya Sudhan Loganathanf8b65202019-02-01 09:49:50 +000046#ifndef __aarch64__
Manuel Bottini65383e22019-06-24 14:25:32 +010047constexpr AbsoluteTolerance<float> tolerance_quant(1); /**< Tolerance value for comparing reference's output against implementation's output for quantized data types */
48#endif //__aarch64__
Georgios Pinitasa84faff2018-12-05 18:17:24 +000049
Sanghoon Lee70f82912017-08-24 14:21:24 +010050/** Input data sets **/
51const auto ArithmeticAdditionU8Dataset = combine(combine(framework::dataset::make("DataType", DataType::U8), framework::dataset::make("DataType", DataType::U8)), framework::dataset::make("DataType",
52 DataType::U8));
53const auto ArithmeticAdditionS16Dataset = combine(combine(framework::dataset::make("DataType", { DataType::U8, DataType::S16 }), framework::dataset::make("DataType", DataType::S16)),
54 framework::dataset::make("DataType", DataType::S16));
Ioan-Cristian Szabo5edbd1c2017-11-13 13:34:08 +000055#ifdef __ARM_FEATURE_FP16_VECTOR_ARITHMETIC
Sanghoon Lee70f82912017-08-24 14:21:24 +010056const auto ArithmeticAdditionFP16Dataset = combine(combine(framework::dataset::make("DataType", DataType::F16), framework::dataset::make("DataType", DataType::F16)),
57 framework::dataset::make("DataType", DataType::F16));
Ioan-Cristian Szabo5edbd1c2017-11-13 13:34:08 +000058#endif /* __ARM_FEATURE_FP16_VECTOR_ARITHMETIC */
Sanghoon Lee70f82912017-08-24 14:21:24 +010059const auto ArithmeticAdditionFP32Dataset = combine(combine(framework::dataset::make("DataType", DataType::F32), framework::dataset::make("DataType", DataType::F32)),
60 framework::dataset::make("DataType", DataType::F32));
Georgios Pinitasa84faff2018-12-05 18:17:24 +000061const auto ArithmeticAdditionQASYMM8Dataset = combine(combine(framework::dataset::make("DataType", DataType::QASYMM8), framework::dataset::make("DataType", DataType::QASYMM8)),
62 framework::dataset::make("DataType", DataType::QASYMM8));
Manuel Bottini3689fcd2019-06-14 17:18:12 +010063const auto ArithmeticAdditionQSYMM16Dataset = combine(combine(framework::dataset::make("DataType", DataType::QSYMM16), framework::dataset::make("DataType", DataType::QSYMM16)),
64 framework::dataset::make("DataType", DataType::QSYMM16));
Sanghoon Lee70f82912017-08-24 14:21:24 +010065} // namespace
66
67TEST_SUITE(NEON)
68TEST_SUITE(ArithmeticAddition)
69
70template <typename T>
71using NEArithmeticAdditionFixture = ArithmeticAdditionValidationFixture<Tensor, Accessor, NEArithmeticAddition, T>;
72
Ioan-Cristian Szabo397d58a2017-11-30 15:19:11 +000073// *INDENT-OFF*
74// clang-format off
75DATA_TEST_CASE(Validate, framework::DatasetMode::ALL, zip(zip(zip(
76 framework::dataset::make("Input1Info", { TensorInfo(TensorShape(32U, 13U, 2U), 1, DataType::U8),
77 TensorInfo(TensorShape(32U, 13U, 2U), 1, DataType::U8),
Georgios Pinitas5a594532018-12-03 14:30:05 +000078 TensorInfo(TensorShape(27U, 13U, 2U), 1, DataType::U8), // Unsupported broadcast
79 TensorInfo(TensorShape(32U, 13U, 2U), 1, DataType::U8), // Invalid data type combination
80 TensorInfo(TensorShape(32U, 13U, 2U), 1, DataType::F32),// Mismatching shapes
Ioan-Cristian Szabo397d58a2017-11-30 15:19:11 +000081 }),
82 framework::dataset::make("Input2Info",{ TensorInfo(TensorShape(32U, 13U, 2U), 1, DataType::U8),
83 TensorInfo(TensorShape(32U, 13U, 2U), 1, DataType::U8),
Georgios Pinitas5a594532018-12-03 14:30:05 +000084 TensorInfo(TensorShape(1U, 13U, 2U), 1, DataType::S16),
Ioan-Cristian Szabo397d58a2017-11-30 15:19:11 +000085 TensorInfo(TensorShape(32U, 13U, 2U), 1, DataType::S16),
86 TensorInfo(TensorShape(48U, 11U, 2U), 1, DataType::F32),
Ioan-Cristian Szabo397d58a2017-11-30 15:19:11 +000087 })),
88 framework::dataset::make("OutputInfo",{ TensorInfo(TensorShape(32U, 13U, 2U), 1, DataType::S16),
89 TensorInfo(TensorShape(32U, 13U, 2U), 1, DataType::U8),
Georgios Pinitas5a594532018-12-03 14:30:05 +000090 TensorInfo(TensorShape(27U, 13U, 2U), 1, DataType::S16),
Ioan-Cristian Szabo397d58a2017-11-30 15:19:11 +000091 TensorInfo(TensorShape(32U, 13U, 2U), 1, DataType::U8),
92 TensorInfo(TensorShape(48U, 11U, 2U), 1, DataType::F32),
Ioan-Cristian Szabo397d58a2017-11-30 15:19:11 +000093 })),
Vidhya Sudhan Loganathan0fc25452018-06-18 14:40:56 +010094 framework::dataset::make("Expected", { true, true, false, false, false})),
Ioan-Cristian Szabo397d58a2017-11-30 15:19:11 +000095 input1_info, input2_info, output_info, expected)
96{
Georgios Pinitas5a594532018-12-03 14:30:05 +000097 Status s = NEArithmeticAddition::validate(&input1_info.clone()->set_is_resizable(false),
98 &input2_info.clone()->set_is_resizable(false),
99 &output_info.clone()->set_is_resizable(false),
100 ConvertPolicy::WRAP);
101 ARM_COMPUTE_EXPECT(bool(s) == expected, framework::LogLevel::ERRORS);
Ioan-Cristian Szabo397d58a2017-11-30 15:19:11 +0000102}
103// clang-format on
104// *INDENT-ON*
105
Georgios Pinitasa84faff2018-12-05 18:17:24 +0000106TEST_SUITE(Integer)
Sanghoon Lee70f82912017-08-24 14:21:24 +0100107TEST_SUITE(U8)
Michalis Spyrou5c9f0c42019-01-16 14:48:48 +0000108DATA_TEST_CASE(Configuration, framework::DatasetMode::ALL, combine(datasets::SmallShapes(), framework::dataset::make("ConvertPolicy", { ConvertPolicy::SATURATE, ConvertPolicy::WRAP })),
Sanghoon Lee70f82912017-08-24 14:21:24 +0100109 shape, policy)
110{
111 // Create tensors
112 Tensor ref_src1 = create_tensor<Tensor>(shape, DataType::U8);
113 Tensor ref_src2 = create_tensor<Tensor>(shape, DataType::U8);
114 Tensor dst = create_tensor<Tensor>(shape, DataType::U8);
115
116 // Create and Configure function
117 NEArithmeticAddition add;
118 add.configure(&ref_src1, &ref_src2, &dst, policy);
119
120 // Validate valid region
121 const ValidRegion valid_region = shape_to_valid_region(shape);
122 validate(dst.info()->valid_region(), valid_region);
123
124 // Validate padding
Georgios Pinitas5a594532018-12-03 14:30:05 +0000125 validate(ref_src1.info()->padding(), PaddingSize());
126 validate(ref_src2.info()->padding(), PaddingSize());
127 validate(dst.info()->padding(), PaddingSize());
Sanghoon Lee70f82912017-08-24 14:21:24 +0100128}
129
130FIXTURE_DATA_TEST_CASE(RunSmall, NEArithmeticAdditionFixture<uint8_t>, framework::DatasetMode::PRECOMMIT, combine(combine(datasets::SmallShapes(), ArithmeticAdditionU8Dataset),
131 framework::dataset::make("ConvertPolicy", { ConvertPolicy::SATURATE, ConvertPolicy::WRAP })))
132{
133 // Validate output
134 validate(Accessor(_target), _reference);
135}
Georgios Pinitasa84faff2018-12-05 18:17:24 +0000136TEST_SUITE_END() // U8
Sanghoon Lee70f82912017-08-24 14:21:24 +0100137
138TEST_SUITE(S16)
Michalis Spyrou5c9f0c42019-01-16 14:48:48 +0000139DATA_TEST_CASE(Configuration, framework::DatasetMode::ALL, combine(combine(datasets::SmallShapes(), framework::dataset::make("DataType", { DataType::U8, DataType::S16 })),
Sanghoon Lee70f82912017-08-24 14:21:24 +0100140 framework::dataset::make("ConvertPolicy", { ConvertPolicy::SATURATE, ConvertPolicy::WRAP })),
141 shape, data_type, policy)
142{
143 // Create tensors
144 Tensor ref_src1 = create_tensor<Tensor>(shape, data_type);
145 Tensor ref_src2 = create_tensor<Tensor>(shape, DataType::S16);
146 Tensor dst = create_tensor<Tensor>(shape, DataType::S16);
147
148 // Create and Configure function
149 NEArithmeticAddition add;
150 add.configure(&ref_src1, &ref_src2, &dst, policy);
151
152 // Validate valid region
153 const ValidRegion valid_region = shape_to_valid_region(shape);
154 validate(dst.info()->valid_region(), valid_region);
155
156 // Validate padding
Georgios Pinitas5a594532018-12-03 14:30:05 +0000157 validate(ref_src1.info()->padding(), PaddingSize());
158 validate(ref_src2.info()->padding(), PaddingSize());
159 validate(dst.info()->padding(), PaddingSize());
Sanghoon Lee70f82912017-08-24 14:21:24 +0100160}
161
162FIXTURE_DATA_TEST_CASE(RunSmall, NEArithmeticAdditionFixture<int16_t>, framework::DatasetMode::PRECOMMIT, combine(combine(datasets::SmallShapes(), ArithmeticAdditionS16Dataset),
163 framework::dataset::make("ConvertPolicy", { ConvertPolicy::SATURATE, ConvertPolicy::WRAP })))
164{
165 // Validate output
166 validate(Accessor(_target), _reference);
167}
168
169FIXTURE_DATA_TEST_CASE(RunLarge, NEArithmeticAdditionFixture<int16_t>, framework::DatasetMode::NIGHTLY, combine(combine(datasets::LargeShapes(), ArithmeticAdditionS16Dataset),
170 framework::dataset::make("ConvertPolicy", { ConvertPolicy::SATURATE, ConvertPolicy::WRAP })))
171{
172 // Validate output
173 validate(Accessor(_target), _reference);
174}
Georgios Pinitasa84faff2018-12-05 18:17:24 +0000175TEST_SUITE_END() // S16
176TEST_SUITE_END() // Integer
Sanghoon Lee70f82912017-08-24 14:21:24 +0100177
Sanghoon Lee70f82912017-08-24 14:21:24 +0100178TEST_SUITE(Float)
Ioan-Cristian Szabo5edbd1c2017-11-13 13:34:08 +0000179#ifdef __ARM_FEATURE_FP16_VECTOR_ARITHMETIC
Sanghoon Lee70f82912017-08-24 14:21:24 +0100180TEST_SUITE(F16)
Georgios Pinitas583137c2017-08-31 18:12:42 +0100181FIXTURE_DATA_TEST_CASE(RunSmall, NEArithmeticAdditionFixture<half>, framework::DatasetMode::ALL, combine(combine(datasets::SmallShapes(), ArithmeticAdditionFP16Dataset),
182 framework::dataset::make("ConvertPolicy", { ConvertPolicy::SATURATE, ConvertPolicy::WRAP })))
Sanghoon Lee70f82912017-08-24 14:21:24 +0100183{
184 // Validate output
185 validate(Accessor(_target), _reference);
186}
Georgios Pinitasa84faff2018-12-05 18:17:24 +0000187TEST_SUITE_END() // F16
188#endif /* __ARM_FEATURE_FP16_VECTOR_ARITHMETIC */
Sanghoon Lee70f82912017-08-24 14:21:24 +0100189
190TEST_SUITE(F32)
Michalis Spyrou5c9f0c42019-01-16 14:48:48 +0000191DATA_TEST_CASE(Configuration, framework::DatasetMode::ALL, combine(datasets::SmallShapes(), framework::dataset::make("ConvertPolicy", { ConvertPolicy::SATURATE, ConvertPolicy::WRAP })),
Sanghoon Lee70f82912017-08-24 14:21:24 +0100192 shape, policy)
193{
194 // Create tensors
195 Tensor ref_src1 = create_tensor<Tensor>(shape, DataType::F32);
196 Tensor ref_src2 = create_tensor<Tensor>(shape, DataType::F32);
197 Tensor dst = create_tensor<Tensor>(shape, DataType::F32);
198
199 // Create and Configure function
200 NEArithmeticAddition add;
201 add.configure(&ref_src1, &ref_src2, &dst, policy);
202
203 // Validate valid region
204 const ValidRegion valid_region = shape_to_valid_region(shape);
205 validate(dst.info()->valid_region(), valid_region);
206
207 // Validate padding
Georgios Pinitas5a594532018-12-03 14:30:05 +0000208 validate(ref_src1.info()->padding(), PaddingSize());
209 validate(ref_src2.info()->padding(), PaddingSize());
210 validate(dst.info()->padding(), PaddingSize());
Sanghoon Lee70f82912017-08-24 14:21:24 +0100211}
212
213FIXTURE_DATA_TEST_CASE(RunSmall, NEArithmeticAdditionFixture<float>, framework::DatasetMode::PRECOMMIT, combine(combine(datasets::SmallShapes(), ArithmeticAdditionFP32Dataset),
214 framework::dataset::make("ConvertPolicy", { ConvertPolicy::SATURATE, ConvertPolicy::WRAP })))
215{
216 // Validate output
217 validate(Accessor(_target), _reference);
218}
219
220FIXTURE_DATA_TEST_CASE(RunLarge, NEArithmeticAdditionFixture<float>, framework::DatasetMode::NIGHTLY, combine(combine(datasets::LargeShapes(), ArithmeticAdditionFP32Dataset),
221 framework::dataset::make("ConvertPolicy", { ConvertPolicy::SATURATE, ConvertPolicy::WRAP })))
222{
223 // Validate output
224 validate(Accessor(_target), _reference);
225}
Diego Lopez Recas0021d752017-12-18 14:42:56 +0000226
227template <typename T>
228using NEArithmeticAdditionBroadcastFixture = ArithmeticAdditionBroadcastValidationFixture<Tensor, Accessor, NEArithmeticAddition, T>;
229
230FIXTURE_DATA_TEST_CASE(RunSmallBroadcast, NEArithmeticAdditionBroadcastFixture<float>, framework::DatasetMode::PRECOMMIT, combine(combine(datasets::SmallShapesBroadcast(),
231 ArithmeticAdditionFP32Dataset),
232 framework::dataset::make("ConvertPolicy", { ConvertPolicy::SATURATE, ConvertPolicy::WRAP })))
233{
234 // Validate output
235 validate(Accessor(_target), _reference);
236}
237
238FIXTURE_DATA_TEST_CASE(RunLargeBroadcast, NEArithmeticAdditionBroadcastFixture<float>, framework::DatasetMode::NIGHTLY, combine(combine(datasets::LargeShapesBroadcast(),
239 ArithmeticAdditionFP32Dataset),
240 framework::dataset::make("ConvertPolicy", { ConvertPolicy::SATURATE, ConvertPolicy::WRAP })))
241{
242 // Validate output
243 validate(Accessor(_target), _reference);
244}
Georgios Pinitasa84faff2018-12-05 18:17:24 +0000245TEST_SUITE_END() // F32
246TEST_SUITE_END() // Float
Sanghoon Lee70f82912017-08-24 14:21:24 +0100247
Georgios Pinitasa84faff2018-12-05 18:17:24 +0000248template <typename T>
249using NEArithmeticAdditionQuantizedFixture = ArithmeticAdditionValidationQuantizedFixture<Tensor, Accessor, NEArithmeticAddition, T>;
250
251TEST_SUITE(Quantized)
252TEST_SUITE(QASYMM8)
Manuel Bottini6a2b6e82019-02-25 13:50:11 +0000253DATA_TEST_CASE(Configuration, framework::DatasetMode::ALL, combine(datasets::SmallShapes(), framework::dataset::make("ConvertPolicy", { ConvertPolicy::SATURATE })),
Georgios Pinitasa84faff2018-12-05 18:17:24 +0000254 shape, policy)
255{
256 // Create tensors
257 Tensor ref_src1 = create_tensor<Tensor>(shape, DataType::QASYMM8);
258 Tensor ref_src2 = create_tensor<Tensor>(shape, DataType::QASYMM8);
259 Tensor dst = create_tensor<Tensor>(shape, DataType::QASYMM8);
260
261 // Create and Configure function
262 NEArithmeticAddition add;
263 add.configure(&ref_src1, &ref_src2, &dst, policy);
264
265 // Validate valid region
266 const ValidRegion valid_region = shape_to_valid_region(shape);
267 validate(dst.info()->valid_region(), valid_region);
268
269 // Validate padding
Georgios Pinitas5a594532018-12-03 14:30:05 +0000270 validate(ref_src1.info()->padding(), PaddingSize());
271 validate(ref_src2.info()->padding(), PaddingSize());
272 validate(dst.info()->padding(), PaddingSize());
Georgios Pinitasa84faff2018-12-05 18:17:24 +0000273}
274
275FIXTURE_DATA_TEST_CASE(RunSmall,
276 NEArithmeticAdditionQuantizedFixture<uint8_t>,
277 framework::DatasetMode::PRECOMMIT,
278 combine(combine(combine(combine(combine(datasets::SmallShapes(), ArithmeticAdditionQASYMM8Dataset),
Manuel Bottini6a2b6e82019-02-25 13:50:11 +0000279 framework::dataset::make("ConvertPolicy", { ConvertPolicy::SATURATE })),
Manuel Bottini3689fcd2019-06-14 17:18:12 +0100280 framework::dataset::make("Src0QInfo", { QuantizationInfo(5.f / 255.f, 20) })),
281 framework::dataset::make("Src1QInfo", { QuantizationInfo(2.f / 255.f, 10) })),
282 framework::dataset::make("OutQInfo", { QuantizationInfo(1.f / 255.f, 5) })))
Georgios Pinitasa84faff2018-12-05 18:17:24 +0000283{
284 // Validate output
Vidhya Sudhan Loganathanf8b65202019-02-01 09:49:50 +0000285#ifdef __aarch64__
286 validate(Accessor(_target), _reference);
Manuel Bottini6a2b6e82019-02-25 13:50:11 +0000287#else //__aarch64__
Manuel Bottini65383e22019-06-24 14:25:32 +0100288 validate(Accessor(_target), _reference, tolerance_quant);
Vidhya Sudhan Loganathanf8b65202019-02-01 09:49:50 +0000289#endif //__aarch64__
Georgios Pinitasa84faff2018-12-05 18:17:24 +0000290}
291TEST_SUITE_END() // QASYMM8
Manuel Bottini3689fcd2019-06-14 17:18:12 +0100292TEST_SUITE(QSYMM16)
293DATA_TEST_CASE(Configuration, framework::DatasetMode::ALL, combine(datasets::SmallShapes(), framework::dataset::make("ConvertPolicy", { ConvertPolicy::SATURATE })),
294 shape, policy)
295{
296 // Create tensors
297 Tensor ref_src1 = create_tensor<Tensor>(shape, DataType::QSYMM16);
298 Tensor ref_src2 = create_tensor<Tensor>(shape, DataType::QSYMM16);
299 Tensor dst = create_tensor<Tensor>(shape, DataType::QSYMM16);
300
301 // Create and Configure function
302 NEArithmeticAddition add;
303 add.configure(&ref_src1, &ref_src2, &dst, policy);
304
305 // Validate valid region
306 const ValidRegion valid_region = shape_to_valid_region(shape);
307 validate(dst.info()->valid_region(), valid_region);
308
309 // Validate padding
310 validate(ref_src1.info()->padding(), PaddingSize());
311 validate(ref_src2.info()->padding(), PaddingSize());
312 validate(dst.info()->padding(), PaddingSize());
313}
314
315FIXTURE_DATA_TEST_CASE(RunSmall,
316 NEArithmeticAdditionQuantizedFixture<int16_t>,
317 framework::DatasetMode::PRECOMMIT,
318 combine(combine(combine(combine(combine(datasets::SmallShapes(), ArithmeticAdditionQSYMM16Dataset),
319 framework::dataset::make("ConvertPolicy", { ConvertPolicy::SATURATE })),
320 framework::dataset::make("Src0QInfo", { QuantizationInfo(1.f / 32768.f, 0), QuantizationInfo(5.f / 32768.f, 0) })),
321 framework::dataset::make("Src1QInfo", { QuantizationInfo(2.f / 32768.f, 0), QuantizationInfo(5.f / 32768.f, 0) })),
322 framework::dataset::make("OutQInfo", { QuantizationInfo(5.f / 32768.f, 0) })))
323{
324 // Validate output
Manuel Bottini65383e22019-06-24 14:25:32 +0100325#ifdef __aarch64__
Manuel Bottini3689fcd2019-06-14 17:18:12 +0100326 validate(Accessor(_target), _reference);
Manuel Bottini65383e22019-06-24 14:25:32 +0100327#else //__aarch64__
328 validate(Accessor(_target), _reference, tolerance_quant);
329#endif //__aarch64__
Manuel Bottini3689fcd2019-06-14 17:18:12 +0100330}
331TEST_SUITE_END() // QSYMM16
Georgios Pinitasa84faff2018-12-05 18:17:24 +0000332TEST_SUITE_END() // Quantized
333
334TEST_SUITE_END() // ArithmeticAddition
335TEST_SUITE_END() // NEON
Sanghoon Lee70f82912017-08-24 14:21:24 +0100336} // namespace validation
337} // namespace test
338} // namespace arm_compute