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