blob: 2397d815478a9f88960b48984bafdd7fa7091dfb [file] [log] [blame]
Moritz Pflanzerf6ad98a2017-07-21 17:19:58 +01001/*
Matthew Bentham314d3e22023-06-23 10:53:52 +00002 * Copyright (c) 2017-2020, 2022-2023 Arm Limited.
Moritz Pflanzerf6ad98a2017-07-21 17:19:58 +01003 *
4 * SPDX-License-Identifier: MIT
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a copy
7 * of this software and associated documentation files (the "Software"), to
8 * deal in the Software without restriction, including without limitation the
9 * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
10 * sell copies of the Software, and to permit persons to whom the Software is
11 * furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be included in all
14 * copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 * SOFTWARE.
23 */
24#include "arm_compute/core/Types.h"
25#include "arm_compute/runtime/NEON/functions/NESoftmaxLayer.h"
26#include "arm_compute/runtime/Tensor.h"
27#include "arm_compute/runtime/TensorAllocator.h"
Dana Zlotnik6a2df882022-01-17 09:54:26 +020028#include "src/common/cpuinfo/CpuIsaInfo.h"
29#include "src/cpu/kernels/CpuSoftmaxKernel.h"
Moritz Pflanzerf6ad98a2017-07-21 17:19:58 +010030#include "tests/NEON/Accessor.h"
Moritz Pflanzera09de0c2017-09-01 20:41:12 +010031#include "tests/datasets/ShapeDatasets.h"
32#include "tests/framework/Asserts.h"
33#include "tests/framework/Macros.h"
34#include "tests/framework/datasets/Datasets.h"
35#include "tests/validation/Validation.h"
36#include "tests/validation/fixtures/SoftmaxLayerFixture.h"
Moritz Pflanzerf6ad98a2017-07-21 17:19:58 +010037namespace arm_compute
38{
39namespace test
40{
41namespace validation
42{
Gunes Bayirfadc9b12023-11-07 05:43:07 +000043using framework::dataset::make;
Moritz Pflanzerf6ad98a2017-07-21 17:19:58 +010044namespace
45{
46/** Tolerance for float operations */
Moritz Pflanzer6106a4d2017-08-02 09:42:27 +010047constexpr AbsoluteTolerance<float> tolerance_f32(0.000001f);
Manuel Bottini678d83a2019-01-07 16:05:36 +000048RelativeTolerance<half> tolerance_f16(half(0.2));
Moritz Pflanzerf6ad98a2017-07-21 17:19:58 +010049
Diego Lopez Recas35ceeb22017-12-04 18:56:10 +000050/** Tolerance for quantized operations */
51constexpr AbsoluteTolerance<uint8_t> tolerance_qasymm8(1);
Sang-Hoon Parkc3a74202019-11-22 16:05:46 +000052constexpr AbsoluteTolerance<int8_t> tolerance_qasymm8_signed(1);
Diego Lopez Recas35ceeb22017-12-04 18:56:10 +000053
Moritz Pflanzerf6ad98a2017-07-21 17:19:58 +010054/** CNN data types */
Gunes Bayirfadc9b12023-11-07 05:43:07 +000055const auto CNNDataTypes = make("DataType",
Moritz Pflanzerf6ad98a2017-07-21 17:19:58 +010056{
Ioan-Cristian Szabo5edbd1c2017-11-13 13:34:08 +000057#ifdef __ARM_FEATURE_FP16_VECTOR_ARITHMETIC
Moritz Pflanzerf6ad98a2017-07-21 17:19:58 +010058 DataType::F16,
Ioan-Cristian Szabo5edbd1c2017-11-13 13:34:08 +000059#endif /* __ARM_FEATURE_FP16_VECTOR_ARITHMETIC */
Moritz Pflanzerf6ad98a2017-07-21 17:19:58 +010060 DataType::F32,
Moritz Pflanzerf6ad98a2017-07-21 17:19:58 +010061});
62} // namespace
63
64TEST_SUITE(NEON)
65TEST_SUITE(SoftmaxLayer)
Michalis Spyrouafa5d812017-11-30 14:25:57 +000066// *INDENT-OFF*
67// clang-format off
Gunes Bayirfadc9b12023-11-07 05:43:07 +000068DATA_TEST_CASE(Validate, framework::DatasetMode::ALL, zip(
69 make("InputInfo", { TensorInfo(TensorShape(27U, 13U), 1, DataType::F32), // Mismatching data types
70 TensorInfo(TensorShape(27U, 13U), 1, DataType::F32), // Mismatching shapes
71 TensorInfo(TensorShape(27U, 13U), 1, DataType::QASYMM8, // Invalid output quantization info
72 QuantizationInfo(1.f/256, 12)),
73 TensorInfo(TensorShape(32U, 13U), 1, DataType::F32),
74 TensorInfo(TensorShape(32U, 13U), 1, DataType::QASYMM8,
75 QuantizationInfo(1.f/256, 12)),
76 TensorInfo(TensorShape(32U, 13U), 1, DataType::F32),
77 TensorInfo(TensorShape(32U, 13U), 1, DataType::QASYMM8, //Invalid axis high
78 QuantizationInfo(1.f/256, 12)),
79 TensorInfo(TensorShape(32U, 13U), 1, DataType::QASYMM8, //Invalid axis low
80 QuantizationInfo(1.f/256, 12)),
81 }),
82 make("OutputInfo",{ TensorInfo(TensorShape(27U, 13U), 1, DataType::F16),
83 TensorInfo(TensorShape(27U, 11U), 1, DataType::F32),
84 TensorInfo(TensorShape(27U, 13U), 1, DataType::QASYMM8,
85 QuantizationInfo(1.f/256, 12)),
86 TensorInfo(TensorShape(32U, 13U), 1, DataType::F32),
87 TensorInfo(TensorShape(32U, 13U), 1, DataType::QASYMM8,
88 QuantizationInfo(1.f/256, 0)),
89 TensorInfo(TensorShape(32U, 13U), 1, DataType::F32),
90 TensorInfo(TensorShape(32U, 13U), 1, DataType::QASYMM8,
91 QuantizationInfo(1.f/256, 0)),
92 TensorInfo(TensorShape(32U, 13U), 1, DataType::QASYMM8,
93 QuantizationInfo(1.f/256, 0)),
94 }),
95 make("beta", { 1.0,
96 2.0,
97 1.0,
98 2.0,
99 1.0,
100 1.0,
101 2.0,
102 1.0,
103 }),
104 make("axis", { 0,
105 0,
106 0,
107 1,
108 0,
109 -1,
110 2,
111 -3,
112 }),
113 make("Expected", { false, false, false, true, true, true, false, false })),
114 input_info, output_info, beta, axis, expected)
Michalis Spyrouafa5d812017-11-30 14:25:57 +0000115{
morgolock9c7fed82020-08-05 12:30:56 +0100116 ARM_COMPUTE_EXPECT(bool(NESoftmaxLayer::validate(&input_info.clone()->set_is_resizable(false), &output_info.clone()->set_is_resizable(false), beta, axis)) == expected, framework::LogLevel::ERRORS);
Michalis Spyrouafa5d812017-11-30 14:25:57 +0000117}
118// clang-format on
119// *INDENT-ON*
120
Moritz Pflanzerf6ad98a2017-07-21 17:19:58 +0100121template <typename T>
122using NESoftmaxLayerFixture = SoftmaxValidationFixture<Tensor, Accessor, NESoftmaxLayer, T>;
123
Gunes Bayirfadc9b12023-11-07 05:43:07 +0000124DATA_TEST_CASE(KernelSelection, framework::DatasetMode::ALL,
125 concat(concat(
126 combine(
127 make("CpuExt", std::string("NEON")),
128 make("DataType", { DataType::F32,
129 DataType::F16,
130 DataType::QASYMM8,
131 DataType::QASYMM8_SIGNED})
132 ),
133 combine(
134 make("CpuExt", std::string("SVE")),
135 make("DataType", { DataType::F32,
136 DataType::F16}))
137 ),
138 combine(
139 make("CpuExt", std::string("SVE2")),
140 make("DataType", { DataType::QASYMM8,
141 DataType::QASYMM8_SIGNED}))
142 ),
143 cpu_ext, data_type)
Dana Zlotnik6a2df882022-01-17 09:54:26 +0200144{
145 using namespace cpu::kernels;
146
147 cpuinfo::CpuIsaInfo cpu_isa{};
148 cpu_isa.neon = (cpu_ext == "NEON");
149 cpu_isa.sve = (cpu_ext == "SVE");
150 cpu_isa.sve2 = (cpu_ext == "SVE2");
151 cpu_isa.fp16 = (data_type == DataType::F16);
152
Gunes Bayirfadc9b12023-11-07 05:43:07 +0000153 const auto *selected_impl = CpuSoftmaxKernel::get_implementation(
154 SoftmaxKernelDataTypeISASelectorData{ data_type, cpu_isa, false /* is_log */ }, cpu::KernelSelectionType::Preferred);
Dana Zlotnik6a2df882022-01-17 09:54:26 +0200155
156 ARM_COMPUTE_ERROR_ON_NULLPTR(selected_impl);
157
Gunes Bayirfadc9b12023-11-07 05:43:07 +0000158 std::string expected = "neon_" + cpu_impl_dt(data_type) + "_softmax";
Dana Zlotnik6a2df882022-01-17 09:54:26 +0200159 std::string actual = selected_impl->name;
160
161 ARM_COMPUTE_EXPECT_EQUAL(expected, actual, framework::LogLevel::ERRORS);
162}
163
Moritz Pflanzerf6ad98a2017-07-21 17:19:58 +0100164TEST_SUITE(Float)
Ioan-Cristian Szabo5edbd1c2017-11-13 13:34:08 +0000165#ifdef __ARM_FEATURE_FP16_VECTOR_ARITHMETIC
Moritz Pflanzerf6ad98a2017-07-21 17:19:58 +0100166TEST_SUITE(FP16)
Gunes Bayirfadc9b12023-11-07 05:43:07 +0000167FIXTURE_DATA_TEST_CASE(RunSmall, NESoftmaxLayerFixture<half>, framework::DatasetMode::PRECOMMIT,
168 combine(
169 datasets::Small4DShapes(),
170 make("DataType", DataType::F16),
171 make("Beta", { 1.0f, 2.0f }),
172 make("Axis", { 0, 1 })))
Moritz Pflanzerf6ad98a2017-07-21 17:19:58 +0100173{
174 // Validate output
Manuel Bottini678d83a2019-01-07 16:05:36 +0000175 validate(Accessor(_target), _reference, tolerance_f16);
176}
Gunes Bayirfadc9b12023-11-07 05:43:07 +0000177FIXTURE_DATA_TEST_CASE(RunSmall4D, NESoftmaxLayerFixture<half>, framework::DatasetMode::PRECOMMIT,
178 combine(
179 datasets::Small4DShapes(),
180 make("DataType", DataType::F16),
181 make("Beta", { 1.0f, 2.0f }),
182 make("Axis", { 0, 2, -1 })))
Manuel Bottini678d83a2019-01-07 16:05:36 +0000183{
184 // Validate output
Manuel Bottini21079dd2019-10-29 17:20:09 +0000185 validate(Accessor(_target), _reference, tolerance_f16);
Moritz Pflanzerf6ad98a2017-07-21 17:19:58 +0100186}
Gunes Bayirfadc9b12023-11-07 05:43:07 +0000187FIXTURE_DATA_TEST_CASE(RunLarge, NESoftmaxLayerFixture<half>, framework::DatasetMode::NIGHTLY,
188 combine(
189 datasets::SoftmaxLayerLargeShapes(),
190 make("DataType", DataType::F16),
191 make("Beta", { 1.0f, 2.0f }),
192 make("Axis", { 0 })))
Moritz Pflanzerf6ad98a2017-07-21 17:19:58 +0100193{
194 // Validate output
Manuel Bottini678d83a2019-01-07 16:05:36 +0000195 validate(Accessor(_target), _reference, tolerance_f16);
Moritz Pflanzerf6ad98a2017-07-21 17:19:58 +0100196}
Manuel Bottini678d83a2019-01-07 16:05:36 +0000197TEST_SUITE_END() //FP16
198#endif /* __ARM_FEATURE_FP16_VECTOR_ARITHMETIC */
Moritz Pflanzerf6ad98a2017-07-21 17:19:58 +0100199
200TEST_SUITE(FP32)
Gunes Bayirfadc9b12023-11-07 05:43:07 +0000201FIXTURE_DATA_TEST_CASE(RunSmall2D, NESoftmaxLayerFixture<float>, framework::DatasetMode::PRECOMMIT,
202 combine(
203 datasets::SoftmaxLayerSmallShapes(),
204 make("DataType", DataType::F32),
205 make("Beta", { 1.0f, 2.0f }),
206 make("Axis", { 0, -1 })))
Manuel Bottini678d83a2019-01-07 16:05:36 +0000207{
208 // Validate output
209 validate(Accessor(_target), _reference, tolerance_f32);
210}
Gunes Bayirfadc9b12023-11-07 05:43:07 +0000211FIXTURE_DATA_TEST_CASE(RunSmall4D, NESoftmaxLayerFixture<float>, framework::DatasetMode::PRECOMMIT,
212 combine(datasets::Small4DShapes(),
213 make("DataType", DataType::F32),
214 make("Beta", { 1.0f, 2.0f }),
215 make("Axis", { 0, -2, 3 })))
Moritz Pflanzerf6ad98a2017-07-21 17:19:58 +0100216{
217 // Validate output
218 validate(Accessor(_target), _reference, tolerance_f32);
219}
Gunes Bayirfadc9b12023-11-07 05:43:07 +0000220FIXTURE_DATA_TEST_CASE(RunLarge, NESoftmaxLayerFixture<float>, framework::DatasetMode::NIGHTLY,
221 combine(datasets::SoftmaxLayerLargeShapes(),
222 make("DataType", DataType::F32),
223 make("Beta", { 1.0f, 2.0f }),
224 make("Axis", { 0 })))
Moritz Pflanzerf6ad98a2017-07-21 17:19:58 +0100225{
226 // Validate output
227 validate(Accessor(_target), _reference, tolerance_f32);
228}
Manuel Bottini678d83a2019-01-07 16:05:36 +0000229TEST_SUITE_END() //FP32
230TEST_SUITE_END() //Float
Moritz Pflanzerf6ad98a2017-07-21 17:19:58 +0100231
232template <typename T>
Diego Lopez Recas35ceeb22017-12-04 18:56:10 +0000233using NESoftmaxLayerQuantizedFixture = SoftmaxValidationQuantizedFixture<Tensor, Accessor, NESoftmaxLayer, T>;
234
235TEST_SUITE(Quantized)
236TEST_SUITE(QASYMM8)
Gunes Bayirfadc9b12023-11-07 05:43:07 +0000237FIXTURE_DATA_TEST_CASE(RunSmall2D, NESoftmaxLayerQuantizedFixture<uint8_t>, framework::DatasetMode::ALL,
238 combine(
239 datasets::SoftmaxLayerSmallShapes(),
240 make("DataType", DataType::QASYMM8),
241 combine(
242 make("QuantizationInfo", { QuantizationInfo(0.5f, -10) }),
243 make("Beta", { 1.0f, 2.f })
244 ),
245 make("Axis", { 0, -1 })))
Manuel Bottini678d83a2019-01-07 16:05:36 +0000246{
247 // Validate output
248 validate(Accessor(_target), _reference, tolerance_qasymm8);
249}
Gunes Bayirfadc9b12023-11-07 05:43:07 +0000250FIXTURE_DATA_TEST_CASE(RunSmall4D, NESoftmaxLayerQuantizedFixture<uint8_t>, framework::DatasetMode::ALL,
251 combine(
252 datasets::Small4DShapes(),
253 make("DataType", DataType::QASYMM8),
254 combine(
255 make("QuantizationInfo", { QuantizationInfo(0.5f, -10) }),
256 make("Beta", { 1.0f, 2.f })),
257 make("Axis", { 0, 1, -2 })))
Diego Lopez Recas35ceeb22017-12-04 18:56:10 +0000258{
259 // Validate output
260 validate(Accessor(_target), _reference, tolerance_qasymm8);
261}
Gunes Bayirfadc9b12023-11-07 05:43:07 +0000262FIXTURE_DATA_TEST_CASE(RunLarge, NESoftmaxLayerQuantizedFixture<uint8_t>, framework::DatasetMode::NIGHTLY,
263 combine(
264 datasets::SoftmaxLayerLargeShapes(),
265 make("DataType", DataType::QASYMM8),
266 combine(
267 make("QuantizationInfo", { QuantizationInfo(0.5f, -10) }),
268 make("Beta", { 1.0f, 2.0f })
269 ),
270 make("Axis", { 0 })))
Diego Lopez Recas35ceeb22017-12-04 18:56:10 +0000271{
272 // Validate output
273 validate(Accessor(_target), _reference, tolerance_qasymm8);
274}
Manuel Bottini678d83a2019-01-07 16:05:36 +0000275TEST_SUITE_END() //QASYMM8
Sang-Hoon Parkc3a74202019-11-22 16:05:46 +0000276
277TEST_SUITE(QASYMM8_SIGNED)
Gunes Bayirfadc9b12023-11-07 05:43:07 +0000278FIXTURE_DATA_TEST_CASE(RunSmall2D, NESoftmaxLayerQuantizedFixture<int8_t>, framework::DatasetMode::ALL,
279 combine(
280 datasets::SoftmaxLayerSmallShapes(),
281 make("DataType", DataType::QASYMM8_SIGNED),
282 combine(
283 make("QuantizationInfo", { QuantizationInfo(0.5f, -10) }),
284 make("Beta", { 1.0f, 2.f })
285 ),
286 make("Axis", { 0, -1 })))
Sang-Hoon Parkc3a74202019-11-22 16:05:46 +0000287{
288 // Validate output
289 validate(Accessor(_target), _reference, tolerance_qasymm8_signed);
290}
Gunes Bayirfadc9b12023-11-07 05:43:07 +0000291FIXTURE_DATA_TEST_CASE(RunSmall4D, NESoftmaxLayerQuantizedFixture<int8_t>, framework::DatasetMode::ALL,
292 combine(
293 datasets::Small4DShapes(),
294 make("DataType", DataType::QASYMM8_SIGNED),
295 combine(
296 make("QuantizationInfo", { QuantizationInfo(0.5f, -10) }),
297 make("Beta", { 1.0f, 2.f })
298 ),
299 make("Axis", { 0, 1, -1 })))
Sang-Hoon Parkc3a74202019-11-22 16:05:46 +0000300{
301 // Validate output
302 validate(Accessor(_target), _reference, tolerance_qasymm8_signed);
303}
304TEST_SUITE_END() //QASYMM8_SIGNED
305
Manuel Bottini678d83a2019-01-07 16:05:36 +0000306TEST_SUITE_END() //Quantized
giuros01efbf6c82018-09-03 09:53:53 +0100307
Manuel Bottini678d83a2019-01-07 16:05:36 +0000308TEST_SUITE_END() //SoftmaxLayer
309TEST_SUITE_END() //NEON
Moritz Pflanzerf6ad98a2017-07-21 17:19:58 +0100310} // namespace validation
311} // namespace test
312} // namespace arm_compute