1 //
2 // Copyright © 2019 Arm Ltd and Contributors. All rights reserved.
3 // SPDX-License-Identifier: MIT
4 //
5
6 #include "SliceTestImpl.hpp"
7
8 #include <armnnUtils/QuantizeHelper.hpp>
9 #include <ResolveType.hpp>
10
11
12 #include <armnnTestUtils/TensorCopyUtils.hpp>
13 #include <armnnTestUtils/WorkloadTestUtils.hpp>
14
15 #include <armnnTestUtils/TensorHelpers.hpp>
16
17 namespace
18 {
19
20 template<typename T, std::size_t NumDims>
SliceTestImpl(armnn::IWorkloadFactory & workloadFactory,const armnn::IBackendInternal::IMemoryManagerSharedPtr & memoryManager,armnn::TensorInfo & inputInfo,armnn::TensorInfo & outputInfo,std::vector<float> & inputData,std::vector<float> & expectedOutputData,armnn::SliceQueueDescriptor descriptor,const float qScale=1.0f,const int qOffset=0)21 LayerTestResult<T, NumDims> SliceTestImpl(
22 armnn::IWorkloadFactory& workloadFactory,
23 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
24 armnn::TensorInfo& inputInfo,
25 armnn::TensorInfo& outputInfo,
26 std::vector<float>& inputData,
27 std::vector<float>& expectedOutputData,
28 armnn::SliceQueueDescriptor descriptor,
29 const float qScale = 1.0f,
30 const int qOffset = 0)
31 {
32 IgnoreUnused(memoryManager);
33 if(armnn::IsQuantizedType<T>())
34 {
35 inputInfo.SetQuantizationScale(qScale);
36 inputInfo.SetQuantizationOffset(qOffset);
37
38 outputInfo.SetQuantizationScale(qScale);
39 outputInfo.SetQuantizationOffset(qOffset);
40 }
41
42 std::vector<T> input = armnnUtils::QuantizedVector<T>(inputData, qScale, qOffset);
43 std::vector<T> expectedOutput = armnnUtils::QuantizedVector<T>(expectedOutputData, qScale, qOffset);
44 std::vector<T> actualOutput(outputInfo.GetNumElements());
45
46 ARMNN_NO_DEPRECATE_WARN_BEGIN
47 std::unique_ptr<armnn::ITensorHandle> inputHandle = workloadFactory.CreateTensorHandle(inputInfo);
48 std::unique_ptr<armnn::ITensorHandle> outputHandle = workloadFactory.CreateTensorHandle(outputInfo);
49 ARMNN_NO_DEPRECATE_WARN_END
50
51 armnn::WorkloadInfo info;
52 AddInputToWorkload(descriptor, info, inputInfo, inputHandle.get());
53 AddOutputToWorkload(descriptor, info, outputInfo, outputHandle.get());
54
55 std::unique_ptr<armnn::IWorkload> workload = workloadFactory.CreateWorkload(armnn::LayerType::Slice,
56 descriptor,
57 info);
58
59 inputHandle->Allocate();
60 outputHandle->Allocate();
61
62 CopyDataToITensorHandle(inputHandle.get(), input.data());
63
64 ExecuteWorkload(*workload, memoryManager);
65
66 CopyDataFromITensorHandle(actualOutput.data(), outputHandle.get());
67
68 return LayerTestResult<T, NumDims>(actualOutput,
69 expectedOutput,
70 outputHandle->GetShape(),
71 outputInfo.GetShape());
72 }
73
74 template<armnn::DataType ArmnnType, typename T = armnn::ResolveType<ArmnnType>>
Slice4dTest(armnn::IWorkloadFactory & workloadFactory,const armnn::IBackendInternal::IMemoryManagerSharedPtr & memoryManager)75 LayerTestResult<T, 4> Slice4dTest(armnn::IWorkloadFactory& workloadFactory,
76 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager)
77 {
78 armnn::TensorShape inputShape = { 3, 2, 3, 5 };
79 armnn::TensorShape outputShape = { 2, 1, 2, 3 };
80
81 armnn::SliceQueueDescriptor desc;
82 desc.m_Parameters.m_Begin = { 1, 0, 1, 2 };
83 desc.m_Parameters.m_Size = { 2, 1, 2, 3 };
84
85 armnn::TensorInfo inputInfo(inputShape, ArmnnType);
86 armnn::TensorInfo outputInfo(outputShape, ArmnnType);
87
88 std::vector<float> input =
89 {
90 0.f, 1.f, 2.f, 3.f, 4.f,
91 5.f, 6.f, 7.f, 8.f, 9.f,
92 10.f, 11.f, 12.f, 13.f, 14.f,
93
94 15.f, 16.f, 17.f, 18.f, 19.f,
95 20.f, 21.f, 22.f, 23.f, 24.f,
96 25.f, 26.f, 27.f, 28.f, 29.f,
97
98
99 30.f, 31.f, 32.f, 33.f, 34.f,
100 35.f, 36.f, 37.f, 38.f, 39.f,
101 40.f, 41.f, 42.f, 43.f, 44.f,
102
103 45.f, 46.f, 47.f, 48.f, 49.f,
104 50.f, 51.f, 52.f, 53.f, 54.f,
105 55.f, 56.f, 57.f, 58.f, 59.f,
106
107
108 60.f, 61.f, 62.f, 63.f, 64.f,
109 65.f, 66.f, 67.f, 68.f, 69.f,
110 70.f, 71.f, 72.f, 73.f, 74.f,
111
112 75.f, 76.f, 77.f, 78.f, 79.f,
113 80.f, 81.f, 82.f, 83.f, 84.f,
114 85.f, 86.f, 87.f, 88.f, 89.f
115 };
116
117 std::vector<float> expectedOutput =
118 {
119 37.f, 38.f, 39.f,
120 42.f, 43.f, 44.f,
121
122
123 67.f, 68.f, 69.f,
124 72.f, 73.f, 74.f
125 };
126
127 return SliceTestImpl<T, 4>(workloadFactory, memoryManager, inputInfo, outputInfo, input, expectedOutput, desc);
128 }
129
130 template<armnn::DataType ArmnnType, typename T = armnn::ResolveType<ArmnnType>>
Slice3dTest(armnn::IWorkloadFactory & workloadFactory,const armnn::IBackendInternal::IMemoryManagerSharedPtr & memoryManager)131 LayerTestResult<T, 3> Slice3dTest(armnn::IWorkloadFactory& workloadFactory,
132 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager)
133 {
134 armnn::TensorShape inputShape = { 2, 3, 5 };
135 armnn::TensorShape outputShape = { 1, 2, 3 };
136
137 armnn::SliceQueueDescriptor desc;
138 desc.m_Parameters.m_Begin = { 0, 1, 2 };
139 desc.m_Parameters.m_Size = { 1, 2, 3 };
140
141 armnn::TensorInfo inputInfo(inputShape, ArmnnType);
142 armnn::TensorInfo outputInfo(outputShape, ArmnnType);
143
144 std::vector<float> input =
145 {
146 0.f, 1.f, 2.f, 3.f, 4.f,
147 5.f, 6.f, 7.f, 8.f, 9.f,
148 10.f, 11.f, 12.f, 13.f, 14.f,
149
150 15.f, 16.f, 17.f, 18.f, 19.f,
151 20.f, 21.f, 22.f, 23.f, 24.f,
152 25.f, 26.f, 27.f, 28.f, 29.f,
153 };
154
155 std::vector<float> expectedOutput =
156 {
157 7.f, 8.f, 9.f,
158 12.f, 13.f, 14.f
159 };
160
161 return SliceTestImpl<T, 3>(workloadFactory, memoryManager, inputInfo, outputInfo, input, expectedOutput, desc);
162 }
163
164 template<armnn::DataType ArmnnType, typename T = armnn::ResolveType<ArmnnType>>
Slice2dTest(armnn::IWorkloadFactory & workloadFactory,const armnn::IBackendInternal::IMemoryManagerSharedPtr & memoryManager)165 LayerTestResult<T, 2> Slice2dTest(armnn::IWorkloadFactory& workloadFactory,
166 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager)
167 {
168 armnn::TensorShape inputShape = { 3, 5 };
169 armnn::TensorShape outputShape = { 2, 3 };
170
171 armnn::SliceQueueDescriptor desc;
172 desc.m_Parameters.m_Begin = { 1, 2 };
173 desc.m_Parameters.m_Size = { 2, 3 };
174
175 armnn::TensorInfo inputInfo(inputShape, ArmnnType);
176 armnn::TensorInfo outputInfo(outputShape, ArmnnType);
177
178 std::vector<float> input =
179 {
180 0.f, 1.f, 2.f, 3.f, 4.f,
181 5.f, 6.f, 7.f, 8.f, 9.f,
182 10.f, 11.f, 12.f, 13.f, 14.f
183 };
184
185 std::vector<float> expectedOutput =
186 {
187 7.f, 8.f, 9.f,
188 12.f, 13.f, 14.f
189 };
190
191 return SliceTestImpl<T, 2>(workloadFactory, memoryManager, inputInfo, outputInfo, input, expectedOutput, desc);
192 }
193
194 template<armnn::DataType ArmnnType, typename T = armnn::ResolveType<ArmnnType>>
Slice1dTest(armnn::IWorkloadFactory & workloadFactory,const armnn::IBackendInternal::IMemoryManagerSharedPtr & memoryManager)195 LayerTestResult<T, 1> Slice1dTest(armnn::IWorkloadFactory& workloadFactory,
196 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager)
197 {
198 armnn::TensorShape inputShape = { 5 };
199 armnn::TensorShape outputShape = { 3 };
200
201 armnn::SliceQueueDescriptor desc;
202 desc.m_Parameters.m_Begin = { 2 };
203 desc.m_Parameters.m_Size = { 3 };
204
205 armnn::TensorInfo inputInfo(inputShape, ArmnnType);
206 armnn::TensorInfo outputInfo(outputShape, ArmnnType);
207
208 std::vector<float> input =
209 {
210 0.f, 1.f, 2.f, 3.f, 4.f
211 };
212
213 std::vector<float> expectedOutput =
214 {
215 2.f, 3.f, 4.f
216 };
217
218 return SliceTestImpl<T, 1>(workloadFactory, memoryManager, inputInfo, outputInfo, input, expectedOutput, desc);
219 }
220
221 } // anonymous namespace
222
223 // Float32 tests
Slice4dFloat32Test(armnn::IWorkloadFactory & workloadFactory,const armnn::IBackendInternal::IMemoryManagerSharedPtr & memoryManager)224 LayerTestResult<float, 4> Slice4dFloat32Test(armnn::IWorkloadFactory& workloadFactory,
225 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager)
226 {
227 return Slice4dTest<armnn::DataType::Float32>(workloadFactory, memoryManager);
228 }
229
Slice3dFloat32Test(armnn::IWorkloadFactory & workloadFactory,const armnn::IBackendInternal::IMemoryManagerSharedPtr & memoryManager)230 LayerTestResult<float, 3> Slice3dFloat32Test(armnn::IWorkloadFactory& workloadFactory,
231 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager)
232 {
233 return Slice3dTest<armnn::DataType::Float32>(workloadFactory, memoryManager);
234 }
235
Slice2dFloat32Test(armnn::IWorkloadFactory & workloadFactory,const armnn::IBackendInternal::IMemoryManagerSharedPtr & memoryManager)236 LayerTestResult<float, 2> Slice2dFloat32Test(armnn::IWorkloadFactory& workloadFactory,
237 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager)
238 {
239 return Slice2dTest<armnn::DataType::Float32>(workloadFactory, memoryManager);
240 }
241
Slice1dFloat32Test(armnn::IWorkloadFactory & workloadFactory,const armnn::IBackendInternal::IMemoryManagerSharedPtr & memoryManager)242 LayerTestResult<float, 1> Slice1dFloat32Test(armnn::IWorkloadFactory& workloadFactory,
243 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager)
244 {
245 return Slice1dTest<armnn::DataType::Float32>(workloadFactory, memoryManager);
246 }
247
248 // Uint8 tests
Slice4dUint8Test(armnn::IWorkloadFactory & workloadFactory,const armnn::IBackendInternal::IMemoryManagerSharedPtr & memoryManager)249 LayerTestResult<uint8_t, 4> Slice4dUint8Test(armnn::IWorkloadFactory& workloadFactory,
250 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager)
251 {
252 return Slice4dTest<armnn::DataType::QAsymmU8>(workloadFactory, memoryManager);
253 }
254
Slice3dUint8Test(armnn::IWorkloadFactory & workloadFactory,const armnn::IBackendInternal::IMemoryManagerSharedPtr & memoryManager)255 LayerTestResult<uint8_t, 3> Slice3dUint8Test(armnn::IWorkloadFactory& workloadFactory,
256 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager)
257 {
258 return Slice3dTest<armnn::DataType::QAsymmU8>(workloadFactory, memoryManager);
259 }
260
Slice2dUint8Test(armnn::IWorkloadFactory & workloadFactory,const armnn::IBackendInternal::IMemoryManagerSharedPtr & memoryManager)261 LayerTestResult<uint8_t, 2> Slice2dUint8Test(armnn::IWorkloadFactory& workloadFactory,
262 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager)
263 {
264 return Slice2dTest<armnn::DataType::QAsymmU8>(workloadFactory, memoryManager);
265 }
266
Slice1dUint8Test(armnn::IWorkloadFactory & workloadFactory,const armnn::IBackendInternal::IMemoryManagerSharedPtr & memoryManager)267 LayerTestResult<uint8_t, 1> Slice1dUint8Test(armnn::IWorkloadFactory& workloadFactory,
268 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager)
269 {
270 return Slice1dTest<armnn::DataType::QAsymmU8>(workloadFactory, memoryManager);
271 }
272
273 // Int16 tests
Slice4dInt16Test(armnn::IWorkloadFactory & workloadFactory,const armnn::IBackendInternal::IMemoryManagerSharedPtr & memoryManager)274 LayerTestResult<int16_t, 4> Slice4dInt16Test(armnn::IWorkloadFactory& workloadFactory,
275 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager)
276 {
277 return Slice4dTest<armnn::DataType::QSymmS16>(workloadFactory, memoryManager);
278 }
279
Slice3dInt16Test(armnn::IWorkloadFactory & workloadFactory,const armnn::IBackendInternal::IMemoryManagerSharedPtr & memoryManager)280 LayerTestResult<int16_t, 3> Slice3dInt16Test(armnn::IWorkloadFactory& workloadFactory,
281 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager)
282 {
283 return Slice3dTest<armnn::DataType::QSymmS16>(workloadFactory, memoryManager);
284 }
285
Slice2dInt16Test(armnn::IWorkloadFactory & workloadFactory,const armnn::IBackendInternal::IMemoryManagerSharedPtr & memoryManager)286 LayerTestResult<int16_t, 2> Slice2dInt16Test(armnn::IWorkloadFactory& workloadFactory,
287 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager)
288 {
289 return Slice2dTest<armnn::DataType::QSymmS16>(workloadFactory, memoryManager);
290 }
291
Slice1dInt16Test(armnn::IWorkloadFactory & workloadFactory,const armnn::IBackendInternal::IMemoryManagerSharedPtr & memoryManager)292 LayerTestResult<int16_t, 1> Slice1dInt16Test(armnn::IWorkloadFactory& workloadFactory,
293 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager)
294 {
295 return Slice1dTest<armnn::DataType::QSymmS16>(workloadFactory, memoryManager);
296 }
297