blob: 2bd9372fe9d776250899acf4e3317235fc87f87c [file] [log] [blame]
James Conroyaba90cd2020-11-06 16:28:18 +00001//
2// Copyright © 2020 Arm Ltd and Contributors. All rights reserved.
3// SPDX-License-Identifier: MIT
4//
5
6#include "LogicalTestImpl.hpp"
7
8#include <armnn/utility/Assert.hpp>
9#include <ResolveType.hpp>
10
Colm Donelan0c479742021-12-10 12:43:54 +000011#include <armnn/backends/Workload.hpp>
12#include <armnn/backends/WorkloadData.hpp>
James Conroyaba90cd2020-11-06 16:28:18 +000013
Sadik Armagana097d2a2021-11-24 15:47:28 +000014#include <armnnTestUtils/TensorCopyUtils.hpp>
Colm Donelan0c479742021-12-10 12:43:54 +000015#include <armnnTestUtils/WorkloadTestUtils.hpp>
James Conroyaba90cd2020-11-06 16:28:18 +000016
Colm Donelanc42a9872022-02-02 16:35:09 +000017#include <armnnTestUtils/TensorHelpers.hpp>
James Conroyaba90cd2020-11-06 16:28:18 +000018
19namespace {
20
21template <std::size_t NumDims>
22LayerTestResult<uint8_t, NumDims> LogicalUnaryTestHelper(
23 armnn::IWorkloadFactory& workloadFactory,
24 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
25 armnn::UnaryOperation op,
26 const armnn::TensorShape& inputShape,
27 std::vector<uint8_t> input,
28 const armnn::TensorShape& outputShape,
29 std::vector<uint8_t> expectedOutput,
30 const armnn::ITensorHandleFactory& tensorHandleFactory)
31{
32 ARMNN_ASSERT(inputShape.GetNumDimensions() == NumDims);
33 armnn::TensorInfo inputTensorInfo(inputShape, armnn::DataType::Boolean);
34
35 ARMNN_ASSERT(outputShape.GetNumDimensions() == NumDims);
36 armnn::TensorInfo outputTensorInfo(outputShape, armnn::DataType::Boolean);
37
Sadik Armagan483c8112021-06-01 09:24:52 +010038 std::vector<uint8_t> actualOutput(outputTensorInfo.GetNumElements());
James Conroyaba90cd2020-11-06 16:28:18 +000039
40 std::unique_ptr <armnn::ITensorHandle> inputHandle = tensorHandleFactory.CreateTensorHandle(inputTensorInfo);
41 std::unique_ptr <armnn::ITensorHandle> outputHandle = tensorHandleFactory.CreateTensorHandle(outputTensorInfo);
42
43 armnn::ElementwiseUnaryDescriptor desc(op);
44 armnn::ElementwiseUnaryQueueDescriptor qDesc;
45 qDesc.m_Parameters = desc;
46
47 armnn::WorkloadInfo info;
48 AddInputToWorkload(qDesc, info, inputTensorInfo, inputHandle.get());
49 AddOutputToWorkload(qDesc, info, outputTensorInfo, outputHandle.get());
50
Teresa Charlin611c7fb2022-01-07 09:47:29 +000051 auto workload = workloadFactory.CreateWorkload(armnn::LayerType::ElementwiseUnary, qDesc, info);
James Conroyaba90cd2020-11-06 16:28:18 +000052
53 inputHandle->Allocate();
54 outputHandle->Allocate();
55
Sadik Armagan483c8112021-06-01 09:24:52 +010056 CopyDataToITensorHandle(inputHandle.get(), input.data());
James Conroyaba90cd2020-11-06 16:28:18 +000057
58 workload->PostAllocationConfigure();
59 ExecuteWorkload(*workload, memoryManager);
60
Sadik Armagan483c8112021-06-01 09:24:52 +010061 CopyDataFromITensorHandle(actualOutput.data(), outputHandle.get());
James Conroyaba90cd2020-11-06 16:28:18 +000062
Sadik Armagan483c8112021-06-01 09:24:52 +010063 return LayerTestResult<uint8_t, NumDims>(actualOutput,
64 expectedOutput,
65 outputHandle->GetShape(),
66 outputTensorInfo.GetShape(),
67 true);
James Conroyaba90cd2020-11-06 16:28:18 +000068}
69
70template <std::size_t NumDims>
71LayerTestResult<uint8_t, NumDims> LogicalBinaryTestHelper(
72 armnn::IWorkloadFactory& workloadFactory,
73 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
74 armnn::LogicalBinaryOperation op,
75 const armnn::TensorShape& inputShape0,
76 const armnn::TensorShape& inputShape1,
77 std::vector<uint8_t> input0,
78 std::vector<uint8_t> input1,
79 const armnn::TensorShape& outputShape,
80 std::vector<uint8_t> expectedOutput,
81 const armnn::ITensorHandleFactory& tensorHandleFactory)
82{
83 ARMNN_ASSERT(inputShape0.GetNumDimensions() == NumDims);
84 armnn::TensorInfo inputTensorInfo0(inputShape0, armnn::DataType::Boolean);
85
86 ARMNN_ASSERT(inputShape1.GetNumDimensions() == NumDims);
87 armnn::TensorInfo inputTensorInfo1(inputShape1, armnn::DataType::Boolean);
88
89 ARMNN_ASSERT(outputShape.GetNumDimensions() == NumDims);
90 armnn::TensorInfo outputTensorInfo(outputShape, armnn::DataType::Boolean);
91
Sadik Armagan483c8112021-06-01 09:24:52 +010092 std::vector<uint8_t> actualOutput(outputTensorInfo.GetNumElements());
James Conroyaba90cd2020-11-06 16:28:18 +000093
94 std::unique_ptr <armnn::ITensorHandle> inputHandle0 = tensorHandleFactory.CreateTensorHandle(inputTensorInfo0);
95 std::unique_ptr <armnn::ITensorHandle> inputHandle1 = tensorHandleFactory.CreateTensorHandle(inputTensorInfo1);
96 std::unique_ptr <armnn::ITensorHandle> outputHandle = tensorHandleFactory.CreateTensorHandle(outputTensorInfo);
97
98 armnn::LogicalBinaryDescriptor desc(op);
99 armnn::LogicalBinaryQueueDescriptor qDesc;
100 qDesc.m_Parameters = desc;
101
102 armnn::WorkloadInfo info;
103 AddInputToWorkload(qDesc, info, inputTensorInfo0, inputHandle0.get());
104 AddInputToWorkload(qDesc, info, inputTensorInfo1, inputHandle1.get());
105 AddOutputToWorkload(qDesc, info, outputTensorInfo, outputHandle.get());
106
Teresa Charlin611c7fb2022-01-07 09:47:29 +0000107 auto workload = workloadFactory.CreateWorkload(armnn::LayerType::LogicalBinary, qDesc, info);
James Conroyaba90cd2020-11-06 16:28:18 +0000108
109 inputHandle0->Allocate();
110 inputHandle1->Allocate();
111 outputHandle->Allocate();
112
Sadik Armagan483c8112021-06-01 09:24:52 +0100113 CopyDataToITensorHandle(inputHandle0.get(), input0.data());
114 CopyDataToITensorHandle(inputHandle1.get(), input1.data());
James Conroyaba90cd2020-11-06 16:28:18 +0000115
116 workload->PostAllocationConfigure();
117 ExecuteWorkload(*workload, memoryManager);
118
Sadik Armagan483c8112021-06-01 09:24:52 +0100119 CopyDataFromITensorHandle(actualOutput.data(), outputHandle.get());
James Conroyaba90cd2020-11-06 16:28:18 +0000120
Sadik Armagan483c8112021-06-01 09:24:52 +0100121 return LayerTestResult<uint8_t, NumDims>(actualOutput,
122 expectedOutput,
123 outputHandle->GetShape(),
124 outputTensorInfo.GetShape(),
125 true);
James Conroyaba90cd2020-11-06 16:28:18 +0000126}
127
128class UnaryTestData
129{
130public:
131 UnaryTestData() = default;
132 virtual ~UnaryTestData() = default;
133
134 armnn::TensorShape m_InputShape;
135 armnn::TensorShape m_OutputShape;
136
137 std::vector<uint8_t> m_InputData;
138
139 std::vector<uint8_t> m_OutputNot;
140};
141
142class BinaryTestData
143{
144public:
145 BinaryTestData() = default;
146 virtual ~BinaryTestData() = default;
147
148 armnn::TensorShape m_InputShape0;
149 armnn::TensorShape m_InputShape1;
150 armnn::TensorShape m_OutputShape;
151
152 std::vector<uint8_t> m_InputData0;
153 std::vector<uint8_t> m_InputData1;
154
155 std::vector<uint8_t> m_OutputAnd;
156 std::vector<uint8_t> m_OutputOr;
157};
158
159class SimpleUnaryTestData : public UnaryTestData
160{
161public:
162 SimpleUnaryTestData() : UnaryTestData()
163 {
164 m_InputShape = { 1, 1, 1, 4 };
165 m_OutputShape = m_InputShape;
166
167 m_InputData =
168 {
169 true, false, false, true
170 };
171
172 m_OutputNot =
173 {
174 false, true, true, false
175 };
176 }
177};
178
179class SimpleUnaryIntTestData : public UnaryTestData
180{
181public:
182 SimpleUnaryIntTestData() : UnaryTestData()
183 {
184 m_InputShape = { 1, 1, 1, 4 };
185 m_OutputShape = m_InputShape;
186
187 m_InputData =
188 {
189 1, 11, 111, 0
190 };
191
192 m_OutputNot =
193 {
194 0, 0, 0, 1
195 };
196 }
197};
198
199class SimpleBinaryTestData : public BinaryTestData
200{
201public:
202 SimpleBinaryTestData() : BinaryTestData()
203 {
204 m_InputShape0 = { 1, 1, 1, 4 };
205 m_InputShape1 = m_InputShape0;
206 m_OutputShape = m_InputShape1;
207
208 m_InputData0 =
209 {
210 true, false, false, true
211 };
212
213 m_InputData1 =
214 {
215 true, false, true, false
216 };
217
218 m_OutputAnd =
219 {
220 true, false, false, false
221 };
222
223 m_OutputOr =
224 {
225 true, false, true, true
226 };
227 }
228};
229
230class SimpleBinaryIntTestData : public BinaryTestData
231{
232public:
233 SimpleBinaryIntTestData() : BinaryTestData()
234 {
235 m_InputShape0 = { 1, 1, 1, 4 };
236 m_InputShape1 = m_InputShape0;
237 m_OutputShape = m_InputShape1;
238
239 m_InputData0 =
240 {
241 1, 11, 111, 0
242 };
243
244 m_InputData1 =
245 {
246 0, 111, 111, 0
247 };
248
249 m_OutputAnd =
250 {
251 0, 1, 1, 0
252 };
253
254 m_OutputOr =
255 {
256 1, 1, 1, 0
257 };
258 }
259};
260
261class BroadcastBinary1TestData : public BinaryTestData
262{
263public:
264 BroadcastBinary1TestData() : BinaryTestData()
265 {
266 m_InputShape0 = { 1, 1, 1, 4 };
267 m_InputShape1 = { 1, 1, 1, 1 };
268 m_OutputShape = m_InputShape0;
269
270 m_InputData0 =
271 {
272 true, false, false, true
273 };
274
275 m_InputData1 =
276 {
277 true
278 };
279
280 m_OutputAnd =
281 {
282 true, false, false, true
283 };
284
285 m_OutputOr =
286 {
287 true, true, true, true
288 };
289 }
290};
291
292class BroadcastBinary2TestData : public BinaryTestData
293{
294public:
295 BroadcastBinary2TestData() : BinaryTestData()
296 {
297 m_InputShape0 = { 1, 1, 1, 1 };
298 m_InputShape1 = { 1, 1, 1, 4 };
299 m_OutputShape = m_InputShape1;
300
301 m_InputData0 =
302 {
303 true
304 };
305
306 m_InputData1 =
307 {
308 true, false, false, true
309 };
310
311 m_OutputAnd =
312 {
313 true, false, false, true
314 };
315
316 m_OutputOr =
317 {
318 true, true, true, true
319 };
320 }
321};
322
323class BroadcastBinary3TestData : public BinaryTestData
324{
325public:
326 BroadcastBinary3TestData() : BinaryTestData()
327 {
328 m_InputShape0 = { 1, 1, 1, 4 };
329 m_InputShape1 = { 1, 1, 1, 1 };
330 m_OutputShape = m_InputShape0;
331
332 m_InputData0 =
333 {
334 true, false, false, true
335 };
336
337 m_InputData1 =
338 {
339 false
340 };
341
342 m_OutputAnd =
343 {
344 false, false, false, false
345 };
346
347 m_OutputOr =
348 {
349 true, false, false, true
350 };
351 }
352};
353
354static SimpleUnaryTestData s_SimpleUnaryTestData;
355static SimpleBinaryTestData s_SimpleBinaryTestData;
356
357static SimpleUnaryIntTestData s_SimpleUnaryIntTestData;
358static SimpleBinaryIntTestData s_SimpleBinaryIntTestData;
359
360static BroadcastBinary1TestData s_BroadcastBinary1TestData;
361static BroadcastBinary2TestData s_BroadcastBinary2TestData;
362static BroadcastBinary3TestData s_BroadcastBinary3TestData;
363
364
365} // anonymous namespace
366
367// Unary - Not
368LayerTestResult<uint8_t, 4> LogicalNotTest(armnn::IWorkloadFactory& workloadFactory,
369 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
370 const armnn::ITensorHandleFactory& tensorHandleFactory)
371{
372 return LogicalUnaryTestHelper<4>(workloadFactory,
373 memoryManager,
374 armnn::UnaryOperation::LogicalNot,
375 s_SimpleUnaryTestData.m_InputShape,
376 s_SimpleUnaryTestData.m_InputData,
377 s_SimpleUnaryTestData.m_OutputShape,
378 s_SimpleUnaryTestData.m_OutputNot,
379 tensorHandleFactory);
380}
381
382// Unary - Not with integers
383LayerTestResult<uint8_t, 4> LogicalNotIntTest(armnn::IWorkloadFactory& workloadFactory,
384 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
385 const armnn::ITensorHandleFactory& tensorHandleFactory)
386{
387 return LogicalUnaryTestHelper<4>(workloadFactory,
388 memoryManager,
389 armnn::UnaryOperation::LogicalNot,
390 s_SimpleUnaryIntTestData.m_InputShape,
391 s_SimpleUnaryIntTestData.m_InputData,
392 s_SimpleUnaryIntTestData.m_OutputShape,
393 s_SimpleUnaryIntTestData.m_OutputNot,
394 tensorHandleFactory);
395}
396
397// Binary - And
398LayerTestResult<uint8_t, 4> LogicalAndTest(armnn::IWorkloadFactory& workloadFactory,
399 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
400 const armnn::ITensorHandleFactory& tensorHandleFactory)
401{
402 return LogicalBinaryTestHelper<4>(workloadFactory,
403 memoryManager,
404 armnn::LogicalBinaryOperation::LogicalAnd,
405 s_SimpleBinaryTestData.m_InputShape0,
406 s_SimpleBinaryTestData.m_InputShape1,
407 s_SimpleBinaryTestData.m_InputData0,
408 s_SimpleBinaryTestData.m_InputData1,
409 s_SimpleBinaryTestData.m_OutputShape,
410 s_SimpleBinaryTestData.m_OutputAnd,
411 tensorHandleFactory);
412}
413
414// Binary - Or
415LayerTestResult<uint8_t, 4> LogicalOrTest(armnn::IWorkloadFactory& workloadFactory,
416 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
417 const armnn::ITensorHandleFactory& tensorHandleFactory)
418{
419 return LogicalBinaryTestHelper<4>(workloadFactory,
420 memoryManager,
421 armnn::LogicalBinaryOperation::LogicalOr,
422 s_SimpleBinaryTestData.m_InputShape0,
423 s_SimpleBinaryTestData.m_InputShape1,
424 s_SimpleBinaryTestData.m_InputData0,
425 s_SimpleBinaryTestData.m_InputData1,
426 s_SimpleBinaryTestData.m_OutputShape,
427 s_SimpleBinaryTestData.m_OutputOr,
428 tensorHandleFactory);
429}
430
431// Binary - And with integers
432LayerTestResult<uint8_t, 4> LogicalAndIntTest(armnn::IWorkloadFactory& workloadFactory,
433 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
434 const armnn::ITensorHandleFactory& tensorHandleFactory)
435{
436 return LogicalBinaryTestHelper<4>(workloadFactory,
437 memoryManager,
438 armnn::LogicalBinaryOperation::LogicalAnd,
439 s_SimpleBinaryIntTestData.m_InputShape0,
440 s_SimpleBinaryIntTestData.m_InputShape1,
441 s_SimpleBinaryIntTestData.m_InputData0,
442 s_SimpleBinaryIntTestData.m_InputData1,
443 s_SimpleBinaryIntTestData.m_OutputShape,
444 s_SimpleBinaryIntTestData.m_OutputAnd,
445 tensorHandleFactory);
446}
447
448// Binary - Or with integers
449LayerTestResult<uint8_t, 4> LogicalOrIntTest(armnn::IWorkloadFactory& workloadFactory,
450 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
451 const armnn::ITensorHandleFactory& tensorHandleFactory)
452{
453 return LogicalBinaryTestHelper<4>(workloadFactory,
454 memoryManager,
455 armnn::LogicalBinaryOperation::LogicalOr,
456 s_SimpleBinaryIntTestData.m_InputShape0,
457 s_SimpleBinaryIntTestData.m_InputShape1,
458 s_SimpleBinaryIntTestData.m_InputData0,
459 s_SimpleBinaryIntTestData.m_InputData1,
460 s_SimpleBinaryIntTestData.m_OutputShape,
461 s_SimpleBinaryIntTestData.m_OutputOr,
462 tensorHandleFactory);
463}
464
465// Binary - And Broadcast
466LayerTestResult<uint8_t, 4> LogicalAndBroadcast1Test(
467 armnn::IWorkloadFactory& workloadFactory,
468 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
469 const armnn::ITensorHandleFactory& tensorHandleFactory)
470{
471 return LogicalBinaryTestHelper<4>(workloadFactory,
472 memoryManager,
473 armnn::LogicalBinaryOperation::LogicalAnd,
474 s_BroadcastBinary1TestData.m_InputShape0,
475 s_BroadcastBinary1TestData.m_InputShape1,
476 s_BroadcastBinary1TestData.m_InputData0,
477 s_BroadcastBinary1TestData.m_InputData1,
478 s_BroadcastBinary1TestData.m_OutputShape,
479 s_BroadcastBinary1TestData.m_OutputAnd,
480 tensorHandleFactory);
481}
482
483// Binary - Or Broadcast
484LayerTestResult<uint8_t, 4> LogicalOrBroadcast1Test(
485 armnn::IWorkloadFactory& workloadFactory,
486 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
487 const armnn::ITensorHandleFactory& tensorHandleFactory)
488{
489 return LogicalBinaryTestHelper<4>(workloadFactory,
490 memoryManager,
491 armnn::LogicalBinaryOperation::LogicalOr,
492 s_BroadcastBinary1TestData.m_InputShape0,
493 s_BroadcastBinary1TestData.m_InputShape1,
494 s_BroadcastBinary1TestData.m_InputData0,
495 s_BroadcastBinary1TestData.m_InputData1,
496 s_BroadcastBinary1TestData.m_OutputShape,
497 s_BroadcastBinary1TestData.m_OutputOr,
498 tensorHandleFactory);
499}
500
501// Binary - And Broadcast
502LayerTestResult<uint8_t, 4> LogicalAndBroadcast2Test(
503 armnn::IWorkloadFactory& workloadFactory,
504 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
505 const armnn::ITensorHandleFactory& tensorHandleFactory)
506{
507 return LogicalBinaryTestHelper<4>(workloadFactory,
508 memoryManager,
509 armnn::LogicalBinaryOperation::LogicalAnd,
510 s_BroadcastBinary2TestData.m_InputShape0,
511 s_BroadcastBinary2TestData.m_InputShape1,
512 s_BroadcastBinary2TestData.m_InputData0,
513 s_BroadcastBinary2TestData.m_InputData1,
514 s_BroadcastBinary2TestData.m_OutputShape,
515 s_BroadcastBinary2TestData.m_OutputAnd,
516 tensorHandleFactory);
517}
518
519// Binary - Or Broadcast
520LayerTestResult<uint8_t, 4> LogicalOrBroadcast2Test(
521 armnn::IWorkloadFactory& workloadFactory,
522 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
523 const armnn::ITensorHandleFactory& tensorHandleFactory)
524{
525 return LogicalBinaryTestHelper<4>(workloadFactory,
526 memoryManager,
527 armnn::LogicalBinaryOperation::LogicalOr,
528 s_BroadcastBinary2TestData.m_InputShape0,
529 s_BroadcastBinary2TestData.m_InputShape1,
530 s_BroadcastBinary2TestData.m_InputData0,
531 s_BroadcastBinary2TestData.m_InputData1,
532 s_BroadcastBinary2TestData.m_OutputShape,
533 s_BroadcastBinary2TestData.m_OutputOr,
534 tensorHandleFactory);
535}
536
537// Binary - And Broadcast
538LayerTestResult<uint8_t, 4> LogicalAndBroadcast3Test(
539 armnn::IWorkloadFactory& workloadFactory,
540 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
541 const armnn::ITensorHandleFactory& tensorHandleFactory)
542{
543 return LogicalBinaryTestHelper<4>(workloadFactory,
544 memoryManager,
545 armnn::LogicalBinaryOperation::LogicalAnd,
546 s_BroadcastBinary3TestData.m_InputShape0,
547 s_BroadcastBinary3TestData.m_InputShape1,
548 s_BroadcastBinary3TestData.m_InputData0,
549 s_BroadcastBinary3TestData.m_InputData1,
550 s_BroadcastBinary3TestData.m_OutputShape,
551 s_BroadcastBinary3TestData.m_OutputAnd,
552 tensorHandleFactory);
553}
554
555// Binary - Or Broadcast
556LayerTestResult<uint8_t, 4> LogicalOrBroadcast3Test(
557 armnn::IWorkloadFactory& workloadFactory,
558 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
559 const armnn::ITensorHandleFactory& tensorHandleFactory)
560{
561 return LogicalBinaryTestHelper<4>(workloadFactory,
562 memoryManager,
563 armnn::LogicalBinaryOperation::LogicalOr,
564 s_BroadcastBinary3TestData.m_InputShape0,
565 s_BroadcastBinary3TestData.m_InputShape1,
566 s_BroadcastBinary3TestData.m_InputData0,
567 s_BroadcastBinary3TestData.m_InputData1,
568 s_BroadcastBinary3TestData.m_OutputShape,
569 s_BroadcastBinary3TestData.m_OutputOr,
570 tensorHandleFactory);
571}