blob: 178e7c93885f30e02373fd8d58e58f1f3c87a1a8 [file] [log] [blame]
Pablo Tello299025a2017-09-29 11:30:12 +01001/*
Michele Di Giorgiod9eaf612020-07-08 11:12:57 +01002 * Copyright (c) 2017-2020 Arm Limited.
Pablo Tello299025a2017-09-29 11:30:12 +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"
Gian Marcoe75a02b2017-11-08 12:24:09 +000025#include "arm_compute/runtime/NEON/functions/NEGEMMLowpMatrixMultiplyCore.h"
26#include "arm_compute/runtime/NEON/functions/NEGEMMLowpOutputStage.h"
Pablo Tello299025a2017-09-29 11:30:12 +010027#include "arm_compute/runtime/Tensor.h"
28#include "arm_compute/runtime/TensorAllocator.h"
29#include "tests/NEON/Accessor.h"
Gian Marco Iodiceab182122017-10-09 15:05:40 +010030#include "tests/NEON/Helper.h"
Gian Marcoe75a02b2017-11-08 12:24:09 +000031#include "tests/PaddingCalculator.h"
George Wort2d7e6832019-02-22 16:37:41 +000032#include "tests/datasets/GEMMLowpFusedOffsetOutputDataset.h"
Gian Marcofa4cacd2017-10-18 17:05:02 +010033#include "tests/datasets/LargeGEMMLowpDataset.h"
Gian Marcoe75a02b2017-11-08 12:24:09 +000034#include "tests/datasets/ShapeDatasets.h"
Gian Marcofa4cacd2017-10-18 17:05:02 +010035#include "tests/datasets/SmallGEMMLowpDataset.h"
Pablo Tello299025a2017-09-29 11:30:12 +010036#include "tests/framework/Asserts.h"
37#include "tests/framework/Macros.h"
38#include "tests/framework/datasets/Datasets.h"
39#include "tests/validation/Validation.h"
Pablo Tello181e6512017-11-15 13:28:27 +000040#include "tests/validation/fixtures/GEMMLowpAssemblyFixture.h"
Pablo Tello299025a2017-09-29 11:30:12 +010041#include "tests/validation/fixtures/GEMMLowpFixture.h"
42
43namespace arm_compute
44{
45namespace test
46{
47namespace validation
48{
Pablo Tello299025a2017-09-29 11:30:12 +010049TEST_SUITE(NEON)
50TEST_SUITE(GEMMLowp)
Gian Marcoe75a02b2017-11-08 12:24:09 +000051TEST_SUITE(MatrixMultiplyCore)
52using NEGEMMLowpMatrixMultiplyCoreFixture = GEMMLowpMatrixMultiplyCoreValidationFixture<Tensor, Accessor, NEGEMMLowpMatrixMultiplyCore>;
Gian Marcofa4cacd2017-10-18 17:05:02 +010053
morgolock4adaddb2020-09-29 14:24:32 +010054DATA_TEST_CASE(Configuration, framework::DatasetMode::ALL, framework::dataset::concat(datasets::SmallGEMMLowpDataset(), datasets::LargeGEMMLowpDataset()),
55 shape_a, shape_b, shape_c, a_offset, b_offset)
56{
57 // Create tensors
58 Tensor a = create_tensor<Tensor>(shape_a, DataType::QASYMM8);
59 Tensor b = create_tensor<Tensor>(shape_b, DataType::QASYMM8);
60 Tensor c = create_tensor<Tensor>(shape_c, DataType::S32);
61
62 a.info()->set_quantization_info(QuantizationInfo(1.0f / 255, a_offset));
63 b.info()->set_quantization_info(QuantizationInfo(1.0f / 255, b_offset));
64
65 ARM_COMPUTE_EXPECT(a.info()->is_resizable(), framework::LogLevel::ERRORS);
66 ARM_COMPUTE_EXPECT(b.info()->is_resizable(), framework::LogLevel::ERRORS);
67 ARM_COMPUTE_EXPECT(c.info()->is_resizable(), framework::LogLevel::ERRORS);
68
69 // Create and configure function
70 NEGEMMLowpMatrixMultiplyCore gemmlowp_mm;
71 gemmlowp_mm.configure(&a, &b, nullptr, &c);
72
73 // Validate padding is zero
74 validate(a.info()->padding(), PaddingSize());
75 validate(b.info()->padding(), PaddingSize());
76 validate(c.info()->padding(), PaddingSize());
77}
78
Georgios Pinitasa3b1b462017-11-16 19:24:39 +000079// *INDENT-OFF*
80// clang-format off
81DATA_TEST_CASE(Validate, framework::DatasetMode::ALL, zip(zip(zip(
82 framework::dataset::make("InputAInfo", { TensorInfo(TensorShape(21U, 13U), 1, DataType::QASYMM8, QuantizationInfo(1.f/255, 10)), // Input not a multiple of 4
Vidhya Sudhan Loganathan7485d5a2018-07-04 09:34:00 +010083 TensorInfo(TensorShape(21U, 13U), 1, DataType::S32), // Mismatching data type
Georgios Pinitasa3b1b462017-11-16 19:24:39 +000084 TensorInfo(TensorShape(20U, 13U), 1, DataType::QASYMM8, QuantizationInfo(1.f/255, 10)), // Invalid dimensions
85 TensorInfo(TensorShape(21U, 13U), 1, DataType::QASYMM8, QuantizationInfo(1.f/255, 10)), // Invalid dimensions
86 TensorInfo(TensorShape(16U, 32U), 1, DataType::QASYMM8, QuantizationInfo(1.f/255, 10)),
87 }),
88 framework::dataset::make("InputBInfo",{ TensorInfo(TensorShape(33U, 21U), 1, DataType::QASYMM8, QuantizationInfo(1.f/256, 10)),
89 TensorInfo(TensorShape(33U, 21U), 1, DataType::QASYMM8, QuantizationInfo(1.f/256, 10)),
90 TensorInfo(TensorShape(33U, 21U), 1, DataType::QASYMM8, QuantizationInfo(1.f/256, 10)),
91 TensorInfo(TensorShape(33U, 21U), 1, DataType::QASYMM8, QuantizationInfo(1.f/256, 10)),
92 TensorInfo(TensorShape(64U, 16U), 1, DataType::QASYMM8, QuantizationInfo(1.f/256, 10)),
93 })),
94 framework::dataset::make("OutputInfo",{ TensorInfo(TensorShape(33U, 13U), 1, DataType::S32),
95 TensorInfo(TensorShape(33U, 13U), 1, DataType::S32),
96 TensorInfo(TensorShape(33U, 13U), 1, DataType::S32),
97 TensorInfo(TensorShape(8U, 11U), 1, DataType::S32),
98 TensorInfo(TensorShape(64U, 32U), 1, DataType::S32),
99 })),
morgolock4adaddb2020-09-29 14:24:32 +0100100 framework::dataset::make("Expected", { true, false, false, false, true })),
Georgios Pinitasa3b1b462017-11-16 19:24:39 +0000101 a_info, b_info, output_info, expected)
102{
103 // Lock tensors
Georgios Pinitas631c41a2017-12-06 11:53:03 +0000104 Status status = NEGEMMLowpMatrixMultiplyCore::validate(&a_info.clone()->set_is_resizable(false),
105 &b_info.clone()->set_is_resizable(false),
Gian Marco Iodice4b908652018-10-18 10:21:02 +0100106 nullptr,
Georgios Pinitas631c41a2017-12-06 11:53:03 +0000107 &output_info.clone()->set_is_resizable(false));
108 ARM_COMPUTE_EXPECT(bool(status) == expected, framework::LogLevel::ERRORS);
Georgios Pinitasa3b1b462017-11-16 19:24:39 +0000109}
110// clang-format on
111// *INDENT-ON*
112
Gian Marcoe75a02b2017-11-08 12:24:09 +0000113FIXTURE_DATA_TEST_CASE(RunSmall, NEGEMMLowpMatrixMultiplyCoreFixture, framework::DatasetMode::ALL, datasets::SmallGEMMLowpDataset())
Pablo Tello299025a2017-09-29 11:30:12 +0100114{
115 // Validate output
Gian Marcofa4cacd2017-10-18 17:05:02 +0100116 validate(Accessor(_target), _reference);
117}
118
Gian Marcoe75a02b2017-11-08 12:24:09 +0000119FIXTURE_DATA_TEST_CASE(RunLarge, NEGEMMLowpMatrixMultiplyCoreFixture, framework::DatasetMode::NIGHTLY, datasets::LargeGEMMLowpDataset())
Gian Marcofa4cacd2017-10-18 17:05:02 +0100120{
121 // Validate output
122 validate(Accessor(_target), _reference);
Pablo Tello299025a2017-09-29 11:30:12 +0100123}
Pablo Tello299025a2017-09-29 11:30:12 +0100124
George Wort2d7e6832019-02-22 16:37:41 +0000125using NEGEMMLowpMatrixMultiplyCoreFusedOffsetOutputFixture = GEMMLowpMatrixMultiplyCoreFusedOffsetOutputValidationFixture<Tensor, Accessor, NEGEMMLowpMatrixMultiplyCore>;
126TEST_SUITE(FusedOffsetOutput)
Manuel Bottini959c26d2019-12-02 16:22:35 +0000127FIXTURE_DATA_TEST_CASE(RunSmall, NEGEMMLowpMatrixMultiplyCoreFusedOffsetOutputFixture, framework::DatasetMode::ALL, combine(datasets::SmallGEMMLowpFusedOffsetOutputUint8Dataset(),
Vidhya Sudhan Loganathan951b8a42019-11-04 14:42:08 +0000128 framework::dataset::make("DataType", { DataType::QASYMM8 })))
George Wort2d7e6832019-02-22 16:37:41 +0000129{
130 // Validate output
131 validate(Accessor(_target), _reference);
132}
133
Manuel Bottini959c26d2019-12-02 16:22:35 +0000134FIXTURE_DATA_TEST_CASE(RunLarge, NEGEMMLowpMatrixMultiplyCoreFusedOffsetOutputFixture, framework::DatasetMode::NIGHTLY, combine(datasets::LargeGEMMLowpFusedOffsetOutputUint8Dataset(),
Vidhya Sudhan Loganathan951b8a42019-11-04 14:42:08 +0000135 framework::dataset::make("DataType", { DataType::QASYMM8 })))
George Wort2d7e6832019-02-22 16:37:41 +0000136{
137 // Validate output
138 validate(Accessor(_target), _reference);
139}
140TEST_SUITE_END() // FusedOffsetOutput
Gian Marcoe75a02b2017-11-08 12:24:09 +0000141TEST_SUITE_END() // MatrixMultiplyCore
142
143TEST_SUITE(OutputStage)
144
Luca Foschiani4b869532020-02-13 15:07:36 +0000145TEST_SUITE(QuantizeDownInt32Scale)
146
147TEST_SUITE(QASYMM8)
Gian Marcoe75a02b2017-11-08 12:24:09 +0000148
Gian Marco05288a22017-11-21 10:57:50 +0000149const auto quantize_down_int32_to_uint8_scale_cases = framework::dataset::make("result_offset", -2, 1) * framework::dataset::make("result_mult_int", 1, 2) * framework::dataset::make("result_shift", 2,
Gian Marco6b77e912017-11-17 09:27:57 +0000150 3)
Giorgio Arena1856ff72020-02-07 13:46:45 +0000151 * framework::dataset::make("min", 0) * framework::dataset::make("max", 255) * framework::dataset::make("addBias", { false, true });
Gian Marco6b77e912017-11-17 09:27:57 +0000152
Gian Marco05288a22017-11-21 10:57:50 +0000153const auto quantize_down_int32_to_uint8_scale_relu_cases = framework::dataset::make("result_offset", -2, 1) * framework::dataset::make("result_mult_int", 1,
Gian Marco6b77e912017-11-17 09:27:57 +0000154 2)
155 * framework::dataset::make("result_shift", 2, 3) * framework::dataset::make("min", 0, 2) * framework::dataset::make("max", 171, 174) * framework::dataset::make("addBias", { false, true });
156
Luca Foschiani4b869532020-02-13 15:07:36 +0000157using NEGEMMLowpQuantizeDownInt32ScaleFixture = GEMMLowpQuantizeDownInt32ToUint8ScaleValidationFixture<Tensor, Accessor, NEGEMMLowpOutputStage>;
Gian Marcoe75a02b2017-11-08 12:24:09 +0000158
Gian Marco7f0f7902017-12-07 09:26:56 +0000159// *INDENT-OFF*
160// clang-format off
161DATA_TEST_CASE(Validate, framework::DatasetMode::ALL, zip(zip(zip(zip(zip(
162 framework::dataset::make("InputAInfo", { TensorInfo(TensorShape(21U, 13U), 1, DataType::S32), // Input not a multiple of 16
Gian Marco7f0f7902017-12-07 09:26:56 +0000163 TensorInfo(TensorShape(20U, 13U), 1, DataType::S32), // Wrong output data type
164 }),
165 framework::dataset::make("InputBInfo",{ TensorInfo(TensorShape(21U), 1, DataType::S32),
Gian Marco7f0f7902017-12-07 09:26:56 +0000166 TensorInfo(TensorShape(20U), 1, DataType::S32),
167 })),
168 framework::dataset::make("OutputInfo",{ TensorInfo(TensorShape(21U, 13U), 1, DataType::QASYMM8),
Gian Marco7f0f7902017-12-07 09:26:56 +0000169 TensorInfo(TensorShape(20U, 13U), 1, DataType::S32),
170 })),
171 framework::dataset::make("Min",{ 0,
Gian Marco7f0f7902017-12-07 09:26:56 +0000172 13,
173 })),
174 framework::dataset::make("Max",{ 205,
Gian Marco7f0f7902017-12-07 09:26:56 +0000175 180,
176 })),
Giorgio Arena1856ff72020-02-07 13:46:45 +0000177 framework::dataset::make("Expected", { true, false })),
Gian Marco7f0f7902017-12-07 09:26:56 +0000178 a_info, b_info, output_info, min, max, expected)
179{
Luca Foschiani4b869532020-02-13 15:07:36 +0000180
181 GEMMLowpOutputStageInfo output_stage = GEMMLowpOutputStageInfo();
182 output_stage.type = GEMMLowpOutputStageType::QUANTIZE_DOWN;
183 output_stage.gemmlowp_min_bound = min;
184 output_stage.gemmlowp_max_bound = max;
185 output_stage.output_data_type = DataType::QASYMM8;
186
Gian Marco7f0f7902017-12-07 09:26:56 +0000187 // Lock tensors
Luca Foschiani4b869532020-02-13 15:07:36 +0000188 Status status = NEGEMMLowpOutputStage::validate(&a_info.clone()->set_is_resizable(false),
Gian Marco7f0f7902017-12-07 09:26:56 +0000189 &b_info.clone()->set_is_resizable(false),
190 &output_info.clone()->set_is_resizable(false),
Luca Foschiani4b869532020-02-13 15:07:36 +0000191 output_stage);
Gian Marco7f0f7902017-12-07 09:26:56 +0000192 ARM_COMPUTE_EXPECT(bool(status) == expected, framework::LogLevel::ERRORS);
193}
194// clang-format on
195// *INDENT-ON*
196
morgolockf1109542020-09-15 14:33:54 +0100197TEST_CASE(NoPaddingAdded, framework::DatasetMode::PRECOMMIT)
198{
199 Tensor input1 = create_tensor<Tensor>(TensorShape(21U, 13U), DataType::S32);
200 Tensor input2 = create_tensor<Tensor>(TensorShape(21U, 1U), DataType::S32);
201 Tensor output = create_tensor<Tensor>(TensorShape(21U, 13U), DataType::QASYMM8);
202
203 GEMMLowpOutputStageInfo output_stage = GEMMLowpOutputStageInfo();
Michalis Spyroud175ece2020-07-30 23:39:32 +0100204 output_stage.type = GEMMLowpOutputStageType::QUANTIZE_DOWN;
205 output_stage.gemmlowp_min_bound = 0;
206 output_stage.gemmlowp_max_bound = 205;
207 output_stage.output_data_type = DataType::QASYMM8;
morgolockf1109542020-09-15 14:33:54 +0100208
209 NEGEMMLowpOutputStage f;
210 f.configure(&input1, &input2, &output, output_stage);
211
212 // Validate padding is zero
213 validate(input1.info()->padding(), PaddingSize());
214 validate(input2.info()->padding(), PaddingSize());
215 validate(output.info()->padding(), PaddingSize());
216}
217
Luca Foschiani4b869532020-02-13 15:07:36 +0000218FIXTURE_DATA_TEST_CASE(RunSmall, NEGEMMLowpQuantizeDownInt32ScaleFixture, framework::DatasetMode::ALL, combine(datasets::SmallShapes(), quantize_down_int32_to_uint8_scale_cases))
Gian Marcoe75a02b2017-11-08 12:24:09 +0000219{
220 // Validate output
221 validate(Accessor(_target), _reference);
222}
223
Gian Marco6b77e912017-11-17 09:27:57 +0000224TEST_SUITE(BoundedReLu)
Luca Foschiani4b869532020-02-13 15:07:36 +0000225FIXTURE_DATA_TEST_CASE(RunSmall, NEGEMMLowpQuantizeDownInt32ScaleFixture, framework::DatasetMode::ALL, combine(datasets::SmallShapes(), quantize_down_int32_to_uint8_scale_relu_cases))
Gian Marco6b77e912017-11-17 09:27:57 +0000226{
227 // Validate output
228 validate(Accessor(_target), _reference);
229}
Gian Marcoe75a02b2017-11-08 12:24:09 +0000230
Gian Marco6b77e912017-11-17 09:27:57 +0000231TEST_SUITE_END() // BoundedReLu
232
Luca Foschiani4b869532020-02-13 15:07:36 +0000233TEST_SUITE_END() // QASYMM8
234
235TEST_SUITE(QASYMM8_SIGNED)
236
237const auto quantize_down_int32_to_int8_scale_cases = framework::dataset::make("result_offset", -2, 1) * framework::dataset::make("result_mult_int", 1, 2) * framework::dataset::make("result_shift", 2,
238 3)
239 * framework::dataset::make("min", 0) * framework::dataset::make("max", 0) * framework::dataset::make("addBias", { false, true });
240
241const auto quantize_down_int32_to_int8_scale_relu_cases = framework::dataset::make("result_offset", -2, 1) * framework::dataset::make("result_mult_int", 1,
242 2)
243 * framework::dataset::make("result_shift", 2, 3) * framework::dataset::make("min", -100, -98) * framework::dataset::make("max", 71, 74) * framework::dataset::make("addBias", { false, true });
244
245using NEGEMMLowpQuantizeDownInt32ScaleFixture = GEMMLowpQuantizeDownInt32ToInt8ScaleValidationFixture<Tensor, Accessor, NEGEMMLowpOutputStage>;
246
247// *INDENT-OFF*
248// clang-format off
249DATA_TEST_CASE(Validate, framework::DatasetMode::ALL, zip(zip(zip(zip(zip(
250 framework::dataset::make("InputAInfo", { TensorInfo(TensorShape(21U, 13U), 1, DataType::S32), // Input not a multiple of 16
251 TensorInfo(TensorShape(21U, 13U), 1, DataType::S32), // Invalid min and max
252 TensorInfo(TensorShape(20U, 13U), 1, DataType::S32), // Wrong output data type
253 }),
254 framework::dataset::make("InputBInfo",{ TensorInfo(TensorShape(21U), 1, DataType::S32),
255 TensorInfo(TensorShape(21U), 1, DataType::S32),
256 TensorInfo(TensorShape(20U), 1, DataType::S32),
257 })),
258 framework::dataset::make("OutputInfo",{ TensorInfo(TensorShape(21U, 13U), 1, DataType::QASYMM8_SIGNED),
259 TensorInfo(TensorShape(21U, 13U), 1, DataType::QASYMM8_SIGNED),
260 TensorInfo(TensorShape(20U, 13U), 1, DataType::S32),
261 })),
262 framework::dataset::make("Min",{ -10,
263 -200,
264 -113,
265 })),
266 framework::dataset::make("Max",{ 105,
267 300,
268 -18,
269 })),
270 framework::dataset::make("Expected", { true, false, false })),
271 a_info, b_info, output_info, min, max, expected)
272{
273 GEMMLowpOutputStageInfo output_stage = GEMMLowpOutputStageInfo();
274 output_stage.type = GEMMLowpOutputStageType::QUANTIZE_DOWN;
275 output_stage.gemmlowp_min_bound = min;
276 output_stage.gemmlowp_max_bound = max;
277 output_stage.output_data_type = DataType::QASYMM8_SIGNED;
278
279 // Lock tensors
280 Status status = NEGEMMLowpOutputStage::validate(&a_info.clone()->set_is_resizable(false),
281 &b_info.clone()->set_is_resizable(false),
282 &output_info.clone()->set_is_resizable(false),
283 output_stage);
284 ARM_COMPUTE_EXPECT(bool(status) == expected, framework::LogLevel::ERRORS);
285}
286// clang-format on
287// *INDENT-ON*
288
289FIXTURE_DATA_TEST_CASE(RunSmall, NEGEMMLowpQuantizeDownInt32ScaleFixture, framework::DatasetMode::ALL, combine(datasets::SmallShapes(), quantize_down_int32_to_int8_scale_cases))
290{
291 // Validate output
292 validate(Accessor(_target), _reference);
293}
294
295TEST_SUITE(BoundedReLu)
296FIXTURE_DATA_TEST_CASE(RunSmall, NEGEMMLowpQuantizeDownInt32ScaleFixture, framework::DatasetMode::ALL, combine(datasets::SmallShapes(), quantize_down_int32_to_int8_scale_relu_cases))
297{
298 // Validate output
299 validate(Accessor(_target), _reference);
300}
301
302TEST_SUITE_END() // BoundedReLu
303
304TEST_SUITE_END() // QASYMM8_SIGNED
305
306TEST_SUITE_END() // QuantizeDownInt32Scale
Gian Marco58c57942017-11-28 09:10:03 +0000307
308TEST_SUITE(QuantizeDownInt32ToUint8ScaleByFixedPoint)
309
310const auto quantize_down_int32_to_uint8_scale_by_fixedpoint_cases = framework::dataset::make("result_fixedpoint_multiplier", 254601600, 254601602) * framework::dataset::make("result_shift", 1,
311 2)
Giorgio Arena1856ff72020-02-07 13:46:45 +0000312 * framework::dataset::make("result_offset_after_shift", 2, 3) * framework::dataset::make("min", 0) * framework::dataset::make("max", 255) * framework::dataset::make("addBias", { false, true });
Gian Marco58c57942017-11-28 09:10:03 +0000313
314const auto quantize_down_int32_to_uint8_scale_by_fixedpoint_relu_cases = framework::dataset::make("result_fixedpoint_multiplier", 254601600, 254601602) * framework::dataset::make("result_shift", 1,
315 2)
316 * framework::dataset::make("result_offset_after_shift", 2, 3) * framework::dataset::make("min", 0, 2) * framework::dataset::make("max", 171, 174) * framework::dataset::make("addBias", { false, true });
317
318using NEGEMMLowpQuantizeDownInt32ToUint8ScaleByFixedPointFixture =
319 GEMMLowpQuantizeDownInt32ToUint8ScaleByFixedPointValidationFixture<Tensor, Accessor, NEGEMMLowpQuantizeDownInt32ToUint8ScaleByFixedPoint>;
320
Gian Marco Iodicebc415af2019-06-13 15:58:32 +0100321using NEGEMMLowpQuantizeDownInt32ToInt16ScaleByFixedPointFixture =
322 GEMMLowpQuantizeDownInt32ToInt16ScaleByFixedPointValidationFixture<Tensor, Accessor, NEGEMMLowpQuantizeDownInt32ToInt16ScaleByFixedPoint>;
323
Gian Marco7f0f7902017-12-07 09:26:56 +0000324// *INDENT-OFF*
325// clang-format off
326DATA_TEST_CASE(Validate, framework::DatasetMode::ALL, zip(zip(zip(zip(zip(
327 framework::dataset::make("InputAInfo", { TensorInfo(TensorShape(21U, 13U), 1, DataType::S32), // Input not a multiple of 16
Gian Marco7f0f7902017-12-07 09:26:56 +0000328 TensorInfo(TensorShape(20U, 13U), 1, DataType::S32), // Wrong output data type
329 }),
330 framework::dataset::make("InputBInfo",{ TensorInfo(TensorShape(21U), 1, DataType::S32),
Gian Marco7f0f7902017-12-07 09:26:56 +0000331 TensorInfo(TensorShape(20U), 1, DataType::S32),
332 })),
333 framework::dataset::make("OutputInfo",{ TensorInfo(TensorShape(21U, 13U), 1, DataType::QASYMM8),
Gian Marco7f0f7902017-12-07 09:26:56 +0000334 TensorInfo(TensorShape(20U, 13U), 1, DataType::S32),
335 })),
336 framework::dataset::make("Min",{ 0,
Gian Marco7f0f7902017-12-07 09:26:56 +0000337 13,
338 })),
339 framework::dataset::make("Max",{ 205,
Gian Marco7f0f7902017-12-07 09:26:56 +0000340 180,
341 })),
Giorgio Arena1856ff72020-02-07 13:46:45 +0000342 framework::dataset::make("Expected", { true, false })),
Gian Marco7f0f7902017-12-07 09:26:56 +0000343 a_info, b_info, output_info, min, max, expected)
344{
345 // Lock tensors
346 Status status = NEGEMMLowpQuantizeDownInt32ToUint8ScaleByFixedPoint::validate(&a_info.clone()->set_is_resizable(false),
347 &b_info.clone()->set_is_resizable(false),
348 &output_info.clone()->set_is_resizable(false),
349 min,
350 max);
351 ARM_COMPUTE_EXPECT(bool(status) == expected, framework::LogLevel::ERRORS);
352}
353// clang-format on
354// *INDENT-ON*
355
Gian Marco58c57942017-11-28 09:10:03 +0000356FIXTURE_DATA_TEST_CASE(RunSmall, NEGEMMLowpQuantizeDownInt32ToUint8ScaleByFixedPointFixture, framework::DatasetMode::ALL, combine(datasets::SmallShapes(),
357 quantize_down_int32_to_uint8_scale_by_fixedpoint_cases))
358{
359 // Validate output
360 validate(Accessor(_target), _reference);
361}
362
363FIXTURE_DATA_TEST_CASE(RunLarge, NEGEMMLowpQuantizeDownInt32ToUint8ScaleByFixedPointFixture, framework::DatasetMode::NIGHTLY, combine(datasets::LargeShapes(),
364 quantize_down_int32_to_uint8_scale_by_fixedpoint_cases))
365{
366 // Validate output
367 validate(Accessor(_target), _reference);
368}
369
370TEST_SUITE(BoundedReLu)
371FIXTURE_DATA_TEST_CASE(RunSmall, NEGEMMLowpQuantizeDownInt32ToUint8ScaleByFixedPointFixture, framework::DatasetMode::ALL, combine(datasets::SmallShapes(),
372 quantize_down_int32_to_uint8_scale_by_fixedpoint_relu_cases))
373{
374 // Validate output
375 validate(Accessor(_target), _reference);
376}
377
378FIXTURE_DATA_TEST_CASE(RunLarge, NEGEMMLowpQuantizeDownInt32ToUint8ScaleByFixedPointFixture, framework::DatasetMode::NIGHTLY, combine(datasets::LargeShapes(),
379 quantize_down_int32_to_uint8_scale_by_fixedpoint_relu_cases))
380{
381 // Validate output
382 validate(Accessor(_target), _reference);
383}
384TEST_SUITE_END() // BoundedReLu
385
386TEST_SUITE_END() // QuantizeDownInt32ToUint8ScaleByFixedPoint
Gian Marco Iodicebc415af2019-06-13 15:58:32 +0100387
Georgios Pinitas448a81f2019-11-21 14:10:25 +0000388TEST_SUITE(QuantizeDownInt32ToInt8ScaleByFixedPoint)
389
390const auto quantize_down_int32_to_int8_scale_by_fixedpoint_cases = framework::dataset::make("result_fixedpoint_multiplier", 254601600, 254601602) * framework::dataset::make("result_shift", 1,
391 2)
Giorgio Arena1856ff72020-02-07 13:46:45 +0000392 * framework::dataset::make("result_offset_after_shift", 2, 3) * framework::dataset::make("min", -128) * framework::dataset::make("max", 128) * framework::dataset::make("addBias", { false, true });
Georgios Pinitas448a81f2019-11-21 14:10:25 +0000393
394const auto quantize_down_int32_to_int8_scale_by_fixedpoint_relu_cases = framework::dataset::make("result_fixedpoint_multiplier", 254601600, 254601602) * framework::dataset::make("result_shift", 1,
395 2)
396 * framework::dataset::make("result_offset_after_shift", 2, 3) * framework::dataset::make("min", -2, 0) * framework::dataset::make("max", 1, 3) * framework::dataset::make("addBias", { false, true });
397
398using NEGEMMLowpQuantizeDownInt32ToInt8ScaleByFixedPointFixture =
399 GEMMLowpQuantizeDownInt32ToInt8ScaleByFixedPointValidationFixture<Tensor, Accessor, NEGEMMLowpQuantizeDownInt32ToInt8ScaleByFixedPoint>;
400
401// *INDENT-OFF*
402// clang-format off
403DATA_TEST_CASE(Validate, framework::DatasetMode::ALL, zip(zip(zip(zip(zip(
404 framework::dataset::make("InputAInfo", { TensorInfo(TensorShape(21U, 13U), 1, DataType::F32), // Invalid input data type
Georgios Pinitas448a81f2019-11-21 14:10:25 +0000405 TensorInfo(TensorShape(20U, 13U), 1, DataType::S32), // Wrong output data type
406 TensorInfo(TensorShape(21U, 13U), 1, DataType::S32),
407 }),
408 framework::dataset::make("InputBInfo",{ TensorInfo(TensorShape(21U), 1, DataType::S32),
Georgios Pinitas448a81f2019-11-21 14:10:25 +0000409 TensorInfo(TensorShape(20U), 1, DataType::S32),
410 TensorInfo(TensorShape(21U), 1, DataType::S32),
411 })),
412 framework::dataset::make("OutputInfo",{ TensorInfo(TensorShape(21U, 13U), 1, DataType::QASYMM8_SIGNED),
Georgios Pinitas448a81f2019-11-21 14:10:25 +0000413 TensorInfo(TensorShape(20U, 13U), 1, DataType::S32),
414 TensorInfo(TensorShape(21U, 13U), 1, DataType::QASYMM8_SIGNED),
415 })),
416 framework::dataset::make("Min",{ -110,
Georgios Pinitas448a81f2019-11-21 14:10:25 +0000417 -113,
418 -113,
419 })),
420 framework::dataset::make("Max",{ 87,
Georgios Pinitas448a81f2019-11-21 14:10:25 +0000421 97,
422 97,
423 })),
Giorgio Arena1856ff72020-02-07 13:46:45 +0000424 framework::dataset::make("Expected", { false, false, true })),
Georgios Pinitas448a81f2019-11-21 14:10:25 +0000425 a_info, b_info, output_info, min, max, expected)
426{
427 // Lock tensors
428 Status status = NEGEMMLowpQuantizeDownInt32ToInt8ScaleByFixedPoint::validate(&a_info.clone()->set_is_resizable(false),
429 &b_info.clone()->set_is_resizable(false),
430 &output_info.clone()->set_is_resizable(false),
431 min,
432 max);
433 ARM_COMPUTE_EXPECT(bool(status) == expected, framework::LogLevel::ERRORS);
434}
435// clang-format on
436// *INDENT-ON*
437
Georgios Pinitas448a81f2019-11-21 14:10:25 +0000438FIXTURE_DATA_TEST_CASE(RunSmall, NEGEMMLowpQuantizeDownInt32ToInt8ScaleByFixedPointFixture, framework::DatasetMode::ALL, combine(datasets::SmallShapes(),
439 quantize_down_int32_to_int8_scale_by_fixedpoint_cases))
440{
441 // Validate output
442 validate(Accessor(_target), _reference);
443}
444
445TEST_SUITE(BoundedReLu)
446FIXTURE_DATA_TEST_CASE(RunSmall, NEGEMMLowpQuantizeDownInt32ToInt8ScaleByFixedPointFixture, framework::DatasetMode::ALL, combine(datasets::SmallShapes(),
447 quantize_down_int32_to_int8_scale_by_fixedpoint_relu_cases))
448{
449 // Validate output
450 validate(Accessor(_target), _reference);
451}
452TEST_SUITE_END() // BoundedReLu
453TEST_SUITE_END() // QuantizeDownInt32ToInt8ScaleByFixedPoint
454
Gian Marco Iodicebc415af2019-06-13 15:58:32 +0100455TEST_SUITE(QuantizeDownInt32ToInt16ScaleByFixedPoint)
456
457const auto quantize_down_int32_to_int16_scale_by_fixedpoint_cases = framework::dataset::make("result_fixedpoint_multiplier", 254601600, 254601602) * framework::dataset::make("result_shift", 1,
458 2)
Giorgio Arena1856ff72020-02-07 13:46:45 +0000459 * framework::dataset::make("min", -32768) * framework::dataset::make("max", 32767) * framework::dataset::make("addBias", { false, true });
Gian Marco Iodicebc415af2019-06-13 15:58:32 +0100460
461const auto quantize_down_int32_to_int16_scale_by_fixedpoint_relu_cases = framework::dataset::make("result_fixedpoint_multiplier", 254601600, 254601602) * framework::dataset::make("result_shift", 1,
462 2)
463 * framework::dataset::make("min", -2, 0) * framework::dataset::make("max", 1, 3) * framework::dataset::make("addBias", { false, true });
Vidhya Sudhan Loganathan951b8a42019-11-04 14:42:08 +0000464const auto quantize_down_int32_to_int16_scale_by_fixedpoint_multgreat1_cases = framework::dataset::make("result_fixedpoint_multiplier", 1073741823,
465 1073741825)
466 * framework::dataset::make("result_shift", -3,
467 -2)
Giorgio Arena1856ff72020-02-07 13:46:45 +0000468 * framework::dataset::make("min", -32768) * framework::dataset::make("max", 32767) * framework::dataset::make("addBias", { false, true });
Manuel Bottini07263982019-10-17 18:37:26 +0100469
Vidhya Sudhan Loganathan951b8a42019-11-04 14:42:08 +0000470const auto quantize_down_int32_to_int16_scale_by_fixedpoint_multgreat1_relu_cases = framework::dataset::make("result_fixedpoint_multiplier", 254601600,
471 254601602)
472 * framework::dataset::make("result_shift", -3,
473 -1)
474 * framework::dataset::make("min", -2, 0) * framework::dataset::make("max", 1, 3) * framework::dataset::make("addBias", { false, true });
Gian Marco Iodicebc415af2019-06-13 15:58:32 +0100475
476using NEGEMMLowpQuantizeDownInt32ToInt16ScaleByFixedPointFixture =
477 GEMMLowpQuantizeDownInt32ToInt16ScaleByFixedPointValidationFixture<Tensor, Accessor, NEGEMMLowpQuantizeDownInt32ToInt16ScaleByFixedPoint>;
478
479// *INDENT-OFF*
480// clang-format off
481DATA_TEST_CASE(Validate, framework::DatasetMode::ALL, zip(zip(zip(zip(zip(
482 framework::dataset::make("InputAInfo", { TensorInfo(TensorShape(21U, 13U), 1, DataType::S32), // Input not a multiple of 16
Gian Marco Iodicebc415af2019-06-13 15:58:32 +0100483 TensorInfo(TensorShape(20U, 13U), 1, DataType::S32), // Wrong output data type
484 }),
485 framework::dataset::make("InputBInfo",{ TensorInfo(TensorShape(21U), 1, DataType::S32),
Gian Marco Iodicebc415af2019-06-13 15:58:32 +0100486 TensorInfo(TensorShape(20U), 1, DataType::S32),
487 })),
488 framework::dataset::make("OutputInfo",{ TensorInfo(TensorShape(21U, 13U), 1, DataType::QSYMM16),
Gian Marco Iodicebc415af2019-06-13 15:58:32 +0100489 TensorInfo(TensorShape(20U, 13U), 1, DataType::S32),
490 })),
491 framework::dataset::make("Min",{ -205,
Gian Marco Iodicebc415af2019-06-13 15:58:32 +0100492 -180,
493 })),
494 framework::dataset::make("Max",{ 205,
Gian Marco Iodicebc415af2019-06-13 15:58:32 +0100495 180,
496 })),
Giorgio Arena1856ff72020-02-07 13:46:45 +0000497 framework::dataset::make("Expected", { true, false })),
Gian Marco Iodicebc415af2019-06-13 15:58:32 +0100498 a_info, b_info, output_info, min, max, expected)
499{
500 // Lock tensors
501 Status status = NEGEMMLowpQuantizeDownInt32ToInt16ScaleByFixedPoint::validate(&a_info.clone()->set_is_resizable(false),
502 &b_info.clone()->set_is_resizable(false),
503 &output_info.clone()->set_is_resizable(false),
504 min,
505 max);
506 ARM_COMPUTE_EXPECT(bool(status) == expected, framework::LogLevel::ERRORS);
507}
508// clang-format on
509// *INDENT-ON*
510
Manuel Bottini07263982019-10-17 18:37:26 +0100511TEST_SUITE(NoRelu)
512TEST_SUITE(MultSmallerEq1)
Gian Marco Iodicebc415af2019-06-13 15:58:32 +0100513FIXTURE_DATA_TEST_CASE(RunSmall, NEGEMMLowpQuantizeDownInt32ToInt16ScaleByFixedPointFixture, framework::DatasetMode::ALL, combine(datasets::SmallShapes(),
514 quantize_down_int32_to_int16_scale_by_fixedpoint_cases))
515{
516 // Validate output
517 validate(Accessor(_target), _reference);
518}
Manuel Bottini07263982019-10-17 18:37:26 +0100519TEST_SUITE_END() // MultSmallerEq1
520TEST_SUITE(MultGreater1)
521FIXTURE_DATA_TEST_CASE(RunSmall, NEGEMMLowpQuantizeDownInt32ToInt16ScaleByFixedPointFixture, framework::DatasetMode::ALL, combine(datasets::SmallShapes(),
522 quantize_down_int32_to_int16_scale_by_fixedpoint_multgreat1_cases))
523{
524 // Validate output
525 validate(Accessor(_target), _reference);
526}
527TEST_SUITE_END() // MultGreater1
528TEST_SUITE_END() // NoRelu
Gian Marco Iodicebc415af2019-06-13 15:58:32 +0100529TEST_SUITE(BoundedReLu)
Manuel Bottini07263982019-10-17 18:37:26 +0100530TEST_SUITE(MultSmallerEq1)
Gian Marco Iodicebc415af2019-06-13 15:58:32 +0100531FIXTURE_DATA_TEST_CASE(RunSmall, NEGEMMLowpQuantizeDownInt32ToInt16ScaleByFixedPointFixture, framework::DatasetMode::ALL, combine(datasets::SmallShapes(),
532 quantize_down_int32_to_int16_scale_by_fixedpoint_relu_cases))
533{
534 // Validate output
535 validate(Accessor(_target), _reference);
536}
Manuel Bottini07263982019-10-17 18:37:26 +0100537TEST_SUITE_END() // MultSmallerEq1
538TEST_SUITE(MultGreater1)
539FIXTURE_DATA_TEST_CASE(RunSmall, NEGEMMLowpQuantizeDownInt32ToInt16ScaleByFixedPointFixture, framework::DatasetMode::ALL, combine(datasets::SmallShapes(),
540 quantize_down_int32_to_int16_scale_by_fixedpoint_multgreat1_relu_cases))
541{
542 // Validate output
543 validate(Accessor(_target), _reference);
544}
545TEST_SUITE_END() // MultGreater1
Gian Marco Iodicebc415af2019-06-13 15:58:32 +0100546TEST_SUITE_END() // BoundedReLu
Gian Marco Iodicebc415af2019-06-13 15:58:32 +0100547TEST_SUITE_END() // QuantizeDownInt32ToInt16ScaleByFixedPoint
Gian Marcoe75a02b2017-11-08 12:24:09 +0000548TEST_SUITE_END() // OutputStage
Gian Marcoe75a02b2017-11-08 12:24:09 +0000549TEST_SUITE_END() // GEMMLowp
550TEST_SUITE_END() // NEON
Pablo Tello299025a2017-09-29 11:30:12 +0100551} // namespace validation
552} // namespace test
553} // namespace arm_compute