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 <armnnUtils/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.CreateWorkload(armnn::LayerType::Addition, 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 = 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 = armnnUtils::QuantizedVector<T>(
203 {
204 0.5f, 1.5f, 2.5f,
205 3.5f, 4.5f, 5.5f,
206 },
207 qScale, qOffset);
208
209 std::vector<T> actualOutput(outputTensorInfo.GetNumElements());
210
211 auto expectedOutput = armnnUtils::QuantizedVector<T>(
212 {
213 0.5f, 1.5f, 2.5f,
214 4.5f, 5.5f, 6.5f,
215
216 2.5f, 3.5f, 4.5f,
217 6.5f, 7.5f, 8.5f,
218
219 4.5f, 5.5f, 6.5f,
220 8.5f, 9.5f, 10.5f,
221 },
222 qScale, qOffset);
223
224 std::unique_ptr<armnn::ITensorHandle> inputHandle1 = tensorHandleFactory.CreateTensorHandle(inputTensorInfo1);
225 std::unique_ptr<armnn::ITensorHandle> inputHandle2 = tensorHandleFactory.CreateTensorHandle(inputTensorInfo2);
226 std::unique_ptr<armnn::ITensorHandle> outputHandle = tensorHandleFactory.CreateTensorHandle(outputTensorInfo);
227
228 armnn::AdditionQueueDescriptor data;
229 armnn::WorkloadInfo info;
230 AddInputToWorkload(data, info, inputTensorInfo1, inputHandle1.get());
231 AddInputToWorkload(data, info, inputTensorInfo2, inputHandle2.get());
232 AddOutputToWorkload(data, info, outputTensorInfo, outputHandle.get());
233
234 std::unique_ptr<armnn::IWorkload> workload = workloadFactory.CreateWorkload(armnn::LayerType::Addition,
235 data, info);
236
237 inputHandle1->Allocate();
238 inputHandle2->Allocate();
239 outputHandle->Allocate();
240
241 CopyDataToITensorHandle(inputHandle1.get(), input1.data());
242 CopyDataToITensorHandle(inputHandle2.get(), input2.data());
243
244 workload->PostAllocationConfigure();
245 workload->Execute();
246
247 CopyDataFromITensorHandle(actualOutput.data(), outputHandle.get());
248
249 return LayerTestResult<T, 4>(actualOutput,
250 expectedOutput,
251 outputHandle->GetShape(),
252 outputTensorInfo.GetShape());
253 }
254
255 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)256 LayerTestResult<T, 4> AdditionBroadcast1ElementTestImpl(
257 armnn::IWorkloadFactory& workloadFactory,
258 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
259 float qScale,
260 int32_t qOffset,
261 const armnn::ITensorHandleFactory& tensorHandleFactory)
262 {
263 IgnoreUnused(memoryManager);
264 armnn::TensorInfo inputTensorInfo1 = armnn::TensorInfo({1, 3, 2, 3}, ArmnnType);
265 armnn::TensorInfo inputTensorInfo2 = armnn::TensorInfo({1, 1, 1, 1}, ArmnnType);
266 armnn::TensorInfo outputTensorInfo = armnn::TensorInfo({1, 3, 2, 3}, ArmnnType);
267
268 if (armnn::IsQuantizedType<T>())
269 {
270 inputTensorInfo1.SetQuantizationScale(qScale);
271 inputTensorInfo1.SetQuantizationOffset(qOffset);
272 inputTensorInfo2.SetQuantizationScale(qScale);
273 inputTensorInfo2.SetQuantizationOffset(qOffset);
274 outputTensorInfo.SetQuantizationScale(qScale);
275 outputTensorInfo.SetQuantizationOffset(qOffset);
276 }
277
278 auto input1 = armnnUtils::QuantizedVector<T>(
279 {
280 0.0f, 1.0f, 2.0f,
281 3.0f, 4.0f, 5.0f,
282 6.0f, 7.0f, 8.0f,
283 9.0f, 10.0f, 11.0f,
284 12.0f, 13.0f, 14.0f,
285 15.0f, 16.0f, 17.0f,
286 },
287 qScale, qOffset);
288
289 auto input2 = armnnUtils::QuantizedVector<T>(
290 {
291 0.5f,
292 },
293 qScale, qOffset);
294
295 std::vector<T> actualOutput(outputTensorInfo.GetNumElements());
296
297 auto expectedOutput = armnnUtils::QuantizedVector<T>(
298 {
299 0.5f, 1.5f, 2.5f,
300 3.5f, 4.5f, 5.5f,
301 6.5f, 7.5f, 8.5f,
302 9.5f, 10.5f, 11.5f,
303 12.5f, 13.5f, 14.5f,
304 15.5f, 16.5f, 17.5f,
305 },
306 qScale, qOffset);
307
308 std::unique_ptr<armnn::ITensorHandle> inputHandle1 = tensorHandleFactory.CreateTensorHandle(inputTensorInfo1);
309 std::unique_ptr<armnn::ITensorHandle> inputHandle2 = tensorHandleFactory.CreateTensorHandle(inputTensorInfo2);
310 std::unique_ptr<armnn::ITensorHandle> outputHandle = tensorHandleFactory.CreateTensorHandle(outputTensorInfo);
311
312 armnn::AdditionQueueDescriptor data;
313 armnn::WorkloadInfo info;
314 AddInputToWorkload(data, info, inputTensorInfo1, inputHandle1.get());
315 AddInputToWorkload(data, info, inputTensorInfo2, inputHandle2.get());
316 AddOutputToWorkload(data, info, outputTensorInfo, outputHandle.get());
317
318 std::unique_ptr<armnn::IWorkload> workload = workloadFactory.CreateWorkload(armnn::LayerType::Addition,
319 data, info);
320
321 inputHandle1->Allocate();
322 inputHandle2->Allocate();
323 outputHandle->Allocate();
324
325 CopyDataToITensorHandle(inputHandle1.get(), input1.data());
326 CopyDataToITensorHandle(inputHandle2.get(), input2.data());
327
328 workload->PostAllocationConfigure();
329 workload->Execute();
330
331 CopyDataFromITensorHandle(actualOutput.data(), outputHandle.get());
332
333 return LayerTestResult<T, 4>(actualOutput,
334 expectedOutput,
335 outputHandle->GetShape(),
336 outputTensorInfo.GetShape());
337 }
338
AdditionBroadcastTest(armnn::IWorkloadFactory & workloadFactory,const armnn::IBackendInternal::IMemoryManagerSharedPtr & memoryManager,const armnn::ITensorHandleFactory & tensorHandleFactory)339 LayerTestResult<float, 4> AdditionBroadcastTest(
340 armnn::IWorkloadFactory& workloadFactory,
341 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
342 const armnn::ITensorHandleFactory& tensorHandleFactory)
343 {
344 return AdditionBroadcastTestImpl<armnn::DataType::Float32>(
345 workloadFactory, memoryManager, 0.0f, 0, tensorHandleFactory);
346 }
347
AdditionBroadcastUint8Test(armnn::IWorkloadFactory & workloadFactory,const armnn::IBackendInternal::IMemoryManagerSharedPtr & memoryManager,const armnn::ITensorHandleFactory & tensorHandleFactory)348 LayerTestResult<uint8_t, 4> AdditionBroadcastUint8Test(
349 armnn::IWorkloadFactory& workloadFactory,
350 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
351 const armnn::ITensorHandleFactory& tensorHandleFactory)
352 {
353 return AdditionBroadcastTestImpl<armnn::DataType::QAsymmU8>(
354 workloadFactory, memoryManager, 2.f, 0, tensorHandleFactory);
355 }
356
AdditionBroadcastInt16Test(armnn::IWorkloadFactory & workloadFactory,const armnn::IBackendInternal::IMemoryManagerSharedPtr & memoryManager,const armnn::ITensorHandleFactory & tensorHandleFactory)357 LayerTestResult<int16_t, 4> AdditionBroadcastInt16Test(
358 armnn::IWorkloadFactory& workloadFactory,
359 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
360 const armnn::ITensorHandleFactory& tensorHandleFactory)
361 {
362 return AdditionBroadcastTestImpl<armnn::DataType::QSymmS16>(
363 workloadFactory, memoryManager, 2.f, 0, tensorHandleFactory);
364 }
365
AdditionBroadcastInt32Test(armnn::IWorkloadFactory & workloadFactory,const armnn::IBackendInternal::IMemoryManagerSharedPtr & memoryManager,const armnn::ITensorHandleFactory & tensorHandleFactory)366 LayerTestResult<int32_t, 4> AdditionBroadcastInt32Test(
367 armnn::IWorkloadFactory& workloadFactory,
368 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
369 const armnn::ITensorHandleFactory& tensorHandleFactory)
370 {
371 return AdditionBroadcastTestImpl<armnn::DataType::Signed32>(
372 workloadFactory, memoryManager, 1.f, 0, tensorHandleFactory);
373 }
374
AdditionBroadcast1ElementTest(armnn::IWorkloadFactory & workloadFactory,const armnn::IBackendInternal::IMemoryManagerSharedPtr & memoryManager,const armnn::ITensorHandleFactory & tensorHandleFactory)375 LayerTestResult<float, 4> AdditionBroadcast1ElementTest(
376 armnn::IWorkloadFactory& workloadFactory,
377 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
378 const armnn::ITensorHandleFactory& tensorHandleFactory)
379 {
380 return AdditionBroadcast1ElementTestImpl<armnn::DataType::Float32>(
381 workloadFactory, memoryManager, 0.0f, 0, tensorHandleFactory);
382 }
383
AdditionBroadcast1ElementUint8Test(armnn::IWorkloadFactory & workloadFactory,const armnn::IBackendInternal::IMemoryManagerSharedPtr & memoryManager,const armnn::ITensorHandleFactory & tensorHandleFactory)384 LayerTestResult<uint8_t, 4> AdditionBroadcast1ElementUint8Test(
385 armnn::IWorkloadFactory& workloadFactory,
386 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
387 const armnn::ITensorHandleFactory& tensorHandleFactory)
388 {
389 return AdditionBroadcast1ElementTestImpl<armnn::DataType::QAsymmU8>(
390 workloadFactory, memoryManager, 0.1333333f, 128, tensorHandleFactory);
391 }
392
AdditionBroadcast1ElementInt16Test(armnn::IWorkloadFactory & workloadFactory,const armnn::IBackendInternal::IMemoryManagerSharedPtr & memoryManager,const armnn::ITensorHandleFactory & tensorHandleFactory)393 LayerTestResult<int16_t, 4> AdditionBroadcast1ElementInt16Test(
394 armnn::IWorkloadFactory& workloadFactory,
395 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
396 const armnn::ITensorHandleFactory& tensorHandleFactory)
397 {
398 return AdditionBroadcast1ElementTestImpl<armnn::DataType::QSymmS16>(
399 workloadFactory, memoryManager, 0.1333333f, 0, tensorHandleFactory);
400 }
401
AdditionBroadcast1ElementInt32Test(armnn::IWorkloadFactory & workloadFactory,const armnn::IBackendInternal::IMemoryManagerSharedPtr & memoryManager,const armnn::ITensorHandleFactory & tensorHandleFactory)402 LayerTestResult<int32_t, 4> AdditionBroadcast1ElementInt32Test(
403 armnn::IWorkloadFactory& workloadFactory,
404 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
405 const armnn::ITensorHandleFactory& tensorHandleFactory)
406 {
407 return AdditionBroadcast1ElementTestImpl<armnn::DataType::Signed32>(
408 workloadFactory, memoryManager, 1.f, 0, tensorHandleFactory);
409 }
410
AdditionUint8Test(armnn::IWorkloadFactory & workloadFactory,const armnn::IBackendInternal::IMemoryManagerSharedPtr & memoryManager,const armnn::ITensorHandleFactory & tensorHandleFactory)411 LayerTestResult<uint8_t, 4> AdditionUint8Test(
412 armnn::IWorkloadFactory& workloadFactory,
413 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
414 const armnn::ITensorHandleFactory& tensorHandleFactory)
415 {
416 const unsigned int shape0[] = { 1, 2, 2, 3 };
417 const unsigned int shape1[] = { 1, 2, 2, 3 };
418
419 std::vector<uint8_t> input0(
420 {
421 63, 35, 77, 70, 56, 112, // 420, 224, 518, 469, 371, 763
422 203, 28, 252, 168, 245, 91 // 1400, 175, 1743, 1155, 1694, 616
423 });
424
425 std::vector<uint8_t> input1(
426 {
427 21, 7, 175, 231, 175, 210, // 126, 28, 1204, 1596, 1204, 1449
428 126, 161, 63, 21, 105, 126 // 861, 1106, 420, 126, 714, 861
429 });
430
431 std::vector<uint8_t> output(
432 {
433 81, 39, 249, 255, 228, 255, // 546, 252, 1722, 2065(clamped), 1575, 2212(clamped)
434 255, 186, 255, 186, 255, 214, // 2261(clamped), 1281, 2163(clamped), 1281, 2408(clamped), 1477
435 });
436
437 return ElementwiseTestHelper<4, armnn::AdditionQueueDescriptor, armnn::DataType::QAsymmU8>(
438 workloadFactory,
439 memoryManager,
440 shape0,
441 input0,
442 7.0f,
443 3,
444 shape1,
445 input1,
446 7.0f,
447 3,
448 shape0,
449 output,
450 tensorHandleFactory,
451 7.0f,
452 3);
453 }
454
AdditionInt16Test(armnn::IWorkloadFactory & workloadFactory,const armnn::IBackendInternal::IMemoryManagerSharedPtr & memoryManager,const armnn::ITensorHandleFactory & tensorHandleFactory)455 LayerTestResult<int16_t, 4> AdditionInt16Test(
456 armnn::IWorkloadFactory& workloadFactory,
457 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
458 const armnn::ITensorHandleFactory& tensorHandleFactory)
459 {
460 const unsigned int shape0[] = { 1, 2, 2, 3 };
461 const unsigned int shape1[] = { 1, 2, 2, 3 };
462
463 std::vector<int16_t> input0 =
464 {
465 63, 35, 77, 70, 56, 112, // 441, 245, 539, 490, 392, 184
466 203, 28, 252, 168, 245, 91 // 1421, 196, 1764, 1176, 1715, 637
467 };
468
469 std::vector<int16_t> input1 =
470 {
471 21, 7, 175, 231, 175, 210, // 126, 28, 1204, 1596, 1204, 1449
472 126, 161, 63, 21, 105, 126 // 861, 1106, 420, 126, 714, 861
473 };
474
475 std::vector<int16_t> output =
476 {
477 84, 42, 252, 301, 231, 322, // 588, 294, 1764, 2107(clamped), 1617, 2254(clamped)
478 329, 189, 315, 189, 350, 217, // 2303(clamped), 1323, 2205(clamped), 1323, 2450(clamped), 1519
479 };
480
481 return ElementwiseTestHelper<4, armnn::AdditionQueueDescriptor, armnn::DataType::QSymmS16>(
482 workloadFactory,
483 memoryManager,
484 shape0,
485 input0,
486 7.0f,
487 0,
488 shape1,
489 input1,
490 7.0f,
491 0,
492 shape0,
493 output,
494 tensorHandleFactory,
495 7.0f,
496 0);
497 }
498
AdditionInt32Test(armnn::IWorkloadFactory & workloadFactory,const armnn::IBackendInternal::IMemoryManagerSharedPtr & memoryManager,const armnn::ITensorHandleFactory & tensorHandleFactory)499 LayerTestResult<int32_t, 4> AdditionInt32Test(
500 armnn::IWorkloadFactory& workloadFactory,
501 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
502 const armnn::ITensorHandleFactory& tensorHandleFactory)
503 {
504 const unsigned int shape0[] = { 1, 2, 2, 3 };
505 const unsigned int shape1[] = { 1, 2, 2, 3 };
506
507 std::vector<int32_t> input0 =
508 {
509 63, 35, 77, 70, 56, 112, // 441, 245, 539, 490, 392, 184
510 203, 28, 252, 168, 245, 91 // 1421, 196, 1764, 1176, 1715, 637
511 };
512
513 std::vector<int32_t> input1 =
514 {
515 21, 7, 175, 231, 175, 210, // 126, 28, 1204, 1596, 1204, 1449
516 126, 161, 63, 21, 105, 126 // 861, 1106, 420, 126, 714, 861
517 };
518
519 std::vector<int32_t> output =
520 {
521 84, 42, 252, 301, 231, 322, // 588, 294, 1764, 2107(clamped), 1617, 2254(clamped)
522 329, 189, 315, 189, 350, 217, // 2303(clamped), 1323, 2205(clamped), 1323, 2450(clamped), 1519
523 };
524
525 return ElementwiseTestHelper<4, armnn::AdditionQueueDescriptor, armnn::DataType::Signed32>(
526 workloadFactory,
527 memoryManager,
528 shape0,
529 input0,
530 1.0f,
531 0,
532 shape1,
533 input1,
534 1.0f,
535 0,
536 shape0,
537 output,
538 tensorHandleFactory,
539 1.0f,
540 0);
541 }
542
AdditionAfterMaxPoolTest(armnn::IWorkloadFactory & workloadFactory,const armnn::IBackendInternal::IMemoryManagerSharedPtr & memoryManager,const armnn::ITensorHandleFactory & tensorHandleFactory)543 LayerTestResult<float, 4> AdditionAfterMaxPoolTest(
544 armnn::IWorkloadFactory& workloadFactory,
545 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
546 const armnn::ITensorHandleFactory& tensorHandleFactory)
547 {
548 IgnoreUnused(memoryManager);
549
550 // Create Initial Tensor
551 // 1, 2, 3
552 // 4, 5, 6
553 // 7, 8, 9
554
555 armnn::TensorInfo poolingInputTensorInfo({ 1, 1, 3, 3}, armnn::DataType::Float32);
556 armnn::TensorInfo poolingOutputTensorInfo({ 1, 1, 2, 2}, armnn::DataType::Float32);
557
558 std::vector<float> poolingInput = {1, 2, 3,
559 4, 5, 6,
560 7, 8, 9
561 };
562 std::unique_ptr<armnn::ITensorHandle> poolingInputHandle =
563 tensorHandleFactory.CreateTensorHandle(poolingInputTensorInfo);
564 std::unique_ptr<armnn::ITensorHandle> poolingOutputHandle =
565 tensorHandleFactory.CreateTensorHandle(poolingOutputTensorInfo);
566
567 // Apply MaxPool poolSize = 1x1, stride=2x2
568 // Result =
569 // 1, 3
570 // 7, 9
571 armnn::Pooling2dDescriptor descriptor;
572 descriptor.m_PoolHeight = 1;
573 descriptor.m_PoolWidth = 1;
574 descriptor.m_StrideX = 2;
575 descriptor.m_StrideY = 2;
576 descriptor.m_PoolType = armnn::PoolingAlgorithm::Max;
577
578 armnn::Pooling2dQueueDescriptor queueDescriptor;
579 queueDescriptor.m_Parameters = descriptor;
580 armnn::WorkloadInfo workloadInfo;
581 AddInputToWorkload(queueDescriptor, workloadInfo, poolingInputTensorInfo, poolingInputHandle.get());
582 AddOutputToWorkload(queueDescriptor, workloadInfo, poolingOutputTensorInfo, poolingOutputHandle.get());
583
584 // Create the MaxPool
585 std::unique_ptr<armnn::IWorkload> workload = workloadFactory.CreateWorkload(armnn::LayerType::Pooling2d,
586 queueDescriptor,
587 workloadInfo);
588
589 std::vector<float> resultMaxPool(poolingOutputTensorInfo.GetNumElements());
590
591 // Create addition with another tensor the same size
592 // This would be the result to apply a Conv2d with kernel ones(2) and stride 1x1
593 // with the initial tensor.
594 // 12, 16
595 // 24, 28
596 armnn::TensorInfo addInputTensorInfo({ 1,1,2,2 }, armnn::DataType::Float32);
597 armnn::TensorInfo addOutputTensorInfo({ 1,1,2,2 }, armnn::DataType::Float32);
598
599 std::vector<float> addInput = { 12, 16,
600 24, 28 };
601
602 // Expected output tensor after MaxPool and Addition.
603 std::vector<float> actualOutput(addOutputTensorInfo.GetNumElements());
604 std::vector<float> expectedOutput = { 13, 19,
605 31, 37 };
606
607 std::unique_ptr<armnn::ITensorHandle> addInputHandle = tensorHandleFactory.CreateTensorHandle(addInputTensorInfo);
608 std::unique_ptr<armnn::ITensorHandle> addOutputHandle = 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.CreateWorkload(armnn::LayerType::Addition,
619 data, info);
620
621 poolingInputHandle->Allocate();
622 poolingOutputHandle->Allocate();
623 addInputHandle->Allocate();
624 addOutputHandle->Allocate();
625
626 CopyDataToITensorHandle(poolingInputHandle.get(), poolingInput.data());
627 CopyDataFromITensorHandle(resultMaxPool.data(), poolingOutputHandle.get());
628
629 CopyDataToITensorHandle(poolingOutputHandle.get(), resultMaxPool.data());
630 CopyDataToITensorHandle(addInputHandle.get(), addInput.data());
631
632 workload->PostAllocationConfigure();
633 workload->Execute();
634 addWorkload->PostAllocationConfigure();
635 addWorkload->Execute();
636
637 CopyDataFromITensorHandle(actualOutput.data(), addOutputHandle.get());
638
639 return LayerTestResult<float, 4>(actualOutput,
640 expectedOutput,
641 addOutputHandle->GetShape(),
642 addOutputTensorInfo.GetShape());
643 }
644
CompareAdditionTest(armnn::IWorkloadFactory & workloadFactory,const armnn::IBackendInternal::IMemoryManagerSharedPtr & memoryManager,armnn::IWorkloadFactory & refWorkloadFactory,const armnn::ITensorHandleFactory & tensorHandleFactory,const armnn::ITensorHandleFactory & refTensorHandleFactory)645 LayerTestResult<float,4> CompareAdditionTest(
646 armnn::IWorkloadFactory& workloadFactory,
647 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
648 armnn::IWorkloadFactory& refWorkloadFactory,
649 const armnn::ITensorHandleFactory& tensorHandleFactory,
650 const armnn::ITensorHandleFactory& refTensorHandleFactory)
651 {
652 IgnoreUnused(memoryManager);
653 unsigned int batchSize = 4;
654 unsigned int channels = 1;
655 unsigned int height = 2;
656 unsigned int width = 3;
657
658 armnn::TensorInfo inputTensorInfo1, inputTensorInfo2;
659 armnn::TensorInfo outputTensorInfo;
660
661 unsigned int shape[] = {batchSize, channels, height, width};
662
663 inputTensorInfo1 = armnn::TensorInfo(4, shape, armnn::DataType::Float32);
664 inputTensorInfo2 = armnn::TensorInfo(4, shape, armnn::DataType::Float32);
665 outputTensorInfo = armnn::TensorInfo(4, shape, armnn::DataType::Float32);
666
667 auto input1 = MakeRandomTensor<float>(inputTensorInfo1, 1232);
668 auto input2 = MakeRandomTensor<float>(inputTensorInfo2, 456);
669
670 std::vector<float> actualOutput(outputTensorInfo.GetNumElements());
671 std::vector<float> expectedOutput(outputTensorInfo.GetNumElements());
672
673 std::unique_ptr<armnn::ITensorHandle> inputHandle1 = tensorHandleFactory.CreateTensorHandle(inputTensorInfo1);
674 std::unique_ptr<armnn::ITensorHandle> inputHandle2 = tensorHandleFactory.CreateTensorHandle(inputTensorInfo2);
675 std::unique_ptr<armnn::ITensorHandle> outputHandle = tensorHandleFactory.CreateTensorHandle(outputTensorInfo);
676
677 std::unique_ptr<armnn::ITensorHandle> inputHandle1Ref = refTensorHandleFactory.CreateTensorHandle(inputTensorInfo1);
678 std::unique_ptr<armnn::ITensorHandle> inputHandle2Ref = refTensorHandleFactory.CreateTensorHandle(inputTensorInfo2);
679 std::unique_ptr<armnn::ITensorHandle> outputHandleRef = refTensorHandleFactory.CreateTensorHandle(outputTensorInfo);
680
681 armnn::AdditionQueueDescriptor data;
682 armnn::WorkloadInfo info;
683 AddInputToWorkload(data, info, inputTensorInfo1, inputHandle1.get());
684 AddInputToWorkload(data, info, inputTensorInfo2, inputHandle2.get());
685 AddOutputToWorkload(data, info, outputTensorInfo, outputHandle.get());
686
687 armnn::AdditionQueueDescriptor refData = data;
688 armnn::WorkloadInfo refInfo = info;
689 SetWorkloadInput(refData, refInfo, 0, inputTensorInfo1, inputHandle1Ref.get());
690 SetWorkloadInput(refData, refInfo, 1, inputTensorInfo2, inputHandle2Ref.get());
691 SetWorkloadOutput(refData, refInfo, 0, outputTensorInfo, outputHandleRef.get());
692
693 std::unique_ptr<armnn::IWorkload> workload = workloadFactory.CreateWorkload(armnn::LayerType::Addition,
694 data, info);
695 std::unique_ptr<armnn::IWorkload> workloadRef = refWorkloadFactory.CreateWorkload(armnn::LayerType::Addition,
696 refData, refInfo);
697
698 inputHandle1->Allocate();
699 inputHandle2->Allocate();
700 outputHandle->Allocate();
701 inputHandle1Ref->Allocate();
702 inputHandle2Ref->Allocate();
703 outputHandleRef->Allocate();
704
705 CopyDataToITensorHandle(inputHandle1.get(), input1.data());
706 CopyDataToITensorHandle(inputHandle2.get(), input2.data());
707 CopyDataToITensorHandle(inputHandle1Ref.get(), input1.data());
708 CopyDataToITensorHandle(inputHandle2Ref.get(), input2.data());
709
710 workload->PostAllocationConfigure();
711 workload->Execute();
712 workloadRef->PostAllocationConfigure();
713 workloadRef->Execute();
714
715 CopyDataFromITensorHandle(actualOutput.data(), outputHandle.get());
716 CopyDataFromITensorHandle(expectedOutput.data(), outputHandleRef.get());
717
718 return LayerTestResult<float, 4>(actualOutput,
719 expectedOutput,
720 outputHandle->GetShape(),
721 outputTensorInfo.GetShape());
722 }