1 /*
2 * Copyright (c) 2018-2021 Arm Limited.
3 *
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/Helpers.h"
25 #include "arm_compute/core/Types.h"
26 #include "arm_compute/core/utils/misc/ShapeCalculator.h"
27 #include "arm_compute/runtime/NEON/functions/NEStackLayer.h"
28 #include "arm_compute/runtime/Tensor.h"
29 #include "arm_compute/runtime/TensorAllocator.h"
30 #include "tests/NEON/Accessor.h"
31 #include "tests/PaddingCalculator.h"
32 #include "tests/datasets/ShapeDatasets.h"
33 #include "tests/framework/Asserts.h"
34 #include "tests/framework/Macros.h"
35 #include "tests/framework/datasets/Datasets.h"
36 #include "tests/validation/Validation.h"
37 #include "tests/validation/fixtures/StackLayerFixture.h"
38
39 #include <vector>
40
41 namespace arm_compute
42 {
43 namespace test
44 {
45 namespace validation
46 {
47 namespace
48 {
49 // *INDENT-OFF*
50 // clang-format off
51 /** Data types */
52 const auto data_types = framework::dataset::make("DataType", { DataType::QASYMM8, DataType::F16, DataType::F32 });
53
54 /** Num tensors values to test */
55 const auto n_values = framework::dataset::make("NumTensors", { 3, 4 });
56
57 /** Shapes 1D to test */
58 const auto shapes_1d_small = combine(datasets::Small1DShapes(), framework::dataset::make("Axis", -1, 2));
59
60 /** Shapes 2D to test */
61 const auto shapes_2d_small = combine(datasets::Small2DShapes(), framework::dataset::make("Axis", -2, 3));
62
63 /** Shapes 3D to test */
64 const auto shapes_3d_small = combine(datasets::Small3DShapes(), framework::dataset::make("Axis", -3, 4));
65
66 /** Shapes 4D to test */
67 const auto shapes_4d_small = combine(datasets::Small4DShapes(), framework::dataset::make("Axis", -4, 5));
68
69 /** Shapes 1D to test */
70 const auto shapes_1d_large = combine(datasets::Large1DShapes(), framework::dataset::make("Axis", -1, 2));
71
72 /** Shapes 2D to test */
73 const auto shapes_2d_large = combine(datasets::Medium2DShapes(), framework::dataset::make("Axis", -2, 3));
74
75 /** Shapes 3D to test */
76 const auto shapes_3d_large = combine(datasets::Medium3DShapes(), framework::dataset::make("Axis", -3, 4));
77
78 /** Shapes 4D to test */
79 const auto shapes_4d_large = combine(datasets::Medium4DShapes(), framework::dataset::make("Axis", -4, 5));
80 } // namespace
81
82 /** Fixture to use */
83 template<typename T>
84 using NEStackLayerFixture = StackLayerValidationFixture<Tensor, ITensor, Accessor, NEStackLayer, T>;
85
86 using namespace arm_compute::misc::shape_calculator;
87
88 TEST_SUITE(NEON)
TEST_SUITE(StackLayer)89 TEST_SUITE(StackLayer)
90
91 DATA_TEST_CASE(Validate, framework::DatasetMode::ALL, zip(zip(zip(
92 framework::dataset::make("InputInfo",
93 {
94 std::vector<TensorInfo>{ TensorInfo(TensorShape(9U, 8U), 1, DataType::U8) },
95 std::vector<TensorInfo>{ TensorInfo(TensorShape(1U, 2U), 1, DataType::U8) , TensorInfo(TensorShape(1U, 2U), 1, DataType::U8), TensorInfo(TensorShape(1U, 2U), 1, DataType::U8)},
96 std::vector<TensorInfo>{ TensorInfo(TensorShape(2U, 3U), 1, DataType::S32) },
97 std::vector<TensorInfo>{ TensorInfo(TensorShape(7U, 5U, 3U, 8U, 2U), 1, DataType::S32), TensorInfo(TensorShape(7U, 5U, 3U, 8U, 2U), 1, DataType::S32)},
98 std::vector<TensorInfo>{ TensorInfo(TensorShape(9U, 8U), 1, DataType::S32) },
99 }),
100 framework::dataset::make("OutputInfo",
101 {
102 TensorInfo(TensorShape(1U, 9U, 8U), 1, DataType::U8), // Passes, stack 1 tensor on x axis
103 TensorInfo(TensorShape(1U, 3U, 2U), 1, DataType::U8), // Passes, stack 3 tensors on y axis
104 TensorInfo(TensorShape(1U, 2U, 3U), 1, DataType::S32), // fails axis < (- input's rank)
105 TensorInfo(TensorShape(3U, 7U, 5U), 1, DataType::S32), // fails, input dimensions > 4
106 TensorInfo(TensorShape(1U, 2U, 3U), 1, DataType::U8), // fails mismatching data types
107 })),
108 framework::dataset::make("Axis", { -3, 1, -4, -3, 1 })),
109 framework::dataset::make("Expected", { true, true, false, false, false })),
110 input_info, output_info, axis, expected)
111 {
112 std::vector<TensorInfo> ti(input_info);
113 std::vector<ITensorInfo *> vec(input_info.size());
114 for(size_t j = 0; j < vec.size(); ++j)
115 {
116 vec[j] = &ti[j];
117 }
118 ARM_COMPUTE_EXPECT(bool(NEStackLayer::validate(vec, axis, &output_info)) == expected, framework::LogLevel::ERRORS);
119 }
120
121 TEST_SUITE(Shapes1D)
TEST_SUITE(S32)122 TEST_SUITE(S32)
123 FIXTURE_DATA_TEST_CASE(RunSmall, NEStackLayerFixture<int>, framework::DatasetMode::ALL,
124 combine(combine(shapes_1d_small,
125 framework::dataset::make("DataType", { DataType::S32 })),
126 n_values))
127 {
128 // Validate output
129 validate(Accessor(_target), _reference);
130 }
131
132 FIXTURE_DATA_TEST_CASE(RunLarge, NEStackLayerFixture<int>, framework::DatasetMode::NIGHTLY,
133 combine(combine(shapes_1d_large,
134 framework::dataset::make("DataType", { DataType::S32 })),
135 n_values))
136 {
137 // Validate output
138 validate(Accessor(_target), _reference);
139 }
140 TEST_SUITE_END() // S32
141
TEST_SUITE(S16)142 TEST_SUITE(S16)
143 FIXTURE_DATA_TEST_CASE(RunSmall, NEStackLayerFixture<short>, framework::DatasetMode::ALL,
144 combine(combine(shapes_1d_small,
145 framework::dataset::make("DataType", { DataType::S16 })),
146 n_values))
147 {
148 // Validate output
149 validate(Accessor(_target), _reference);
150 }
151
152 FIXTURE_DATA_TEST_CASE(RunLarge, NEStackLayerFixture<short>, framework::DatasetMode::NIGHTLY,
153 combine(combine(shapes_1d_large,
154 framework::dataset::make("DataType", { DataType::S16 })),
155 n_values))
156 {
157 // Validate output
158 validate(Accessor(_target), _reference);
159 }
160 TEST_SUITE_END() // S16
161
TEST_SUITE(S8)162 TEST_SUITE(S8)
163 FIXTURE_DATA_TEST_CASE(RunSmall, NEStackLayerFixture<char>, framework::DatasetMode::ALL,
164 combine(combine(shapes_1d_small,
165 framework::dataset::make("DataType", { DataType::S8 })),
166 n_values))
167 {
168 // Validate output
169 validate(Accessor(_target), _reference);
170 }
171
172 FIXTURE_DATA_TEST_CASE(RunLarge, NEStackLayerFixture<char>, framework::DatasetMode::NIGHTLY,
173 combine(combine(shapes_1d_large,
174 framework::dataset::make("DataType", { DataType::S8 })),
175 n_values))
176 {
177 // Validate output
178 validate(Accessor(_target), _reference);
179 }
180 TEST_SUITE_END() // S8
TEST_SUITE_END()181 TEST_SUITE_END() // Shapes1D
182
183 TEST_SUITE(Shapes2D)
184 TEST_SUITE(S32)
185 FIXTURE_DATA_TEST_CASE(RunSmall, NEStackLayerFixture<int>, framework::DatasetMode::ALL,
186 combine(combine(shapes_2d_small,
187 framework::dataset::make("DataType", { DataType::S32 })),
188 n_values))
189 {
190 // Validate output
191 validate(Accessor(_target), _reference);
192 }
193
194 FIXTURE_DATA_TEST_CASE(RunLarge, NEStackLayerFixture<int>, framework::DatasetMode::NIGHTLY,
195 combine(combine(shapes_2d_large,
196 framework::dataset::make("DataType", { DataType::S32 })),
197 n_values))
198 {
199 // Validate output
200 validate(Accessor(_target), _reference);
201 }
202 TEST_SUITE_END() // S32
203
TEST_SUITE(S16)204 TEST_SUITE(S16)
205 FIXTURE_DATA_TEST_CASE(RunSmall, NEStackLayerFixture<short>, framework::DatasetMode::ALL,
206 combine(combine(shapes_2d_small,
207 framework::dataset::make("DataType", { DataType::S16 })),
208 n_values))
209 {
210 // Validate output
211 validate(Accessor(_target), _reference);
212 }
213
214 FIXTURE_DATA_TEST_CASE(RunLarge, NEStackLayerFixture<short>, framework::DatasetMode::NIGHTLY,
215 combine(combine(shapes_2d_large,
216 framework::dataset::make("DataType", { DataType::S16 })),
217 n_values))
218 {
219 // Validate output
220 validate(Accessor(_target), _reference);
221 }
222 TEST_SUITE_END() // S16
223
TEST_SUITE(S8)224 TEST_SUITE(S8)
225 FIXTURE_DATA_TEST_CASE(RunSmall, NEStackLayerFixture<char>, framework::DatasetMode::ALL,
226 combine(combine(shapes_2d_small,
227 framework::dataset::make("DataType", { DataType::S8 })),
228 n_values))
229 {
230 // Validate output
231 validate(Accessor(_target), _reference);
232 }
233
234 FIXTURE_DATA_TEST_CASE(RunLarge, NEStackLayerFixture<char>, framework::DatasetMode::NIGHTLY,
235 combine(combine(shapes_2d_large,
236 framework::dataset::make("DataType", { DataType::S8 })),
237 n_values))
238 {
239 // Validate output
240 validate(Accessor(_target), _reference);
241 }
242 TEST_SUITE_END() // S8
TEST_SUITE_END()243 TEST_SUITE_END() // Shapes2D
244
245 TEST_SUITE(Shapes3D)
246 TEST_SUITE(S32)
247 FIXTURE_DATA_TEST_CASE(RunSmall, NEStackLayerFixture<int>, framework::DatasetMode::ALL,
248 combine(combine(shapes_3d_small,
249 framework::dataset::make("DataType", { DataType::S32 })),
250 n_values))
251 {
252 // Validate output
253 validate(Accessor(_target), _reference);
254 }
255
256 FIXTURE_DATA_TEST_CASE(RunLarge, NEStackLayerFixture<int>, framework::DatasetMode::NIGHTLY,
257 combine(combine(shapes_3d_large,
258 framework::dataset::make("DataType", { DataType::S32 })),
259 n_values))
260 {
261 // Validate output
262 validate(Accessor(_target), _reference);
263 }
264 TEST_SUITE_END() // S32
265
TEST_SUITE(S16)266 TEST_SUITE(S16)
267 FIXTURE_DATA_TEST_CASE(RunSmall, NEStackLayerFixture<short>, framework::DatasetMode::ALL,
268 combine(combine(shapes_3d_small,
269 framework::dataset::make("DataType", { DataType::S16 })),
270 n_values))
271 {
272 // Validate output
273 validate(Accessor(_target), _reference);
274 }
275
276 FIXTURE_DATA_TEST_CASE(RunLarge, NEStackLayerFixture<short>, framework::DatasetMode::NIGHTLY,
277 combine(combine(shapes_3d_large,
278 framework::dataset::make("DataType", { DataType::S16 })),
279 n_values))
280 {
281 // Validate output
282 validate(Accessor(_target), _reference);
283 }
284 TEST_SUITE_END() // S16
285
TEST_SUITE(S8)286 TEST_SUITE(S8)
287 FIXTURE_DATA_TEST_CASE(RunSmall, NEStackLayerFixture<char>, framework::DatasetMode::ALL,
288 combine(combine(shapes_3d_small,
289 framework::dataset::make("DataType", { DataType::S8 })),
290 n_values))
291 {
292 // Validate output
293 validate(Accessor(_target), _reference);
294 }
295
296 FIXTURE_DATA_TEST_CASE(RunLarge, NEStackLayerFixture<char>, framework::DatasetMode::NIGHTLY,
297 combine(combine(shapes_3d_large,
298 framework::dataset::make("DataType", { DataType::S8 })),
299 n_values))
300 {
301 // Validate output
302 validate(Accessor(_target), _reference);
303 }
304 TEST_SUITE_END() // S8
TEST_SUITE_END()305 TEST_SUITE_END() // Shapes3D
306
307 TEST_SUITE(Shapes4D)
308 TEST_SUITE(S32)
309 FIXTURE_DATA_TEST_CASE(RunSmall, NEStackLayerFixture<int>, framework::DatasetMode::ALL,
310 combine(combine(shapes_4d_small,
311 framework::dataset::make("DataType", { DataType::S32 })),
312 n_values))
313 {
314 // Validate output
315 validate(Accessor(_target), _reference);
316 }
317
318 FIXTURE_DATA_TEST_CASE(RunLarge, NEStackLayerFixture<int>, framework::DatasetMode::NIGHTLY,
319 combine(combine(shapes_4d_large,
320 framework::dataset::make("DataType", { DataType::S32 })),
321 n_values))
322 {
323 // Validate output
324 validate(Accessor(_target), _reference);
325 }
326 TEST_SUITE_END() // S32
327
TEST_SUITE(S16)328 TEST_SUITE(S16)
329 FIXTURE_DATA_TEST_CASE(RunSmall, NEStackLayerFixture<short>, framework::DatasetMode::ALL,
330 combine(combine(shapes_4d_small,
331 framework::dataset::make("DataType", { DataType::S16 })),
332 n_values))
333 {
334 // Validate output
335 validate(Accessor(_target), _reference);
336 }
337
338 FIXTURE_DATA_TEST_CASE(RunLarge, NEStackLayerFixture<short>, framework::DatasetMode::NIGHTLY,
339 combine(combine(shapes_4d_large,
340 framework::dataset::make("DataType", { DataType::S16 })),
341 n_values))
342 {
343 // Validate output
344 validate(Accessor(_target), _reference);
345 }
346 TEST_SUITE_END() // S16
347
TEST_SUITE(S8)348 TEST_SUITE(S8)
349 FIXTURE_DATA_TEST_CASE(RunSmall, NEStackLayerFixture<char>, framework::DatasetMode::ALL,
350 combine(combine(shapes_4d_small,
351 framework::dataset::make("DataType", { DataType::S8 })),
352 n_values))
353 {
354 // Validate output
355 validate(Accessor(_target), _reference);
356 }
357
358 FIXTURE_DATA_TEST_CASE(RunLarge, NEStackLayerFixture<char>, framework::DatasetMode::NIGHTLY,
359 combine(combine(shapes_4d_large,
360 framework::dataset::make("DataType", { DataType::S8 })),
361 n_values))
362 {
363 // Validate output
364 validate(Accessor(_target), _reference);
365 }
366 TEST_SUITE_END() // S8
367 TEST_SUITE_END() // Shapes4D
368 TEST_SUITE_END() // StackLayer
369 TEST_SUITE_END() // Neon
370 } // namespace validation
371 } // namespace test
372 } // namespace arm_compute
373