2 // Copyright © 2017 Arm Ltd. All rights reserved.
3 // SPDX-License-Identifier: MIT
6 #include "MultiplicationTestImpl.hpp"
8 #include "ElementwiseTestImpl.hpp"
11 std::unique_ptr<armnn::IWorkload> CreateWorkload<armnn::MultiplicationQueueDescriptor>(
12 const armnn::IWorkloadFactory& workloadFactory,
13 const armnn::WorkloadInfo& info,
14 const armnn::MultiplicationQueueDescriptor& descriptor)
16 return workloadFactory.CreateMultiplication(descriptor, info);
19 LayerTestResult<float, 4> MultiplicationTest(armnn::IWorkloadFactory& workloadFactory,
20 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager)
22 const unsigned int width = 2u;
23 const unsigned int height = 2u;
24 const unsigned int channelCount = 2u;
25 const unsigned int batchSize = 2u;
27 unsigned int shape[] = { batchSize, channelCount, height, width };
29 std::vector<float> input0 =
31 1, 1, 1, 1, 2, 2, 2, 2,
32 3, 3, 3, 3, 4, 4, 4, 4
35 std::vector<float> input1 =
37 2, 2, 2, 2, 3, 3, 3, 3,
38 4, 4, 4, 4, 5, 5, 5, 5
41 std::vector<float> output =
43 2, 2, 2, 2, 6, 6, 6, 6,
44 12, 12, 12, 12, 20, 20, 20, 20
47 return ElementwiseTestHelper<4, armnn::MultiplicationQueueDescriptor, armnn::DataType::Float32>(
58 LayerTestResult<float, 5> Multiplication5dTest(armnn::IWorkloadFactory& workloadFactory,
59 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager)
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;
67 unsigned int shape[] = { depth, batchSize, channelCount, height, width };
69 std::vector<float> input0 =
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,
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,
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,
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,
85 std::vector<float> input1 =
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,
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,
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,
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,
101 std::vector<float> output =
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,
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,
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,
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,
117 return ElementwiseTestHelper<5, armnn::MultiplicationQueueDescriptor, armnn::DataType::Float32>(
128 LayerTestResult<float, 4> MultiplicationBroadcast1ElementTest(
129 armnn::IWorkloadFactory& workloadFactory,
130 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager)
132 unsigned int shape0[] = { 1, 2, 2, 2 };
133 unsigned int shape1[] = { 1, 1, 1, 1 };
135 std::vector<float> input0 = { 1, 2, 3, 4, 5, 6, 7, 8};
137 std::vector<float> input1 = { 2 };
139 std::vector<float> output = { 2, 4, 6, 8, 10, 12, 14, 16};
141 return ElementwiseTestHelper<4, armnn::MultiplicationQueueDescriptor, armnn::DataType::Float32>(
152 LayerTestResult<float, 4> MultiplicationBroadcast1DVectorTest(
153 armnn::IWorkloadFactory& workloadFactory,
154 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager)
156 unsigned int shape0[] = { 1, 3, 3, 2 };
157 unsigned int shape1[] = { 1, 1, 1, 2 };
159 std::vector<float> input0 =
163 13, 14, 15, 16, 17, 18
166 std::vector<float> input1 = { 1, 2 };
168 std::vector<float> output =
171 7, 16, 9, 20, 11, 24,
172 13, 28, 15, 32, 17, 36
175 return ElementwiseTestHelper<4, armnn::MultiplicationQueueDescriptor, armnn::DataType::Float32>(
186 LayerTestResult<uint8_t, 4> MultiplicationUint8Test(
187 armnn::IWorkloadFactory& workloadFactory,
188 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager)
190 constexpr unsigned int batchSize = 1u;
191 constexpr unsigned int channels = 2u;
192 constexpr unsigned int height = 2u;
193 constexpr unsigned int width = 3u;
195 const unsigned int shape[] = { batchSize, channels, height, width };
197 // See dequantized values to the right
198 std::vector<uint8_t> input0 =
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
204 // See dequantized values to the right
205 std::vector<uint8_t> input1 =
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
211 // See dequantized values to the right
212 std::vector<uint8_t> output =
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
218 // Scale/offset chosen to have output values out of range
219 return ElementwiseTestHelper<4, armnn::MultiplicationQueueDescriptor, armnn::DataType::QuantisedAsymm8>(
236 LayerTestResult<uint8_t, 4> MultiplicationBroadcast1ElementUint8Test(
237 armnn::IWorkloadFactory& workloadFactory,
238 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager)
240 const unsigned int shape0[] = { 1, 2, 2, 3 };
241 const unsigned int shape1[] = { 1, 1, 1, 1 };
243 std::vector<uint8_t> input0 =
249 std::vector<uint8_t> input1 = { 2 };
251 std::vector<uint8_t> output =
254 14, 16, 18, 20, 22, 24
257 return ElementwiseTestHelper<4, armnn::MultiplicationQueueDescriptor, armnn::DataType::QuantisedAsymm8>(
268 LayerTestResult<uint8_t, 4> MultiplicationBroadcast1DVectorUint8Test(
269 armnn::IWorkloadFactory& workloadFactory,
270 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager)
272 const unsigned int shape0[] = { 1, 2, 2, 3 };
273 const unsigned int shape1[] = { 1, 1, 1, 3 };
275 std::vector<uint8_t> input0 =
281 std::vector<uint8_t> input1 = { 1, 2, 3 };
283 std::vector<uint8_t> output =
286 7, 16, 27, 10, 22, 36
289 return ElementwiseTestHelper<4, armnn::MultiplicationQueueDescriptor, armnn::DataType::QuantisedAsymm8>(
300 LayerTestResult<int16_t, 4> MultiplicationInt16Test(
301 armnn::IWorkloadFactory& workloadFactory,
302 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager)
304 const unsigned int shape[] = { 1, 2, 2, 3 };
306 std::vector<int16_t> input0 =
309 12, 13, 14, 15, 16, 17
312 std::vector<int16_t> input1 =
318 std::vector<int16_t> output =
320 6, 14, 24, 36, 50, 66,
321 84, 104, 126, 150, 176, 204
324 return ElementwiseTestHelper<4, armnn::MultiplicationQueueDescriptor, armnn::DataType::QuantisedSymm16>(
335 LayerTestResult<int16_t, 4> MultiplicationBroadcast1ElementInt16Test(
336 armnn::IWorkloadFactory& workloadFactory,
337 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager)
339 const unsigned int shape0[] = { 1, 2, 2, 3 };
340 const unsigned int shape1[] = { 1, 1, 1, 1 };
342 std::vector<int16_t> input0 =
348 std::vector<int16_t> input1 = { 2 };
350 std::vector<int16_t> output =
353 14, 16, 18, 20, 22, 24
356 return ElementwiseTestHelper<4, armnn::MultiplicationQueueDescriptor, armnn::DataType::QuantisedSymm16>(
367 LayerTestResult<int16_t, 4> MultiplicationBroadcast1DVectorInt16Test(
368 armnn::IWorkloadFactory& workloadFactory,
369 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager)
371 const unsigned int shape0[] = { 1, 2, 2, 3 };
372 const unsigned int shape1[] = { 1, 1, 1, 3 };
374 std::vector<int16_t> input0 =
380 std::vector<int16_t> input1 = { 1, 2, 3 };
382 std::vector<int16_t> output =
385 7, 16, 27, 10, 22, 36
388 return ElementwiseTestHelper<4, armnn::MultiplicationQueueDescriptor, armnn::DataType::QuantisedSymm16>(
399 LayerTestResult<float,4> CompareMultiplicationTest(
400 armnn::IWorkloadFactory& workloadFactory,
401 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
402 armnn::IWorkloadFactory& refWorkloadFactory)
404 boost::ignore_unused(memoryManager);
405 const unsigned int width = 16;
406 const unsigned int height = 32;
407 const unsigned int channelCount = 2;
408 const unsigned int batchSize = 5;
410 armnn::TensorInfo inputTensorInfo0;
411 armnn::TensorInfo inputTensorInfo1;
412 armnn::TensorInfo outputTensorInfo;
414 constexpr unsigned int shape[] = { batchSize, channelCount, height, width };
416 inputTensorInfo0 = armnn::TensorInfo(4, shape, armnn::DataType::Float32);
417 inputTensorInfo1 = armnn::TensorInfo(4, shape, armnn::DataType::Float32);
418 outputTensorInfo = armnn::TensorInfo(4, shape, armnn::DataType::Float32);
420 LayerTestResult<float,4> comparisonResult(outputTensorInfo);
422 auto input0 = MakeRandomTensor<float, 4>(inputTensorInfo0, 803506992);
423 auto input1 = MakeRandomTensor<float, 4>(inputTensorInfo1, 54902257);
425 std::unique_ptr<armnn::ITensorHandle> inputHandle0 = workloadFactory.CreateTensorHandle(inputTensorInfo0);
426 std::unique_ptr<armnn::ITensorHandle> inputHandle1 = workloadFactory.CreateTensorHandle(inputTensorInfo1);
427 std::unique_ptr<armnn::ITensorHandle> outputHandle = workloadFactory.CreateTensorHandle(outputTensorInfo);
429 std::unique_ptr<armnn::ITensorHandle> inputHandle0Ref = refWorkloadFactory.CreateTensorHandle(inputTensorInfo0);
430 std::unique_ptr<armnn::ITensorHandle> inputHandle1Ref = refWorkloadFactory.CreateTensorHandle(inputTensorInfo1);
431 std::unique_ptr<armnn::ITensorHandle> outputHandleRef = refWorkloadFactory.CreateTensorHandle(outputTensorInfo);
433 armnn::MultiplicationQueueDescriptor data;
434 armnn::WorkloadInfo info;
435 AddInputToWorkload(data, info, inputTensorInfo0, inputHandle0.get());
436 AddInputToWorkload(data, info, inputTensorInfo1, inputHandle1.get());
437 AddOutputToWorkload(data, info, outputTensorInfo, outputHandle.get());
439 armnn::MultiplicationQueueDescriptor refData = data;
440 armnn::WorkloadInfo refInfo = info;
441 SetWorkloadInput(refData, refInfo, 0, inputTensorInfo0, inputHandle0Ref.get());
442 SetWorkloadInput(refData, refInfo, 1, inputTensorInfo1, inputHandle1Ref.get());
443 SetWorkloadOutput(refData, refInfo, 0, outputTensorInfo, outputHandleRef.get());
445 std::unique_ptr<armnn::IWorkload> workload = workloadFactory.CreateMultiplication(data, info);
446 std::unique_ptr<armnn::IWorkload> workloadRef = refWorkloadFactory.CreateMultiplication(refData, refInfo);
448 inputHandle0->Allocate();
449 inputHandle1->Allocate();
450 outputHandle->Allocate();
451 inputHandle0Ref->Allocate();
452 inputHandle1Ref->Allocate();
453 outputHandleRef->Allocate();
455 CopyDataToITensorHandle(inputHandle0.get(), input0.origin());
456 CopyDataToITensorHandle(inputHandle1.get(), input1.origin());
457 CopyDataToITensorHandle(inputHandle0Ref.get(), input0.origin());
458 CopyDataToITensorHandle(inputHandle1Ref.get(), input1.origin());
460 workload->PostAllocationConfigure();
462 workloadRef->PostAllocationConfigure();
463 workloadRef->Execute();
464 CopyDataFromITensorHandle(comparisonResult.output.origin(), outputHandle.get());
465 CopyDataFromITensorHandle(comparisonResult.outputExpected.origin(), outputHandleRef.get());
467 return comparisonResult;