blob: e6e1574ae821c17d4e061fbe96943fac9c6576fc [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,
155 DataType::QuantisedAsymm8>();
156}
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,
181 DataType::QuantisedAsymm8>();
182}
183
telsoa01c577f2c2018-08-31 09:22:23 +0100184template <typename BatchNormalizationWorkloadType, typename armnn::DataType DataType>
Nikhil Rajd1340932018-10-18 14:27:50 +0100185static void NeonCreateBatchNormalizationWorkloadTest(DataLayout dataLayout)
telsoa014fcda012018-03-09 14:13:49 +0000186{
Aron Virginas-Tar5caf9072018-11-14 18:35:18 +0000187 Graph graph;
188 NeonWorkloadFactory factory =
189 NeonWorkloadFactoryHelper::GetFactory(NeonWorkloadFactoryHelper::GetMemoryManager());
190
Nikhil Rajd1340932018-10-18 14:27:50 +0100191 auto workload = CreateBatchNormalizationWorkloadTest<BatchNormalizationWorkloadType, DataType>
192 (factory, graph, dataLayout);
telsoa014fcda012018-03-09 14:13:49 +0000193
telsoa01c577f2c2018-08-31 09:22:23 +0100194 // Checks that outputs and inputs are as we expect them (see definition of CreateBatchNormalizationWorkloadTest).
telsoa014fcda012018-03-09 14:13:49 +0000195 BatchNormalizationQueueDescriptor queueDescriptor = workload->GetData();
Derek Lambertic81855f2019-06-13 17:34:19 +0100196 auto inputHandle = boost::polymorphic_downcast<IAclTensorHandle*>(queueDescriptor.m_Inputs[0]);
197 auto outputHandle = boost::polymorphic_downcast<IAclTensorHandle*>(queueDescriptor.m_Outputs[0]);
Nikhil Rajd1340932018-10-18 14:27:50 +0100198
199 TensorShape inputShape = (dataLayout == DataLayout::NCHW) ? TensorShape{2, 3, 4, 4} : TensorShape{2, 4, 4, 3};
200 TensorShape outputShape = (dataLayout == DataLayout::NCHW) ? TensorShape{2, 3, 4, 4} : TensorShape{2, 4, 4, 3};
201
202 BOOST_TEST(TestNeonTensorHandleInfo(inputHandle, TensorInfo(inputShape, DataType)));
203 BOOST_TEST(TestNeonTensorHandleInfo(outputHandle, TensorInfo(outputShape, DataType)));
telsoa014fcda012018-03-09 14:13:49 +0000204}
205
telsoa01c577f2c2018-08-31 09:22:23 +0100206#ifdef __ARM_FEATURE_FP16_VECTOR_ARITHMETIC
Nikhil Rajd1340932018-10-18 14:27:50 +0100207BOOST_AUTO_TEST_CASE(CreateBatchNormalizationFloat16NchwWorkload)
telsoa01c577f2c2018-08-31 09:22:23 +0100208{
Matthew Benthamc48ac8c2018-12-12 16:15:59 +0000209 NeonCreateBatchNormalizationWorkloadTest<NeonBatchNormalizationWorkload, DataType::Float16>(DataLayout::NCHW);
Nikhil Rajd1340932018-10-18 14:27:50 +0100210}
211
212BOOST_AUTO_TEST_CASE(CreateBatchNormalizationFloat16NhwcWorkload)
213{
Matthew Benthamc48ac8c2018-12-12 16:15:59 +0000214 NeonCreateBatchNormalizationWorkloadTest<NeonBatchNormalizationWorkload, DataType::Float16>(DataLayout::NHWC);
telsoa01c577f2c2018-08-31 09:22:23 +0100215}
216#endif
217
Nikhil Rajd1340932018-10-18 14:27:50 +0100218BOOST_AUTO_TEST_CASE(CreateBatchNormalizationFloatNchwWorkload)
telsoa01c577f2c2018-08-31 09:22:23 +0100219{
Matthew Benthamc48ac8c2018-12-12 16:15:59 +0000220 NeonCreateBatchNormalizationWorkloadTest<NeonBatchNormalizationWorkload, DataType::Float32>(DataLayout::NCHW);
Nikhil Rajd1340932018-10-18 14:27:50 +0100221}
222
223BOOST_AUTO_TEST_CASE(CreateBatchNormalizationFloatNhwcWorkload)
224{
Matthew Benthamc48ac8c2018-12-12 16:15:59 +0000225 NeonCreateBatchNormalizationWorkloadTest<NeonBatchNormalizationWorkload, DataType::Float32>(DataLayout::NHWC);
telsoa01c577f2c2018-08-31 09:22:23 +0100226}
227
Nattapat Chaimanowong974b65f2018-10-15 15:07:34 +0100228template <typename armnn::DataType DataType>
Francis Murtagh0d9d4192018-10-09 16:22:33 +0100229static void NeonCreateConvolution2dWorkloadTest(DataLayout dataLayout = DataLayout::NCHW)
telsoa014fcda012018-03-09 14:13:49 +0000230{
Aron Virginas-Tar5caf9072018-11-14 18:35:18 +0000231 Graph graph;
232 NeonWorkloadFactory factory =
233 NeonWorkloadFactoryHelper::GetFactory(NeonWorkloadFactoryHelper::GetMemoryManager());
234
235 auto workload = CreateConvolution2dWorkloadTest<NeonConvolution2dWorkload, DataType>(factory, graph, dataLayout);
Francis Murtagh0d9d4192018-10-09 16:22:33 +0100236
237 TensorShape inputShape = (dataLayout == DataLayout::NCHW) ? TensorShape{2, 3, 8, 16} : TensorShape{2, 8, 16, 3};
238 TensorShape outputShape = (dataLayout == DataLayout::NCHW) ? TensorShape{2, 2, 2, 10} : TensorShape{2, 2, 10, 2};
telsoa014fcda012018-03-09 14:13:49 +0000239
telsoa01c577f2c2018-08-31 09:22:23 +0100240 // Checks that outputs and inputs are as we expect them (see definition of CreateConvolution2dWorkloadTest).
telsoa014fcda012018-03-09 14:13:49 +0000241 Convolution2dQueueDescriptor queueDescriptor = workload->GetData();
Derek Lambertic81855f2019-06-13 17:34:19 +0100242 auto inputHandle = boost::polymorphic_downcast<IAclTensorHandle*>(queueDescriptor.m_Inputs[0]);
243 auto outputHandle = boost::polymorphic_downcast<IAclTensorHandle*>(queueDescriptor.m_Outputs[0]);
Francis Murtagh0d9d4192018-10-09 16:22:33 +0100244 BOOST_TEST(TestNeonTensorHandleInfo(inputHandle, TensorInfo(inputShape, DataType)));
245 BOOST_TEST(TestNeonTensorHandleInfo(outputHandle, TensorInfo(outputShape, DataType)));
telsoa014fcda012018-03-09 14:13:49 +0000246}
247
telsoa01c577f2c2018-08-31 09:22:23 +0100248#ifdef __ARM_FEATURE_FP16_VECTOR_ARITHMETIC
Francis Murtagh0d9d4192018-10-09 16:22:33 +0100249BOOST_AUTO_TEST_CASE(CreateConvolution2dFloat16NchwWorkload)
telsoa01c577f2c2018-08-31 09:22:23 +0100250{
Nattapat Chaimanowong974b65f2018-10-15 15:07:34 +0100251 NeonCreateConvolution2dWorkloadTest<DataType::Float16>();
telsoa01c577f2c2018-08-31 09:22:23 +0100252}
telsoa01c577f2c2018-08-31 09:22:23 +0100253
Francis Murtagh0d9d4192018-10-09 16:22:33 +0100254BOOST_AUTO_TEST_CASE(CreateConvolution2dFloat16NhwcWorkload)
255{
Nattapat Chaimanowong974b65f2018-10-15 15:07:34 +0100256 NeonCreateConvolution2dWorkloadTest<DataType::Float16>(DataLayout::NHWC);
Francis Murtagh0d9d4192018-10-09 16:22:33 +0100257}
258
259#endif
260BOOST_AUTO_TEST_CASE(CreateConvolution2dFloatNchwWorkload)
telsoa01c577f2c2018-08-31 09:22:23 +0100261{
Nattapat Chaimanowong974b65f2018-10-15 15:07:34 +0100262 NeonCreateConvolution2dWorkloadTest<DataType::Float32>();
telsoa01c577f2c2018-08-31 09:22:23 +0100263}
264
Francis Murtagh0d9d4192018-10-09 16:22:33 +0100265BOOST_AUTO_TEST_CASE(CreateConvolution2dFloatNhwcWorkload)
266{
Nattapat Chaimanowong974b65f2018-10-15 15:07:34 +0100267 NeonCreateConvolution2dWorkloadTest<DataType::Float32>(DataLayout::NHWC);
Francis Murtagh0d9d4192018-10-09 16:22:33 +0100268}
269
Nattapat Chaimanowong77140882018-10-17 11:12:19 +0100270template <typename armnn::DataType DataType>
Nikhil Rajcec6b652018-10-12 13:51:57 +0100271static void NeonCreateDepthWiseConvolutionWorkloadTest(DataLayout dataLayout)
272{
273 Graph graph;
Aron Virginas-Tar5caf9072018-11-14 18:35:18 +0000274 NeonWorkloadFactory factory =
275 NeonWorkloadFactoryHelper::GetFactory(NeonWorkloadFactoryHelper::GetMemoryManager());
Nikhil Rajcec6b652018-10-12 13:51:57 +0100276
Nattapat Chaimanowong77140882018-10-17 11:12:19 +0100277 auto workload = CreateDepthwiseConvolution2dWorkloadTest<NeonDepthwiseConvolutionWorkload,
Nikhil Rajcec6b652018-10-12 13:51:57 +0100278 DataType>(factory, graph, dataLayout);
279
280 // Checks that inputs/outputs are as we expect them (see definition of CreateNormalizationWorkloadTest).
281 DepthwiseConvolution2dQueueDescriptor queueDescriptor = workload->GetData();
Derek Lambertic81855f2019-06-13 17:34:19 +0100282 auto inputHandle = boost::polymorphic_downcast<IAclTensorHandle*>(queueDescriptor.m_Inputs[0]);
283 auto outputHandle = boost::polymorphic_downcast<IAclTensorHandle*>(queueDescriptor.m_Outputs[0]);
Nikhil Rajcec6b652018-10-12 13:51:57 +0100284
Mike Kellydb482882019-06-14 12:35:24 +0100285 TensorShape inputShape = (dataLayout == DataLayout::NCHW) ? std::initializer_list<unsigned int>({ 2, 2, 5, 5 })
286 : std::initializer_list<unsigned int>({ 2, 5, 5, 2 });
287 TensorShape outputShape = (dataLayout == DataLayout::NCHW) ? std::initializer_list<unsigned int>({ 2, 2, 5, 5 })
288 : std::initializer_list<unsigned int>({ 2, 5, 5, 2 });
Nikhil Rajcec6b652018-10-12 13:51:57 +0100289
290 BOOST_TEST(TestNeonTensorHandleInfo(inputHandle, TensorInfo(inputShape, DataType)));
291 BOOST_TEST(TestNeonTensorHandleInfo(outputHandle, TensorInfo(outputShape, DataType)));
292}
293
294BOOST_AUTO_TEST_CASE(CreateDepthWiseConvolution2dFloat32NhwcWorkload)
295{
Nattapat Chaimanowong77140882018-10-17 11:12:19 +0100296 NeonCreateDepthWiseConvolutionWorkloadTest<DataType::Float32>(DataLayout::NHWC);
Nikhil Rajcec6b652018-10-12 13:51:57 +0100297}
298
299#ifdef __ARM_FEATURE_FP16_VECTOR_ARITHMETIC
300BOOST_AUTO_TEST_CASE(CreateDepthWiseConvolution2dFloat16NhwcWorkload)
301{
Nattapat Chaimanowong77140882018-10-17 11:12:19 +0100302 NeonCreateDepthWiseConvolutionWorkloadTest<DataType::Float16>(DataLayout::NHWC);
Nikhil Rajcec6b652018-10-12 13:51:57 +0100303}
304#endif
305
telsoa01c577f2c2018-08-31 09:22:23 +0100306template <typename FullyConnectedWorkloadType, typename armnn::DataType DataType>
307static void NeonCreateFullyConnectedWorkloadTest()
telsoa014fcda012018-03-09 14:13:49 +0000308{
Aron Virginas-Tar5caf9072018-11-14 18:35:18 +0000309 Graph graph;
310 NeonWorkloadFactory factory =
311 NeonWorkloadFactoryHelper::GetFactory(NeonWorkloadFactoryHelper::GetMemoryManager());
312
313 auto workload = CreateFullyConnectedWorkloadTest<FullyConnectedWorkloadType, DataType>(factory, graph);
telsoa014fcda012018-03-09 14:13:49 +0000314
telsoa01c577f2c2018-08-31 09:22:23 +0100315 // Checks that outputs and inputs are as we expect them (see definition of CreateFullyConnectedWorkloadTest).
telsoa014fcda012018-03-09 14:13:49 +0000316 FullyConnectedQueueDescriptor queueDescriptor = workload->GetData();
Derek Lambertic81855f2019-06-13 17:34:19 +0100317 auto inputHandle = boost::polymorphic_downcast<IAclTensorHandle*>(queueDescriptor.m_Inputs[0]);
318 auto outputHandle = boost::polymorphic_downcast<IAclTensorHandle*>(queueDescriptor.m_Outputs[0]);
telsoa01c577f2c2018-08-31 09:22:23 +0100319 BOOST_TEST(TestNeonTensorHandleInfo(inputHandle, TensorInfo({3, 1, 4, 5}, DataType)));
320 BOOST_TEST(TestNeonTensorHandleInfo(outputHandle, TensorInfo({3, 7}, DataType)));
telsoa014fcda012018-03-09 14:13:49 +0000321}
322
telsoa01c577f2c2018-08-31 09:22:23 +0100323#ifdef __ARM_FEATURE_FP16_VECTOR_ARITHMETIC
324BOOST_AUTO_TEST_CASE(CreateFullyConnectedFloat16Workload)
325{
kevmay01e448be32018-09-26 10:21:55 +0100326 NeonCreateFullyConnectedWorkloadTest<NeonFullyConnectedWorkload, DataType::Float16>();
telsoa01c577f2c2018-08-31 09:22:23 +0100327}
328#endif
329
arovir019e53a352018-08-31 15:26:35 +0100330BOOST_AUTO_TEST_CASE(CreateFullyConnectedFloatWorkload)
telsoa01c577f2c2018-08-31 09:22:23 +0100331{
kevmay01e448be32018-09-26 10:21:55 +0100332 NeonCreateFullyConnectedWorkloadTest<NeonFullyConnectedWorkload, DataType::Float32>();
telsoa01c577f2c2018-08-31 09:22:23 +0100333}
334
telsoa01c577f2c2018-08-31 09:22:23 +0100335template <typename NormalizationWorkloadType, typename armnn::DataType DataType>
narpra0155a97bc2018-10-02 14:35:53 +0100336static void NeonCreateNormalizationWorkloadTest(DataLayout dataLayout)
telsoa014fcda012018-03-09 14:13:49 +0000337{
narpra0155a97bc2018-10-02 14:35:53 +0100338 Graph graph;
Aron Virginas-Tar5caf9072018-11-14 18:35:18 +0000339 NeonWorkloadFactory factory =
340 NeonWorkloadFactoryHelper::GetFactory(NeonWorkloadFactoryHelper::GetMemoryManager());
341
narpra0155a97bc2018-10-02 14:35:53 +0100342 auto workload = CreateNormalizationWorkloadTest<NormalizationWorkloadType, DataType>(factory, graph, dataLayout);
telsoa014fcda012018-03-09 14:13:49 +0000343
telsoa01c577f2c2018-08-31 09:22:23 +0100344 // Checks that outputs and inputs are as we expect them (see definition of CreateNormalizationWorkloadTest).
telsoa014fcda012018-03-09 14:13:49 +0000345 NormalizationQueueDescriptor queueDescriptor = workload->GetData();
Derek Lambertic81855f2019-06-13 17:34:19 +0100346 auto inputHandle = boost::polymorphic_downcast<IAclTensorHandle*>(queueDescriptor.m_Inputs[0]);
347 auto outputHandle = boost::polymorphic_downcast<IAclTensorHandle*>(queueDescriptor.m_Outputs[0]);
Matteo Martincigha160b242018-10-18 10:33:23 +0100348
349 TensorShape inputShape = (dataLayout == DataLayout::NCHW) ? TensorShape{3, 5, 5, 1} : TensorShape{3, 1, 5, 5};
350 TensorShape outputShape = (dataLayout == DataLayout::NCHW) ? TensorShape{3, 5, 5, 1} : TensorShape{3, 1, 5, 5};
351
352 BOOST_TEST(TestNeonTensorHandleInfo(inputHandle, TensorInfo(inputShape, DataType)));
353 BOOST_TEST(TestNeonTensorHandleInfo(outputHandle, TensorInfo(outputShape, DataType)));
telsoa014fcda012018-03-09 14:13:49 +0000354}
355
telsoa01c577f2c2018-08-31 09:22:23 +0100356#ifdef __ARM_FEATURE_FP16_VECTOR_ARITHMETIC
narpra0155a97bc2018-10-02 14:35:53 +0100357BOOST_AUTO_TEST_CASE(CreateNormalizationFloat16NchwWorkload)
telsoa01c577f2c2018-08-31 09:22:23 +0100358{
narpra0155a97bc2018-10-02 14:35:53 +0100359 NeonCreateNormalizationWorkloadTest<NeonNormalizationFloatWorkload, DataType::Float16>(DataLayout::NCHW);
360}
361
362BOOST_AUTO_TEST_CASE(CreateNormalizationFloat16NhwcWorkload)
363{
364 NeonCreateNormalizationWorkloadTest<NeonNormalizationFloatWorkload, DataType::Float16>(DataLayout::NHWC);
telsoa01c577f2c2018-08-31 09:22:23 +0100365}
366#endif
367
narpra0155a97bc2018-10-02 14:35:53 +0100368BOOST_AUTO_TEST_CASE(CreateNormalizationFloatNchwWorkload)
telsoa01c577f2c2018-08-31 09:22:23 +0100369{
narpra0155a97bc2018-10-02 14:35:53 +0100370 NeonCreateNormalizationWorkloadTest<NeonNormalizationFloatWorkload, DataType::Float32>(DataLayout::NCHW);
telsoa01c577f2c2018-08-31 09:22:23 +0100371}
372
narpra0155a97bc2018-10-02 14:35:53 +0100373BOOST_AUTO_TEST_CASE(CreateNormalizationFloatNhwcWorkload)
374{
375 NeonCreateNormalizationWorkloadTest<NeonNormalizationFloatWorkload, DataType::Float32>(DataLayout::NHWC);
376}
377
378
Nattapat Chaimanowong5d2e7002018-10-12 16:03:56 +0100379template <typename armnn::DataType DataType>
Nina Drozdb48e6862018-10-09 12:09:56 +0100380static void NeonCreatePooling2dWorkloadTest(DataLayout dataLayout = DataLayout::NCHW)
telsoa014fcda012018-03-09 14:13:49 +0000381{
Aron Virginas-Tar5caf9072018-11-14 18:35:18 +0000382 Graph graph;
383 NeonWorkloadFactory factory =
384 NeonWorkloadFactoryHelper::GetFactory(NeonWorkloadFactoryHelper::GetMemoryManager());
385
386 auto workload = CreatePooling2dWorkloadTest<NeonPooling2dWorkload, DataType>(factory, graph, dataLayout);
Nina Drozdb48e6862018-10-09 12:09:56 +0100387
388 TensorShape inputShape = (dataLayout == DataLayout::NCHW) ? TensorShape{3, 2, 5, 5} : TensorShape{3, 5, 5, 2};
389 TensorShape outputShape = (dataLayout == DataLayout::NCHW) ? TensorShape{3, 2, 2, 4} : TensorShape{3, 2, 4, 2};
telsoa014fcda012018-03-09 14:13:49 +0000390
telsoa01c577f2c2018-08-31 09:22:23 +0100391 // Checks that outputs and inputs are as we expect them (see definition of CreatePooling2dWorkloadTest).
telsoa014fcda012018-03-09 14:13:49 +0000392 Pooling2dQueueDescriptor queueDescriptor = workload->GetData();
Derek Lambertic81855f2019-06-13 17:34:19 +0100393 auto inputHandle = boost::polymorphic_downcast<IAclTensorHandle*>(queueDescriptor.m_Inputs[0]);
394 auto outputHandle = boost::polymorphic_downcast<IAclTensorHandle*>(queueDescriptor.m_Outputs[0]);
Nina Drozdb48e6862018-10-09 12:09:56 +0100395 BOOST_TEST(TestNeonTensorHandleInfo(inputHandle, TensorInfo(inputShape, DataType)));
396 BOOST_TEST(TestNeonTensorHandleInfo(outputHandle, TensorInfo(outputShape, DataType)));
telsoa014fcda012018-03-09 14:13:49 +0000397}
398
telsoa01c577f2c2018-08-31 09:22:23 +0100399#ifdef __ARM_FEATURE_FP16_VECTOR_ARITHMETIC
400BOOST_AUTO_TEST_CASE(CreatePooling2dFloat16Workload)
401{
Nattapat Chaimanowong5d2e7002018-10-12 16:03:56 +0100402 NeonCreatePooling2dWorkloadTest<DataType::Float16>();
telsoa01c577f2c2018-08-31 09:22:23 +0100403}
404#endif
405
Nina Drozdb48e6862018-10-09 12:09:56 +0100406BOOST_AUTO_TEST_CASE(CreatePooling2dFloatNchwWorkload)
telsoa01c577f2c2018-08-31 09:22:23 +0100407{
Nattapat Chaimanowong5d2e7002018-10-12 16:03:56 +0100408 NeonCreatePooling2dWorkloadTest<DataType::Float32>(DataLayout::NCHW);
telsoa01c577f2c2018-08-31 09:22:23 +0100409}
410
Nina Drozdb48e6862018-10-09 12:09:56 +0100411BOOST_AUTO_TEST_CASE(CreatePooling2dFloatNhwcWorkload)
telsoa01c577f2c2018-08-31 09:22:23 +0100412{
Nattapat Chaimanowong5d2e7002018-10-12 16:03:56 +0100413 NeonCreatePooling2dWorkloadTest<DataType::Float32>(DataLayout::NHWC);
Nina Drozdb48e6862018-10-09 12:09:56 +0100414}
415
416BOOST_AUTO_TEST_CASE(CreatePooling2dUint8NchwWorkload)
417{
Nattapat Chaimanowong5d2e7002018-10-12 16:03:56 +0100418 NeonCreatePooling2dWorkloadTest<DataType::QuantisedAsymm8>(DataLayout::NCHW);
Nina Drozdb48e6862018-10-09 12:09:56 +0100419}
420
421BOOST_AUTO_TEST_CASE(CreatePooling2dUint8NhwcWorkload)
422{
Nattapat Chaimanowong5d2e7002018-10-12 16:03:56 +0100423 NeonCreatePooling2dWorkloadTest<DataType::QuantisedAsymm8>(DataLayout::NHWC);
telsoa01c577f2c2018-08-31 09:22:23 +0100424}
425
Nikhil Raj9b461482019-07-03 15:58:31 +0100426static void NeonCreatePreluWorkloadTest(const armnn::TensorShape& inputShape,
427 const armnn::TensorShape& alphaShape,
428 const armnn::TensorShape& outputShape,
429 armnn::DataType dataType)
430{
431 Graph graph;
432 NeonWorkloadFactory factory =
433 NeonWorkloadFactoryHelper::GetFactory(NeonWorkloadFactoryHelper::GetMemoryManager());
434
435 auto workload = CreatePreluWorkloadTest<NeonPreluWorkload>(factory,
436 graph,
437 inputShape,
438 alphaShape,
439 outputShape,
440 dataType);
441
442 // Checks that outputs and inputs are as we expect them (see definition of CreateReshapeWorkloadTest).
443 PreluQueueDescriptor queueDescriptor = workload->GetData();
444 auto inputHandle = boost::polymorphic_downcast<IAclTensorHandle*>(queueDescriptor.m_Inputs[0]);
445 auto alphaHandle = boost::polymorphic_downcast<IAclTensorHandle*>(queueDescriptor.m_Inputs[1]);
446 auto outputHandle = boost::polymorphic_downcast<IAclTensorHandle*>(queueDescriptor.m_Outputs[0]);
447 BOOST_TEST(TestNeonTensorHandleInfo(inputHandle, TensorInfo(inputShape, dataType)));
448 BOOST_TEST(TestNeonTensorHandleInfo(alphaHandle, TensorInfo(alphaShape, dataType)));
449 BOOST_TEST(TestNeonTensorHandleInfo(outputHandle, TensorInfo(outputShape, dataType)));
450}
451
452#ifdef __ARM_FEATURE_FP16_VECTOR_ARITHMETIC
453 BOOST_AUTO_TEST_CASE(CreatePreluFloat16Workload)
454{
455 NeonCreatePreluWorkloadTest({ 1, 4, 1, 2 }, { 5, 4, 3, 1 }, { 5, 4, 3, 2 }, DataType::Float16);
456}
457#endif
458
459BOOST_AUTO_TEST_CASE(CreatePreluFloatWorkload)
460{
461 NeonCreatePreluWorkloadTest({ 1, 4, 1, 2 }, { 5, 4, 3, 1 }, { 5, 4, 3, 2 }, DataType::Float32);
462}
463
464BOOST_AUTO_TEST_CASE(CreatePreluUint8Workload)
465{
466 NeonCreatePreluWorkloadTest({ 1, 4, 1, 2 }, { 5, 4, 3, 1 }, { 5, 4, 3, 2 }, DataType::QuantisedAsymm8);
467}
468
Nattapat Chaimanowongcce11fc2018-10-12 16:30:56 +0100469template <typename armnn::DataType DataType>
telsoa01c577f2c2018-08-31 09:22:23 +0100470static void NeonCreateReshapeWorkloadTest()
telsoa014fcda012018-03-09 14:13:49 +0000471{
Aron Virginas-Tar5caf9072018-11-14 18:35:18 +0000472 Graph graph;
473 NeonWorkloadFactory factory =
474 NeonWorkloadFactoryHelper::GetFactory(NeonWorkloadFactoryHelper::GetMemoryManager());
475
476 auto workload = CreateReshapeWorkloadTest<NeonReshapeWorkload, DataType>(factory, graph);
telsoa014fcda012018-03-09 14:13:49 +0000477
telsoa01c577f2c2018-08-31 09:22:23 +0100478 // Checks that outputs and inputs are as we expect them (see definition of CreateReshapeWorkloadTest).
telsoa014fcda012018-03-09 14:13:49 +0000479 ReshapeQueueDescriptor queueDescriptor = workload->GetData();
Derek Lambertic81855f2019-06-13 17:34:19 +0100480 auto inputHandle = boost::polymorphic_downcast<IAclTensorHandle*>(queueDescriptor.m_Inputs[0]);
481 auto outputHandle = boost::polymorphic_downcast<IAclTensorHandle*>(queueDescriptor.m_Outputs[0]);
telsoa01c577f2c2018-08-31 09:22:23 +0100482 BOOST_TEST(TestNeonTensorHandleInfo(inputHandle, TensorInfo({4, 1}, DataType)));
483 BOOST_TEST(TestNeonTensorHandleInfo(outputHandle, TensorInfo({1, 4}, DataType)));
telsoa014fcda012018-03-09 14:13:49 +0000484}
485
telsoa01c577f2c2018-08-31 09:22:23 +0100486#ifdef __ARM_FEATURE_FP16_VECTOR_ARITHMETIC
487BOOST_AUTO_TEST_CASE(CreateReshapeFloat16Workload)
488{
Nattapat Chaimanowongcce11fc2018-10-12 16:30:56 +0100489 NeonCreateReshapeWorkloadTest<DataType::Float16>();
telsoa01c577f2c2018-08-31 09:22:23 +0100490}
491#endif
492
arovir019e53a352018-08-31 15:26:35 +0100493BOOST_AUTO_TEST_CASE(CreateReshapeFloatWorkload)
telsoa014fcda012018-03-09 14:13:49 +0000494{
Nattapat Chaimanowongcce11fc2018-10-12 16:30:56 +0100495 NeonCreateReshapeWorkloadTest<DataType::Float32>();
telsoa014fcda012018-03-09 14:13:49 +0000496}
497
498BOOST_AUTO_TEST_CASE(CreateReshapeUint8Workload)
499{
Nattapat Chaimanowongcce11fc2018-10-12 16:30:56 +0100500 NeonCreateReshapeWorkloadTest<DataType::QuantisedAsymm8>();
telsoa014fcda012018-03-09 14:13:49 +0000501}
502
Ellen Norris-Thompson37e68682019-07-15 14:23:30 +0100503template <typename ResizeWorkloadType, armnn::DataType DataType>
504static void NeonCreateResizeWorkloadTest(DataLayout dataLayout)
505{
506 Graph graph;
507 NeonWorkloadFactory factory =
508 NeonWorkloadFactoryHelper::GetFactory(NeonWorkloadFactoryHelper::GetMemoryManager());
509 auto workload = CreateResizeBilinearWorkloadTest<ResizeWorkloadType, DataType>(factory, graph, dataLayout);
510
511 auto queueDescriptor = workload->GetData();
512
513 auto inputHandle = boost::polymorphic_downcast<IAclTensorHandle*>(queueDescriptor.m_Inputs[0]);
514 auto outputHandle = boost::polymorphic_downcast<IAclTensorHandle*>(queueDescriptor.m_Outputs[0]);
515
516 switch (dataLayout)
517 {
518 case DataLayout::NHWC:
519 BOOST_TEST(CompareIAclTensorHandleShape(inputHandle, { 2, 4, 4, 3 }));
520 BOOST_TEST(CompareIAclTensorHandleShape(outputHandle, { 2, 2, 2, 3 }));
521 break;
522 case DataLayout::NCHW:
523 default:
524 BOOST_TEST(CompareIAclTensorHandleShape(inputHandle, { 2, 3, 4, 4 }));
525 BOOST_TEST(CompareIAclTensorHandleShape(outputHandle, { 2, 3, 2, 2 }));
526 }
527}
528
529BOOST_AUTO_TEST_CASE(CreateResizeFloat32NchwWorkload)
530{
531 NeonCreateResizeWorkloadTest<NeonResizeWorkload, armnn::DataType::Float32>(DataLayout::NCHW);
532}
533
534BOOST_AUTO_TEST_CASE(CreateResizeUint8NchwWorkload)
535{
536 NeonCreateResizeWorkloadTest<NeonResizeWorkload, armnn::DataType::QuantisedAsymm8>(DataLayout::NCHW);
537}
538
539BOOST_AUTO_TEST_CASE(CreateResizeFloat32NhwcWorkload)
540{
541 NeonCreateResizeWorkloadTest<NeonResizeWorkload, armnn::DataType::Float32>(DataLayout::NHWC);
542}
543
544BOOST_AUTO_TEST_CASE(CreateResizeUint8NhwcWorkload)
545{
546 NeonCreateResizeWorkloadTest<NeonResizeWorkload, armnn::DataType::QuantisedAsymm8>(DataLayout::NHWC);
547}
548
telsoa01c577f2c2018-08-31 09:22:23 +0100549template <typename SoftmaxWorkloadType, typename armnn::DataType DataType>
550static void NeonCreateSoftmaxWorkloadTest()
telsoa014fcda012018-03-09 14:13:49 +0000551{
Aron Virginas-Tar5caf9072018-11-14 18:35:18 +0000552 Graph graph;
553 NeonWorkloadFactory factory =
554 NeonWorkloadFactoryHelper::GetFactory(NeonWorkloadFactoryHelper::GetMemoryManager());
555
telsoa01c577f2c2018-08-31 09:22:23 +0100556 auto workload = CreateSoftmaxWorkloadTest<SoftmaxWorkloadType, DataType>(factory, graph);
telsoa014fcda012018-03-09 14:13:49 +0000557
telsoa01c577f2c2018-08-31 09:22:23 +0100558 // Checks that outputs and inputs are as we expect them (see definition of CreateSoftmaxWorkloadTest).
telsoa014fcda012018-03-09 14:13:49 +0000559 SoftmaxQueueDescriptor queueDescriptor = workload->GetData();
Derek Lambertic81855f2019-06-13 17:34:19 +0100560 auto inputHandle = boost::polymorphic_downcast<IAclTensorHandle*>(queueDescriptor.m_Inputs[0]);
561 auto outputHandle = boost::polymorphic_downcast<IAclTensorHandle*>(queueDescriptor.m_Outputs[0]);
telsoa01c577f2c2018-08-31 09:22:23 +0100562 BOOST_TEST(TestNeonTensorHandleInfo(inputHandle, TensorInfo({4, 1}, DataType)));
563 BOOST_TEST(TestNeonTensorHandleInfo(outputHandle, TensorInfo({4, 1}, DataType)));
564}
565
566#ifdef __ARM_FEATURE_FP16_VECTOR_ARITHMETIC
567BOOST_AUTO_TEST_CASE(CreateSoftmaxFloat16Workload)
568{
arovir019e53a352018-08-31 15:26:35 +0100569 NeonCreateSoftmaxWorkloadTest<NeonSoftmaxFloatWorkload, DataType::Float16>();
telsoa01c577f2c2018-08-31 09:22:23 +0100570}
571#endif
572
arovir019e53a352018-08-31 15:26:35 +0100573BOOST_AUTO_TEST_CASE(CreateSoftmaxFloatWorkload)
telsoa01c577f2c2018-08-31 09:22:23 +0100574{
arovir019e53a352018-08-31 15:26:35 +0100575 NeonCreateSoftmaxWorkloadTest<NeonSoftmaxFloatWorkload, DataType::Float32>();
telsoa014fcda012018-03-09 14:13:49 +0000576}
577
Ellen Norris-Thompson29794572019-06-26 16:40:36 +0100578template <typename SpaceToDepthWorkloadType, typename armnn::DataType DataType>
579static void NeonSpaceToDepthWorkloadTest()
580{
581 Graph graph;
582 NeonWorkloadFactory factory =
583 NeonWorkloadFactoryHelper::GetFactory(NeonWorkloadFactoryHelper::GetMemoryManager());
584
585 auto workload = CreateSpaceToDepthWorkloadTest<SpaceToDepthWorkloadType, DataType>(factory, graph);
586
587 SpaceToDepthQueueDescriptor queueDescriptor = workload->GetData();
588 auto inputHandle = boost::polymorphic_downcast<IAclTensorHandle*>(queueDescriptor.m_Inputs[0]);
589 auto outputHandle = boost::polymorphic_downcast<IAclTensorHandle*>(queueDescriptor.m_Outputs[0]);
590
591 BOOST_TEST(TestNeonTensorHandleInfo(inputHandle, TensorInfo({ 1, 2, 2, 1 }, DataType)));
592 BOOST_TEST(TestNeonTensorHandleInfo(outputHandle, TensorInfo({ 1, 1, 1, 4 }, DataType)));
593}
594
595BOOST_AUTO_TEST_CASE(CreateSpaceToDepthFloat32Workload)
596{
597 NeonSpaceToDepthWorkloadTest<NeonSpaceToDepthWorkload, armnn::DataType::Float32>();
598}
599
600BOOST_AUTO_TEST_CASE(CreateSpaceToDepthFloat16Workload)
601{
602 NeonSpaceToDepthWorkloadTest<NeonSpaceToDepthWorkload, armnn::DataType::Float16>();
603}
604
605BOOST_AUTO_TEST_CASE(CreateSpaceToDepthQAsymm8Workload)
606{
607 NeonSpaceToDepthWorkloadTest<NeonSpaceToDepthWorkload, armnn::DataType::QuantisedAsymm8>();
608}
609
610BOOST_AUTO_TEST_CASE(CreateSpaceToDepthQSymm16Workload)
611{
612 NeonSpaceToDepthWorkloadTest<NeonSpaceToDepthWorkload, armnn::DataType::QuantisedSymm16>();
613}
614
telsoa014fcda012018-03-09 14:13:49 +0000615BOOST_AUTO_TEST_CASE(CreateSplitterWorkload)
616{
617 Graph graph;
Aron Virginas-Tar5caf9072018-11-14 18:35:18 +0000618 NeonWorkloadFactory factory =
619 NeonWorkloadFactoryHelper::GetFactory(NeonWorkloadFactoryHelper::GetMemoryManager());
620
Nattapat Chaimanowong14766d72018-10-12 15:09:53 +0100621 auto workload = CreateSplitterWorkloadTest<NeonSplitterWorkload, DataType::Float32>(factory, graph);
telsoa014fcda012018-03-09 14:13:49 +0000622
telsoa01c577f2c2018-08-31 09:22:23 +0100623 // Checks that outputs are as we expect them (see definition of CreateSplitterWorkloadTest).
telsoa014fcda012018-03-09 14:13:49 +0000624 SplitterQueueDescriptor queueDescriptor = workload->GetData();
Derek Lambertic81855f2019-06-13 17:34:19 +0100625 auto inputHandle = boost::polymorphic_downcast<IAclTensorHandle*>(queueDescriptor.m_Inputs[0]);
surmeh013537c2c2018-05-18 16:31:43 +0100626 BOOST_TEST(TestNeonTensorHandleInfo(inputHandle, TensorInfo({5, 7, 7}, DataType::Float32)));
627
Derek Lambertic81855f2019-06-13 17:34:19 +0100628 auto outputHandle0 = boost::polymorphic_downcast<IAclTensorHandle*>(queueDescriptor.m_Outputs[0]);
surmeh013537c2c2018-05-18 16:31:43 +0100629 BOOST_TEST(TestNeonTensorHandleInfo(outputHandle0, TensorInfo({1, 7, 7}, DataType::Float32)));
630
Derek Lambertic81855f2019-06-13 17:34:19 +0100631 auto outputHandle1 = boost::polymorphic_downcast<IAclTensorHandle*>(queueDescriptor.m_Outputs[1]);
surmeh013537c2c2018-05-18 16:31:43 +0100632 BOOST_TEST(TestNeonTensorHandleInfo(outputHandle1, TensorInfo({2, 7, 7}, DataType::Float32)));
633
Derek Lambertic81855f2019-06-13 17:34:19 +0100634 auto outputHandle2 = boost::polymorphic_downcast<IAclTensorHandle*>(queueDescriptor.m_Outputs[2]);
surmeh013537c2c2018-05-18 16:31:43 +0100635 BOOST_TEST(TestNeonTensorHandleInfo(outputHandle2, TensorInfo({2, 7, 7}, DataType::Float32)));
telsoa014fcda012018-03-09 14:13:49 +0000636}
637
Jim Flynne242f2d2019-05-22 14:24:13 +0100638BOOST_AUTO_TEST_CASE(CreateSplitterConcat)
telsoa014fcda012018-03-09 14:13:49 +0000639{
telsoa01c577f2c2018-08-31 09:22:23 +0100640 // Tests that it is possible to decide which output of the splitter layer
Jim Flynne242f2d2019-05-22 14:24:13 +0100641 // should be lined to which input of the concat layer.
telsoa01c577f2c2018-08-31 09:22:23 +0100642 // We tested that is is possible to specify 0th output
Jim Flynne242f2d2019-05-22 14:24:13 +0100643 // of the splitter to be the 1st input to the concat, and the 1st output of the splitter to be 0th input
644 // of the concat.
telsoa014fcda012018-03-09 14:13:49 +0000645
646 Graph graph;
Aron Virginas-Tar5caf9072018-11-14 18:35:18 +0000647 NeonWorkloadFactory factory =
648 NeonWorkloadFactoryHelper::GetFactory(NeonWorkloadFactoryHelper::GetMemoryManager());
telsoa014fcda012018-03-09 14:13:49 +0000649
650 auto workloads =
Jim Flynne242f2d2019-05-22 14:24:13 +0100651 CreateSplitterConcatWorkloadTest<NeonSplitterWorkload, NeonConcatWorkload,
telsoa01c577f2c2018-08-31 09:22:23 +0100652 DataType::Float32>(factory, graph);
telsoa014fcda012018-03-09 14:13:49 +0000653
654 auto wlSplitter = std::move(workloads.first);
Jim Flynne242f2d2019-05-22 14:24:13 +0100655 auto wlConcat = std::move(workloads.second);
telsoa014fcda012018-03-09 14:13:49 +0000656
telsoa01c577f2c2018-08-31 09:22:23 +0100657 //Checks that the index of inputs/outputs matches what we declared on InputDescriptor construction.
Derek Lambertic81855f2019-06-13 17:34:19 +0100658 armnn::IAclTensorHandle* sOut0 = dynamic_cast<armnn::IAclTensorHandle*>(wlSplitter->GetData().m_Outputs[0]);
659 armnn::IAclTensorHandle* sOut1 = dynamic_cast<armnn::IAclTensorHandle*>(wlSplitter->GetData().m_Outputs[1]);
660 armnn::IAclTensorHandle* mIn0 = dynamic_cast<armnn::IAclTensorHandle*>(wlConcat->GetData().m_Inputs[0]);
661 armnn::IAclTensorHandle* mIn1 = dynamic_cast<armnn::IAclTensorHandle*>(wlConcat->GetData().m_Inputs[1]);
telsoa014fcda012018-03-09 14:13:49 +0000662
663 BOOST_TEST(sOut0);
664 BOOST_TEST(sOut1);
665 BOOST_TEST(mIn0);
666 BOOST_TEST(mIn1);
667
668 bool validDataPointers = (sOut0 == mIn1) && (sOut1 == mIn0);
669
670 BOOST_TEST(validDataPointers);
671}
672
673BOOST_AUTO_TEST_CASE(CreateSingleOutputMultipleInputs)
674{
telsoa01c577f2c2018-08-31 09:22:23 +0100675 // Tests that it is possible to assign multiple (two) different layers to each of the outputs of a splitter layer.
676 // 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 +0000677
678 Graph graph;
Aron Virginas-Tar5caf9072018-11-14 18:35:18 +0000679 NeonWorkloadFactory factory =
680 NeonWorkloadFactoryHelper::GetFactory(NeonWorkloadFactoryHelper::GetMemoryManager());
681
Nattapat Chaimanowong14766d72018-10-12 15:09:53 +0100682 std::unique_ptr<NeonSplitterWorkload> wlSplitter;
Nattapat Chaimanowongd4b70592018-10-12 11:21:49 +0100683 std::unique_ptr<NeonActivationWorkload> wlActiv0_0;
684 std::unique_ptr<NeonActivationWorkload> wlActiv0_1;
685 std::unique_ptr<NeonActivationWorkload> wlActiv1_0;
686 std::unique_ptr<NeonActivationWorkload> wlActiv1_1;
telsoa014fcda012018-03-09 14:13:49 +0000687
Nattapat Chaimanowong14766d72018-10-12 15:09:53 +0100688 CreateSplitterMultipleInputsOneOutputWorkloadTest<NeonSplitterWorkload,
Nattapat Chaimanowongd4b70592018-10-12 11:21:49 +0100689 NeonActivationWorkload, DataType::Float32>(factory, graph, wlSplitter, wlActiv0_0, wlActiv0_1,
690 wlActiv1_0, wlActiv1_1);
telsoa014fcda012018-03-09 14:13:49 +0000691
Derek Lambertic81855f2019-06-13 17:34:19 +0100692 armnn::IAclTensorHandle* sOut0 = dynamic_cast<armnn::IAclTensorHandle*>(wlSplitter->GetData().m_Outputs[0]);
693 armnn::IAclTensorHandle* sOut1 = dynamic_cast<armnn::IAclTensorHandle*>(wlSplitter->GetData().m_Outputs[1]);
694 armnn::IAclTensorHandle* activ0_0Im = dynamic_cast<armnn::IAclTensorHandle*>(wlActiv0_0->GetData().m_Inputs[0]);
695 armnn::IAclTensorHandle* activ0_1Im = dynamic_cast<armnn::IAclTensorHandle*>(wlActiv0_1->GetData().m_Inputs[0]);
696 armnn::IAclTensorHandle* activ1_0Im = dynamic_cast<armnn::IAclTensorHandle*>(wlActiv1_0->GetData().m_Inputs[0]);
697 armnn::IAclTensorHandle* activ1_1Im = dynamic_cast<armnn::IAclTensorHandle*>(wlActiv1_1->GetData().m_Inputs[0]);
telsoa014fcda012018-03-09 14:13:49 +0000698
699
700 BOOST_TEST(sOut0);
701 BOOST_TEST(sOut1);
702 BOOST_TEST(activ0_0Im);
703 BOOST_TEST(activ0_1Im);
704 BOOST_TEST(activ1_0Im);
705 BOOST_TEST(activ1_1Im);
706
707 bool validDataPointers = (sOut0 == activ0_0Im) && (sOut0 == activ0_1Im) &&
708 (sOut1 == activ1_0Im) && (sOut1 == activ1_1Im);
709
710 BOOST_TEST(validDataPointers);
711}
712
Matteo Martincigh14a25f02019-08-27 16:41:11 +0100713#if defined(ARMNNREF_ENABLED)
Matteo Martincighe67edb22019-08-14 14:05:46 +0100714
715// This test unit needs the reference backend, it's not available if the reference backend is not built
716
telsoa014fcda012018-03-09 14:13:49 +0000717BOOST_AUTO_TEST_CASE(CreateMemCopyWorkloadsNeon)
718{
Aron Virginas-Tar5caf9072018-11-14 18:35:18 +0000719 NeonWorkloadFactory factory =
720 NeonWorkloadFactoryHelper::GetFactory(NeonWorkloadFactoryHelper::GetMemoryManager());
Derek Lambertic81855f2019-06-13 17:34:19 +0100721 CreateMemCopyWorkloads<IAclTensorHandle>(factory);
telsoa014fcda012018-03-09 14:13:49 +0000722}
723
Matteo Martincighe67edb22019-08-14 14:05:46 +0100724#endif
725
Matteo Martincighbcd3c852018-09-28 14:14:12 +0100726template <typename L2NormalizationWorkloadType, typename armnn::DataType DataType>
727static void NeonCreateL2NormalizationWorkloadTest(DataLayout dataLayout)
728{
Matteo Martincigh2400b6d2018-10-09 18:19:20 +0100729 Graph graph;
Aron Virginas-Tar5caf9072018-11-14 18:35:18 +0000730 NeonWorkloadFactory factory =
731 NeonWorkloadFactoryHelper::GetFactory(NeonWorkloadFactoryHelper::GetMemoryManager());
732
Matteo Martincigh2400b6d2018-10-09 18:19:20 +0100733 auto workload =
734 CreateL2NormalizationWorkloadTest<L2NormalizationWorkloadType, DataType>(factory, graph, dataLayout);
Matteo Martincighbcd3c852018-09-28 14:14:12 +0100735
736 // Checks that inputs/outputs are as we expect them (see definition of CreateNormalizationWorkloadTest).
737 L2NormalizationQueueDescriptor queueDescriptor = workload->GetData();
Derek Lambertic81855f2019-06-13 17:34:19 +0100738 auto inputHandle = boost::polymorphic_downcast<IAclTensorHandle*>(queueDescriptor.m_Inputs[0]);
739 auto outputHandle = boost::polymorphic_downcast<IAclTensorHandle*>(queueDescriptor.m_Outputs[0]);
Matteo Martincigh2400b6d2018-10-09 18:19:20 +0100740
741 TensorShape inputShape = (dataLayout == DataLayout::NCHW) ?
742 TensorShape{ 5, 20, 50, 67 } : TensorShape{ 5, 50, 67, 20 };
743 TensorShape outputShape = (dataLayout == DataLayout::NCHW) ?
744 TensorShape{ 5, 20, 50, 67 } : TensorShape{ 5, 50, 67, 20 };
745
746 BOOST_TEST(TestNeonTensorHandleInfo(inputHandle, TensorInfo(inputShape, DataType)));
747 BOOST_TEST(TestNeonTensorHandleInfo(outputHandle, TensorInfo(outputShape, DataType)));
Matteo Martincighbcd3c852018-09-28 14:14:12 +0100748}
749
750#ifdef __ARM_FEATURE_FP16_VECTOR_ARITHMETIC
751BOOST_AUTO_TEST_CASE(CreateL2NormalizationFloat16NchwWorkload)
752{
753 NeonCreateL2NormalizationWorkloadTest<NeonL2NormalizationFloatWorkload, DataType::Float16>(DataLayout::NCHW);
754}
755
756BOOST_AUTO_TEST_CASE(CreateL2NormalizationFloat16NhwcWorkload)
757{
758 NeonCreateL2NormalizationWorkloadTest<NeonL2NormalizationFloatWorkload, DataType::Float16>(DataLayout::NHWC);
759}
760#endif
761
762BOOST_AUTO_TEST_CASE(CreateL2NormalizationNchwWorkload)
763{
764 NeonCreateL2NormalizationWorkloadTest<NeonL2NormalizationFloatWorkload, DataType::Float32>(DataLayout::NCHW);
765}
766
767BOOST_AUTO_TEST_CASE(CreateL2NormalizationNhwcWorkload)
768{
769 NeonCreateL2NormalizationWorkloadTest<NeonL2NormalizationFloatWorkload, DataType::Float32>(DataLayout::NHWC);
770}
771
Jan Eilersad5293a2019-07-08 09:57:55 +0100772template <typename LstmWorkloadType>
773static void NeonCreateLstmWorkloadTest()
774{
775 Graph graph;
776 NeonWorkloadFactory factory =
777 NeonWorkloadFactoryHelper::GetFactory(NeonWorkloadFactoryHelper::GetMemoryManager());
778
779 auto workload = CreateLstmWorkloadTest<LstmWorkloadType>(factory, graph);
780
781 LstmQueueDescriptor queueDescriptor = workload->GetData();
782
783 auto inputHandle = boost::polymorphic_downcast<IAclTensorHandle*>(queueDescriptor.m_Inputs[0]);
784 auto outputHandle = boost::polymorphic_downcast<IAclTensorHandle*>(queueDescriptor.m_Outputs[1]);
785
786 BOOST_TEST(TestNeonTensorHandleInfo(inputHandle, TensorInfo({ 2, 2 }, DataType::Float32)));
787 BOOST_TEST(TestNeonTensorHandleInfo(outputHandle, TensorInfo({ 2, 4 }, DataType::Float32)));
788}
789
790BOOST_AUTO_TEST_CASE(CreateLSTMWorkloadFloatWorkload)
791{
792 NeonCreateLstmWorkloadTest<NeonLstmFloatWorkload>();
793}
794
Jim Flynne242f2d2019-05-22 14:24:13 +0100795template <typename ConcatWorkloadType, armnn::DataType DataType>
796static void NeonCreateConcatWorkloadTest(std::initializer_list<unsigned int> outputShape,
narpra015cdda352018-11-19 15:30:27 +0000797 unsigned int concatAxis)
798{
799 Graph graph;
800 NeonWorkloadFactory factory =
801 NeonWorkloadFactoryHelper::GetFactory(NeonWorkloadFactoryHelper::GetMemoryManager());
802
Jim Flynne242f2d2019-05-22 14:24:13 +0100803 auto workload = CreateConcatWorkloadTest<ConcatWorkloadType, DataType>(factory, graph, outputShape, concatAxis);
narpra015cdda352018-11-19 15:30:27 +0000804
Jim Flynne242f2d2019-05-22 14:24:13 +0100805 ConcatQueueDescriptor queueDescriptor = workload->GetData();
Derek Lambertic81855f2019-06-13 17:34:19 +0100806 auto inputHandle0 = boost::polymorphic_downcast<IAclTensorHandle*>(queueDescriptor.m_Inputs[0]);
807 auto inputHandle1 = boost::polymorphic_downcast<IAclTensorHandle*>(queueDescriptor.m_Inputs[1]);
808 auto outputHandle = boost::polymorphic_downcast<IAclTensorHandle*>(queueDescriptor.m_Outputs[0]);
narpra015cdda352018-11-19 15:30:27 +0000809
810 BOOST_TEST(TestNeonTensorHandleInfo(inputHandle0, TensorInfo({ 2, 3, 2, 5 }, DataType)));
811 BOOST_TEST(TestNeonTensorHandleInfo(inputHandle1, TensorInfo({ 2, 3, 2, 5 }, DataType)));
812 BOOST_TEST(TestNeonTensorHandleInfo(outputHandle, TensorInfo(outputShape, DataType)));
813}
814
Jim Flynne242f2d2019-05-22 14:24:13 +0100815BOOST_AUTO_TEST_CASE(CreateConcatDim0Float32Workload)
narpra015cdda352018-11-19 15:30:27 +0000816{
Jim Flynne242f2d2019-05-22 14:24:13 +0100817 NeonCreateConcatWorkloadTest<NeonConcatWorkload, armnn::DataType::Float32>({ 4, 3, 2, 5 }, 0);
narpra015cdda352018-11-19 15:30:27 +0000818}
819
Jim Flynne242f2d2019-05-22 14:24:13 +0100820BOOST_AUTO_TEST_CASE(CreateConcatDim1Float32Workload)
narpra015cdda352018-11-19 15:30:27 +0000821{
Jim Flynne242f2d2019-05-22 14:24:13 +0100822 NeonCreateConcatWorkloadTest<NeonConcatWorkload, armnn::DataType::Float32>({ 2, 6, 2, 5 }, 1);
narpra015cdda352018-11-19 15:30:27 +0000823}
824
Jim Flynne242f2d2019-05-22 14:24:13 +0100825BOOST_AUTO_TEST_CASE(CreateConcatDim3Float32Workload)
narpra015cdda352018-11-19 15:30:27 +0000826{
Jim Flynne242f2d2019-05-22 14:24:13 +0100827 NeonCreateConcatWorkloadTest<NeonConcatWorkload, armnn::DataType::Float32>({ 2, 3, 2, 10 }, 3);
narpra015cdda352018-11-19 15:30:27 +0000828}
829
Jim Flynne242f2d2019-05-22 14:24:13 +0100830BOOST_AUTO_TEST_CASE(CreateConcatDim0Uint8Workload)
narpra0163b08822018-11-20 11:29:12 +0000831{
Jim Flynne242f2d2019-05-22 14:24:13 +0100832 NeonCreateConcatWorkloadTest<NeonConcatWorkload, armnn::DataType::QuantisedAsymm8>({ 4, 3, 2, 5 }, 0);
narpra0163b08822018-11-20 11:29:12 +0000833}
834
Jim Flynne242f2d2019-05-22 14:24:13 +0100835BOOST_AUTO_TEST_CASE(CreateConcatDim1Uint8Workload)
narpra0163b08822018-11-20 11:29:12 +0000836{
Jim Flynne242f2d2019-05-22 14:24:13 +0100837 NeonCreateConcatWorkloadTest<NeonConcatWorkload, armnn::DataType::QuantisedAsymm8>({ 2, 6, 2, 5 }, 1);
narpra0163b08822018-11-20 11:29:12 +0000838}
839
Jim Flynne242f2d2019-05-22 14:24:13 +0100840BOOST_AUTO_TEST_CASE(CreateConcatDim3Uint8Workload)
narpra0163b08822018-11-20 11:29:12 +0000841{
Jim Flynne242f2d2019-05-22 14:24:13 +0100842 NeonCreateConcatWorkloadTest<NeonConcatWorkload, armnn::DataType::QuantisedAsymm8>({ 2, 3, 2, 10 }, 3);
narpra0163b08822018-11-20 11:29:12 +0000843}
844
Matthew Jackson87f65ea2019-08-01 10:01:34 +0100845template <armnn::DataType DataType>
846static void NeonCreateStackWorkloadTest(const std::initializer_list<unsigned int>& inputShape,
847 const std::initializer_list<unsigned int>& outputShape,
848 unsigned int axis,
849 unsigned int numInputs)
850{
851 armnn::Graph graph;
852 NeonWorkloadFactory factory =
853 NeonWorkloadFactoryHelper::GetFactory(NeonWorkloadFactoryHelper::GetMemoryManager());
854
855 auto workload = CreateStackWorkloadTest<NeonStackWorkload, DataType>(factory,
856 graph,
857 TensorShape(inputShape),
858 TensorShape(outputShape),
859 axis,
860 numInputs);
861
862 // Check inputs and output are as expected
863 StackQueueDescriptor queueDescriptor = workload->GetData();
864 for (unsigned int i = 0; i < numInputs; ++i)
865 {
866 auto inputHandle = boost::polymorphic_downcast<IAclTensorHandle*>(queueDescriptor.m_Inputs[i]);
867 BOOST_TEST(TestNeonTensorHandleInfo(inputHandle, TensorInfo(inputShape, DataType)));
868 }
869 auto outputHandle = boost::polymorphic_downcast<IAclTensorHandle*>(queueDescriptor.m_Outputs[0]);
870 BOOST_TEST(TestNeonTensorHandleInfo(outputHandle, TensorInfo(outputShape, DataType)));
871}
872
873BOOST_AUTO_TEST_CASE(CreateStackFloat32Workload)
874{
875 NeonCreateStackWorkloadTest<armnn::DataType::Float32>({ 3, 4, 5 }, { 3, 4, 2, 5 }, 2, 2);
876}
877
878BOOST_AUTO_TEST_CASE(CreateStackUint8Workload)
879{
880 NeonCreateStackWorkloadTest<armnn::DataType::QuantisedAsymm8>({ 3, 4, 5 }, { 3, 4, 2, 5 }, 2, 2);
881}
882
Francis Murtagh4fc3c482019-08-02 13:20:54 +0100883template <typename QuantizedLstmWorkloadType>
884static void NeonCreateQuantizedLstmWorkloadTest()
885{
886 using boost::polymorphic_downcast;
887
888 Graph graph;
889 NeonWorkloadFactory factory = NeonWorkloadFactoryHelper::GetFactory(NeonWorkloadFactoryHelper::GetMemoryManager());
890
891 auto workload = CreateQuantizedLstmWorkloadTest<QuantizedLstmWorkloadType>(factory, graph);
892
893 QuantizedLstmQueueDescriptor queueDescriptor = workload->GetData();
894
895 IAclTensorHandle* inputHandle = polymorphic_downcast<IAclTensorHandle*>(queueDescriptor.m_Inputs[0]);
896 BOOST_TEST((inputHandle->GetShape() == TensorShape({2, 2})));
897 BOOST_TEST((inputHandle->GetDataType() == arm_compute::DataType::QASYMM8));
898
899 IAclTensorHandle* cellStateInHandle = polymorphic_downcast<IAclTensorHandle*>(queueDescriptor.m_Inputs[1]);
900 BOOST_TEST((cellStateInHandle->GetShape() == TensorShape({2, 4})));
901 BOOST_TEST((cellStateInHandle->GetDataType() == arm_compute::DataType::QSYMM16));
902
903 IAclTensorHandle* outputStateInHandle = polymorphic_downcast<IAclTensorHandle*>(queueDescriptor.m_Inputs[2]);
904 BOOST_TEST((outputStateInHandle->GetShape() == TensorShape({2, 4})));
905 BOOST_TEST((outputStateInHandle->GetDataType() == arm_compute::DataType::QASYMM8));
906
907 IAclTensorHandle* cellStateOutHandle = polymorphic_downcast<IAclTensorHandle*>(queueDescriptor.m_Outputs[0]);
908 BOOST_TEST((cellStateOutHandle->GetShape() == TensorShape({2, 4})));
909 BOOST_TEST((cellStateOutHandle->GetDataType() == arm_compute::DataType::QSYMM16));
910
911 IAclTensorHandle* outputStateOutHandle = polymorphic_downcast<IAclTensorHandle*>(queueDescriptor.m_Outputs[1]);
912 BOOST_TEST((outputStateOutHandle->GetShape() == TensorShape({2, 4})));
913 BOOST_TEST((outputStateOutHandle->GetDataType() == arm_compute::DataType::QASYMM8));
914}
915
916BOOST_AUTO_TEST_CASE(CreateQuantizedLstmWorkload)
917{
918 NeonCreateQuantizedLstmWorkloadTest<NeonQuantizedLstmWorkload>();
919}
920
telsoa014fcda012018-03-09 14:13:49 +0000921BOOST_AUTO_TEST_SUITE_END()