Compute Library
 22.05
StackLayer.cpp
Go to the documentation of this file.
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  */
25 #include "arm_compute/core/Types.h"
30 #include "tests/NEON/Accessor.h"
32 #include "tests/datasets/ShapeDatasets.h"
34 #include "tests/framework/Macros.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 
87 
88 TEST_SUITE(NEON)
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 })),
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  }
119 }
120 
121 TEST_SUITE(Shapes1D)
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 
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 
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 
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 
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 
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
181 TEST_SUITE_END() // Shapes1D
182 
183 TEST_SUITE(Shapes2D)
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 
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 
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 
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 
224 TEST_SUITE(S8)
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 
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
243 TEST_SUITE_END() // Shapes2D
244 
245 TEST_SUITE(Shapes3D)
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 
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 
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 
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 
286 TEST_SUITE(S8)
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 
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
305 TEST_SUITE_END() // Shapes3D
306 
307 TEST_SUITE(Shapes4D)
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 
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 
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 
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 
348 TEST_SUITE(S8)
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 
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
Shape of a tensor.
Definition: TensorShape.h:39
1 channel, 1 U8 per channel
1 channel, 1 F32 per channel
ARM_COMPUTE_EXPECT(has_error==expected, framework::LogLevel::ERRORS)
std::enable_if< is_container< T >::value, ContainerDataset< T > >::type make(std::string name, T &&values)
Helper function to create a ContainerDataset.
static Status validate(const std::vector< ITensorInfo *> &input, int axis, const ITensorInfo *output)
Static function to check if given info will lead to a valid configuration of NEStackLayerKernel.
Copyright (c) 2017-2022 Arm Limited.
1 channel, 1 F16 per channel
1 channel, 1 S32 per channel
DATA_TEST_CASE(Validate, framework::DatasetMode::ALL, zip(zip(zip(framework::dataset::make("InputInfo", { TensorInfo(TensorShape(27U, 13U, 2U), 1, DataType::F32), TensorInfo(TensorShape(27U, 13U, 2U), 1, DataType::F32), TensorInfo(TensorShape(32U, 13U, 2U), 1, DataType::F32), TensorInfo(TensorShape(32U, 13U, 2U), 1, DataType::QASYMM8), TensorInfo(TensorShape(27U, 13U, 2U), 1, DataType::QASYMM8), TensorInfo(TensorShape(27U, 13U, 2U), 1, DataType::F32), TensorInfo(TensorShape(32U, 13U, 2U), 1, DataType::QSYMM16), TensorInfo(TensorShape(32U, 13U, 2U), 1, DataType::QSYMM16), TensorInfo(TensorShape(32U, 13U, 2U), 1, DataType::QSYMM16), }), framework::dataset::make("OutputInfo",{ TensorInfo(TensorShape(27U, 13U, 2U), 1, DataType::F16), TensorInfo(TensorShape(27U, 13U, 2U), 1, DataType::F32), TensorInfo(TensorShape(32U, 13U, 2U), 1, DataType::F32), TensorInfo(TensorShape(32U, 13U, 2U), 1, DataType::QASYMM8), TensorInfo(TensorShape(27U, 13U, 2U), 1, DataType::QASYMM8), TensorInfo(TensorShape(30U, 11U, 2U), 1, DataType::F32), TensorInfo(TensorShape(32U, 13U, 2U), 1, DataType::QSYMM16, QuantizationInfo(1.f/32768.f, 0)), TensorInfo(TensorShape(32U, 13U, 2U), 1, DataType::QSYMM16, QuantizationInfo(1.f/32768.f, 0)), TensorInfo(TensorShape(32U, 13U, 2U), 1, DataType::QSYMM16, QuantizationInfo(1.f/32768.f, 0)), })), framework::dataset::make("ActivationInfo", { ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU), ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU), ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU), ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::LU_BOUNDED_RELU), ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::TANH), ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU), ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::TANH), ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::LOGISTIC), ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::SQRT), })), framework::dataset::make("Expected", { false, true, true, true, false, false, true, true, false })), input_info, output_info, act_info, expected)
Accessor implementation for Tensor objects.
Definition: Accessor.h:35
DatasetMode
Possible dataset modes.
Definition: DatasetModes.h:40
StackLayerValidationFixture< Tensor, ITensor, Accessor, NEStackLayer, T > NEStackLayerFixture
Fixture to use.
Definition: StackLayer.cpp:84
TEST_SUITE_END() FIXTURE_DATA_TEST_CASE(RunSmall
[CLActivationLayer Test snippet]
quantized, asymmetric fixed-point 8-bit number unsigned
validate(CLAccessor(output_state), expected_output)
1 channel, 1 S16 per channel
FIXTURE_DATA_TEST_CASE(RunSmall, CLAbsLayerFixture< half >, framework::DatasetMode::PRECOMMIT, combine(datasets::SmallShapes(), framework::dataset::make("DataType", DataType::F16)))
Definition: AbsLayer.cpp:50
Store the tensor&#39;s metadata.
Definition: TensorInfo.h:43
zip(zip(framework::dataset::make("Weights", { TensorInfo(TensorShape(32U, 13U, 2U, 2U), 1, DataType::F32), TensorInfo(TensorShape(32U, 13U, 2U, 2U), 1, DataType::F32), TensorInfo(TensorShape(32U, 13U, 2U, 1U), 1, DataType::F32), }), framework::dataset::make("MVBGInfo",{ TensorInfo(TensorShape(2U), 1, DataType::F32), TensorInfo(TensorShape(2U), 1, DataType::F16), TensorInfo(TensorShape(5U), 1, DataType::F32), })), framework::dataset::make("Expected", { true, false, false}))
TEST_SUITE(QASYMM8_to_F32) FIXTURE_DATA_TEST_CASE(RunSmall
DataType
Available data types.
Definition: Types.h:79
signed 8-bit number
combine(datasets::SmallShapes(), framework::dataset::make("DataType", DataType::F32)))
Definition: AbsLayer.cpp:65