blob: 99b1b18c502db2b52e9ac6f69dbf774b9a49144d [file] [log] [blame]
Aron Virginas-Tare89ebad2019-08-27 18:14:26 +01001//
2// Copyright © 2017 Arm Ltd. All rights reserved.
3// 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
219 return ElementwiseTestHelper<4, armnn::MultiplicationQueueDescriptor, armnn::DataType::QuantisedAsymm8>(
220 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
257 return ElementwiseTestHelper<4, armnn::MultiplicationQueueDescriptor, armnn::DataType::QuantisedAsymm8>(
258 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
289 return ElementwiseTestHelper<4, armnn::MultiplicationQueueDescriptor, armnn::DataType::QuantisedAsymm8>(
290 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
324 return ElementwiseTestHelper<4, armnn::MultiplicationQueueDescriptor, armnn::DataType::QuantisedSymm16>(
325 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
356 return ElementwiseTestHelper<4, armnn::MultiplicationQueueDescriptor, armnn::DataType::QuantisedSymm16>(
357 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
388 return ElementwiseTestHelper<4, armnn::MultiplicationQueueDescriptor, armnn::DataType::QuantisedSymm16>(
389 workloadFactory,
390 memoryManager,
391 shape0,
392 input0,
393 shape1,
394 input1,
395 shape0,
396 output);
397}
398
399LayerTestResult<float,4> CompareMultiplicationTest(
400 armnn::IWorkloadFactory& workloadFactory,
401 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
402 armnn::IWorkloadFactory& refWorkloadFactory)
403{
404 const unsigned int width = 16;
405 const unsigned int height = 32;
406 const unsigned int channelCount = 2;
407 const unsigned int batchSize = 5;
408
409 armnn::TensorInfo inputTensorInfo0;
410 armnn::TensorInfo inputTensorInfo1;
411 armnn::TensorInfo outputTensorInfo;
412
413 constexpr unsigned int shape[] = { batchSize, channelCount, height, width };
414
415 inputTensorInfo0 = armnn::TensorInfo(4, shape, armnn::DataType::Float32);
416 inputTensorInfo1 = armnn::TensorInfo(4, shape, armnn::DataType::Float32);
417 outputTensorInfo = armnn::TensorInfo(4, shape, armnn::DataType::Float32);
418
419 LayerTestResult<float,4> comparisonResult(outputTensorInfo);
420
421 auto input0 = MakeRandomTensor<float, 4>(inputTensorInfo0, 803506992);
422 auto input1 = MakeRandomTensor<float, 4>(inputTensorInfo1, 54902257);
423
424 std::unique_ptr<armnn::ITensorHandle> inputHandle0 = workloadFactory.CreateTensorHandle(inputTensorInfo0);
425 std::unique_ptr<armnn::ITensorHandle> inputHandle1 = workloadFactory.CreateTensorHandle(inputTensorInfo1);
426 std::unique_ptr<armnn::ITensorHandle> outputHandle = workloadFactory.CreateTensorHandle(outputTensorInfo);
427
428 std::unique_ptr<armnn::ITensorHandle> inputHandle0Ref = refWorkloadFactory.CreateTensorHandle(inputTensorInfo0);
429 std::unique_ptr<armnn::ITensorHandle> inputHandle1Ref = refWorkloadFactory.CreateTensorHandle(inputTensorInfo1);
430 std::unique_ptr<armnn::ITensorHandle> outputHandleRef = refWorkloadFactory.CreateTensorHandle(outputTensorInfo);
431
432 armnn::MultiplicationQueueDescriptor data;
433 armnn::WorkloadInfo info;
434 AddInputToWorkload(data, info, inputTensorInfo0, inputHandle0.get());
435 AddInputToWorkload(data, info, inputTensorInfo1, inputHandle1.get());
436 AddOutputToWorkload(data, info, outputTensorInfo, outputHandle.get());
437
438 armnn::MultiplicationQueueDescriptor refData = data;
439 armnn::WorkloadInfo refInfo = info;
440 SetWorkloadInput(refData, refInfo, 0, inputTensorInfo0, inputHandle0Ref.get());
441 SetWorkloadInput(refData, refInfo, 1, inputTensorInfo1, inputHandle1Ref.get());
442 SetWorkloadOutput(refData, refInfo, 0, outputTensorInfo, outputHandleRef.get());
443
444 std::unique_ptr<armnn::IWorkload> workload = workloadFactory.CreateMultiplication(data, info);
445 std::unique_ptr<armnn::IWorkload> workloadRef = refWorkloadFactory.CreateMultiplication(refData, refInfo);
446
447 inputHandle0->Allocate();
448 inputHandle1->Allocate();
449 outputHandle->Allocate();
450 inputHandle0Ref->Allocate();
451 inputHandle1Ref->Allocate();
452 outputHandleRef->Allocate();
453
454 CopyDataToITensorHandle(inputHandle0.get(), input0.origin());
455 CopyDataToITensorHandle(inputHandle1.get(), input1.origin());
456 CopyDataToITensorHandle(inputHandle0Ref.get(), input0.origin());
457 CopyDataToITensorHandle(inputHandle1Ref.get(), input1.origin());
458
459 workload->PostAllocationConfigure();
460 workload->Execute();
461 workloadRef->PostAllocationConfigure();
462 workloadRef->Execute();
463 CopyDataFromITensorHandle(comparisonResult.output.origin(), outputHandle.get());
464 CopyDataFromITensorHandle(comparisonResult.outputExpected.origin(), outputHandleRef.get());
465
466 return comparisonResult;
467}