blob: 595fbd4556dfb369f8431885af4c391dadd574d3 [file] [log] [blame]
Aron Virginas-Tare89ebad2019-08-27 18:14:26 +01001//
Teresa Charlinfbf0e5b2020-08-17 01:01:06 +01002// Copyright © 2017 Arm Ltd and Contributors. All rights reserved.
Aron Virginas-Tare89ebad2019-08-27 18:14:26 +01003// SPDX-License-Identifier: MIT
4//
5
6#include "MultiplicationTestImpl.hpp"
7
8#include "ElementwiseTestImpl.hpp"
9
10template<>
11std::unique_ptr<armnn::IWorkload> CreateWorkload<armnn::MultiplicationQueueDescriptor>(
12 const armnn::IWorkloadFactory& workloadFactory,
13 const armnn::WorkloadInfo& info,
14 const armnn::MultiplicationQueueDescriptor& descriptor)
15{
16 return workloadFactory.CreateMultiplication(descriptor, info);
17}
18
19LayerTestResult<float, 4> MultiplicationTest(armnn::IWorkloadFactory& workloadFactory,
20 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager)
21{
22 const unsigned int width = 2u;
23 const unsigned int height = 2u;
24 const unsigned int channelCount = 2u;
25 const unsigned int batchSize = 2u;
26
27 unsigned int shape[] = { batchSize, channelCount, height, width };
28
29 std::vector<float> input0 =
30 {
31 1, 1, 1, 1, 2, 2, 2, 2,
32 3, 3, 3, 3, 4, 4, 4, 4
33 };
34
35 std::vector<float> input1 =
36 {
37 2, 2, 2, 2, 3, 3, 3, 3,
38 4, 4, 4, 4, 5, 5, 5, 5
39 };
40
41 std::vector<float> output =
42 {
43 2, 2, 2, 2, 6, 6, 6, 6,
44 12, 12, 12, 12, 20, 20, 20, 20
45 };
46
47 return ElementwiseTestHelper<4, armnn::MultiplicationQueueDescriptor, armnn::DataType::Float32>(
48 workloadFactory,
49 memoryManager,
50 shape,
51 input0,
52 shape,
53 input1,
54 shape,
55 output);
56}
57
58LayerTestResult<float, 5> Multiplication5dTest(armnn::IWorkloadFactory& workloadFactory,
59 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager)
60{
61 const unsigned int width = 3u;
62 const unsigned int height = 2u;
63 const unsigned int channelCount = 2u;
64 const unsigned int batchSize = 2u;;
65 const unsigned int depth = 2u;
66
67 unsigned int shape[] = { depth, batchSize, channelCount, height, width };
68
69 std::vector<float> input0 =
70 {
71 1.80f, 0.20f, 2.30f, 1.30f, 2.10f, 1.00f,
72 2.60f, 0.60f, 2.10f, 2.30f, 2.30f, 2.00f,
73
74 2.50f, 1.00f, 2.90f, 3.10f, 1.50f, 2.40f,
75 2.80f, 1.10f, 1.00f, 3.20f, 1.00f, 2.30f,
76
77
78 0.30f, 2.20f, 1.00f, 0.20f, 1.60f, 1.40f,
79 0.80f, 3.20f, 0.10f, 0.10f, 3.10f, 2.10f,
80
81 1.50f, 2.40f, 1.40f, 0.70f, 2.40f, 1.40f,
82 1.60f, 1.20f, 1.90f, 0.80f, 0.00f, 0.10f,
83 };
84
85 std::vector<float> input1 =
86 {
87 0.70f, 1.00f, 2.90f, 2.20f, 3.10f, 2.80f,
88 1.80f, 2.00f, 0.50f, 2.30f, 1.20f, 2.70f,
89
90 2.40f, 0.20f, 3.20f, 1.60f, 0.20f, 2.50f,
91 2.30f, 0.70f, 2.70f, 1.80f, 2.90f, 2.70f,
92
93
94 3.20f, 3.20f, 0.70f, 1.90f, 2.70f, 2.50f,
95 2.40f, 0.90f, 2.30f, 1.80f, 2.50f, 2.00f,
96
97 1.60f, 2.20f, 1.60f, 2.00f, 0.30f, 3.20f,
98 0.40f, 3.00f, 2.60f, 0.30f, 0.00f, 2.50f,
99 };
100
101 std::vector<float> output =
102 {
103 1.26f, 0.20f, 6.67f, 2.86f, 6.51f, 2.80f,
104 4.68f, 1.20f, 1.05f, 5.29f, 2.76f, 5.40f,
105
106 6.00f, 0.20f, 9.28f, 4.96f, 0.30f, 6.00f,
107 6.44f, 0.77f, 2.70f, 5.76f, 2.90f, 6.21f,
108
109
110 0.96f, 7.04f, 0.70f, 0.38f, 4.32f, 3.50f,
111 1.92f, 2.88f, 0.23f, 0.18f, 7.75f, 4.20f,
112
113 2.40f, 5.28f, 2.24f, 1.40f, 0.72f, 4.48f,
114 0.64f, 3.60f, 4.94f, 0.24f, 0.00f, 0.25f,
115 };
116
117 return ElementwiseTestHelper<5, armnn::MultiplicationQueueDescriptor, armnn::DataType::Float32>(
118 workloadFactory,
119 memoryManager,
120 shape,
121 input0,
122 shape,
123 input1,
124 shape,
125 output);
126}
127
128LayerTestResult<float, 4> MultiplicationBroadcast1ElementTest(
129 armnn::IWorkloadFactory& workloadFactory,
130 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager)
131{
132 unsigned int shape0[] = { 1, 2, 2, 2 };
133 unsigned int shape1[] = { 1, 1, 1, 1 };
134
135 std::vector<float> input0 = { 1, 2, 3, 4, 5, 6, 7, 8};
136
137 std::vector<float> input1 = { 2 };
138
139 std::vector<float> output = { 2, 4, 6, 8, 10, 12, 14, 16};
140
141 return ElementwiseTestHelper<4, armnn::MultiplicationQueueDescriptor, armnn::DataType::Float32>(
142 workloadFactory,
143 memoryManager,
144 shape0,
145 input0,
146 shape1,
147 input1,
148 shape0,
149 output);
150}
151
152LayerTestResult<float, 4> MultiplicationBroadcast1DVectorTest(
153 armnn::IWorkloadFactory& workloadFactory,
154 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager)
155{
156 unsigned int shape0[] = { 1, 3, 3, 2 };
157 unsigned int shape1[] = { 1, 1, 1, 2 };
158
159 std::vector<float> input0 =
160 {
161 1, 2, 3, 4, 5, 6,
162 7, 8, 9, 10, 11, 12,
163 13, 14, 15, 16, 17, 18
164 };
165
166 std::vector<float> input1 = { 1, 2 };
167
168 std::vector<float> output =
169 {
170 1, 4, 3, 8, 5, 12,
171 7, 16, 9, 20, 11, 24,
172 13, 28, 15, 32, 17, 36
173 };
174
175 return ElementwiseTestHelper<4, armnn::MultiplicationQueueDescriptor, armnn::DataType::Float32>(
176 workloadFactory,
177 memoryManager,
178 shape0,
179 input0,
180 shape1,
181 input1,
182 shape0,
183 output);
184}
185
186LayerTestResult<uint8_t, 4> MultiplicationUint8Test(
187 armnn::IWorkloadFactory& workloadFactory,
188 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager)
189{
190 constexpr unsigned int batchSize = 1u;
191 constexpr unsigned int channels = 2u;
192 constexpr unsigned int height = 2u;
193 constexpr unsigned int width = 3u;
194
195 const unsigned int shape[] = { batchSize, channels, height, width };
196
197 // See dequantized values to the right
198 std::vector<uint8_t> input0 =
199 {
200 62, 37, 3, 172, 13, 111, // 244, 144, 8, 684, 48, 440,
201 188, 20, 73, 31, 23, 31 // 748, 76, 288, 120, 88, 120
202 };
203
204 // See dequantized values to the right
205 std::vector<uint8_t> input1 =
206 {
207 126, 240, 252, 183, 121, 247, // 384, 726, 762, 555, 369, 747,
208 48, 115, 151, 79, 78, 97 // 150, 351, 459, 243, 240, 297
209 };
210
211 // See dequantized values to the right
212 std::vector<uint8_t> output =
213 {
214 64, 72, 0, 255, 8, 236, // 93696, 104544, 6096(clamped), 379620(clamped), 17712, 328680,
215 77, 15, 92, 16, 10, 21, // 112200, 26676, 132192, 29160, 21120, 35640
216 };
217
218 // Scale/offset chosen to have output values out of range
Derek Lambertif90c56d2020-01-10 17:14:08 +0000219 return ElementwiseTestHelper<4, armnn::MultiplicationQueueDescriptor, armnn::DataType::QAsymmU8>(
Aron Virginas-Tare89ebad2019-08-27 18:14:26 +0100220 workloadFactory,
221 memoryManager,
222 shape,
223 input0,
224 4.0f,
225 1,
226 shape,
227 input1,
228 3.0f,
229 -2,
230 shape,
231 output,
232 1366.255f,
233 -5);
234}
235
236LayerTestResult<uint8_t, 4> MultiplicationBroadcast1ElementUint8Test(
237 armnn::IWorkloadFactory& workloadFactory,
238 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager)
239{
240 const unsigned int shape0[] = { 1, 2, 2, 3 };
241 const unsigned int shape1[] = { 1, 1, 1, 1 };
242
243 std::vector<uint8_t> input0 =
244 {
245 1, 2, 3, 4, 5, 6,
246 7, 8, 9, 10, 11, 12
247 };
248
249 std::vector<uint8_t> input1 = { 2 };
250
251 std::vector<uint8_t> output =
252 {
253 2, 4, 6, 8, 10, 12,
254 14, 16, 18, 20, 22, 24
255 };
256
Derek Lambertif90c56d2020-01-10 17:14:08 +0000257 return ElementwiseTestHelper<4, armnn::MultiplicationQueueDescriptor, armnn::DataType::QAsymmU8>(
Aron Virginas-Tare89ebad2019-08-27 18:14:26 +0100258 workloadFactory,
259 memoryManager,
260 shape0,
261 input0,
262 shape1,
263 input1,
264 shape0,
265 output);
266}
267
268LayerTestResult<uint8_t, 4> MultiplicationBroadcast1DVectorUint8Test(
269 armnn::IWorkloadFactory& workloadFactory,
270 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager)
271{
272 const unsigned int shape0[] = { 1, 2, 2, 3 };
273 const unsigned int shape1[] = { 1, 1, 1, 3 };
274
275 std::vector<uint8_t> input0 =
276 {
277 1, 2, 3, 4, 5, 6,
278 7, 8, 9, 10, 11, 12
279 };
280
281 std::vector<uint8_t> input1 = { 1, 2, 3 };
282
283 std::vector<uint8_t> output =
284 {
285 1, 4, 9, 4, 10, 18,
286 7, 16, 27, 10, 22, 36
287 };
288
Derek Lambertif90c56d2020-01-10 17:14:08 +0000289 return ElementwiseTestHelper<4, armnn::MultiplicationQueueDescriptor, armnn::DataType::QAsymmU8>(
Aron Virginas-Tare89ebad2019-08-27 18:14:26 +0100290 workloadFactory,
291 memoryManager,
292 shape0,
293 input0,
294 shape1,
295 input1,
296 shape0,
297 output);
298}
299
300LayerTestResult<int16_t, 4> MultiplicationInt16Test(
301 armnn::IWorkloadFactory& workloadFactory,
302 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager)
303{
304 const unsigned int shape[] = { 1, 2, 2, 3 };
305
306 std::vector<int16_t> input0 =
307 {
308 6, 7, 8, 9, 10, 11,
309 12, 13, 14, 15, 16, 17
310 };
311
312 std::vector<int16_t> input1 =
313 {
314 1, 2, 3, 4, 5, 6,
315 7, 8, 9, 10, 11, 12
316 };
317
318 std::vector<int16_t> output =
319 {
320 6, 14, 24, 36, 50, 66,
321 84, 104, 126, 150, 176, 204
322 };
323
Derek Lambertif90c56d2020-01-10 17:14:08 +0000324 return ElementwiseTestHelper<4, armnn::MultiplicationQueueDescriptor, armnn::DataType::QSymmS16>(
Aron Virginas-Tare89ebad2019-08-27 18:14:26 +0100325 workloadFactory,
326 memoryManager,
327 shape,
328 input0,
329 shape,
330 input1,
331 shape,
332 output);
333}
334
335LayerTestResult<int16_t, 4> MultiplicationBroadcast1ElementInt16Test(
336 armnn::IWorkloadFactory& workloadFactory,
337 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager)
338{
339 const unsigned int shape0[] = { 1, 2, 2, 3 };
340 const unsigned int shape1[] = { 1, 1, 1, 1 };
341
342 std::vector<int16_t> input0 =
343 {
344 1, 2, 3, 4, 5, 6,
345 7, 8, 9, 10, 11, 12
346 };
347
348 std::vector<int16_t> input1 = { 2 };
349
350 std::vector<int16_t> output =
351 {
352 2, 4, 6, 8, 10, 12,
353 14, 16, 18, 20, 22, 24
354 };
355
Derek Lambertif90c56d2020-01-10 17:14:08 +0000356 return ElementwiseTestHelper<4, armnn::MultiplicationQueueDescriptor, armnn::DataType::QSymmS16>(
Aron Virginas-Tare89ebad2019-08-27 18:14:26 +0100357 workloadFactory,
358 memoryManager,
359 shape0,
360 input0,
361 shape1,
362 input1,
363 shape0,
364 output);
365}
366
367LayerTestResult<int16_t, 4> MultiplicationBroadcast1DVectorInt16Test(
368 armnn::IWorkloadFactory& workloadFactory,
369 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager)
370{
371 const unsigned int shape0[] = { 1, 2, 2, 3 };
372 const unsigned int shape1[] = { 1, 1, 1, 3 };
373
374 std::vector<int16_t> input0 =
375 {
376 1, 2, 3, 4, 5, 6,
377 7, 8, 9, 10, 11, 12
378 };
379
380 std::vector<int16_t> input1 = { 1, 2, 3 };
381
382 std::vector<int16_t> output =
383 {
384 1, 4, 9, 4, 10, 18,
385 7, 16, 27, 10, 22, 36
386 };
387
Derek Lambertif90c56d2020-01-10 17:14:08 +0000388 return ElementwiseTestHelper<4, armnn::MultiplicationQueueDescriptor, armnn::DataType::QSymmS16>(
Aron Virginas-Tare89ebad2019-08-27 18:14:26 +0100389 workloadFactory,
390 memoryManager,
391 shape0,
392 input0,
393 shape1,
394 input1,
395 shape0,
396 output);
397}
398
Teresa Charlinecb6b8e2020-05-22 18:08:23 +0100399LayerTestResult<int32_t, 4> MultiplicationInt32Test(
400 armnn::IWorkloadFactory& workloadFactory,
401 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager)
402{
403 const unsigned int shape[] = { 1, 2, 2, 3 };
404
405 std::vector<int32_t> input0 =
406 {
407 6, 7, 8, 9, 10, 11,
408 12, 13, 14, 15, 16, 17
409 };
410
411 std::vector<int32_t> input1 =
412 {
413 1, 2, 3, 4, 5, 6,
414 7, 8, 9, 10, 11, 12
415 };
416
417 std::vector<int32_t> output =
418 {
419 6, 14, 24, 36, 50, 66,
420 84, 104, 126, 150, 176, 204
421 };
422
423 return ElementwiseTestHelper<4, armnn::MultiplicationQueueDescriptor, armnn::DataType::Signed32>(
424 workloadFactory,
425 memoryManager,
426 shape,
427 input0,
428 shape,
429 input1,
430 shape,
431 output);
432}
433
434LayerTestResult<int32_t, 4> MultiplicationBroadcast1ElementInt32Test(
435 armnn::IWorkloadFactory& workloadFactory,
436 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager)
437{
438 const unsigned int shape0[] = { 1, 2, 2, 3 };
439 const unsigned int shape1[] = { 1, 1, 1, 1 };
440
441 std::vector<int32_t> input0 =
442 {
443 1, 2, 3, 4, 5, 6,
444 7, 8, 9, 10, 11, 12
445 };
446
447 std::vector<int32_t> input1 = { 2 };
448
449 std::vector<int32_t> output =
450 {
451 2, 4, 6, 8, 10, 12,
452 14, 16, 18, 20, 22, 24
453 };
454
455 return ElementwiseTestHelper<4, armnn::MultiplicationQueueDescriptor, armnn::DataType::Signed32>(
456 workloadFactory,
457 memoryManager,
458 shape0,
459 input0,
460 shape1,
461 input1,
462 shape0,
463 output);
464}
465
466LayerTestResult<int32_t, 4> MultiplicationBroadcast1DVectorInt32Test(
467 armnn::IWorkloadFactory& workloadFactory,
468 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager)
469{
470 const unsigned int shape0[] = { 1, 2, 2, 3 };
471 const unsigned int shape1[] = { 1, 1, 1, 3 };
472
473 std::vector<int32_t> input0 =
474 {
475 1, 2, 3, 4, 5, 6,
476 7, 8, 9, 10, 11, 12
477 };
478
479 std::vector<int32_t> input1 = { 1, 2, 3 };
480
481 std::vector<int32_t> output =
482 {
483 1, 4, 9, 4, 10, 18,
484 7, 16, 27, 10, 22, 36
485 };
486
487 return ElementwiseTestHelper<4, armnn::MultiplicationQueueDescriptor, armnn::DataType::Signed32>(
488 workloadFactory,
489 memoryManager,
490 shape0,
491 input0,
492 shape1,
493 input1,
494 shape0,
495 output);
496}
497
Aron Virginas-Tare89ebad2019-08-27 18:14:26 +0100498LayerTestResult<float,4> CompareMultiplicationTest(
499 armnn::IWorkloadFactory& workloadFactory,
500 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
501 armnn::IWorkloadFactory& refWorkloadFactory)
502{
Jan Eilers8eb25602020-03-09 12:13:48 +0000503 IgnoreUnused(memoryManager);
Aron Virginas-Tare89ebad2019-08-27 18:14:26 +0100504 const unsigned int width = 16;
505 const unsigned int height = 32;
506 const unsigned int channelCount = 2;
507 const unsigned int batchSize = 5;
508
509 armnn::TensorInfo inputTensorInfo0;
510 armnn::TensorInfo inputTensorInfo1;
511 armnn::TensorInfo outputTensorInfo;
512
513 constexpr unsigned int shape[] = { batchSize, channelCount, height, width };
514
515 inputTensorInfo0 = armnn::TensorInfo(4, shape, armnn::DataType::Float32);
516 inputTensorInfo1 = armnn::TensorInfo(4, shape, armnn::DataType::Float32);
517 outputTensorInfo = armnn::TensorInfo(4, shape, armnn::DataType::Float32);
518
519 LayerTestResult<float,4> comparisonResult(outputTensorInfo);
520
521 auto input0 = MakeRandomTensor<float, 4>(inputTensorInfo0, 803506992);
522 auto input1 = MakeRandomTensor<float, 4>(inputTensorInfo1, 54902257);
523
Teresa Charlinfbf0e5b2020-08-17 01:01:06 +0100524 ARMNN_NO_DEPRECATE_WARN_BEGIN
Aron Virginas-Tare89ebad2019-08-27 18:14:26 +0100525 std::unique_ptr<armnn::ITensorHandle> inputHandle0 = workloadFactory.CreateTensorHandle(inputTensorInfo0);
526 std::unique_ptr<armnn::ITensorHandle> inputHandle1 = workloadFactory.CreateTensorHandle(inputTensorInfo1);
527 std::unique_ptr<armnn::ITensorHandle> outputHandle = workloadFactory.CreateTensorHandle(outputTensorInfo);
528
529 std::unique_ptr<armnn::ITensorHandle> inputHandle0Ref = refWorkloadFactory.CreateTensorHandle(inputTensorInfo0);
530 std::unique_ptr<armnn::ITensorHandle> inputHandle1Ref = refWorkloadFactory.CreateTensorHandle(inputTensorInfo1);
531 std::unique_ptr<armnn::ITensorHandle> outputHandleRef = refWorkloadFactory.CreateTensorHandle(outputTensorInfo);
Teresa Charlinfbf0e5b2020-08-17 01:01:06 +0100532 ARMNN_NO_DEPRECATE_WARN_END
Aron Virginas-Tare89ebad2019-08-27 18:14:26 +0100533
534 armnn::MultiplicationQueueDescriptor data;
535 armnn::WorkloadInfo info;
536 AddInputToWorkload(data, info, inputTensorInfo0, inputHandle0.get());
537 AddInputToWorkload(data, info, inputTensorInfo1, inputHandle1.get());
538 AddOutputToWorkload(data, info, outputTensorInfo, outputHandle.get());
539
540 armnn::MultiplicationQueueDescriptor refData = data;
541 armnn::WorkloadInfo refInfo = info;
542 SetWorkloadInput(refData, refInfo, 0, inputTensorInfo0, inputHandle0Ref.get());
543 SetWorkloadInput(refData, refInfo, 1, inputTensorInfo1, inputHandle1Ref.get());
544 SetWorkloadOutput(refData, refInfo, 0, outputTensorInfo, outputHandleRef.get());
545
546 std::unique_ptr<armnn::IWorkload> workload = workloadFactory.CreateMultiplication(data, info);
547 std::unique_ptr<armnn::IWorkload> workloadRef = refWorkloadFactory.CreateMultiplication(refData, refInfo);
548
549 inputHandle0->Allocate();
550 inputHandle1->Allocate();
551 outputHandle->Allocate();
552 inputHandle0Ref->Allocate();
553 inputHandle1Ref->Allocate();
554 outputHandleRef->Allocate();
555
556 CopyDataToITensorHandle(inputHandle0.get(), input0.origin());
557 CopyDataToITensorHandle(inputHandle1.get(), input1.origin());
558 CopyDataToITensorHandle(inputHandle0Ref.get(), input0.origin());
559 CopyDataToITensorHandle(inputHandle1Ref.get(), input1.origin());
560
561 workload->PostAllocationConfigure();
562 workload->Execute();
563 workloadRef->PostAllocationConfigure();
564 workloadRef->Execute();
565 CopyDataFromITensorHandle(comparisonResult.output.origin(), outputHandle.get());
566 CopyDataFromITensorHandle(comparisonResult.outputExpected.origin(), outputHandleRef.get());
567
568 return comparisonResult;
569}