1 //
2 // Copyright © 2017 Arm Ltd and Contributors. All rights reserved.
3 // SPDX-License-Identifier: MIT
4 //
5
6 #include "AdditionTestImpl.hpp"
7
8 #include "ElementwiseTestImpl.hpp"
9
10 #include <QuantizeHelper.hpp>
11 #include <reference/test/RefWorkloadFactoryHelper.hpp>
12
13 template<>
CreateWorkload(const armnn::IWorkloadFactory & workloadFactory,const armnn::WorkloadInfo & info,const armnn::AdditionQueueDescriptor & descriptor)14 std::unique_ptr<armnn::IWorkload> CreateWorkload<armnn::AdditionQueueDescriptor>(
15 const armnn::IWorkloadFactory& workloadFactory,
16 const armnn::WorkloadInfo& info,
17 const armnn::AdditionQueueDescriptor& descriptor)
18 {
19 return workloadFactory.CreateAddition(descriptor, info);
20 }
21
AdditionTest(armnn::IWorkloadFactory & workloadFactory,const armnn::IBackendInternal::IMemoryManagerSharedPtr & memoryManager,const armnn::ITensorHandleFactory & tensorHandleFactory)22 LayerTestResult<float,4> AdditionTest(
23 armnn::IWorkloadFactory& workloadFactory,
24 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
25 const armnn::ITensorHandleFactory& tensorHandleFactory)
26 {
27 unsigned int batchSize = 2u;
28 unsigned int channels = 2u;
29 unsigned int height = 2u;
30 unsigned int width = 3u;
31
32 unsigned int shape[] = { batchSize, channels, height, width };
33
34 std::vector<float> input1 =
35 {
36 0.0f, 2.0f, 1.0f,
37 0.2f, 1.0f, 2.0f,
38
39 1.0f, 2.0f, 1.0f,
40 0.2f, 1.0f, 2.0f,
41
42 0.0f, 2.0f, 1.0f,
43 4.2f, 1.0f, 2.0f,
44
45 0.0f, 0.0f, 1.0f,
46 0.2f, 1.0f, 2.0f,
47 };
48
49 std::vector<float> input2 =
50 {
51 1.0f, 2.0f, 1.0f,
52 0.0f, 1.0f, 2.0f,
53
54 1.0f, 2.0f, -2.0f,
55 0.2f, 1.0f, 2.0f,
56
57 0.0f, 2.0f, 1.0f,
58 4.2f, 0.0f, -3.0f,
59
60 0.0f, 0.0f, 1.0f,
61 0.7f, 1.0f, 5.0f,
62 };
63
64
65 std::vector<float> output
66 {
67 1.0f, 4.0f, 2.0f,
68 0.2f, 2.0f, 4.0f,
69
70 2.0f, 4.0f, -1.0f,
71 0.4f, 2.0f, 4.0f,
72
73 0.0f, 4.0f, 2.0f,
74 8.4f, 1.0f, -1.0f,
75
76 0.0f, 0.0f, 2.0f,
77 0.9f, 2.0f, 7.0f,
78 };
79
80 return ElementwiseTestHelper<4, armnn::AdditionQueueDescriptor, armnn::DataType::Float32>(
81 workloadFactory,
82 memoryManager,
83 shape,
84 input1,
85 shape,
86 input2,
87 shape,
88 output,
89 tensorHandleFactory);
90 }
91
Addition5dTest(armnn::IWorkloadFactory & workloadFactory,const armnn::IBackendInternal::IMemoryManagerSharedPtr & memoryManager,const armnn::ITensorHandleFactory & tensorHandleFactory)92 LayerTestResult<float, 5> Addition5dTest(
93 armnn::IWorkloadFactory& workloadFactory,
94 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
95 const armnn::ITensorHandleFactory& tensorHandleFactory)
96 {
97 unsigned int depth = 2u;
98 unsigned int batchSize = 2u;
99 unsigned int channels = 2u;
100 unsigned int height = 2u;
101 unsigned int width = 3u;
102
103 unsigned int shape[] = { depth, batchSize, channels, height, width };
104
105 std::vector<float> input1 =
106 {
107 2.6f, 4.0f, 4.4f, 2.7f, 4.6f, 2.8f,
108 2.3f, 1.9f, 3.4f, 2.9f, 2.2f, 4.5f,
109
110 2.8f, 1.9f, 2.3f, 2.6f, 4.7f, 3.5f,
111 0.4f, 1.5f, 2.1f, 0.7f, 5.0f, 1.1f,
112
113
114 1.0f, 2.7f, 0.0f, 0.6f, 0.8f, 0.9f,
115 1.0f, 2.6f, 0.4f, 3.8f, 0.4f, 0.8f,
116
117 0.5f, 4.3f, 3.1f, 4.4f, 0.7f, 1.4f,
118 0.4f, 4.4f, 0.7f, 0.6f, 4.7f, 1.2f,
119
120 };
121
122 std::vector<float> input2 =
123 {
124 4.4f, 3.0f, 1.0f, 0.0f, 3.9f, 3.1f,
125 1.7f, 2.9f, 1.3f, 0.4f, 0.4f, 4.3f,
126
127 4.5f, 0.2f, 2.2f, 4.1f, 3.9f, 3.0f,
128 0.1f, 2.5f, 4.1f, 4.6f, 1.5f, 0.0f,
129
130
131 0.5f, 4.9f, 2.5f, 1.5f, 3.4f, 4.5f,
132 2.0f, 3.0f, 4.9f, 1.6f, 2.4f, 3.4f,
133
134 3.6f, 1.8f, 1.3f, 2.6f, 2.1f, 4.8f,
135 2.0f, 4.3f, 4.0f, 0.2f, 0.6f, 4.4f,
136 };
137
138 std::vector<float> output =
139 {
140 7.0f, 7.0f, 5.4f, 2.7f, 8.5f, 5.9f,
141 4.0f, 4.8f, 4.7f, 3.3f, 2.6f, 8.8f,
142
143 7.3f, 2.1f, 4.5f, 6.7f, 8.6f, 6.5f,
144 0.5f, 4.0f, 6.2f, 5.3f, 6.5f, 1.1f,
145
146
147 1.5f, 7.6f, 2.5f, 2.1f, 4.2f, 5.4f,
148 3.0f, 5.6f, 5.3f, 5.4f, 2.8f, 4.2f,
149
150 4.1f, 6.1f, 4.4f, 7.0f, 2.8f, 6.2f,
151 2.4f, 8.7f, 4.7f, 0.8f, 5.3f, 5.6f,
152 };
153
154 return ElementwiseTestHelper<5, armnn::AdditionQueueDescriptor, armnn::DataType::Float32>(
155 workloadFactory,
156 memoryManager,
157 shape,
158 input1,
159 shape,
160 input2,
161 shape,
162 output,
163 tensorHandleFactory);
164 }
165
166 template<armnn::DataType ArmnnType, typename T = armnn::ResolveType<ArmnnType>>
AdditionBroadcastTestImpl(armnn::IWorkloadFactory & workloadFactory,const armnn::IBackendInternal::IMemoryManagerSharedPtr & memoryManager,float qScale,int32_t qOffset,const armnn::ITensorHandleFactory & tensorHandleFactory)167 LayerTestResult<T, 4> AdditionBroadcastTestImpl(
168 armnn::IWorkloadFactory& workloadFactory,
169 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
170 float qScale,
171 int32_t qOffset,
172 const armnn::ITensorHandleFactory& tensorHandleFactory)
173 {
174 IgnoreUnused(memoryManager);
175 armnn::TensorInfo inputTensorInfo1 = armnn::TensorInfo({1, 3, 2, 1}, ArmnnType);
176 armnn::TensorInfo inputTensorInfo2 = armnn::TensorInfo({1, 1, 2, 3}, ArmnnType);
177 armnn::TensorInfo outputTensorInfo = armnn::TensorInfo({1, 3, 2, 3}, ArmnnType);
178
179 if (armnn::IsQuantizedType<T>())
180 {
181 inputTensorInfo1.SetQuantizationScale(qScale);
182 inputTensorInfo1.SetQuantizationOffset(qOffset);
183 inputTensorInfo2.SetQuantizationScale(qScale);
184 inputTensorInfo2.SetQuantizationOffset(qOffset);
185 outputTensorInfo.SetQuantizationScale(qScale);
186 outputTensorInfo.SetQuantizationOffset(qOffset);
187 }
188
189 auto input1 = MakeTensor<T, 4>(inputTensorInfo1, armnnUtils::QuantizedVector<T>(
190 {
191 0.0f,
192 1.0f,
193
194 2.0f,
195 3.0f,
196
197 4.0f,
198 5.0f,
199 },
200 qScale, qOffset));
201
202 auto input2 = MakeTensor<T, 4>(inputTensorInfo2, armnnUtils::QuantizedVector<T>(
203 {
204 0.5f, 1.5f, 2.5f,
205 3.5f, 4.5f, 5.5f,
206 },
207 qScale, qOffset));
208
209 LayerTestResult<T,4> ret(outputTensorInfo);
210 ret.outputExpected = MakeTensor<T, 4>(outputTensorInfo, armnnUtils::QuantizedVector<T>(
211 {
212 0.5f, 1.5f, 2.5f,
213 4.5f, 5.5f, 6.5f,
214
215 2.5f, 3.5f, 4.5f,
216 6.5f, 7.5f, 8.5f,
217
218 4.5f, 5.5f, 6.5f,
219 8.5f, 9.5f, 10.5f,
220 },
221 qScale, qOffset));
222
223 std::unique_ptr<armnn::ITensorHandle> inputHandle1 = tensorHandleFactory.CreateTensorHandle(inputTensorInfo1);
224 std::unique_ptr<armnn::ITensorHandle> inputHandle2 = tensorHandleFactory.CreateTensorHandle(inputTensorInfo2);
225 std::unique_ptr<armnn::ITensorHandle> outputHandle = tensorHandleFactory.CreateTensorHandle(outputTensorInfo);
226
227 armnn::AdditionQueueDescriptor data;
228 armnn::WorkloadInfo info;
229 AddInputToWorkload(data, info, inputTensorInfo1, inputHandle1.get());
230 AddInputToWorkload(data, info, inputTensorInfo2, inputHandle2.get());
231 AddOutputToWorkload(data, info, outputTensorInfo, outputHandle.get());
232
233 std::unique_ptr<armnn::IWorkload> workload = workloadFactory.CreateAddition(data, info);
234
235 inputHandle1->Allocate();
236 inputHandle2->Allocate();
237 outputHandle->Allocate();
238
239 CopyDataToITensorHandle(inputHandle1.get(), &input1[0][0][0][0]);
240 CopyDataToITensorHandle(inputHandle2.get(), &input2[0][0][0][0]);
241
242 workload->PostAllocationConfigure();
243 workload->Execute();
244
245 CopyDataFromITensorHandle(&ret.output[0][0][0][0], outputHandle.get());
246
247 return ret;
248 }
249
250 template<armnn::DataType ArmnnType, typename T = armnn::ResolveType<ArmnnType>>
AdditionBroadcast1ElementTestImpl(armnn::IWorkloadFactory & workloadFactory,const armnn::IBackendInternal::IMemoryManagerSharedPtr & memoryManager,float qScale,int32_t qOffset,const armnn::ITensorHandleFactory & tensorHandleFactory)251 LayerTestResult<T, 4> AdditionBroadcast1ElementTestImpl(
252 armnn::IWorkloadFactory& workloadFactory,
253 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
254 float qScale,
255 int32_t qOffset,
256 const armnn::ITensorHandleFactory& tensorHandleFactory)
257 {
258 IgnoreUnused(memoryManager);
259 armnn::TensorInfo inputTensorInfo1 = armnn::TensorInfo({1, 3, 2, 3}, ArmnnType);
260 armnn::TensorInfo inputTensorInfo2 = armnn::TensorInfo({1, 1, 1, 1}, ArmnnType);
261 armnn::TensorInfo outputTensorInfo = armnn::TensorInfo({1, 3, 2, 3}, ArmnnType);
262
263 if (armnn::IsQuantizedType<T>())
264 {
265 inputTensorInfo1.SetQuantizationScale(qScale);
266 inputTensorInfo1.SetQuantizationOffset(qOffset);
267 inputTensorInfo2.SetQuantizationScale(qScale);
268 inputTensorInfo2.SetQuantizationOffset(qOffset);
269 outputTensorInfo.SetQuantizationScale(qScale);
270 outputTensorInfo.SetQuantizationOffset(qOffset);
271 }
272
273 auto input1 = MakeTensor<T, 4>(inputTensorInfo1, armnnUtils::QuantizedVector<T>(
274 {
275 0.0f, 1.0f, 2.0f,
276 3.0f, 4.0f, 5.0f,
277 6.0f, 7.0f, 8.0f,
278 9.0f, 10.0f, 11.0f,
279 12.0f, 13.0f, 14.0f,
280 15.0f, 16.0f, 17.0f,
281 },
282 qScale, qOffset));
283
284 auto input2 = MakeTensor<T, 4>(inputTensorInfo2, armnnUtils::QuantizedVector<T>(
285 {
286 0.5f,
287 },
288 qScale, qOffset));
289
290 LayerTestResult<T,4> ret(outputTensorInfo);
291 ret.outputExpected = MakeTensor<T, 4>(outputTensorInfo, armnnUtils::QuantizedVector<T>(
292 {
293 0.5f, 1.5f, 2.5f,
294 3.5f, 4.5f, 5.5f,
295 6.5f, 7.5f, 8.5f,
296 9.5f, 10.5f, 11.5f,
297 12.5f, 13.5f, 14.5f,
298 15.5f, 16.5f, 17.5f,
299 },
300 qScale, qOffset));
301
302 std::unique_ptr<armnn::ITensorHandle> inputHandle1 = tensorHandleFactory.CreateTensorHandle(inputTensorInfo1);
303 std::unique_ptr<armnn::ITensorHandle> inputHandle2 = tensorHandleFactory.CreateTensorHandle(inputTensorInfo2);
304 std::unique_ptr<armnn::ITensorHandle> outputHandle = tensorHandleFactory.CreateTensorHandle(outputTensorInfo);
305
306 armnn::AdditionQueueDescriptor data;
307 armnn::WorkloadInfo info;
308 AddInputToWorkload(data, info, inputTensorInfo1, inputHandle1.get());
309 AddInputToWorkload(data, info, inputTensorInfo2, inputHandle2.get());
310 AddOutputToWorkload(data, info, outputTensorInfo, outputHandle.get());
311
312 std::unique_ptr<armnn::IWorkload> workload = workloadFactory.CreateAddition(data, info);
313
314 inputHandle1->Allocate();
315 inputHandle2->Allocate();
316 outputHandle->Allocate();
317
318 CopyDataToITensorHandle(inputHandle1.get(), &input1[0][0][0][0]);
319 CopyDataToITensorHandle(inputHandle2.get(), &input2[0][0][0][0]);
320
321 workload->PostAllocationConfigure();
322 workload->Execute();
323
324 CopyDataFromITensorHandle(&ret.output[0][0][0][0], outputHandle.get());
325
326 return ret;
327 }
328
AdditionBroadcastTest(armnn::IWorkloadFactory & workloadFactory,const armnn::IBackendInternal::IMemoryManagerSharedPtr & memoryManager,const armnn::ITensorHandleFactory & tensorHandleFactory)329 LayerTestResult<float, 4> AdditionBroadcastTest(
330 armnn::IWorkloadFactory& workloadFactory,
331 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
332 const armnn::ITensorHandleFactory& tensorHandleFactory)
333 {
334 return AdditionBroadcastTestImpl<armnn::DataType::Float32>(
335 workloadFactory, memoryManager, 0.0f, 0, tensorHandleFactory);
336 }
337
AdditionBroadcastUint8Test(armnn::IWorkloadFactory & workloadFactory,const armnn::IBackendInternal::IMemoryManagerSharedPtr & memoryManager,const armnn::ITensorHandleFactory & tensorHandleFactory)338 LayerTestResult<uint8_t, 4> AdditionBroadcastUint8Test(
339 armnn::IWorkloadFactory& workloadFactory,
340 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
341 const armnn::ITensorHandleFactory& tensorHandleFactory)
342 {
343 return AdditionBroadcastTestImpl<armnn::DataType::QAsymmU8>(
344 workloadFactory, memoryManager, 2.f, 0, tensorHandleFactory);
345 }
346
AdditionBroadcastInt16Test(armnn::IWorkloadFactory & workloadFactory,const armnn::IBackendInternal::IMemoryManagerSharedPtr & memoryManager,const armnn::ITensorHandleFactory & tensorHandleFactory)347 LayerTestResult<int16_t, 4> AdditionBroadcastInt16Test(
348 armnn::IWorkloadFactory& workloadFactory,
349 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
350 const armnn::ITensorHandleFactory& tensorHandleFactory)
351 {
352 return AdditionBroadcastTestImpl<armnn::DataType::QSymmS16>(
353 workloadFactory, memoryManager, 2.f, 0, tensorHandleFactory);
354 }
355
AdditionBroadcastInt32Test(armnn::IWorkloadFactory & workloadFactory,const armnn::IBackendInternal::IMemoryManagerSharedPtr & memoryManager,const armnn::ITensorHandleFactory & tensorHandleFactory)356 LayerTestResult<int32_t, 4> AdditionBroadcastInt32Test(
357 armnn::IWorkloadFactory& workloadFactory,
358 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
359 const armnn::ITensorHandleFactory& tensorHandleFactory)
360 {
361 return AdditionBroadcastTestImpl<armnn::DataType::Signed32>(
362 workloadFactory, memoryManager, 1.f, 0, tensorHandleFactory);
363 }
364
AdditionBroadcast1ElementTest(armnn::IWorkloadFactory & workloadFactory,const armnn::IBackendInternal::IMemoryManagerSharedPtr & memoryManager,const armnn::ITensorHandleFactory & tensorHandleFactory)365 LayerTestResult<float, 4> AdditionBroadcast1ElementTest(
366 armnn::IWorkloadFactory& workloadFactory,
367 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
368 const armnn::ITensorHandleFactory& tensorHandleFactory)
369 {
370 return AdditionBroadcast1ElementTestImpl<armnn::DataType::Float32>(
371 workloadFactory, memoryManager, 0.0f, 0, tensorHandleFactory);
372 }
373
AdditionBroadcast1ElementUint8Test(armnn::IWorkloadFactory & workloadFactory,const armnn::IBackendInternal::IMemoryManagerSharedPtr & memoryManager,const armnn::ITensorHandleFactory & tensorHandleFactory)374 LayerTestResult<uint8_t, 4> AdditionBroadcast1ElementUint8Test(
375 armnn::IWorkloadFactory& workloadFactory,
376 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
377 const armnn::ITensorHandleFactory& tensorHandleFactory)
378 {
379 return AdditionBroadcast1ElementTestImpl<armnn::DataType::QAsymmU8>(
380 workloadFactory, memoryManager, 0.1333333f, 128, tensorHandleFactory);
381 }
382
AdditionBroadcast1ElementInt16Test(armnn::IWorkloadFactory & workloadFactory,const armnn::IBackendInternal::IMemoryManagerSharedPtr & memoryManager,const armnn::ITensorHandleFactory & tensorHandleFactory)383 LayerTestResult<int16_t, 4> AdditionBroadcast1ElementInt16Test(
384 armnn::IWorkloadFactory& workloadFactory,
385 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
386 const armnn::ITensorHandleFactory& tensorHandleFactory)
387 {
388 return AdditionBroadcast1ElementTestImpl<armnn::DataType::QSymmS16>(
389 workloadFactory, memoryManager, 0.1333333f, 0, tensorHandleFactory);
390 }
391
AdditionBroadcast1ElementInt32Test(armnn::IWorkloadFactory & workloadFactory,const armnn::IBackendInternal::IMemoryManagerSharedPtr & memoryManager,const armnn::ITensorHandleFactory & tensorHandleFactory)392 LayerTestResult<int32_t, 4> AdditionBroadcast1ElementInt32Test(
393 armnn::IWorkloadFactory& workloadFactory,
394 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
395 const armnn::ITensorHandleFactory& tensorHandleFactory)
396 {
397 return AdditionBroadcast1ElementTestImpl<armnn::DataType::Signed32>(
398 workloadFactory, memoryManager, 1.f, 0, tensorHandleFactory);
399 }
400
AdditionUint8Test(armnn::IWorkloadFactory & workloadFactory,const armnn::IBackendInternal::IMemoryManagerSharedPtr & memoryManager,const armnn::ITensorHandleFactory & tensorHandleFactory)401 LayerTestResult<uint8_t, 4> AdditionUint8Test(
402 armnn::IWorkloadFactory& workloadFactory,
403 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
404 const armnn::ITensorHandleFactory& tensorHandleFactory)
405 {
406 const unsigned int shape0[] = { 1, 2, 2, 3 };
407 const unsigned int shape1[] = { 1, 2, 2, 3 };
408
409 std::vector<uint8_t> input0(
410 {
411 63, 35, 77, 70, 56, 112, // 420, 224, 518, 469, 371, 763
412 203, 28, 252, 168, 245, 91 // 1400, 175, 1743, 1155, 1694, 616
413 });
414
415 std::vector<uint8_t> input1(
416 {
417 21, 7, 175, 231, 175, 210, // 126, 28, 1204, 1596, 1204, 1449
418 126, 161, 63, 21, 105, 126 // 861, 1106, 420, 126, 714, 861
419 });
420
421 std::vector<uint8_t> output(
422 {
423 81, 39, 249, 255, 228, 255, // 546, 252, 1722, 2065(clamped), 1575, 2212(clamped)
424 255, 186, 255, 186, 255, 214, // 2261(clamped), 1281, 2163(clamped), 1281, 2408(clamped), 1477
425 });
426
427 return ElementwiseTestHelper<4, armnn::AdditionQueueDescriptor, armnn::DataType::QAsymmU8>(
428 workloadFactory,
429 memoryManager,
430 shape0,
431 input0,
432 7.0f,
433 3,
434 shape1,
435 input1,
436 7.0f,
437 3,
438 shape0,
439 output,
440 tensorHandleFactory,
441 7.0f,
442 3);
443 }
444
AdditionInt16Test(armnn::IWorkloadFactory & workloadFactory,const armnn::IBackendInternal::IMemoryManagerSharedPtr & memoryManager,const armnn::ITensorHandleFactory & tensorHandleFactory)445 LayerTestResult<int16_t, 4> AdditionInt16Test(
446 armnn::IWorkloadFactory& workloadFactory,
447 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
448 const armnn::ITensorHandleFactory& tensorHandleFactory)
449 {
450 const unsigned int shape0[] = { 1, 2, 2, 3 };
451 const unsigned int shape1[] = { 1, 2, 2, 3 };
452
453 std::vector<int16_t> input0 =
454 {
455 63, 35, 77, 70, 56, 112, // 441, 245, 539, 490, 392, 184
456 203, 28, 252, 168, 245, 91 // 1421, 196, 1764, 1176, 1715, 637
457 };
458
459 std::vector<int16_t> input1 =
460 {
461 21, 7, 175, 231, 175, 210, // 126, 28, 1204, 1596, 1204, 1449
462 126, 161, 63, 21, 105, 126 // 861, 1106, 420, 126, 714, 861
463 };
464
465 std::vector<int16_t> output =
466 {
467 84, 42, 252, 301, 231, 322, // 588, 294, 1764, 2107(clamped), 1617, 2254(clamped)
468 329, 189, 315, 189, 350, 217, // 2303(clamped), 1323, 2205(clamped), 1323, 2450(clamped), 1519
469 };
470
471 return ElementwiseTestHelper<4, armnn::AdditionQueueDescriptor, armnn::DataType::QSymmS16>(
472 workloadFactory,
473 memoryManager,
474 shape0,
475 input0,
476 7.0f,
477 0,
478 shape1,
479 input1,
480 7.0f,
481 0,
482 shape0,
483 output,
484 tensorHandleFactory,
485 7.0f,
486 0);
487 }
488
AdditionInt32Test(armnn::IWorkloadFactory & workloadFactory,const armnn::IBackendInternal::IMemoryManagerSharedPtr & memoryManager,const armnn::ITensorHandleFactory & tensorHandleFactory)489 LayerTestResult<int32_t, 4> AdditionInt32Test(
490 armnn::IWorkloadFactory& workloadFactory,
491 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
492 const armnn::ITensorHandleFactory& tensorHandleFactory)
493 {
494 const unsigned int shape0[] = { 1, 2, 2, 3 };
495 const unsigned int shape1[] = { 1, 2, 2, 3 };
496
497 std::vector<int32_t> input0 =
498 {
499 63, 35, 77, 70, 56, 112, // 441, 245, 539, 490, 392, 184
500 203, 28, 252, 168, 245, 91 // 1421, 196, 1764, 1176, 1715, 637
501 };
502
503 std::vector<int32_t> input1 =
504 {
505 21, 7, 175, 231, 175, 210, // 126, 28, 1204, 1596, 1204, 1449
506 126, 161, 63, 21, 105, 126 // 861, 1106, 420, 126, 714, 861
507 };
508
509 std::vector<int32_t> output =
510 {
511 84, 42, 252, 301, 231, 322, // 588, 294, 1764, 2107(clamped), 1617, 2254(clamped)
512 329, 189, 315, 189, 350, 217, // 2303(clamped), 1323, 2205(clamped), 1323, 2450(clamped), 1519
513 };
514
515 return ElementwiseTestHelper<4, armnn::AdditionQueueDescriptor, armnn::DataType::Signed32>(
516 workloadFactory,
517 memoryManager,
518 shape0,
519 input0,
520 1.0f,
521 0,
522 shape1,
523 input1,
524 1.0f,
525 0,
526 shape0,
527 output,
528 tensorHandleFactory,
529 1.0f,
530 0);
531 }
532
AdditionAfterMaxPoolTest(armnn::IWorkloadFactory & workloadFactory,const armnn::IBackendInternal::IMemoryManagerSharedPtr & memoryManager,const armnn::ITensorHandleFactory & tensorHandleFactory)533 LayerTestResult<float, 4> AdditionAfterMaxPoolTest(
534 armnn::IWorkloadFactory& workloadFactory,
535 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
536 const armnn::ITensorHandleFactory& tensorHandleFactory)
537 {
538 IgnoreUnused(memoryManager);
539
540 // Create Initial Tensor
541 // 1, 2, 3
542 // 4, 5, 6
543 // 7, 8, 9
544
545 armnn::TensorInfo poolingInputTensorInfo({ 1, 1, 3, 3}, armnn::DataType::Float32);
546 armnn::TensorInfo poolingOutputTensorInfo({ 1, 1, 2, 2}, armnn::DataType::Float32);
547
548 boost::multi_array<float, 4> poolingInput = MakeTensor<float,4>(poolingInputTensorInfo,
549 {1, 2, 3,
550 4, 5, 6,
551 7, 8, 9
552 });
553 std::unique_ptr<armnn::ITensorHandle> poolingInputHandle =
554 tensorHandleFactory.CreateTensorHandle(poolingInputTensorInfo);
555 std::unique_ptr<armnn::ITensorHandle> poolingOutputHandle =
556 tensorHandleFactory.CreateTensorHandle(poolingOutputTensorInfo);
557
558 // Apply MaxPool poolSize = 1x1, stride=2x2
559 // Result =
560 // 1, 3
561 // 7, 9
562 armnn::Pooling2dDescriptor descriptor;
563 descriptor.m_PoolHeight = 1;
564 descriptor.m_PoolWidth = 1;
565 descriptor.m_StrideX = 2;
566 descriptor.m_StrideY = 2;
567 descriptor.m_PoolType = armnn::PoolingAlgorithm::Max;
568
569 armnn::Pooling2dQueueDescriptor queueDescriptor;
570 queueDescriptor.m_Parameters = descriptor;
571 armnn::WorkloadInfo workloadInfo;
572 AddInputToWorkload(queueDescriptor, workloadInfo, poolingInputTensorInfo, poolingInputHandle.get());
573 AddOutputToWorkload(queueDescriptor, workloadInfo, poolingOutputTensorInfo, poolingOutputHandle.get());
574
575 // Create the MaxPool
576 std::unique_ptr<armnn::IWorkload> workload = workloadFactory.CreatePooling2d(queueDescriptor, workloadInfo);
577
578 //LayerTestResult<float, 4> result(poolingOutputTensorInfo);
579 auto shape( GetTensorShapeAsArray<4>(poolingOutputTensorInfo));
580 boost::multi_array<float, 4> resultMaxPool;
581 resultMaxPool.resize(shape);
582
583
584 // Create addition with another tensor the same size
585 // This would be the result to apply a Conv2d with kernel ones(2) and stride 1x1
586 // with the initial tensor.
587 // 12, 16
588 // 24, 28
589
590 armnn::TensorInfo addInputTensorInfo({ 1,1,2,2}, armnn::DataType::Float32);
591 armnn::TensorInfo addOutputTensorInfo({ 1,1,2,2}, armnn::DataType::Float32);
592
593 boost::multi_array<float, 4> addInput = MakeTensor<float,4>(addInputTensorInfo,
594 {12, 16,
595 24, 28,
596 });
597
598 // Expected output tensor after MaxPool and Addition.
599 LayerTestResult<float,4> addRet(addOutputTensorInfo);
600 addRet.outputExpected = MakeTensor<float, 4>(addOutputTensorInfo, std::vector<float>(
601 {
602 13, 19,
603 31, 37
604 }));
605
606 std::unique_ptr<armnn::ITensorHandle> addInputHandle = tensorHandleFactory.CreateTensorHandle(addInputTensorInfo);
607 std::unique_ptr<armnn::ITensorHandle> addOutputHandle =
608 tensorHandleFactory.CreateTensorHandle(addOutputTensorInfo);
609
610 armnn::AdditionQueueDescriptor data;
611 armnn::WorkloadInfo info;
612
613 // Add the output of the MaxPool and the new tensor
614 AddInputToWorkload(data, info, poolingOutputTensorInfo, poolingOutputHandle.get());
615 AddInputToWorkload(data, info, addInputTensorInfo, addInputHandle.get());
616 AddOutputToWorkload(data, info, addOutputTensorInfo, addOutputHandle.get());
617
618 std::unique_ptr<armnn::IWorkload> addWorkload = workloadFactory.CreateAddition(data, info);
619
620 poolingInputHandle->Allocate();
621 poolingOutputHandle->Allocate();
622 addInputHandle->Allocate();
623 addOutputHandle->Allocate();
624
625 CopyDataToITensorHandle(poolingInputHandle.get(), &poolingInput[0][0][0][0]);
626 CopyDataFromITensorHandle(&resultMaxPool[0][0][0][0], poolingOutputHandle.get());
627
628 CopyDataToITensorHandle(poolingOutputHandle.get(), &resultMaxPool[0][0][0][0]);
629 CopyDataToITensorHandle(addInputHandle.get(), &addInput[0][0][0][0]);
630
631 workload->PostAllocationConfigure();
632 workload->Execute();
633 addWorkload->PostAllocationConfigure();
634 addWorkload->Execute();
635
636 CopyDataFromITensorHandle(&addRet.output[0][0][0][0], addOutputHandle.get());
637
638 return addRet;
639 }
640
CompareAdditionTest(armnn::IWorkloadFactory & workloadFactory,const armnn::IBackendInternal::IMemoryManagerSharedPtr & memoryManager,armnn::IWorkloadFactory & refWorkloadFactory,const armnn::ITensorHandleFactory & tensorHandleFactory,const armnn::ITensorHandleFactory & refTensorHandleFactory)641 LayerTestResult<float,4> CompareAdditionTest(
642 armnn::IWorkloadFactory& workloadFactory,
643 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
644 armnn::IWorkloadFactory& refWorkloadFactory,
645 const armnn::ITensorHandleFactory& tensorHandleFactory,
646 const armnn::ITensorHandleFactory& refTensorHandleFactory)
647 {
648 IgnoreUnused(memoryManager);
649 unsigned int batchSize = 4;
650 unsigned int channels = 1;
651 unsigned int height = 2;
652 unsigned int width = 3;
653
654 armnn::TensorInfo inputTensorInfo1, inputTensorInfo2;
655 armnn::TensorInfo outputTensorInfo;
656
657 unsigned int shape[] = {batchSize, channels, height, width};
658
659 inputTensorInfo1 = armnn::TensorInfo(4, shape, armnn::DataType::Float32);
660 inputTensorInfo2 = armnn::TensorInfo(4, shape, armnn::DataType::Float32);
661 outputTensorInfo = armnn::TensorInfo(4, shape, armnn::DataType::Float32);
662
663 auto input1 = MakeRandomTensor<float, 4>(inputTensorInfo1, 1232);
664 auto input2 = MakeRandomTensor<float, 4>(inputTensorInfo2, 456);
665
666 LayerTestResult<float,4> ret(outputTensorInfo);
667
668 std::unique_ptr<armnn::ITensorHandle> inputHandle1 = tensorHandleFactory.CreateTensorHandle(inputTensorInfo1);
669 std::unique_ptr<armnn::ITensorHandle> inputHandle2 = tensorHandleFactory.CreateTensorHandle(inputTensorInfo2);
670 std::unique_ptr<armnn::ITensorHandle> outputHandle = tensorHandleFactory.CreateTensorHandle(outputTensorInfo);
671
672 std::unique_ptr<armnn::ITensorHandle> inputHandle1Ref = refTensorHandleFactory.CreateTensorHandle(inputTensorInfo1);
673 std::unique_ptr<armnn::ITensorHandle> inputHandle2Ref = refTensorHandleFactory.CreateTensorHandle(inputTensorInfo2);
674 std::unique_ptr<armnn::ITensorHandle> outputHandleRef = refTensorHandleFactory.CreateTensorHandle(outputTensorInfo);
675
676 armnn::AdditionQueueDescriptor data;
677 armnn::WorkloadInfo info;
678 AddInputToWorkload(data, info, inputTensorInfo1, inputHandle1.get());
679 AddInputToWorkload(data, info, inputTensorInfo2, inputHandle2.get());
680 AddOutputToWorkload(data, info, outputTensorInfo, outputHandle.get());
681
682 armnn::AdditionQueueDescriptor refData = data;
683 armnn::WorkloadInfo refInfo = info;
684 SetWorkloadInput(refData, refInfo, 0, inputTensorInfo1, inputHandle1Ref.get());
685 SetWorkloadInput(refData, refInfo, 1, inputTensorInfo2, inputHandle2Ref.get());
686 SetWorkloadOutput(refData, refInfo, 0, outputTensorInfo, outputHandleRef.get());
687
688 std::unique_ptr<armnn::IWorkload> workload = workloadFactory.CreateAddition(data, info);
689 std::unique_ptr<armnn::IWorkload> workloadRef = refWorkloadFactory.CreateAddition(refData, refInfo);
690
691 inputHandle1->Allocate();
692 inputHandle2->Allocate();
693 outputHandle->Allocate();
694 inputHandle1Ref->Allocate();
695 inputHandle2Ref->Allocate();
696 outputHandleRef->Allocate();
697
698 CopyDataToITensorHandle(inputHandle1.get(), &input1[0][0][0][0]);
699 CopyDataToITensorHandle(inputHandle2.get(), &input2[0][0][0][0]);
700 CopyDataToITensorHandle(inputHandle1Ref.get(), &input1[0][0][0][0]);
701 CopyDataToITensorHandle(inputHandle2Ref.get(), &input2[0][0][0][0]);
702
703 workload->PostAllocationConfigure();
704 workload->Execute();
705 workloadRef->PostAllocationConfigure();
706 workloadRef->Execute();
707
708 CopyDataFromITensorHandle(&ret.output[0][0][0][0], outputHandle.get());
709 CopyDataFromITensorHandle(&ret.outputExpected[0][0][0][0], outputHandleRef.get());
710
711 return ret;
712 }