1 //
2 // Copyright © 2019 Arm Ltd and Contributors. All rights reserved.
3 // SPDX-License-Identifier: MIT
4 //
5
6 #include "StackTestImpl.hpp"
7 #include <armnnTestUtils/LayerTestResult.hpp>
8
9 #include <ResolveType.hpp>
10
11
12 #include <armnn/backends/IBackendInternal.hpp>
13 #include <armnn/backends/WorkloadFactory.hpp>
14
15 #include <armnnTestUtils/TensorCopyUtils.hpp>
16 #include <armnnTestUtils/WorkloadTestUtils.hpp>
17
18 #include <armnnTestUtils/TensorHelpers.hpp>
19
20 namespace
21 {
22
23 template<armnn::DataType ArmnnType, typename T, std::size_t outputDimLength>
StackTestHelper(armnn::IWorkloadFactory & workloadFactory,const armnn::IBackendInternal::IMemoryManagerSharedPtr & memoryManager,const armnn::ITensorHandleFactory & tensorHandleFactory,const armnn::TensorInfo & inputTensorInfo,const armnn::TensorInfo & outputTensorInfo,unsigned int axis,const std::vector<std::vector<T>> & inputData,const std::vector<T> & outputExpectedData)24 LayerTestResult<T, outputDimLength> StackTestHelper(
25 armnn::IWorkloadFactory& workloadFactory,
26 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
27 const armnn::ITensorHandleFactory& tensorHandleFactory,
28 const armnn::TensorInfo& inputTensorInfo,
29 const armnn::TensorInfo& outputTensorInfo,
30 unsigned int axis,
31 const std::vector<std::vector<T>>& inputData,
32 const std::vector<T>& outputExpectedData)
33 {
34 IgnoreUnused(memoryManager);
35 unsigned int numInputs = static_cast<unsigned int>(inputData.size());
36 std::vector<std::vector<T>> inputs;
37 for (unsigned int i = 0; i < numInputs; ++i)
38 {
39 inputs.emplace_back(inputData[i]);
40 }
41
42 std::vector<T> actualOutput(outputTensorInfo.GetNumElements());
43
44 std::vector<std::unique_ptr<armnn::ITensorHandle>> inputHandles;
45 for (unsigned int i = 0; i < numInputs; ++i)
46 {
47 inputHandles.push_back(tensorHandleFactory.CreateTensorHandle(inputTensorInfo));
48 }
49 std::unique_ptr<armnn::ITensorHandle> outputHandle = tensorHandleFactory.CreateTensorHandle(outputTensorInfo);
50
51 armnn::StackQueueDescriptor descriptor;
52 descriptor.m_Parameters.m_Axis = axis;
53 descriptor.m_Parameters.m_InputShape = inputTensorInfo.GetShape();
54 descriptor.m_Parameters.m_NumInputs = numInputs;
55
56 armnn::WorkloadInfo info;
57 for (unsigned int i = 0; i < numInputs; ++i)
58 {
59 std::unique_ptr<armnn::ITensorHandle>& inputHandle = inputHandles[i];
60 AddInputToWorkload(descriptor, info, inputTensorInfo, inputHandle.get());
61 inputHandle->Allocate();
62 CopyDataToITensorHandle(inputHandle.get(), inputs[i].data());
63 }
64
65 AddOutputToWorkload(descriptor, info, outputTensorInfo, outputHandle.get());
66 outputHandle->Allocate();
67
68 std::unique_ptr<armnn::IWorkload> workload = workloadFactory.CreateWorkload(armnn::LayerType::Stack,
69 descriptor,
70 info);
71
72 workload->Execute();
73
74 CopyDataFromITensorHandle(actualOutput.data(), outputHandle.get());
75
76 return LayerTestResult<T, outputDimLength>(actualOutput,
77 outputExpectedData,
78 outputHandle->GetShape(),
79 outputTensorInfo.GetShape());
80 }
81
82 } // anonymous namespace
83
84 //
85 // Implementation templates
86 //
87
88 template<armnn::DataType ArmnnType, typename T = armnn::ResolveType<ArmnnType>>
StackAxis0TestImpl(armnn::IWorkloadFactory & workloadFactory,const armnn::IBackendInternal::IMemoryManagerSharedPtr & memoryManager,const armnn::ITensorHandleFactory & tensorHandleFactory)89 LayerTestResult<T, 4> StackAxis0TestImpl(
90 armnn::IWorkloadFactory& workloadFactory,
91 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
92 const armnn::ITensorHandleFactory& tensorHandleFactory)
93 {
94 armnn::TensorInfo inputTensorInfo ({ 3, 2, 3 }, ArmnnType);
95 armnn::TensorInfo outputTensorInfo({ 2, 3, 2, 3 }, ArmnnType);
96
97 std::vector<std::vector<T>> inputData;
98
99 inputData.push_back(
100 {
101 1, 2, 3,
102 4, 5, 6,
103
104 7, 8, 9,
105 10, 11, 12,
106
107 13, 14, 15,
108 16, 17, 18
109 });
110
111 inputData.push_back(
112 {
113 19, 20, 21,
114 22, 23, 24,
115
116 25, 26, 27,
117 28, 29, 30,
118
119 31, 32, 33,
120 34, 35, 36
121 });
122
123 std::vector<T> outputExpectedData =
124 {
125 1, 2, 3,
126 4, 5, 6,
127
128 7, 8, 9,
129 10, 11, 12,
130
131 13, 14, 15,
132 16, 17, 18,
133
134
135 19, 20, 21,
136 22, 23, 24,
137
138 25, 26, 27,
139 28, 29, 30,
140
141 31, 32, 33,
142 34, 35, 36
143 };
144
145 return StackTestHelper<ArmnnType, T, 4>(
146 workloadFactory,
147 memoryManager,
148 tensorHandleFactory,
149 inputTensorInfo,
150 outputTensorInfo,
151 0U,
152 inputData,
153 outputExpectedData
154 );
155 }
156
157 template<armnn::DataType ArmnnType, typename T = armnn::ResolveType<ArmnnType>>
StackOutput4DAxis1TestImpl(armnn::IWorkloadFactory & workloadFactory,const armnn::IBackendInternal::IMemoryManagerSharedPtr & memoryManager,const armnn::ITensorHandleFactory & tensorHandleFactory)158 LayerTestResult<T, 4> StackOutput4DAxis1TestImpl(
159 armnn::IWorkloadFactory& workloadFactory,
160 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
161 const armnn::ITensorHandleFactory& tensorHandleFactory)
162 {
163 armnn::TensorInfo inputTensorInfo ({ 3, 2, 3 }, ArmnnType);
164 armnn::TensorInfo outputTensorInfo({ 3, 2, 2, 3 }, ArmnnType);
165
166 std::vector<std::vector<T>> inputData;
167
168 inputData.push_back(
169 {
170 1, 2, 3,
171 4, 5, 6,
172
173 7, 8, 9,
174 10, 11, 12,
175
176 13, 14, 15,
177 16, 17, 18
178 });
179
180 inputData.push_back(
181 {
182 19, 20, 21,
183 22, 23, 24,
184
185 25, 26, 27,
186 28, 29, 30,
187
188 31, 32, 33,
189 34, 35, 36
190 });
191
192 std::vector<T> outputExpectedData =
193 {
194 1, 2, 3,
195 4, 5, 6,
196
197 19, 20, 21,
198 22, 23, 24,
199
200
201 7, 8, 9,
202 10, 11, 12,
203
204 25, 26, 27,
205 28, 29, 30,
206
207
208 13, 14, 15,
209 16, 17, 18,
210
211 31, 32, 33,
212 34, 35, 36
213 };
214
215 return StackTestHelper<ArmnnType, T, 4>(
216 workloadFactory,
217 memoryManager,
218 tensorHandleFactory,
219 inputTensorInfo,
220 outputTensorInfo,
221 1U,
222 inputData,
223 outputExpectedData
224 );
225 }
226
227 template<armnn::DataType ArmnnType, typename T = armnn::ResolveType<ArmnnType>>
StackOutput4DAxis2TestImpl(armnn::IWorkloadFactory & workloadFactory,const armnn::IBackendInternal::IMemoryManagerSharedPtr & memoryManager,const armnn::ITensorHandleFactory & tensorHandleFactory)228 LayerTestResult<T, 4> StackOutput4DAxis2TestImpl(
229 armnn::IWorkloadFactory& workloadFactory,
230 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
231 const armnn::ITensorHandleFactory& tensorHandleFactory)
232 {
233 armnn::TensorInfo inputTensorInfo ({ 3, 2, 3 }, ArmnnType);
234 armnn::TensorInfo outputTensorInfo({ 3, 2, 2, 3 }, ArmnnType);
235
236 std::vector<std::vector<T>> inputData;
237
238 inputData.push_back(
239 {
240 1, 2, 3,
241 4, 5, 6,
242
243 7, 8, 9,
244 10, 11, 12,
245
246 13, 14, 15,
247 16, 17, 18
248 });
249
250 inputData.push_back(
251 {
252 19, 20, 21,
253 22, 23, 24,
254
255 25, 26, 27,
256 28, 29, 30,
257
258 31, 32, 33,
259 34, 35, 36
260 });
261
262 std::vector<T> outputExpectedData =
263 {
264 1, 2, 3,
265 19, 20, 21,
266
267 4, 5, 6,
268 22, 23, 24,
269
270 7, 8, 9,
271 25, 26, 27,
272
273 10, 11, 12,
274 28, 29, 30,
275
276 13, 14, 15,
277 31, 32, 33,
278
279 16, 17, 18,
280 34, 35, 36
281 };
282
283 return StackTestHelper<ArmnnType, T, 4>(
284 workloadFactory,
285 memoryManager,
286 tensorHandleFactory,
287 inputTensorInfo,
288 outputTensorInfo,
289 2U,
290 inputData,
291 outputExpectedData
292 );
293 }
294
295 template<armnn::DataType ArmnnType, typename T = armnn::ResolveType<ArmnnType>>
StackOutput4DAxis3TestImpl(armnn::IWorkloadFactory & workloadFactory,const armnn::IBackendInternal::IMemoryManagerSharedPtr & memoryManager,const armnn::ITensorHandleFactory & tensorHandleFactory)296 LayerTestResult<T, 4> StackOutput4DAxis3TestImpl(
297 armnn::IWorkloadFactory& workloadFactory,
298 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
299 const armnn::ITensorHandleFactory& tensorHandleFactory)
300 {
301 armnn::TensorInfo inputTensorInfo ({ 3, 2, 3 }, ArmnnType);
302 armnn::TensorInfo outputTensorInfo({ 3, 2, 3, 2 }, ArmnnType);
303
304 std::vector<std::vector<T>> inputData;
305
306 inputData.push_back(
307 {
308 1, 2, 3,
309 4, 5, 6,
310
311 7, 8, 9,
312 10, 11, 12,
313
314 13, 14, 15,
315 16, 17, 18
316 });
317
318 inputData.push_back(
319 {
320 19, 20, 21,
321 22, 23, 24,
322
323 25, 26, 27,
324 28, 29, 30,
325
326 31, 32, 33,
327 34, 35, 36
328 });
329
330 std::vector<T> outputExpectedData =
331 {
332 1, 19,
333 2, 20,
334 3, 21,
335
336 4, 22,
337 5, 23,
338 6, 24,
339
340
341 7, 25,
342 8, 26,
343 9, 27,
344
345 10, 28,
346 11, 29,
347 12, 30,
348
349
350 13, 31,
351 14, 32,
352 15, 33,
353
354 16, 34,
355 17, 35,
356 18, 36
357 };
358
359 return StackTestHelper<ArmnnType, T, 4>(
360 workloadFactory,
361 memoryManager,
362 tensorHandleFactory,
363 inputTensorInfo,
364 outputTensorInfo,
365 3U,
366 inputData,
367 outputExpectedData
368 );
369 }
370
371 template<armnn::DataType ArmnnType, typename T = armnn::ResolveType<ArmnnType>>
StackOutput3DInputs3TestImpl(armnn::IWorkloadFactory & workloadFactory,const armnn::IBackendInternal::IMemoryManagerSharedPtr & memoryManager,const armnn::ITensorHandleFactory & tensorHandleFactory)372 LayerTestResult<T, 3> StackOutput3DInputs3TestImpl(
373 armnn::IWorkloadFactory& workloadFactory,
374 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
375 const armnn::ITensorHandleFactory& tensorHandleFactory)
376 {
377 armnn::TensorInfo inputTensorInfo ({ 3, 3 }, ArmnnType);
378 armnn::TensorInfo outputTensorInfo({ 3, 3, 3 }, ArmnnType);
379
380 std::vector<std::vector<T>> inputData;
381
382 inputData.push_back(
383 {
384 1, 2, 3,
385 4, 5, 6,
386 7, 8, 9
387 });
388
389 inputData.push_back(
390 {
391 10, 11, 12,
392 13, 14, 15,
393 16, 17, 18
394 });
395
396 inputData.push_back(
397 {
398 19, 20, 21,
399 22, 23, 24,
400 25, 26, 27
401 });
402
403 std::vector<T> outputExpectedData =
404 {
405 1, 2, 3,
406 10, 11, 12,
407 19, 20, 21,
408
409 4, 5, 6,
410 13, 14, 15,
411 22, 23, 24,
412
413 7, 8, 9,
414 16, 17, 18,
415 25, 26, 27
416 };
417
418 return StackTestHelper<ArmnnType, T, 3>(
419 workloadFactory,
420 memoryManager,
421 tensorHandleFactory,
422 inputTensorInfo,
423 outputTensorInfo,
424 1U,
425 inputData,
426 outputExpectedData
427 );
428 }
429
430 template<armnn::DataType ArmnnType, typename T = armnn::ResolveType<ArmnnType>>
StackOutput5DTestImpl(armnn::IWorkloadFactory & workloadFactory,const armnn::IBackendInternal::IMemoryManagerSharedPtr & memoryManager,const armnn::ITensorHandleFactory & tensorHandleFactory)431 LayerTestResult<T, 5> StackOutput5DTestImpl(
432 armnn::IWorkloadFactory& workloadFactory,
433 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
434 const armnn::ITensorHandleFactory& tensorHandleFactory)
435 {
436 armnn::TensorInfo inputTensorInfo ({ 2, 2, 2, 3 }, ArmnnType);
437 armnn::TensorInfo outputTensorInfo({ 2, 2, 2, 2, 3 }, ArmnnType);
438
439 std::vector<std::vector<T>> inputData;
440
441 inputData.push_back(
442 {
443 1, 2, 3,
444 4, 5, 6,
445
446 7, 8, 9,
447 10, 11, 12,
448
449
450 13, 14, 15,
451 16, 17, 18,
452
453 19, 20, 21,
454 22, 23, 24
455 });
456
457 inputData.push_back(
458 {
459 25, 26, 27,
460 28, 29, 30,
461
462 31, 32, 33,
463 34, 35, 36,
464
465
466 37, 38, 39,
467 40, 41, 42,
468
469 43, 44, 45,
470 46, 47, 48
471 });
472
473 std::vector<T> outputExpectedData =
474 {
475 1, 2, 3,
476 4, 5, 6,
477
478 7, 8, 9,
479 10, 11, 12,
480
481
482 25, 26, 27,
483 28, 29, 30,
484
485 31, 32, 33,
486 34, 35, 36,
487
488
489
490 13, 14, 15,
491 16, 17, 18,
492
493 19, 20, 21,
494 22, 23, 24,
495
496
497 37, 38, 39,
498 40, 41, 42,
499
500 43, 44, 45,
501 46, 47, 48
502
503 };
504
505 return StackTestHelper<ArmnnType, T, 5>(
506 workloadFactory,
507 memoryManager,
508 tensorHandleFactory,
509 inputTensorInfo,
510 outputTensorInfo,
511 1U,
512 inputData,
513 outputExpectedData
514 );
515 }
516
517 //
518 // Implementation functions
519 //
520
StackAxis0Float32Test(armnn::IWorkloadFactory & workloadFactory,const armnn::IBackendInternal::IMemoryManagerSharedPtr & memoryManager,const armnn::ITensorHandleFactory & tensorHandleFactory)521 LayerTestResult<float, 4> StackAxis0Float32Test(
522 armnn::IWorkloadFactory& workloadFactory,
523 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
524 const armnn::ITensorHandleFactory& tensorHandleFactory)
525 {
526 return StackAxis0TestImpl<armnn::DataType::Float32>(workloadFactory, memoryManager, tensorHandleFactory);
527 }
528
StackOutput4DAxis1Float32Test(armnn::IWorkloadFactory & workloadFactory,const armnn::IBackendInternal::IMemoryManagerSharedPtr & memoryManager,const armnn::ITensorHandleFactory & tensorHandleFactory)529 LayerTestResult<float, 4> StackOutput4DAxis1Float32Test(
530 armnn::IWorkloadFactory& workloadFactory,
531 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
532 const armnn::ITensorHandleFactory& tensorHandleFactory)
533 {
534 return StackOutput4DAxis1TestImpl<armnn::DataType::Float32>(workloadFactory, memoryManager, tensorHandleFactory);
535 }
536
StackOutput4DAxis2Float32Test(armnn::IWorkloadFactory & workloadFactory,const armnn::IBackendInternal::IMemoryManagerSharedPtr & memoryManager,const armnn::ITensorHandleFactory & tensorHandleFactory)537 LayerTestResult<float, 4> StackOutput4DAxis2Float32Test(
538 armnn::IWorkloadFactory& workloadFactory,
539 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
540 const armnn::ITensorHandleFactory& tensorHandleFactory)
541 {
542 return StackOutput4DAxis2TestImpl<armnn::DataType::Float32>(workloadFactory, memoryManager, tensorHandleFactory);
543 }
544
StackOutput4DAxis3Float32Test(armnn::IWorkloadFactory & workloadFactory,const armnn::IBackendInternal::IMemoryManagerSharedPtr & memoryManager,const armnn::ITensorHandleFactory & tensorHandleFactory)545 LayerTestResult<float, 4> StackOutput4DAxis3Float32Test(
546 armnn::IWorkloadFactory& workloadFactory,
547 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
548 const armnn::ITensorHandleFactory& tensorHandleFactory)
549 {
550 return StackOutput4DAxis3TestImpl<armnn::DataType::Float32>(workloadFactory, memoryManager, tensorHandleFactory);
551 }
552
StackOutput3DInputs3Float32Test(armnn::IWorkloadFactory & workloadFactory,const armnn::IBackendInternal::IMemoryManagerSharedPtr & memoryManager,const armnn::ITensorHandleFactory & tensorHandleFactory)553 LayerTestResult<float, 3> StackOutput3DInputs3Float32Test(
554 armnn::IWorkloadFactory& workloadFactory,
555 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
556 const armnn::ITensorHandleFactory& tensorHandleFactory)
557 {
558 return StackOutput3DInputs3TestImpl<armnn::DataType::Float32>(workloadFactory, memoryManager, tensorHandleFactory);
559 }
560
StackOutput5DFloat32Test(armnn::IWorkloadFactory & workloadFactory,const armnn::IBackendInternal::IMemoryManagerSharedPtr & memoryManager,const armnn::ITensorHandleFactory & tensorHandleFactory)561 LayerTestResult<float, 5> StackOutput5DFloat32Test(
562 armnn::IWorkloadFactory& workloadFactory,
563 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
564 const armnn::ITensorHandleFactory& tensorHandleFactory)
565 {
566 return StackOutput5DTestImpl<armnn::DataType::Float32>(workloadFactory, memoryManager, tensorHandleFactory);
567 }
568
StackFloat16Test(armnn::IWorkloadFactory & workloadFactory,const armnn::IBackendInternal::IMemoryManagerSharedPtr & memoryManager,const armnn::ITensorHandleFactory & tensorHandleFactory)569 LayerTestResult<armnn::Half, 4> StackFloat16Test(
570 armnn::IWorkloadFactory& workloadFactory,
571 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
572 const armnn::ITensorHandleFactory& tensorHandleFactory)
573 {
574 using namespace half_float::literal;
575
576 armnn::TensorInfo inputTensorInfo ({ 3, 2, 3 }, armnn::DataType::Float16);
577 armnn::TensorInfo outputTensorInfo({ 3, 2, 2, 3 }, armnn::DataType::Float16);
578
579 std::vector<std::vector<armnn::Half>> inputData;
580
581 inputData.push_back(
582 {
583 1.0_h, 2.0_h, 3.0_h,
584 4.0_h, 5.0_h, 6.0_h,
585
586 7.0_h, 8.0_h, 9.0_h,
587 10.0_h, 11.0_h, 12.0_h,
588
589 13.0_h, 14.0_h, 15.0_h,
590 16.0_h, 17.0_h, 18.0_h
591 });
592
593 inputData.push_back(
594 {
595 19.0_h, 20.0_h, 21.0_h,
596 22.0_h, 23.0_h, 24.0_h,
597
598 25.0_h, 26.0_h, 27.0_h,
599 28.0_h, 29.0_h, 30.0_h,
600
601 31.0_h, 32.0_h, 33.0_h,
602 34.0_h, 35.0_h, 36.0_h
603 });
604
605 std::vector<armnn::Half> outputExpectedData =
606 {
607 1.0_h, 2.0_h, 3.0_h,
608 19.0_h, 20.0_h, 21.0_h,
609
610 4.0_h, 5.0_h, 6.0_h,
611 22.0_h, 23.0_h, 24.0_h,
612
613 7.0_h, 8.0_h, 9.0_h,
614 25.0_h, 26.0_h, 27.0_h,
615
616 10.0_h, 11.0_h, 12.0_h,
617 28.0_h, 29.0_h, 30.0_h,
618
619 13.0_h, 14.0_h, 15.0_h,
620 31.0_h, 32.0_h, 33.0_h,
621
622 16.0_h, 17.0_h, 18.0_h,
623 34.0_h, 35.0_h, 36.0_h
624 };
625
626 return StackTestHelper<armnn::DataType::Float16, armnn::Half, 4>(
627 workloadFactory,
628 memoryManager,
629 tensorHandleFactory,
630 inputTensorInfo,
631 outputTensorInfo,
632 2U,
633 inputData,
634 outputExpectedData
635 );
636 }
637
StackInt32Test(armnn::IWorkloadFactory & workloadFactory,const armnn::IBackendInternal::IMemoryManagerSharedPtr & memoryManager,const armnn::ITensorHandleFactory & tensorHandleFactory)638 LayerTestResult<int32_t, 4> StackInt32Test(
639 armnn::IWorkloadFactory& workloadFactory,
640 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
641 const armnn::ITensorHandleFactory& tensorHandleFactory)
642 {
643 return StackAxis0TestImpl<armnn::DataType::Signed32>(workloadFactory, memoryManager, tensorHandleFactory);
644 }