blob: 3e1888cb547a25f34a6bbe6993f5411fb29667a5 [file] [log] [blame]
telsoa014fcda012018-03-09 14:13:49 +00001//
2// Copyright © 2017 Arm Ltd. All rights reserved.
David Beckecb56cd2018-09-05 12:52:57 +01003// SPDX-License-Identifier: MIT
telsoa014fcda012018-03-09 14:13:49 +00004//
arovir0143095f32018-10-09 18:04:24 +01005
Aron Virginas-Tar56055192018-11-12 18:10:43 +00006#include "NeonWorkloadFactoryHelper.hpp"
7
Francis Murtagh4fc3c482019-08-02 13:20:54 +01008#include <aclCommon/ArmComputeTensorUtils.hpp>
Aron Virginas-Tarc9cc8042018-11-01 16:15:57 +00009#include <backendsCommon/MemCopyWorkload.hpp>
Aron Virginas-Tar3b278e92018-10-12 13:00:55 +010010
Aron Virginas-Tarc9cc8042018-11-01 16:15:57 +000011#include <aclCommon/test/CreateWorkloadClNeon.hpp>
Aron Virginas-Tar3b278e92018-10-12 13:00:55 +010012
Aron Virginas-Tarc9cc8042018-11-01 16:15:57 +000013#include <neon/NeonWorkloadFactory.hpp>
14#include <neon/NeonTensorHandle.hpp>
15#include <neon/workloads/NeonWorkloadUtils.hpp>
16#include <neon/workloads/NeonWorkloads.hpp>
telsoa014fcda012018-03-09 14:13:49 +000017
18BOOST_AUTO_TEST_SUITE(CreateWorkloadNeon)
19
20namespace
21{
22
Ellen Norris-Thompson37e68682019-07-15 14:23:30 +010023boost::test_tools::predicate_result CompareIAclTensorHandleShape(IAclTensorHandle* tensorHandle,
24 std::initializer_list<unsigned int> expectedDimensions)
25{
26 return CompareTensorHandleShape<IAclTensorHandle>(tensorHandle, expectedDimensions);
27}
28
Derek Lambertic81855f2019-06-13 17:34:19 +010029bool TestNeonTensorHandleInfo(armnn::IAclTensorHandle* handle, const armnn::TensorInfo& expectedInfo)
telsoa014fcda012018-03-09 14:13:49 +000030{
31 using namespace armnn::armcomputetensorutils;
32
33 const arm_compute::ITensorInfo* handleInfo = handle->GetTensor().info();
34 const arm_compute::TensorInfo expectedAclInfo = BuildArmComputeTensorInfo(expectedInfo);
35
36 if (handleInfo->data_type() != expectedAclInfo.data_type())
37 {
38 return false;
39 }
40
41 if (handleInfo->num_dimensions() != expectedAclInfo.num_dimensions())
42 {
43 return false;
44 }
45
46 if (handleInfo->quantization_info() != expectedAclInfo.quantization_info())
47 {
48 return false;
49 }
50
51 for (std::size_t d = 0; d < expectedAclInfo.num_dimensions(); ++d)
52 {
53 if (handleInfo->dimension(d) != expectedAclInfo.dimension(d))
54 {
55 return false;
56 }
57 }
58
59 return true;
60}
61
62} // namespace
63
Nattapat Chaimanowongd4b70592018-10-12 11:21:49 +010064template <typename armnn::DataType DataType>
telsoa01c577f2c2018-08-31 09:22:23 +010065static void NeonCreateActivationWorkloadTest()
telsoa014fcda012018-03-09 14:13:49 +000066{
67 Graph graph;
Aron Virginas-Tar5caf9072018-11-14 18:35:18 +000068 NeonWorkloadFactory factory =
69 NeonWorkloadFactoryHelper::GetFactory(NeonWorkloadFactoryHelper::GetMemoryManager());
70
Nattapat Chaimanowongd4b70592018-10-12 11:21:49 +010071 auto workload = CreateActivationWorkloadTest<NeonActivationWorkload, DataType>(factory, graph);
telsoa014fcda012018-03-09 14:13:49 +000072
telsoa01c577f2c2018-08-31 09:22:23 +010073 // Checks that inputs/outputs are as we expect them (see definition of CreateActivationWorkloadTest).
telsoa014fcda012018-03-09 14:13:49 +000074 ActivationQueueDescriptor queueDescriptor = workload->GetData();
Derek Lambertic81855f2019-06-13 17:34:19 +010075 auto inputHandle = boost::polymorphic_downcast<IAclTensorHandle*>(queueDescriptor.m_Inputs[0]);
76 auto outputHandle = boost::polymorphic_downcast<IAclTensorHandle*>(queueDescriptor.m_Outputs[0]);
telsoa01c577f2c2018-08-31 09:22:23 +010077 BOOST_TEST(TestNeonTensorHandleInfo(inputHandle, TensorInfo({1, 1}, DataType)));
78 BOOST_TEST(TestNeonTensorHandleInfo(outputHandle, TensorInfo({1, 1}, DataType)));
telsoa014fcda012018-03-09 14:13:49 +000079}
80
telsoa01c577f2c2018-08-31 09:22:23 +010081#ifdef __ARM_FEATURE_FP16_VECTOR_ARITHMETIC
82BOOST_AUTO_TEST_CASE(CreateActivationFloat16Workload)
83{
Nattapat Chaimanowongd4b70592018-10-12 11:21:49 +010084 NeonCreateActivationWorkloadTest<DataType::Float16>();
telsoa01c577f2c2018-08-31 09:22:23 +010085}
86#endif
87
arovir019e53a352018-08-31 15:26:35 +010088BOOST_AUTO_TEST_CASE(CreateActivationFloatWorkload)
telsoa01c577f2c2018-08-31 09:22:23 +010089{
Nattapat Chaimanowongd4b70592018-10-12 11:21:49 +010090 NeonCreateActivationWorkloadTest<DataType::Float32>();
telsoa01c577f2c2018-08-31 09:22:23 +010091}
92
David Beckbc392452018-09-10 14:47:28 +010093template <typename WorkloadType,
94 typename DescriptorType,
95 typename LayerType,
96 armnn::DataType DataType>
Éanna Ó Catháind57415d2018-11-28 16:24:38 +000097static void NeonCreateElementwiseWorkloadTest()
telsoa014fcda012018-03-09 14:13:49 +000098{
David Beckbc392452018-09-10 14:47:28 +010099 Graph graph;
Aron Virginas-Tar5caf9072018-11-14 18:35:18 +0000100 NeonWorkloadFactory factory =
101 NeonWorkloadFactoryHelper::GetFactory(NeonWorkloadFactoryHelper::GetMemoryManager());
102
Éanna Ó Catháind57415d2018-11-28 16:24:38 +0000103 auto workload = CreateElementwiseWorkloadTest<WorkloadType, DescriptorType, LayerType, DataType>(factory, graph);
telsoa014fcda012018-03-09 14:13:49 +0000104
David Beckbc392452018-09-10 14:47:28 +0100105 DescriptorType queueDescriptor = workload->GetData();
Derek Lambertic81855f2019-06-13 17:34:19 +0100106 auto inputHandle1 = boost::polymorphic_downcast<IAclTensorHandle*>(queueDescriptor.m_Inputs[0]);
107 auto inputHandle2 = boost::polymorphic_downcast<IAclTensorHandle*>(queueDescriptor.m_Inputs[1]);
108 auto outputHandle = boost::polymorphic_downcast<IAclTensorHandle*>(queueDescriptor.m_Outputs[0]);
telsoa01c577f2c2018-08-31 09:22:23 +0100109 BOOST_TEST(TestNeonTensorHandleInfo(inputHandle1, TensorInfo({2, 3}, DataType)));
110 BOOST_TEST(TestNeonTensorHandleInfo(inputHandle2, TensorInfo({2, 3}, DataType)));
111 BOOST_TEST(TestNeonTensorHandleInfo(outputHandle, TensorInfo({2, 3}, DataType)));
telsoa014fcda012018-03-09 14:13:49 +0000112}
113
telsoa01c577f2c2018-08-31 09:22:23 +0100114#ifdef __ARM_FEATURE_FP16_VECTOR_ARITHMETIC
115BOOST_AUTO_TEST_CASE(CreateAdditionFloat16Workload)
116{
Matthew Bentham955258d2018-12-10 10:48:52 +0000117 NeonCreateElementwiseWorkloadTest<NeonAdditionWorkload,
David Beckbc392452018-09-10 14:47:28 +0100118 AdditionQueueDescriptor,
119 AdditionLayer,
120 DataType::Float16>();
telsoa01c577f2c2018-08-31 09:22:23 +0100121}
122#endif
123
arovir019e53a352018-08-31 15:26:35 +0100124BOOST_AUTO_TEST_CASE(CreateAdditionFloatWorkload)
telsoa01c577f2c2018-08-31 09:22:23 +0100125{
Matthew Bentham955258d2018-12-10 10:48:52 +0000126 NeonCreateElementwiseWorkloadTest<NeonAdditionWorkload,
David Beckbc392452018-09-10 14:47:28 +0100127 AdditionQueueDescriptor,
128 AdditionLayer,
129 DataType::Float32>();
130}
131
132#ifdef __ARM_FEATURE_FP16_VECTOR_ARITHMETIC
133BOOST_AUTO_TEST_CASE(CreateSubtractionFloat16Workload)
134{
Conor Kennedyb99480b2019-03-08 08:24:41 +0000135 NeonCreateElementwiseWorkloadTest<NeonSubtractionWorkload,
David Beckbc392452018-09-10 14:47:28 +0100136 SubtractionQueueDescriptor,
137 SubtractionLayer,
138 DataType::Float16>();
139}
140#endif
141
142BOOST_AUTO_TEST_CASE(CreateSubtractionFloatWorkload)
143{
Conor Kennedyb99480b2019-03-08 08:24:41 +0000144 NeonCreateElementwiseWorkloadTest<NeonSubtractionWorkload,
David Beckbc392452018-09-10 14:47:28 +0100145 SubtractionQueueDescriptor,
146 SubtractionLayer,
147 DataType::Float32>();
148}
149
Conor Kennedyb99480b2019-03-08 08:24:41 +0000150BOOST_AUTO_TEST_CASE(CreateSubtractionUint8Workload)
151{
152 NeonCreateElementwiseWorkloadTest<NeonSubtractionWorkload,
153 SubtractionQueueDescriptor,
154 SubtractionLayer,
Derek Lambertif90c56d2020-01-10 17:14:08 +0000155 DataType::QAsymmU8>();
Conor Kennedyb99480b2019-03-08 08:24:41 +0000156}
157
David Beckbc392452018-09-10 14:47:28 +0100158#ifdef __ARM_FEATURE_FP16_VECTOR_ARITHMETIC
159BOOST_AUTO_TEST_CASE(CreateMultiplicationFloat16Workload)
160{
Conor Kennedyb99480b2019-03-08 08:24:41 +0000161 NeonCreateElementwiseWorkloadTest<NeonMultiplicationWorkload,
David Beckbc392452018-09-10 14:47:28 +0100162 MultiplicationQueueDescriptor,
163 MultiplicationLayer,
164 DataType::Float16>();
165}
166#endif
167
168BOOST_AUTO_TEST_CASE(CreateMultiplicationFloatWorkload)
169{
Conor Kennedyb99480b2019-03-08 08:24:41 +0000170 NeonCreateElementwiseWorkloadTest<NeonMultiplicationWorkload,
David Beckbc392452018-09-10 14:47:28 +0100171 MultiplicationQueueDescriptor,
172 MultiplicationLayer,
173 DataType::Float32>();
telsoa01c577f2c2018-08-31 09:22:23 +0100174}
175
Conor Kennedyb99480b2019-03-08 08:24:41 +0000176BOOST_AUTO_TEST_CASE(CreateMultiplicationUint8Workload)
177{
178 NeonCreateElementwiseWorkloadTest<NeonMultiplicationWorkload,
179 MultiplicationQueueDescriptor,
180 MultiplicationLayer,
Derek Lambertif90c56d2020-01-10 17:14:08 +0000181 DataType::QAsymmU8>();
Conor Kennedyb99480b2019-03-08 08:24:41 +0000182}
183
Pablo Telloe61f0712020-01-23 10:37:17 +0000184BOOST_AUTO_TEST_CASE(CreateDivisionFloatWorkloadTest)
185{
186 NeonCreateElementwiseWorkloadTest<NeonDivisionWorkload,
187 DivisionQueueDescriptor,
188 DivisionLayer,
189 armnn::DataType::Float32>();
190}
191
telsoa01c577f2c2018-08-31 09:22:23 +0100192template <typename BatchNormalizationWorkloadType, typename armnn::DataType DataType>
Nikhil Rajd1340932018-10-18 14:27:50 +0100193static void NeonCreateBatchNormalizationWorkloadTest(DataLayout dataLayout)
telsoa014fcda012018-03-09 14:13:49 +0000194{
Aron Virginas-Tar5caf9072018-11-14 18:35:18 +0000195 Graph graph;
196 NeonWorkloadFactory factory =
197 NeonWorkloadFactoryHelper::GetFactory(NeonWorkloadFactoryHelper::GetMemoryManager());
198
Nikhil Rajd1340932018-10-18 14:27:50 +0100199 auto workload = CreateBatchNormalizationWorkloadTest<BatchNormalizationWorkloadType, DataType>
200 (factory, graph, dataLayout);
telsoa014fcda012018-03-09 14:13:49 +0000201
telsoa01c577f2c2018-08-31 09:22:23 +0100202 // Checks that outputs and inputs are as we expect them (see definition of CreateBatchNormalizationWorkloadTest).
telsoa014fcda012018-03-09 14:13:49 +0000203 BatchNormalizationQueueDescriptor queueDescriptor = workload->GetData();
Derek Lambertic81855f2019-06-13 17:34:19 +0100204 auto inputHandle = boost::polymorphic_downcast<IAclTensorHandle*>(queueDescriptor.m_Inputs[0]);
205 auto outputHandle = boost::polymorphic_downcast<IAclTensorHandle*>(queueDescriptor.m_Outputs[0]);
Nikhil Rajd1340932018-10-18 14:27:50 +0100206
207 TensorShape inputShape = (dataLayout == DataLayout::NCHW) ? TensorShape{2, 3, 4, 4} : TensorShape{2, 4, 4, 3};
208 TensorShape outputShape = (dataLayout == DataLayout::NCHW) ? TensorShape{2, 3, 4, 4} : TensorShape{2, 4, 4, 3};
209
210 BOOST_TEST(TestNeonTensorHandleInfo(inputHandle, TensorInfo(inputShape, DataType)));
211 BOOST_TEST(TestNeonTensorHandleInfo(outputHandle, TensorInfo(outputShape, DataType)));
telsoa014fcda012018-03-09 14:13:49 +0000212}
213
telsoa01c577f2c2018-08-31 09:22:23 +0100214#ifdef __ARM_FEATURE_FP16_VECTOR_ARITHMETIC
Nikhil Rajd1340932018-10-18 14:27:50 +0100215BOOST_AUTO_TEST_CASE(CreateBatchNormalizationFloat16NchwWorkload)
telsoa01c577f2c2018-08-31 09:22:23 +0100216{
Matthew Benthamc48ac8c2018-12-12 16:15:59 +0000217 NeonCreateBatchNormalizationWorkloadTest<NeonBatchNormalizationWorkload, DataType::Float16>(DataLayout::NCHW);
Nikhil Rajd1340932018-10-18 14:27:50 +0100218}
219
220BOOST_AUTO_TEST_CASE(CreateBatchNormalizationFloat16NhwcWorkload)
221{
Matthew Benthamc48ac8c2018-12-12 16:15:59 +0000222 NeonCreateBatchNormalizationWorkloadTest<NeonBatchNormalizationWorkload, DataType::Float16>(DataLayout::NHWC);
telsoa01c577f2c2018-08-31 09:22:23 +0100223}
224#endif
225
Nikhil Rajd1340932018-10-18 14:27:50 +0100226BOOST_AUTO_TEST_CASE(CreateBatchNormalizationFloatNchwWorkload)
telsoa01c577f2c2018-08-31 09:22:23 +0100227{
Matthew Benthamc48ac8c2018-12-12 16:15:59 +0000228 NeonCreateBatchNormalizationWorkloadTest<NeonBatchNormalizationWorkload, DataType::Float32>(DataLayout::NCHW);
Nikhil Rajd1340932018-10-18 14:27:50 +0100229}
230
231BOOST_AUTO_TEST_CASE(CreateBatchNormalizationFloatNhwcWorkload)
232{
Matthew Benthamc48ac8c2018-12-12 16:15:59 +0000233 NeonCreateBatchNormalizationWorkloadTest<NeonBatchNormalizationWorkload, DataType::Float32>(DataLayout::NHWC);
telsoa01c577f2c2018-08-31 09:22:23 +0100234}
235
Nattapat Chaimanowong974b65f2018-10-15 15:07:34 +0100236template <typename armnn::DataType DataType>
Francis Murtagh0d9d4192018-10-09 16:22:33 +0100237static void NeonCreateConvolution2dWorkloadTest(DataLayout dataLayout = DataLayout::NCHW)
telsoa014fcda012018-03-09 14:13:49 +0000238{
Aron Virginas-Tar5caf9072018-11-14 18:35:18 +0000239 Graph graph;
240 NeonWorkloadFactory factory =
241 NeonWorkloadFactoryHelper::GetFactory(NeonWorkloadFactoryHelper::GetMemoryManager());
242
243 auto workload = CreateConvolution2dWorkloadTest<NeonConvolution2dWorkload, DataType>(factory, graph, dataLayout);
Francis Murtagh0d9d4192018-10-09 16:22:33 +0100244
245 TensorShape inputShape = (dataLayout == DataLayout::NCHW) ? TensorShape{2, 3, 8, 16} : TensorShape{2, 8, 16, 3};
246 TensorShape outputShape = (dataLayout == DataLayout::NCHW) ? TensorShape{2, 2, 2, 10} : TensorShape{2, 2, 10, 2};
telsoa014fcda012018-03-09 14:13:49 +0000247
telsoa01c577f2c2018-08-31 09:22:23 +0100248 // Checks that outputs and inputs are as we expect them (see definition of CreateConvolution2dWorkloadTest).
telsoa014fcda012018-03-09 14:13:49 +0000249 Convolution2dQueueDescriptor queueDescriptor = workload->GetData();
Derek Lambertic81855f2019-06-13 17:34:19 +0100250 auto inputHandle = boost::polymorphic_downcast<IAclTensorHandle*>(queueDescriptor.m_Inputs[0]);
251 auto outputHandle = boost::polymorphic_downcast<IAclTensorHandle*>(queueDescriptor.m_Outputs[0]);
Francis Murtagh0d9d4192018-10-09 16:22:33 +0100252 BOOST_TEST(TestNeonTensorHandleInfo(inputHandle, TensorInfo(inputShape, DataType)));
253 BOOST_TEST(TestNeonTensorHandleInfo(outputHandle, TensorInfo(outputShape, DataType)));
telsoa014fcda012018-03-09 14:13:49 +0000254}
255
telsoa01c577f2c2018-08-31 09:22:23 +0100256#ifdef __ARM_FEATURE_FP16_VECTOR_ARITHMETIC
Francis Murtagh0d9d4192018-10-09 16:22:33 +0100257BOOST_AUTO_TEST_CASE(CreateConvolution2dFloat16NchwWorkload)
telsoa01c577f2c2018-08-31 09:22:23 +0100258{
Nattapat Chaimanowong974b65f2018-10-15 15:07:34 +0100259 NeonCreateConvolution2dWorkloadTest<DataType::Float16>();
telsoa01c577f2c2018-08-31 09:22:23 +0100260}
telsoa01c577f2c2018-08-31 09:22:23 +0100261
Francis Murtagh0d9d4192018-10-09 16:22:33 +0100262BOOST_AUTO_TEST_CASE(CreateConvolution2dFloat16NhwcWorkload)
263{
Nattapat Chaimanowong974b65f2018-10-15 15:07:34 +0100264 NeonCreateConvolution2dWorkloadTest<DataType::Float16>(DataLayout::NHWC);
Francis Murtagh0d9d4192018-10-09 16:22:33 +0100265}
266
267#endif
268BOOST_AUTO_TEST_CASE(CreateConvolution2dFloatNchwWorkload)
telsoa01c577f2c2018-08-31 09:22:23 +0100269{
Nattapat Chaimanowong974b65f2018-10-15 15:07:34 +0100270 NeonCreateConvolution2dWorkloadTest<DataType::Float32>();
telsoa01c577f2c2018-08-31 09:22:23 +0100271}
272
Francis Murtagh0d9d4192018-10-09 16:22:33 +0100273BOOST_AUTO_TEST_CASE(CreateConvolution2dFloatNhwcWorkload)
274{
Nattapat Chaimanowong974b65f2018-10-15 15:07:34 +0100275 NeonCreateConvolution2dWorkloadTest<DataType::Float32>(DataLayout::NHWC);
Francis Murtagh0d9d4192018-10-09 16:22:33 +0100276}
277
Nattapat Chaimanowong77140882018-10-17 11:12:19 +0100278template <typename armnn::DataType DataType>
Nikhil Rajcec6b652018-10-12 13:51:57 +0100279static void NeonCreateDepthWiseConvolutionWorkloadTest(DataLayout dataLayout)
280{
281 Graph graph;
Aron Virginas-Tar5caf9072018-11-14 18:35:18 +0000282 NeonWorkloadFactory factory =
283 NeonWorkloadFactoryHelper::GetFactory(NeonWorkloadFactoryHelper::GetMemoryManager());
Nikhil Rajcec6b652018-10-12 13:51:57 +0100284
Nattapat Chaimanowong77140882018-10-17 11:12:19 +0100285 auto workload = CreateDepthwiseConvolution2dWorkloadTest<NeonDepthwiseConvolutionWorkload,
Nikhil Rajcec6b652018-10-12 13:51:57 +0100286 DataType>(factory, graph, dataLayout);
287
288 // Checks that inputs/outputs are as we expect them (see definition of CreateNormalizationWorkloadTest).
289 DepthwiseConvolution2dQueueDescriptor queueDescriptor = workload->GetData();
Derek Lambertic81855f2019-06-13 17:34:19 +0100290 auto inputHandle = boost::polymorphic_downcast<IAclTensorHandle*>(queueDescriptor.m_Inputs[0]);
291 auto outputHandle = boost::polymorphic_downcast<IAclTensorHandle*>(queueDescriptor.m_Outputs[0]);
Nikhil Rajcec6b652018-10-12 13:51:57 +0100292
Mike Kellydb482882019-06-14 12:35:24 +0100293 TensorShape inputShape = (dataLayout == DataLayout::NCHW) ? std::initializer_list<unsigned int>({ 2, 2, 5, 5 })
294 : std::initializer_list<unsigned int>({ 2, 5, 5, 2 });
295 TensorShape outputShape = (dataLayout == DataLayout::NCHW) ? std::initializer_list<unsigned int>({ 2, 2, 5, 5 })
296 : std::initializer_list<unsigned int>({ 2, 5, 5, 2 });
Nikhil Rajcec6b652018-10-12 13:51:57 +0100297
298 BOOST_TEST(TestNeonTensorHandleInfo(inputHandle, TensorInfo(inputShape, DataType)));
299 BOOST_TEST(TestNeonTensorHandleInfo(outputHandle, TensorInfo(outputShape, DataType)));
300}
301
302BOOST_AUTO_TEST_CASE(CreateDepthWiseConvolution2dFloat32NhwcWorkload)
303{
Nattapat Chaimanowong77140882018-10-17 11:12:19 +0100304 NeonCreateDepthWiseConvolutionWorkloadTest<DataType::Float32>(DataLayout::NHWC);
Nikhil Rajcec6b652018-10-12 13:51:57 +0100305}
306
307#ifdef __ARM_FEATURE_FP16_VECTOR_ARITHMETIC
308BOOST_AUTO_TEST_CASE(CreateDepthWiseConvolution2dFloat16NhwcWorkload)
309{
Nattapat Chaimanowong77140882018-10-17 11:12:19 +0100310 NeonCreateDepthWiseConvolutionWorkloadTest<DataType::Float16>(DataLayout::NHWC);
Nikhil Rajcec6b652018-10-12 13:51:57 +0100311}
312#endif
313
telsoa01c577f2c2018-08-31 09:22:23 +0100314template <typename FullyConnectedWorkloadType, typename armnn::DataType DataType>
315static void NeonCreateFullyConnectedWorkloadTest()
telsoa014fcda012018-03-09 14:13:49 +0000316{
Aron Virginas-Tar5caf9072018-11-14 18:35:18 +0000317 Graph graph;
318 NeonWorkloadFactory factory =
319 NeonWorkloadFactoryHelper::GetFactory(NeonWorkloadFactoryHelper::GetMemoryManager());
320
321 auto workload = CreateFullyConnectedWorkloadTest<FullyConnectedWorkloadType, DataType>(factory, graph);
telsoa014fcda012018-03-09 14:13:49 +0000322
telsoa01c577f2c2018-08-31 09:22:23 +0100323 // Checks that outputs and inputs are as we expect them (see definition of CreateFullyConnectedWorkloadTest).
telsoa014fcda012018-03-09 14:13:49 +0000324 FullyConnectedQueueDescriptor queueDescriptor = workload->GetData();
Derek Lambertic81855f2019-06-13 17:34:19 +0100325 auto inputHandle = boost::polymorphic_downcast<IAclTensorHandle*>(queueDescriptor.m_Inputs[0]);
326 auto outputHandle = boost::polymorphic_downcast<IAclTensorHandle*>(queueDescriptor.m_Outputs[0]);
telsoa01c577f2c2018-08-31 09:22:23 +0100327 BOOST_TEST(TestNeonTensorHandleInfo(inputHandle, TensorInfo({3, 1, 4, 5}, DataType)));
328 BOOST_TEST(TestNeonTensorHandleInfo(outputHandle, TensorInfo({3, 7}, DataType)));
telsoa014fcda012018-03-09 14:13:49 +0000329}
330
telsoa01c577f2c2018-08-31 09:22:23 +0100331#ifdef __ARM_FEATURE_FP16_VECTOR_ARITHMETIC
332BOOST_AUTO_TEST_CASE(CreateFullyConnectedFloat16Workload)
333{
kevmay01e448be32018-09-26 10:21:55 +0100334 NeonCreateFullyConnectedWorkloadTest<NeonFullyConnectedWorkload, DataType::Float16>();
telsoa01c577f2c2018-08-31 09:22:23 +0100335}
336#endif
337
arovir019e53a352018-08-31 15:26:35 +0100338BOOST_AUTO_TEST_CASE(CreateFullyConnectedFloatWorkload)
telsoa01c577f2c2018-08-31 09:22:23 +0100339{
kevmay01e448be32018-09-26 10:21:55 +0100340 NeonCreateFullyConnectedWorkloadTest<NeonFullyConnectedWorkload, DataType::Float32>();
telsoa01c577f2c2018-08-31 09:22:23 +0100341}
342
telsoa01c577f2c2018-08-31 09:22:23 +0100343template <typename NormalizationWorkloadType, typename armnn::DataType DataType>
narpra0155a97bc2018-10-02 14:35:53 +0100344static void NeonCreateNormalizationWorkloadTest(DataLayout dataLayout)
telsoa014fcda012018-03-09 14:13:49 +0000345{
narpra0155a97bc2018-10-02 14:35:53 +0100346 Graph graph;
Aron Virginas-Tar5caf9072018-11-14 18:35:18 +0000347 NeonWorkloadFactory factory =
348 NeonWorkloadFactoryHelper::GetFactory(NeonWorkloadFactoryHelper::GetMemoryManager());
349
narpra0155a97bc2018-10-02 14:35:53 +0100350 auto workload = CreateNormalizationWorkloadTest<NormalizationWorkloadType, DataType>(factory, graph, dataLayout);
telsoa014fcda012018-03-09 14:13:49 +0000351
telsoa01c577f2c2018-08-31 09:22:23 +0100352 // Checks that outputs and inputs are as we expect them (see definition of CreateNormalizationWorkloadTest).
telsoa014fcda012018-03-09 14:13:49 +0000353 NormalizationQueueDescriptor queueDescriptor = workload->GetData();
Derek Lambertic81855f2019-06-13 17:34:19 +0100354 auto inputHandle = boost::polymorphic_downcast<IAclTensorHandle*>(queueDescriptor.m_Inputs[0]);
355 auto outputHandle = boost::polymorphic_downcast<IAclTensorHandle*>(queueDescriptor.m_Outputs[0]);
Matteo Martincigha160b242018-10-18 10:33:23 +0100356
357 TensorShape inputShape = (dataLayout == DataLayout::NCHW) ? TensorShape{3, 5, 5, 1} : TensorShape{3, 1, 5, 5};
358 TensorShape outputShape = (dataLayout == DataLayout::NCHW) ? TensorShape{3, 5, 5, 1} : TensorShape{3, 1, 5, 5};
359
360 BOOST_TEST(TestNeonTensorHandleInfo(inputHandle, TensorInfo(inputShape, DataType)));
361 BOOST_TEST(TestNeonTensorHandleInfo(outputHandle, TensorInfo(outputShape, DataType)));
telsoa014fcda012018-03-09 14:13:49 +0000362}
363
telsoa01c577f2c2018-08-31 09:22:23 +0100364#ifdef __ARM_FEATURE_FP16_VECTOR_ARITHMETIC
narpra0155a97bc2018-10-02 14:35:53 +0100365BOOST_AUTO_TEST_CASE(CreateNormalizationFloat16NchwWorkload)
telsoa01c577f2c2018-08-31 09:22:23 +0100366{
narpra0155a97bc2018-10-02 14:35:53 +0100367 NeonCreateNormalizationWorkloadTest<NeonNormalizationFloatWorkload, DataType::Float16>(DataLayout::NCHW);
368}
369
370BOOST_AUTO_TEST_CASE(CreateNormalizationFloat16NhwcWorkload)
371{
372 NeonCreateNormalizationWorkloadTest<NeonNormalizationFloatWorkload, DataType::Float16>(DataLayout::NHWC);
telsoa01c577f2c2018-08-31 09:22:23 +0100373}
374#endif
375
narpra0155a97bc2018-10-02 14:35:53 +0100376BOOST_AUTO_TEST_CASE(CreateNormalizationFloatNchwWorkload)
telsoa01c577f2c2018-08-31 09:22:23 +0100377{
narpra0155a97bc2018-10-02 14:35:53 +0100378 NeonCreateNormalizationWorkloadTest<NeonNormalizationFloatWorkload, DataType::Float32>(DataLayout::NCHW);
telsoa01c577f2c2018-08-31 09:22:23 +0100379}
380
narpra0155a97bc2018-10-02 14:35:53 +0100381BOOST_AUTO_TEST_CASE(CreateNormalizationFloatNhwcWorkload)
382{
383 NeonCreateNormalizationWorkloadTest<NeonNormalizationFloatWorkload, DataType::Float32>(DataLayout::NHWC);
384}
385
386
Nattapat Chaimanowong5d2e7002018-10-12 16:03:56 +0100387template <typename armnn::DataType DataType>
Nina Drozdb48e6862018-10-09 12:09:56 +0100388static void NeonCreatePooling2dWorkloadTest(DataLayout dataLayout = DataLayout::NCHW)
telsoa014fcda012018-03-09 14:13:49 +0000389{
Aron Virginas-Tar5caf9072018-11-14 18:35:18 +0000390 Graph graph;
391 NeonWorkloadFactory factory =
392 NeonWorkloadFactoryHelper::GetFactory(NeonWorkloadFactoryHelper::GetMemoryManager());
393
394 auto workload = CreatePooling2dWorkloadTest<NeonPooling2dWorkload, DataType>(factory, graph, dataLayout);
Nina Drozdb48e6862018-10-09 12:09:56 +0100395
396 TensorShape inputShape = (dataLayout == DataLayout::NCHW) ? TensorShape{3, 2, 5, 5} : TensorShape{3, 5, 5, 2};
397 TensorShape outputShape = (dataLayout == DataLayout::NCHW) ? TensorShape{3, 2, 2, 4} : TensorShape{3, 2, 4, 2};
telsoa014fcda012018-03-09 14:13:49 +0000398
telsoa01c577f2c2018-08-31 09:22:23 +0100399 // Checks that outputs and inputs are as we expect them (see definition of CreatePooling2dWorkloadTest).
telsoa014fcda012018-03-09 14:13:49 +0000400 Pooling2dQueueDescriptor queueDescriptor = workload->GetData();
Derek Lambertic81855f2019-06-13 17:34:19 +0100401 auto inputHandle = boost::polymorphic_downcast<IAclTensorHandle*>(queueDescriptor.m_Inputs[0]);
402 auto outputHandle = boost::polymorphic_downcast<IAclTensorHandle*>(queueDescriptor.m_Outputs[0]);
Nina Drozdb48e6862018-10-09 12:09:56 +0100403 BOOST_TEST(TestNeonTensorHandleInfo(inputHandle, TensorInfo(inputShape, DataType)));
404 BOOST_TEST(TestNeonTensorHandleInfo(outputHandle, TensorInfo(outputShape, DataType)));
telsoa014fcda012018-03-09 14:13:49 +0000405}
406
telsoa01c577f2c2018-08-31 09:22:23 +0100407#ifdef __ARM_FEATURE_FP16_VECTOR_ARITHMETIC
408BOOST_AUTO_TEST_CASE(CreatePooling2dFloat16Workload)
409{
Nattapat Chaimanowong5d2e7002018-10-12 16:03:56 +0100410 NeonCreatePooling2dWorkloadTest<DataType::Float16>();
telsoa01c577f2c2018-08-31 09:22:23 +0100411}
412#endif
413
Nina Drozdb48e6862018-10-09 12:09:56 +0100414BOOST_AUTO_TEST_CASE(CreatePooling2dFloatNchwWorkload)
telsoa01c577f2c2018-08-31 09:22:23 +0100415{
Nattapat Chaimanowong5d2e7002018-10-12 16:03:56 +0100416 NeonCreatePooling2dWorkloadTest<DataType::Float32>(DataLayout::NCHW);
telsoa01c577f2c2018-08-31 09:22:23 +0100417}
418
Nina Drozdb48e6862018-10-09 12:09:56 +0100419BOOST_AUTO_TEST_CASE(CreatePooling2dFloatNhwcWorkload)
telsoa01c577f2c2018-08-31 09:22:23 +0100420{
Nattapat Chaimanowong5d2e7002018-10-12 16:03:56 +0100421 NeonCreatePooling2dWorkloadTest<DataType::Float32>(DataLayout::NHWC);
Nina Drozdb48e6862018-10-09 12:09:56 +0100422}
423
424BOOST_AUTO_TEST_CASE(CreatePooling2dUint8NchwWorkload)
425{
Derek Lambertif90c56d2020-01-10 17:14:08 +0000426 NeonCreatePooling2dWorkloadTest<DataType::QAsymmU8>(DataLayout::NCHW);
Nina Drozdb48e6862018-10-09 12:09:56 +0100427}
428
429BOOST_AUTO_TEST_CASE(CreatePooling2dUint8NhwcWorkload)
430{
Derek Lambertif90c56d2020-01-10 17:14:08 +0000431 NeonCreatePooling2dWorkloadTest<DataType::QAsymmU8>(DataLayout::NHWC);
telsoa01c577f2c2018-08-31 09:22:23 +0100432}
433
Nikhil Raj9b461482019-07-03 15:58:31 +0100434static void NeonCreatePreluWorkloadTest(const armnn::TensorShape& inputShape,
435 const armnn::TensorShape& alphaShape,
436 const armnn::TensorShape& outputShape,
437 armnn::DataType dataType)
438{
439 Graph graph;
440 NeonWorkloadFactory factory =
441 NeonWorkloadFactoryHelper::GetFactory(NeonWorkloadFactoryHelper::GetMemoryManager());
442
443 auto workload = CreatePreluWorkloadTest<NeonPreluWorkload>(factory,
444 graph,
445 inputShape,
446 alphaShape,
447 outputShape,
448 dataType);
449
450 // Checks that outputs and inputs are as we expect them (see definition of CreateReshapeWorkloadTest).
451 PreluQueueDescriptor queueDescriptor = workload->GetData();
452 auto inputHandle = boost::polymorphic_downcast<IAclTensorHandle*>(queueDescriptor.m_Inputs[0]);
453 auto alphaHandle = boost::polymorphic_downcast<IAclTensorHandle*>(queueDescriptor.m_Inputs[1]);
454 auto outputHandle = boost::polymorphic_downcast<IAclTensorHandle*>(queueDescriptor.m_Outputs[0]);
455 BOOST_TEST(TestNeonTensorHandleInfo(inputHandle, TensorInfo(inputShape, dataType)));
456 BOOST_TEST(TestNeonTensorHandleInfo(alphaHandle, TensorInfo(alphaShape, dataType)));
457 BOOST_TEST(TestNeonTensorHandleInfo(outputHandle, TensorInfo(outputShape, dataType)));
458}
459
460#ifdef __ARM_FEATURE_FP16_VECTOR_ARITHMETIC
461 BOOST_AUTO_TEST_CASE(CreatePreluFloat16Workload)
462{
463 NeonCreatePreluWorkloadTest({ 1, 4, 1, 2 }, { 5, 4, 3, 1 }, { 5, 4, 3, 2 }, DataType::Float16);
464}
465#endif
466
467BOOST_AUTO_TEST_CASE(CreatePreluFloatWorkload)
468{
469 NeonCreatePreluWorkloadTest({ 1, 4, 1, 2 }, { 5, 4, 3, 1 }, { 5, 4, 3, 2 }, DataType::Float32);
470}
471
472BOOST_AUTO_TEST_CASE(CreatePreluUint8Workload)
473{
Derek Lambertif90c56d2020-01-10 17:14:08 +0000474 NeonCreatePreluWorkloadTest({ 1, 4, 1, 2 }, { 5, 4, 3, 1 }, { 5, 4, 3, 2 }, DataType::QAsymmU8);
Nikhil Raj9b461482019-07-03 15:58:31 +0100475}
476
Nattapat Chaimanowongcce11fc2018-10-12 16:30:56 +0100477template <typename armnn::DataType DataType>
telsoa01c577f2c2018-08-31 09:22:23 +0100478static void NeonCreateReshapeWorkloadTest()
telsoa014fcda012018-03-09 14:13:49 +0000479{
Aron Virginas-Tar5caf9072018-11-14 18:35:18 +0000480 Graph graph;
481 NeonWorkloadFactory factory =
482 NeonWorkloadFactoryHelper::GetFactory(NeonWorkloadFactoryHelper::GetMemoryManager());
483
484 auto workload = CreateReshapeWorkloadTest<NeonReshapeWorkload, DataType>(factory, graph);
telsoa014fcda012018-03-09 14:13:49 +0000485
telsoa01c577f2c2018-08-31 09:22:23 +0100486 // Checks that outputs and inputs are as we expect them (see definition of CreateReshapeWorkloadTest).
telsoa014fcda012018-03-09 14:13:49 +0000487 ReshapeQueueDescriptor queueDescriptor = workload->GetData();
Derek Lambertic81855f2019-06-13 17:34:19 +0100488 auto inputHandle = boost::polymorphic_downcast<IAclTensorHandle*>(queueDescriptor.m_Inputs[0]);
489 auto outputHandle = boost::polymorphic_downcast<IAclTensorHandle*>(queueDescriptor.m_Outputs[0]);
telsoa01c577f2c2018-08-31 09:22:23 +0100490 BOOST_TEST(TestNeonTensorHandleInfo(inputHandle, TensorInfo({4, 1}, DataType)));
491 BOOST_TEST(TestNeonTensorHandleInfo(outputHandle, TensorInfo({1, 4}, DataType)));
telsoa014fcda012018-03-09 14:13:49 +0000492}
493
telsoa01c577f2c2018-08-31 09:22:23 +0100494#ifdef __ARM_FEATURE_FP16_VECTOR_ARITHMETIC
495BOOST_AUTO_TEST_CASE(CreateReshapeFloat16Workload)
496{
Nattapat Chaimanowongcce11fc2018-10-12 16:30:56 +0100497 NeonCreateReshapeWorkloadTest<DataType::Float16>();
telsoa01c577f2c2018-08-31 09:22:23 +0100498}
499#endif
500
arovir019e53a352018-08-31 15:26:35 +0100501BOOST_AUTO_TEST_CASE(CreateReshapeFloatWorkload)
telsoa014fcda012018-03-09 14:13:49 +0000502{
Nattapat Chaimanowongcce11fc2018-10-12 16:30:56 +0100503 NeonCreateReshapeWorkloadTest<DataType::Float32>();
telsoa014fcda012018-03-09 14:13:49 +0000504}
505
506BOOST_AUTO_TEST_CASE(CreateReshapeUint8Workload)
507{
Derek Lambertif90c56d2020-01-10 17:14:08 +0000508 NeonCreateReshapeWorkloadTest<DataType::QAsymmU8>();
telsoa014fcda012018-03-09 14:13:49 +0000509}
510
Ellen Norris-Thompson37e68682019-07-15 14:23:30 +0100511template <typename ResizeWorkloadType, armnn::DataType DataType>
512static void NeonCreateResizeWorkloadTest(DataLayout dataLayout)
513{
514 Graph graph;
515 NeonWorkloadFactory factory =
516 NeonWorkloadFactoryHelper::GetFactory(NeonWorkloadFactoryHelper::GetMemoryManager());
517 auto workload = CreateResizeBilinearWorkloadTest<ResizeWorkloadType, DataType>(factory, graph, dataLayout);
518
519 auto queueDescriptor = workload->GetData();
520
521 auto inputHandle = boost::polymorphic_downcast<IAclTensorHandle*>(queueDescriptor.m_Inputs[0]);
522 auto outputHandle = boost::polymorphic_downcast<IAclTensorHandle*>(queueDescriptor.m_Outputs[0]);
523
524 switch (dataLayout)
525 {
526 case DataLayout::NHWC:
527 BOOST_TEST(CompareIAclTensorHandleShape(inputHandle, { 2, 4, 4, 3 }));
528 BOOST_TEST(CompareIAclTensorHandleShape(outputHandle, { 2, 2, 2, 3 }));
529 break;
530 case DataLayout::NCHW:
531 default:
532 BOOST_TEST(CompareIAclTensorHandleShape(inputHandle, { 2, 3, 4, 4 }));
533 BOOST_TEST(CompareIAclTensorHandleShape(outputHandle, { 2, 3, 2, 2 }));
534 }
535}
536
537BOOST_AUTO_TEST_CASE(CreateResizeFloat32NchwWorkload)
538{
539 NeonCreateResizeWorkloadTest<NeonResizeWorkload, armnn::DataType::Float32>(DataLayout::NCHW);
540}
541
542BOOST_AUTO_TEST_CASE(CreateResizeUint8NchwWorkload)
543{
Derek Lambertif90c56d2020-01-10 17:14:08 +0000544 NeonCreateResizeWorkloadTest<NeonResizeWorkload, armnn::DataType::QAsymmU8>(DataLayout::NCHW);
Ellen Norris-Thompson37e68682019-07-15 14:23:30 +0100545}
546
547BOOST_AUTO_TEST_CASE(CreateResizeFloat32NhwcWorkload)
548{
549 NeonCreateResizeWorkloadTest<NeonResizeWorkload, armnn::DataType::Float32>(DataLayout::NHWC);
550}
551
552BOOST_AUTO_TEST_CASE(CreateResizeUint8NhwcWorkload)
553{
Derek Lambertif90c56d2020-01-10 17:14:08 +0000554 NeonCreateResizeWorkloadTest<NeonResizeWorkload, armnn::DataType::QAsymmU8>(DataLayout::NHWC);
Ellen Norris-Thompson37e68682019-07-15 14:23:30 +0100555}
556
telsoa01c577f2c2018-08-31 09:22:23 +0100557template <typename SoftmaxWorkloadType, typename armnn::DataType DataType>
558static void NeonCreateSoftmaxWorkloadTest()
telsoa014fcda012018-03-09 14:13:49 +0000559{
Aron Virginas-Tar5caf9072018-11-14 18:35:18 +0000560 Graph graph;
561 NeonWorkloadFactory factory =
562 NeonWorkloadFactoryHelper::GetFactory(NeonWorkloadFactoryHelper::GetMemoryManager());
563
telsoa01c577f2c2018-08-31 09:22:23 +0100564 auto workload = CreateSoftmaxWorkloadTest<SoftmaxWorkloadType, DataType>(factory, graph);
telsoa014fcda012018-03-09 14:13:49 +0000565
telsoa01c577f2c2018-08-31 09:22:23 +0100566 // Checks that outputs and inputs are as we expect them (see definition of CreateSoftmaxWorkloadTest).
telsoa014fcda012018-03-09 14:13:49 +0000567 SoftmaxQueueDescriptor queueDescriptor = workload->GetData();
Derek Lambertic81855f2019-06-13 17:34:19 +0100568 auto inputHandle = boost::polymorphic_downcast<IAclTensorHandle*>(queueDescriptor.m_Inputs[0]);
569 auto outputHandle = boost::polymorphic_downcast<IAclTensorHandle*>(queueDescriptor.m_Outputs[0]);
telsoa01c577f2c2018-08-31 09:22:23 +0100570 BOOST_TEST(TestNeonTensorHandleInfo(inputHandle, TensorInfo({4, 1}, DataType)));
571 BOOST_TEST(TestNeonTensorHandleInfo(outputHandle, TensorInfo({4, 1}, DataType)));
572}
573
574#ifdef __ARM_FEATURE_FP16_VECTOR_ARITHMETIC
575BOOST_AUTO_TEST_CASE(CreateSoftmaxFloat16Workload)
576{
arovir019e53a352018-08-31 15:26:35 +0100577 NeonCreateSoftmaxWorkloadTest<NeonSoftmaxFloatWorkload, DataType::Float16>();
telsoa01c577f2c2018-08-31 09:22:23 +0100578}
579#endif
580
arovir019e53a352018-08-31 15:26:35 +0100581BOOST_AUTO_TEST_CASE(CreateSoftmaxFloatWorkload)
telsoa01c577f2c2018-08-31 09:22:23 +0100582{
arovir019e53a352018-08-31 15:26:35 +0100583 NeonCreateSoftmaxWorkloadTest<NeonSoftmaxFloatWorkload, DataType::Float32>();
telsoa014fcda012018-03-09 14:13:49 +0000584}
585
Ellen Norris-Thompson29794572019-06-26 16:40:36 +0100586template <typename SpaceToDepthWorkloadType, typename armnn::DataType DataType>
587static void NeonSpaceToDepthWorkloadTest()
588{
589 Graph graph;
590 NeonWorkloadFactory factory =
591 NeonWorkloadFactoryHelper::GetFactory(NeonWorkloadFactoryHelper::GetMemoryManager());
592
593 auto workload = CreateSpaceToDepthWorkloadTest<SpaceToDepthWorkloadType, DataType>(factory, graph);
594
595 SpaceToDepthQueueDescriptor queueDescriptor = workload->GetData();
596 auto inputHandle = boost::polymorphic_downcast<IAclTensorHandle*>(queueDescriptor.m_Inputs[0]);
597 auto outputHandle = boost::polymorphic_downcast<IAclTensorHandle*>(queueDescriptor.m_Outputs[0]);
598
599 BOOST_TEST(TestNeonTensorHandleInfo(inputHandle, TensorInfo({ 1, 2, 2, 1 }, DataType)));
600 BOOST_TEST(TestNeonTensorHandleInfo(outputHandle, TensorInfo({ 1, 1, 1, 4 }, DataType)));
601}
602
603BOOST_AUTO_TEST_CASE(CreateSpaceToDepthFloat32Workload)
604{
605 NeonSpaceToDepthWorkloadTest<NeonSpaceToDepthWorkload, armnn::DataType::Float32>();
606}
607
608BOOST_AUTO_TEST_CASE(CreateSpaceToDepthFloat16Workload)
609{
610 NeonSpaceToDepthWorkloadTest<NeonSpaceToDepthWorkload, armnn::DataType::Float16>();
611}
612
613BOOST_AUTO_TEST_CASE(CreateSpaceToDepthQAsymm8Workload)
614{
Derek Lambertif90c56d2020-01-10 17:14:08 +0000615 NeonSpaceToDepthWorkloadTest<NeonSpaceToDepthWorkload, armnn::DataType::QAsymmU8>();
Ellen Norris-Thompson29794572019-06-26 16:40:36 +0100616}
617
618BOOST_AUTO_TEST_CASE(CreateSpaceToDepthQSymm16Workload)
619{
Derek Lambertif90c56d2020-01-10 17:14:08 +0000620 NeonSpaceToDepthWorkloadTest<NeonSpaceToDepthWorkload, armnn::DataType::QSymmS16>();
Ellen Norris-Thompson29794572019-06-26 16:40:36 +0100621}
622
telsoa014fcda012018-03-09 14:13:49 +0000623BOOST_AUTO_TEST_CASE(CreateSplitterWorkload)
624{
625 Graph graph;
Aron Virginas-Tar5caf9072018-11-14 18:35:18 +0000626 NeonWorkloadFactory factory =
627 NeonWorkloadFactoryHelper::GetFactory(NeonWorkloadFactoryHelper::GetMemoryManager());
628
Nattapat Chaimanowong14766d72018-10-12 15:09:53 +0100629 auto workload = CreateSplitterWorkloadTest<NeonSplitterWorkload, DataType::Float32>(factory, graph);
telsoa014fcda012018-03-09 14:13:49 +0000630
telsoa01c577f2c2018-08-31 09:22:23 +0100631 // Checks that outputs are as we expect them (see definition of CreateSplitterWorkloadTest).
telsoa014fcda012018-03-09 14:13:49 +0000632 SplitterQueueDescriptor queueDescriptor = workload->GetData();
Derek Lambertic81855f2019-06-13 17:34:19 +0100633 auto inputHandle = boost::polymorphic_downcast<IAclTensorHandle*>(queueDescriptor.m_Inputs[0]);
surmeh013537c2c2018-05-18 16:31:43 +0100634 BOOST_TEST(TestNeonTensorHandleInfo(inputHandle, TensorInfo({5, 7, 7}, DataType::Float32)));
635
Derek Lambertic81855f2019-06-13 17:34:19 +0100636 auto outputHandle0 = boost::polymorphic_downcast<IAclTensorHandle*>(queueDescriptor.m_Outputs[0]);
surmeh013537c2c2018-05-18 16:31:43 +0100637 BOOST_TEST(TestNeonTensorHandleInfo(outputHandle0, TensorInfo({1, 7, 7}, DataType::Float32)));
638
Derek Lambertic81855f2019-06-13 17:34:19 +0100639 auto outputHandle1 = boost::polymorphic_downcast<IAclTensorHandle*>(queueDescriptor.m_Outputs[1]);
surmeh013537c2c2018-05-18 16:31:43 +0100640 BOOST_TEST(TestNeonTensorHandleInfo(outputHandle1, TensorInfo({2, 7, 7}, DataType::Float32)));
641
Derek Lambertic81855f2019-06-13 17:34:19 +0100642 auto outputHandle2 = boost::polymorphic_downcast<IAclTensorHandle*>(queueDescriptor.m_Outputs[2]);
surmeh013537c2c2018-05-18 16:31:43 +0100643 BOOST_TEST(TestNeonTensorHandleInfo(outputHandle2, TensorInfo({2, 7, 7}, DataType::Float32)));
telsoa014fcda012018-03-09 14:13:49 +0000644}
645
Jim Flynne242f2d2019-05-22 14:24:13 +0100646BOOST_AUTO_TEST_CASE(CreateSplitterConcat)
telsoa014fcda012018-03-09 14:13:49 +0000647{
telsoa01c577f2c2018-08-31 09:22:23 +0100648 // Tests that it is possible to decide which output of the splitter layer
Jim Flynne242f2d2019-05-22 14:24:13 +0100649 // should be lined to which input of the concat layer.
telsoa01c577f2c2018-08-31 09:22:23 +0100650 // We tested that is is possible to specify 0th output
Jim Flynne242f2d2019-05-22 14:24:13 +0100651 // of the splitter to be the 1st input to the concat, and the 1st output of the splitter to be 0th input
652 // of the concat.
telsoa014fcda012018-03-09 14:13:49 +0000653
654 Graph graph;
Aron Virginas-Tar5caf9072018-11-14 18:35:18 +0000655 NeonWorkloadFactory factory =
656 NeonWorkloadFactoryHelper::GetFactory(NeonWorkloadFactoryHelper::GetMemoryManager());
telsoa014fcda012018-03-09 14:13:49 +0000657
658 auto workloads =
Jim Flynne242f2d2019-05-22 14:24:13 +0100659 CreateSplitterConcatWorkloadTest<NeonSplitterWorkload, NeonConcatWorkload,
telsoa01c577f2c2018-08-31 09:22:23 +0100660 DataType::Float32>(factory, graph);
telsoa014fcda012018-03-09 14:13:49 +0000661
662 auto wlSplitter = std::move(workloads.first);
Jim Flynne242f2d2019-05-22 14:24:13 +0100663 auto wlConcat = std::move(workloads.second);
telsoa014fcda012018-03-09 14:13:49 +0000664
telsoa01c577f2c2018-08-31 09:22:23 +0100665 //Checks that the index of inputs/outputs matches what we declared on InputDescriptor construction.
Derek Lambertic81855f2019-06-13 17:34:19 +0100666 armnn::IAclTensorHandle* sOut0 = dynamic_cast<armnn::IAclTensorHandle*>(wlSplitter->GetData().m_Outputs[0]);
667 armnn::IAclTensorHandle* sOut1 = dynamic_cast<armnn::IAclTensorHandle*>(wlSplitter->GetData().m_Outputs[1]);
668 armnn::IAclTensorHandle* mIn0 = dynamic_cast<armnn::IAclTensorHandle*>(wlConcat->GetData().m_Inputs[0]);
669 armnn::IAclTensorHandle* mIn1 = dynamic_cast<armnn::IAclTensorHandle*>(wlConcat->GetData().m_Inputs[1]);
telsoa014fcda012018-03-09 14:13:49 +0000670
671 BOOST_TEST(sOut0);
672 BOOST_TEST(sOut1);
673 BOOST_TEST(mIn0);
674 BOOST_TEST(mIn1);
675
676 bool validDataPointers = (sOut0 == mIn1) && (sOut1 == mIn0);
677
678 BOOST_TEST(validDataPointers);
679}
680
681BOOST_AUTO_TEST_CASE(CreateSingleOutputMultipleInputs)
682{
telsoa01c577f2c2018-08-31 09:22:23 +0100683 // Tests that it is possible to assign multiple (two) different layers to each of the outputs of a splitter layer.
684 // We created a splitter with two outputs. That each of those outputs is used by two different activation layers
telsoa014fcda012018-03-09 14:13:49 +0000685
686 Graph graph;
Aron Virginas-Tar5caf9072018-11-14 18:35:18 +0000687 NeonWorkloadFactory factory =
688 NeonWorkloadFactoryHelper::GetFactory(NeonWorkloadFactoryHelper::GetMemoryManager());
689
Nattapat Chaimanowong14766d72018-10-12 15:09:53 +0100690 std::unique_ptr<NeonSplitterWorkload> wlSplitter;
Nattapat Chaimanowongd4b70592018-10-12 11:21:49 +0100691 std::unique_ptr<NeonActivationWorkload> wlActiv0_0;
692 std::unique_ptr<NeonActivationWorkload> wlActiv0_1;
693 std::unique_ptr<NeonActivationWorkload> wlActiv1_0;
694 std::unique_ptr<NeonActivationWorkload> wlActiv1_1;
telsoa014fcda012018-03-09 14:13:49 +0000695
Nattapat Chaimanowong14766d72018-10-12 15:09:53 +0100696 CreateSplitterMultipleInputsOneOutputWorkloadTest<NeonSplitterWorkload,
Nattapat Chaimanowongd4b70592018-10-12 11:21:49 +0100697 NeonActivationWorkload, DataType::Float32>(factory, graph, wlSplitter, wlActiv0_0, wlActiv0_1,
698 wlActiv1_0, wlActiv1_1);
telsoa014fcda012018-03-09 14:13:49 +0000699
Derek Lambertic81855f2019-06-13 17:34:19 +0100700 armnn::IAclTensorHandle* sOut0 = dynamic_cast<armnn::IAclTensorHandle*>(wlSplitter->GetData().m_Outputs[0]);
701 armnn::IAclTensorHandle* sOut1 = dynamic_cast<armnn::IAclTensorHandle*>(wlSplitter->GetData().m_Outputs[1]);
702 armnn::IAclTensorHandle* activ0_0Im = dynamic_cast<armnn::IAclTensorHandle*>(wlActiv0_0->GetData().m_Inputs[0]);
703 armnn::IAclTensorHandle* activ0_1Im = dynamic_cast<armnn::IAclTensorHandle*>(wlActiv0_1->GetData().m_Inputs[0]);
704 armnn::IAclTensorHandle* activ1_0Im = dynamic_cast<armnn::IAclTensorHandle*>(wlActiv1_0->GetData().m_Inputs[0]);
705 armnn::IAclTensorHandle* activ1_1Im = dynamic_cast<armnn::IAclTensorHandle*>(wlActiv1_1->GetData().m_Inputs[0]);
telsoa014fcda012018-03-09 14:13:49 +0000706
707
708 BOOST_TEST(sOut0);
709 BOOST_TEST(sOut1);
710 BOOST_TEST(activ0_0Im);
711 BOOST_TEST(activ0_1Im);
712 BOOST_TEST(activ1_0Im);
713 BOOST_TEST(activ1_1Im);
714
715 bool validDataPointers = (sOut0 == activ0_0Im) && (sOut0 == activ0_1Im) &&
716 (sOut1 == activ1_0Im) && (sOut1 == activ1_1Im);
717
718 BOOST_TEST(validDataPointers);
719}
720
Matteo Martincighdb16dd32019-08-27 16:41:11 +0100721#if defined(ARMNNREF_ENABLED)
Matteo Martincighe67edb22019-08-14 14:05:46 +0100722
723// This test unit needs the reference backend, it's not available if the reference backend is not built
724
telsoa014fcda012018-03-09 14:13:49 +0000725BOOST_AUTO_TEST_CASE(CreateMemCopyWorkloadsNeon)
726{
Aron Virginas-Tar5caf9072018-11-14 18:35:18 +0000727 NeonWorkloadFactory factory =
728 NeonWorkloadFactoryHelper::GetFactory(NeonWorkloadFactoryHelper::GetMemoryManager());
Derek Lambertic81855f2019-06-13 17:34:19 +0100729 CreateMemCopyWorkloads<IAclTensorHandle>(factory);
telsoa014fcda012018-03-09 14:13:49 +0000730}
731
Matteo Martincighe67edb22019-08-14 14:05:46 +0100732#endif
733
Matteo Martincighbcd3c852018-09-28 14:14:12 +0100734template <typename L2NormalizationWorkloadType, typename armnn::DataType DataType>
735static void NeonCreateL2NormalizationWorkloadTest(DataLayout dataLayout)
736{
Matteo Martincigh2400b6d2018-10-09 18:19:20 +0100737 Graph graph;
Aron Virginas-Tar5caf9072018-11-14 18:35:18 +0000738 NeonWorkloadFactory factory =
739 NeonWorkloadFactoryHelper::GetFactory(NeonWorkloadFactoryHelper::GetMemoryManager());
740
Matteo Martincigh2400b6d2018-10-09 18:19:20 +0100741 auto workload =
742 CreateL2NormalizationWorkloadTest<L2NormalizationWorkloadType, DataType>(factory, graph, dataLayout);
Matteo Martincighbcd3c852018-09-28 14:14:12 +0100743
744 // Checks that inputs/outputs are as we expect them (see definition of CreateNormalizationWorkloadTest).
745 L2NormalizationQueueDescriptor queueDescriptor = workload->GetData();
Derek Lambertic81855f2019-06-13 17:34:19 +0100746 auto inputHandle = boost::polymorphic_downcast<IAclTensorHandle*>(queueDescriptor.m_Inputs[0]);
747 auto outputHandle = boost::polymorphic_downcast<IAclTensorHandle*>(queueDescriptor.m_Outputs[0]);
Matteo Martincigh2400b6d2018-10-09 18:19:20 +0100748
749 TensorShape inputShape = (dataLayout == DataLayout::NCHW) ?
750 TensorShape{ 5, 20, 50, 67 } : TensorShape{ 5, 50, 67, 20 };
751 TensorShape outputShape = (dataLayout == DataLayout::NCHW) ?
752 TensorShape{ 5, 20, 50, 67 } : TensorShape{ 5, 50, 67, 20 };
753
754 BOOST_TEST(TestNeonTensorHandleInfo(inputHandle, TensorInfo(inputShape, DataType)));
755 BOOST_TEST(TestNeonTensorHandleInfo(outputHandle, TensorInfo(outputShape, DataType)));
Matteo Martincighbcd3c852018-09-28 14:14:12 +0100756}
757
758#ifdef __ARM_FEATURE_FP16_VECTOR_ARITHMETIC
759BOOST_AUTO_TEST_CASE(CreateL2NormalizationFloat16NchwWorkload)
760{
761 NeonCreateL2NormalizationWorkloadTest<NeonL2NormalizationFloatWorkload, DataType::Float16>(DataLayout::NCHW);
762}
763
764BOOST_AUTO_TEST_CASE(CreateL2NormalizationFloat16NhwcWorkload)
765{
766 NeonCreateL2NormalizationWorkloadTest<NeonL2NormalizationFloatWorkload, DataType::Float16>(DataLayout::NHWC);
767}
768#endif
769
770BOOST_AUTO_TEST_CASE(CreateL2NormalizationNchwWorkload)
771{
772 NeonCreateL2NormalizationWorkloadTest<NeonL2NormalizationFloatWorkload, DataType::Float32>(DataLayout::NCHW);
773}
774
775BOOST_AUTO_TEST_CASE(CreateL2NormalizationNhwcWorkload)
776{
777 NeonCreateL2NormalizationWorkloadTest<NeonL2NormalizationFloatWorkload, DataType::Float32>(DataLayout::NHWC);
778}
779
Jan Eilersad5293a2019-07-08 09:57:55 +0100780template <typename LstmWorkloadType>
781static void NeonCreateLstmWorkloadTest()
782{
783 Graph graph;
784 NeonWorkloadFactory factory =
785 NeonWorkloadFactoryHelper::GetFactory(NeonWorkloadFactoryHelper::GetMemoryManager());
786
787 auto workload = CreateLstmWorkloadTest<LstmWorkloadType>(factory, graph);
788
789 LstmQueueDescriptor queueDescriptor = workload->GetData();
790
791 auto inputHandle = boost::polymorphic_downcast<IAclTensorHandle*>(queueDescriptor.m_Inputs[0]);
792 auto outputHandle = boost::polymorphic_downcast<IAclTensorHandle*>(queueDescriptor.m_Outputs[1]);
793
794 BOOST_TEST(TestNeonTensorHandleInfo(inputHandle, TensorInfo({ 2, 2 }, DataType::Float32)));
795 BOOST_TEST(TestNeonTensorHandleInfo(outputHandle, TensorInfo({ 2, 4 }, DataType::Float32)));
796}
797
798BOOST_AUTO_TEST_CASE(CreateLSTMWorkloadFloatWorkload)
799{
800 NeonCreateLstmWorkloadTest<NeonLstmFloatWorkload>();
801}
802
Jim Flynne242f2d2019-05-22 14:24:13 +0100803template <typename ConcatWorkloadType, armnn::DataType DataType>
804static void NeonCreateConcatWorkloadTest(std::initializer_list<unsigned int> outputShape,
narpra015cdda352018-11-19 15:30:27 +0000805 unsigned int concatAxis)
806{
807 Graph graph;
808 NeonWorkloadFactory factory =
809 NeonWorkloadFactoryHelper::GetFactory(NeonWorkloadFactoryHelper::GetMemoryManager());
810
Jim Flynne242f2d2019-05-22 14:24:13 +0100811 auto workload = CreateConcatWorkloadTest<ConcatWorkloadType, DataType>(factory, graph, outputShape, concatAxis);
narpra015cdda352018-11-19 15:30:27 +0000812
Jim Flynne242f2d2019-05-22 14:24:13 +0100813 ConcatQueueDescriptor queueDescriptor = workload->GetData();
Derek Lambertic81855f2019-06-13 17:34:19 +0100814 auto inputHandle0 = boost::polymorphic_downcast<IAclTensorHandle*>(queueDescriptor.m_Inputs[0]);
815 auto inputHandle1 = boost::polymorphic_downcast<IAclTensorHandle*>(queueDescriptor.m_Inputs[1]);
816 auto outputHandle = boost::polymorphic_downcast<IAclTensorHandle*>(queueDescriptor.m_Outputs[0]);
narpra015cdda352018-11-19 15:30:27 +0000817
818 BOOST_TEST(TestNeonTensorHandleInfo(inputHandle0, TensorInfo({ 2, 3, 2, 5 }, DataType)));
819 BOOST_TEST(TestNeonTensorHandleInfo(inputHandle1, TensorInfo({ 2, 3, 2, 5 }, DataType)));
820 BOOST_TEST(TestNeonTensorHandleInfo(outputHandle, TensorInfo(outputShape, DataType)));
821}
822
Jim Flynne242f2d2019-05-22 14:24:13 +0100823BOOST_AUTO_TEST_CASE(CreateConcatDim0Float32Workload)
narpra015cdda352018-11-19 15:30:27 +0000824{
Jim Flynne242f2d2019-05-22 14:24:13 +0100825 NeonCreateConcatWorkloadTest<NeonConcatWorkload, armnn::DataType::Float32>({ 4, 3, 2, 5 }, 0);
narpra015cdda352018-11-19 15:30:27 +0000826}
827
Jim Flynne242f2d2019-05-22 14:24:13 +0100828BOOST_AUTO_TEST_CASE(CreateConcatDim1Float32Workload)
narpra015cdda352018-11-19 15:30:27 +0000829{
Jim Flynne242f2d2019-05-22 14:24:13 +0100830 NeonCreateConcatWorkloadTest<NeonConcatWorkload, armnn::DataType::Float32>({ 2, 6, 2, 5 }, 1);
narpra015cdda352018-11-19 15:30:27 +0000831}
832
Jim Flynne242f2d2019-05-22 14:24:13 +0100833BOOST_AUTO_TEST_CASE(CreateConcatDim3Float32Workload)
narpra015cdda352018-11-19 15:30:27 +0000834{
Jim Flynne242f2d2019-05-22 14:24:13 +0100835 NeonCreateConcatWorkloadTest<NeonConcatWorkload, armnn::DataType::Float32>({ 2, 3, 2, 10 }, 3);
narpra015cdda352018-11-19 15:30:27 +0000836}
837
Jim Flynne242f2d2019-05-22 14:24:13 +0100838BOOST_AUTO_TEST_CASE(CreateConcatDim0Uint8Workload)
narpra0163b08822018-11-20 11:29:12 +0000839{
Derek Lambertif90c56d2020-01-10 17:14:08 +0000840 NeonCreateConcatWorkloadTest<NeonConcatWorkload, armnn::DataType::QAsymmU8>({ 4, 3, 2, 5 }, 0);
narpra0163b08822018-11-20 11:29:12 +0000841}
842
Jim Flynne242f2d2019-05-22 14:24:13 +0100843BOOST_AUTO_TEST_CASE(CreateConcatDim1Uint8Workload)
narpra0163b08822018-11-20 11:29:12 +0000844{
Derek Lambertif90c56d2020-01-10 17:14:08 +0000845 NeonCreateConcatWorkloadTest<NeonConcatWorkload, armnn::DataType::QAsymmU8>({ 2, 6, 2, 5 }, 1);
narpra0163b08822018-11-20 11:29:12 +0000846}
847
Jim Flynne242f2d2019-05-22 14:24:13 +0100848BOOST_AUTO_TEST_CASE(CreateConcatDim3Uint8Workload)
narpra0163b08822018-11-20 11:29:12 +0000849{
Derek Lambertif90c56d2020-01-10 17:14:08 +0000850 NeonCreateConcatWorkloadTest<NeonConcatWorkload, armnn::DataType::QAsymmU8>({ 2, 3, 2, 10 }, 3);
narpra0163b08822018-11-20 11:29:12 +0000851}
852
Matthew Jackson87f65ea2019-08-01 10:01:34 +0100853template <armnn::DataType DataType>
854static void NeonCreateStackWorkloadTest(const std::initializer_list<unsigned int>& inputShape,
855 const std::initializer_list<unsigned int>& outputShape,
856 unsigned int axis,
857 unsigned int numInputs)
858{
859 armnn::Graph graph;
860 NeonWorkloadFactory factory =
861 NeonWorkloadFactoryHelper::GetFactory(NeonWorkloadFactoryHelper::GetMemoryManager());
862
863 auto workload = CreateStackWorkloadTest<NeonStackWorkload, DataType>(factory,
864 graph,
865 TensorShape(inputShape),
866 TensorShape(outputShape),
867 axis,
868 numInputs);
869
870 // Check inputs and output are as expected
871 StackQueueDescriptor queueDescriptor = workload->GetData();
872 for (unsigned int i = 0; i < numInputs; ++i)
873 {
874 auto inputHandle = boost::polymorphic_downcast<IAclTensorHandle*>(queueDescriptor.m_Inputs[i]);
875 BOOST_TEST(TestNeonTensorHandleInfo(inputHandle, TensorInfo(inputShape, DataType)));
876 }
877 auto outputHandle = boost::polymorphic_downcast<IAclTensorHandle*>(queueDescriptor.m_Outputs[0]);
878 BOOST_TEST(TestNeonTensorHandleInfo(outputHandle, TensorInfo(outputShape, DataType)));
879}
880
881BOOST_AUTO_TEST_CASE(CreateStackFloat32Workload)
882{
883 NeonCreateStackWorkloadTest<armnn::DataType::Float32>({ 3, 4, 5 }, { 3, 4, 2, 5 }, 2, 2);
884}
885
Matthew Jacksone69c3992019-09-09 14:31:21 +0100886#ifdef __ARM_FEATURE_FP16_VECTOR_ARITHMETIC
887BOOST_AUTO_TEST_CASE(CreateStackFloat16Workload)
888{
889 NeonCreateStackWorkloadTest<armnn::DataType::Float16>({ 3, 4, 5 }, { 3, 4, 2, 5 }, 2, 2);
890}
891#endif
892
Matthew Jackson87f65ea2019-08-01 10:01:34 +0100893BOOST_AUTO_TEST_CASE(CreateStackUint8Workload)
894{
Derek Lambertif90c56d2020-01-10 17:14:08 +0000895 NeonCreateStackWorkloadTest<armnn::DataType::QAsymmU8>({ 3, 4, 5 }, { 3, 4, 2, 5 }, 2, 2);
Matthew Jackson87f65ea2019-08-01 10:01:34 +0100896}
897
Francis Murtagh4fc3c482019-08-02 13:20:54 +0100898template <typename QuantizedLstmWorkloadType>
899static void NeonCreateQuantizedLstmWorkloadTest()
900{
901 using boost::polymorphic_downcast;
902
903 Graph graph;
904 NeonWorkloadFactory factory = NeonWorkloadFactoryHelper::GetFactory(NeonWorkloadFactoryHelper::GetMemoryManager());
905
906 auto workload = CreateQuantizedLstmWorkloadTest<QuantizedLstmWorkloadType>(factory, graph);
907
908 QuantizedLstmQueueDescriptor queueDescriptor = workload->GetData();
909
910 IAclTensorHandle* inputHandle = polymorphic_downcast<IAclTensorHandle*>(queueDescriptor.m_Inputs[0]);
911 BOOST_TEST((inputHandle->GetShape() == TensorShape({2, 2})));
912 BOOST_TEST((inputHandle->GetDataType() == arm_compute::DataType::QASYMM8));
913
914 IAclTensorHandle* cellStateInHandle = polymorphic_downcast<IAclTensorHandle*>(queueDescriptor.m_Inputs[1]);
915 BOOST_TEST((cellStateInHandle->GetShape() == TensorShape({2, 4})));
916 BOOST_TEST((cellStateInHandle->GetDataType() == arm_compute::DataType::QSYMM16));
917
918 IAclTensorHandle* outputStateInHandle = polymorphic_downcast<IAclTensorHandle*>(queueDescriptor.m_Inputs[2]);
919 BOOST_TEST((outputStateInHandle->GetShape() == TensorShape({2, 4})));
920 BOOST_TEST((outputStateInHandle->GetDataType() == arm_compute::DataType::QASYMM8));
921
922 IAclTensorHandle* cellStateOutHandle = polymorphic_downcast<IAclTensorHandle*>(queueDescriptor.m_Outputs[0]);
923 BOOST_TEST((cellStateOutHandle->GetShape() == TensorShape({2, 4})));
924 BOOST_TEST((cellStateOutHandle->GetDataType() == arm_compute::DataType::QSYMM16));
925
926 IAclTensorHandle* outputStateOutHandle = polymorphic_downcast<IAclTensorHandle*>(queueDescriptor.m_Outputs[1]);
927 BOOST_TEST((outputStateOutHandle->GetShape() == TensorShape({2, 4})));
928 BOOST_TEST((outputStateOutHandle->GetDataType() == arm_compute::DataType::QASYMM8));
929}
930
931BOOST_AUTO_TEST_CASE(CreateQuantizedLstmWorkload)
932{
933 NeonCreateQuantizedLstmWorkloadTest<NeonQuantizedLstmWorkload>();
934}
935
telsoa014fcda012018-03-09 14:13:49 +0000936BOOST_AUTO_TEST_SUITE_END()