blob: 4f046731715b2eae8c9db282c2009ace3dd0275a [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
11#include <backendsCommon/Workload.hpp>
12#include <backendsCommon/WorkloadData.hpp>
13
14#include <backendsCommon/test/TensorCopyUtils.hpp>
15#include <backendsCommon/test/WorkloadTestUtils.hpp>
16
17#include <test/TensorHelpers.hpp>
18
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
38 auto inputTensor = MakeTensor<uint8_t, NumDims>(inputTensorInfo, input);
39
40 LayerTestResult <uint8_t, NumDims> ret(outputTensorInfo);
41
42 std::unique_ptr <armnn::ITensorHandle> inputHandle = tensorHandleFactory.CreateTensorHandle(inputTensorInfo);
43 std::unique_ptr <armnn::ITensorHandle> outputHandle = tensorHandleFactory.CreateTensorHandle(outputTensorInfo);
44
45 armnn::ElementwiseUnaryDescriptor desc(op);
46 armnn::ElementwiseUnaryQueueDescriptor qDesc;
47 qDesc.m_Parameters = desc;
48
49 armnn::WorkloadInfo info;
50 AddInputToWorkload(qDesc, info, inputTensorInfo, inputHandle.get());
51 AddOutputToWorkload(qDesc, info, outputTensorInfo, outputHandle.get());
52
James Conroy58f8ecd2020-11-19 14:44:01 +000053 auto workload = workloadFactory.CreateElementwiseUnary(qDesc, info);
James Conroyaba90cd2020-11-06 16:28:18 +000054
55 inputHandle->Allocate();
56 outputHandle->Allocate();
57
58 CopyDataToITensorHandle(inputHandle.get(), inputTensor.origin());
59
60 workload->PostAllocationConfigure();
61 ExecuteWorkload(*workload, memoryManager);
62
63 CopyDataFromITensorHandle(ret.output.origin(), outputHandle.get());
64
65 ret.outputExpected = MakeTensor<uint8_t, NumDims>(outputTensorInfo, expectedOutput);
66 ret.compareBoolean = true;
67 return ret;
68}
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
92 auto inputTensor0 = MakeTensor<uint8_t, NumDims>(inputTensorInfo0, input0);
93 auto inputTensor1 = MakeTensor<uint8_t, NumDims>(inputTensorInfo1, input1);
94
95 LayerTestResult <uint8_t, NumDims> ret(outputTensorInfo);
96
97 std::unique_ptr <armnn::ITensorHandle> inputHandle0 = tensorHandleFactory.CreateTensorHandle(inputTensorInfo0);
98 std::unique_ptr <armnn::ITensorHandle> inputHandle1 = tensorHandleFactory.CreateTensorHandle(inputTensorInfo1);
99 std::unique_ptr <armnn::ITensorHandle> outputHandle = tensorHandleFactory.CreateTensorHandle(outputTensorInfo);
100
101 armnn::LogicalBinaryDescriptor desc(op);
102 armnn::LogicalBinaryQueueDescriptor qDesc;
103 qDesc.m_Parameters = desc;
104
105 armnn::WorkloadInfo info;
106 AddInputToWorkload(qDesc, info, inputTensorInfo0, inputHandle0.get());
107 AddInputToWorkload(qDesc, info, inputTensorInfo1, inputHandle1.get());
108 AddOutputToWorkload(qDesc, info, outputTensorInfo, outputHandle.get());
109
110 auto workload = workloadFactory.CreateLogicalBinary(qDesc, info);
111
112 inputHandle0->Allocate();
113 inputHandle1->Allocate();
114 outputHandle->Allocate();
115
116 CopyDataToITensorHandle(inputHandle0.get(), inputTensor0.origin());
117 CopyDataToITensorHandle(inputHandle1.get(), inputTensor1.origin());
118
119 workload->PostAllocationConfigure();
120 ExecuteWorkload(*workload, memoryManager);
121
122 CopyDataFromITensorHandle(ret.output.origin(), outputHandle.get());
123
124 ret.outputExpected = MakeTensor<uint8_t, NumDims>(outputTensorInfo, expectedOutput);
125 ret.compareBoolean = true;
126 return ret;
127}
128
129class UnaryTestData
130{
131public:
132 UnaryTestData() = default;
133 virtual ~UnaryTestData() = default;
134
135 armnn::TensorShape m_InputShape;
136 armnn::TensorShape m_OutputShape;
137
138 std::vector<uint8_t> m_InputData;
139
140 std::vector<uint8_t> m_OutputNot;
141};
142
143class BinaryTestData
144{
145public:
146 BinaryTestData() = default;
147 virtual ~BinaryTestData() = default;
148
149 armnn::TensorShape m_InputShape0;
150 armnn::TensorShape m_InputShape1;
151 armnn::TensorShape m_OutputShape;
152
153 std::vector<uint8_t> m_InputData0;
154 std::vector<uint8_t> m_InputData1;
155
156 std::vector<uint8_t> m_OutputAnd;
157 std::vector<uint8_t> m_OutputOr;
158};
159
160class SimpleUnaryTestData : public UnaryTestData
161{
162public:
163 SimpleUnaryTestData() : UnaryTestData()
164 {
165 m_InputShape = { 1, 1, 1, 4 };
166 m_OutputShape = m_InputShape;
167
168 m_InputData =
169 {
170 true, false, false, true
171 };
172
173 m_OutputNot =
174 {
175 false, true, true, false
176 };
177 }
178};
179
180class SimpleUnaryIntTestData : public UnaryTestData
181{
182public:
183 SimpleUnaryIntTestData() : UnaryTestData()
184 {
185 m_InputShape = { 1, 1, 1, 4 };
186 m_OutputShape = m_InputShape;
187
188 m_InputData =
189 {
190 1, 11, 111, 0
191 };
192
193 m_OutputNot =
194 {
195 0, 0, 0, 1
196 };
197 }
198};
199
200class SimpleBinaryTestData : public BinaryTestData
201{
202public:
203 SimpleBinaryTestData() : BinaryTestData()
204 {
205 m_InputShape0 = { 1, 1, 1, 4 };
206 m_InputShape1 = m_InputShape0;
207 m_OutputShape = m_InputShape1;
208
209 m_InputData0 =
210 {
211 true, false, false, true
212 };
213
214 m_InputData1 =
215 {
216 true, false, true, false
217 };
218
219 m_OutputAnd =
220 {
221 true, false, false, false
222 };
223
224 m_OutputOr =
225 {
226 true, false, true, true
227 };
228 }
229};
230
231class SimpleBinaryIntTestData : public BinaryTestData
232{
233public:
234 SimpleBinaryIntTestData() : BinaryTestData()
235 {
236 m_InputShape0 = { 1, 1, 1, 4 };
237 m_InputShape1 = m_InputShape0;
238 m_OutputShape = m_InputShape1;
239
240 m_InputData0 =
241 {
242 1, 11, 111, 0
243 };
244
245 m_InputData1 =
246 {
247 0, 111, 111, 0
248 };
249
250 m_OutputAnd =
251 {
252 0, 1, 1, 0
253 };
254
255 m_OutputOr =
256 {
257 1, 1, 1, 0
258 };
259 }
260};
261
262class BroadcastBinary1TestData : public BinaryTestData
263{
264public:
265 BroadcastBinary1TestData() : BinaryTestData()
266 {
267 m_InputShape0 = { 1, 1, 1, 4 };
268 m_InputShape1 = { 1, 1, 1, 1 };
269 m_OutputShape = m_InputShape0;
270
271 m_InputData0 =
272 {
273 true, false, false, true
274 };
275
276 m_InputData1 =
277 {
278 true
279 };
280
281 m_OutputAnd =
282 {
283 true, false, false, true
284 };
285
286 m_OutputOr =
287 {
288 true, true, true, true
289 };
290 }
291};
292
293class BroadcastBinary2TestData : public BinaryTestData
294{
295public:
296 BroadcastBinary2TestData() : BinaryTestData()
297 {
298 m_InputShape0 = { 1, 1, 1, 1 };
299 m_InputShape1 = { 1, 1, 1, 4 };
300 m_OutputShape = m_InputShape1;
301
302 m_InputData0 =
303 {
304 true
305 };
306
307 m_InputData1 =
308 {
309 true, false, false, true
310 };
311
312 m_OutputAnd =
313 {
314 true, false, false, true
315 };
316
317 m_OutputOr =
318 {
319 true, true, true, true
320 };
321 }
322};
323
324class BroadcastBinary3TestData : public BinaryTestData
325{
326public:
327 BroadcastBinary3TestData() : BinaryTestData()
328 {
329 m_InputShape0 = { 1, 1, 1, 4 };
330 m_InputShape1 = { 1, 1, 1, 1 };
331 m_OutputShape = m_InputShape0;
332
333 m_InputData0 =
334 {
335 true, false, false, true
336 };
337
338 m_InputData1 =
339 {
340 false
341 };
342
343 m_OutputAnd =
344 {
345 false, false, false, false
346 };
347
348 m_OutputOr =
349 {
350 true, false, false, true
351 };
352 }
353};
354
355static SimpleUnaryTestData s_SimpleUnaryTestData;
356static SimpleBinaryTestData s_SimpleBinaryTestData;
357
358static SimpleUnaryIntTestData s_SimpleUnaryIntTestData;
359static SimpleBinaryIntTestData s_SimpleBinaryIntTestData;
360
361static BroadcastBinary1TestData s_BroadcastBinary1TestData;
362static BroadcastBinary2TestData s_BroadcastBinary2TestData;
363static BroadcastBinary3TestData s_BroadcastBinary3TestData;
364
365
366} // anonymous namespace
367
368// Unary - Not
369LayerTestResult<uint8_t, 4> LogicalNotTest(armnn::IWorkloadFactory& workloadFactory,
370 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
371 const armnn::ITensorHandleFactory& tensorHandleFactory)
372{
373 return LogicalUnaryTestHelper<4>(workloadFactory,
374 memoryManager,
375 armnn::UnaryOperation::LogicalNot,
376 s_SimpleUnaryTestData.m_InputShape,
377 s_SimpleUnaryTestData.m_InputData,
378 s_SimpleUnaryTestData.m_OutputShape,
379 s_SimpleUnaryTestData.m_OutputNot,
380 tensorHandleFactory);
381}
382
383// Unary - Not with integers
384LayerTestResult<uint8_t, 4> LogicalNotIntTest(armnn::IWorkloadFactory& workloadFactory,
385 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
386 const armnn::ITensorHandleFactory& tensorHandleFactory)
387{
388 return LogicalUnaryTestHelper<4>(workloadFactory,
389 memoryManager,
390 armnn::UnaryOperation::LogicalNot,
391 s_SimpleUnaryIntTestData.m_InputShape,
392 s_SimpleUnaryIntTestData.m_InputData,
393 s_SimpleUnaryIntTestData.m_OutputShape,
394 s_SimpleUnaryIntTestData.m_OutputNot,
395 tensorHandleFactory);
396}
397
398// Binary - And
399LayerTestResult<uint8_t, 4> LogicalAndTest(armnn::IWorkloadFactory& workloadFactory,
400 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
401 const armnn::ITensorHandleFactory& tensorHandleFactory)
402{
403 return LogicalBinaryTestHelper<4>(workloadFactory,
404 memoryManager,
405 armnn::LogicalBinaryOperation::LogicalAnd,
406 s_SimpleBinaryTestData.m_InputShape0,
407 s_SimpleBinaryTestData.m_InputShape1,
408 s_SimpleBinaryTestData.m_InputData0,
409 s_SimpleBinaryTestData.m_InputData1,
410 s_SimpleBinaryTestData.m_OutputShape,
411 s_SimpleBinaryTestData.m_OutputAnd,
412 tensorHandleFactory);
413}
414
415// Binary - Or
416LayerTestResult<uint8_t, 4> LogicalOrTest(armnn::IWorkloadFactory& workloadFactory,
417 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
418 const armnn::ITensorHandleFactory& tensorHandleFactory)
419{
420 return LogicalBinaryTestHelper<4>(workloadFactory,
421 memoryManager,
422 armnn::LogicalBinaryOperation::LogicalOr,
423 s_SimpleBinaryTestData.m_InputShape0,
424 s_SimpleBinaryTestData.m_InputShape1,
425 s_SimpleBinaryTestData.m_InputData0,
426 s_SimpleBinaryTestData.m_InputData1,
427 s_SimpleBinaryTestData.m_OutputShape,
428 s_SimpleBinaryTestData.m_OutputOr,
429 tensorHandleFactory);
430}
431
432// Binary - And with integers
433LayerTestResult<uint8_t, 4> LogicalAndIntTest(armnn::IWorkloadFactory& workloadFactory,
434 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
435 const armnn::ITensorHandleFactory& tensorHandleFactory)
436{
437 return LogicalBinaryTestHelper<4>(workloadFactory,
438 memoryManager,
439 armnn::LogicalBinaryOperation::LogicalAnd,
440 s_SimpleBinaryIntTestData.m_InputShape0,
441 s_SimpleBinaryIntTestData.m_InputShape1,
442 s_SimpleBinaryIntTestData.m_InputData0,
443 s_SimpleBinaryIntTestData.m_InputData1,
444 s_SimpleBinaryIntTestData.m_OutputShape,
445 s_SimpleBinaryIntTestData.m_OutputAnd,
446 tensorHandleFactory);
447}
448
449// Binary - Or with integers
450LayerTestResult<uint8_t, 4> LogicalOrIntTest(armnn::IWorkloadFactory& workloadFactory,
451 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
452 const armnn::ITensorHandleFactory& tensorHandleFactory)
453{
454 return LogicalBinaryTestHelper<4>(workloadFactory,
455 memoryManager,
456 armnn::LogicalBinaryOperation::LogicalOr,
457 s_SimpleBinaryIntTestData.m_InputShape0,
458 s_SimpleBinaryIntTestData.m_InputShape1,
459 s_SimpleBinaryIntTestData.m_InputData0,
460 s_SimpleBinaryIntTestData.m_InputData1,
461 s_SimpleBinaryIntTestData.m_OutputShape,
462 s_SimpleBinaryIntTestData.m_OutputOr,
463 tensorHandleFactory);
464}
465
466// Binary - And Broadcast
467LayerTestResult<uint8_t, 4> LogicalAndBroadcast1Test(
468 armnn::IWorkloadFactory& workloadFactory,
469 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
470 const armnn::ITensorHandleFactory& tensorHandleFactory)
471{
472 return LogicalBinaryTestHelper<4>(workloadFactory,
473 memoryManager,
474 armnn::LogicalBinaryOperation::LogicalAnd,
475 s_BroadcastBinary1TestData.m_InputShape0,
476 s_BroadcastBinary1TestData.m_InputShape1,
477 s_BroadcastBinary1TestData.m_InputData0,
478 s_BroadcastBinary1TestData.m_InputData1,
479 s_BroadcastBinary1TestData.m_OutputShape,
480 s_BroadcastBinary1TestData.m_OutputAnd,
481 tensorHandleFactory);
482}
483
484// Binary - Or Broadcast
485LayerTestResult<uint8_t, 4> LogicalOrBroadcast1Test(
486 armnn::IWorkloadFactory& workloadFactory,
487 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
488 const armnn::ITensorHandleFactory& tensorHandleFactory)
489{
490 return LogicalBinaryTestHelper<4>(workloadFactory,
491 memoryManager,
492 armnn::LogicalBinaryOperation::LogicalOr,
493 s_BroadcastBinary1TestData.m_InputShape0,
494 s_BroadcastBinary1TestData.m_InputShape1,
495 s_BroadcastBinary1TestData.m_InputData0,
496 s_BroadcastBinary1TestData.m_InputData1,
497 s_BroadcastBinary1TestData.m_OutputShape,
498 s_BroadcastBinary1TestData.m_OutputOr,
499 tensorHandleFactory);
500}
501
502// Binary - And Broadcast
503LayerTestResult<uint8_t, 4> LogicalAndBroadcast2Test(
504 armnn::IWorkloadFactory& workloadFactory,
505 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
506 const armnn::ITensorHandleFactory& tensorHandleFactory)
507{
508 return LogicalBinaryTestHelper<4>(workloadFactory,
509 memoryManager,
510 armnn::LogicalBinaryOperation::LogicalAnd,
511 s_BroadcastBinary2TestData.m_InputShape0,
512 s_BroadcastBinary2TestData.m_InputShape1,
513 s_BroadcastBinary2TestData.m_InputData0,
514 s_BroadcastBinary2TestData.m_InputData1,
515 s_BroadcastBinary2TestData.m_OutputShape,
516 s_BroadcastBinary2TestData.m_OutputAnd,
517 tensorHandleFactory);
518}
519
520// Binary - Or Broadcast
521LayerTestResult<uint8_t, 4> LogicalOrBroadcast2Test(
522 armnn::IWorkloadFactory& workloadFactory,
523 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
524 const armnn::ITensorHandleFactory& tensorHandleFactory)
525{
526 return LogicalBinaryTestHelper<4>(workloadFactory,
527 memoryManager,
528 armnn::LogicalBinaryOperation::LogicalOr,
529 s_BroadcastBinary2TestData.m_InputShape0,
530 s_BroadcastBinary2TestData.m_InputShape1,
531 s_BroadcastBinary2TestData.m_InputData0,
532 s_BroadcastBinary2TestData.m_InputData1,
533 s_BroadcastBinary2TestData.m_OutputShape,
534 s_BroadcastBinary2TestData.m_OutputOr,
535 tensorHandleFactory);
536}
537
538// Binary - And Broadcast
539LayerTestResult<uint8_t, 4> LogicalAndBroadcast3Test(
540 armnn::IWorkloadFactory& workloadFactory,
541 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
542 const armnn::ITensorHandleFactory& tensorHandleFactory)
543{
544 return LogicalBinaryTestHelper<4>(workloadFactory,
545 memoryManager,
546 armnn::LogicalBinaryOperation::LogicalAnd,
547 s_BroadcastBinary3TestData.m_InputShape0,
548 s_BroadcastBinary3TestData.m_InputShape1,
549 s_BroadcastBinary3TestData.m_InputData0,
550 s_BroadcastBinary3TestData.m_InputData1,
551 s_BroadcastBinary3TestData.m_OutputShape,
552 s_BroadcastBinary3TestData.m_OutputAnd,
553 tensorHandleFactory);
554}
555
556// Binary - Or Broadcast
557LayerTestResult<uint8_t, 4> LogicalOrBroadcast3Test(
558 armnn::IWorkloadFactory& workloadFactory,
559 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
560 const armnn::ITensorHandleFactory& tensorHandleFactory)
561{
562 return LogicalBinaryTestHelper<4>(workloadFactory,
563 memoryManager,
564 armnn::LogicalBinaryOperation::LogicalOr,
565 s_BroadcastBinary3TestData.m_InputShape0,
566 s_BroadcastBinary3TestData.m_InputShape1,
567 s_BroadcastBinary3TestData.m_InputData0,
568 s_BroadcastBinary3TestData.m_InputData1,
569 s_BroadcastBinary3TestData.m_OutputShape,
570 s_BroadcastBinary3TestData.m_OutputOr,
571 tensorHandleFactory);
572}