blob: 6a4f612881b6bbcec163a1e58d5b49b2393b3788 [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
Aron Virginas-Tar0dd3b432019-09-10 13:55:09 +0100184template <typename WorkloadType,
185 typename DescriptorType,
186 typename LayerType,
187 armnn::DataType DataType>
188static void NeonCreateElementwiseUnaryWorkloadTest()
189{
190 Graph graph;
191 NeonWorkloadFactory factory =
192 NeonWorkloadFactoryHelper::GetFactory(NeonWorkloadFactoryHelper::GetMemoryManager());
193
194 auto workload = CreateElementwiseUnaryWorkloadTest
195 <WorkloadType, DescriptorType, LayerType, DataType>(factory, graph);
196
197 DescriptorType queueDescriptor = workload->GetData();
198
199 auto inputHandle = boost::polymorphic_downcast<IAclTensorHandle*>(queueDescriptor.m_Inputs[0]);
200 auto outputHandle = boost::polymorphic_downcast<IAclTensorHandle*>(queueDescriptor.m_Outputs[0]);
201
202 BOOST_TEST(TestNeonTensorHandleInfo(inputHandle, TensorInfo({2, 3}, DataType)));
203 BOOST_TEST(TestNeonTensorHandleInfo(outputHandle, TensorInfo({2, 3}, DataType)));
204}
205
206BOOST_AUTO_TEST_CASE(CreateRsqrtFloat32Workload)
207{
208 NeonCreateElementwiseUnaryWorkloadTest<NeonRsqrtWorkload,
209 RsqrtQueueDescriptor,
210 RsqrtLayer,
211 DataType::Float32>();
212}
213
telsoa01c577f2c2018-08-31 09:22:23 +0100214template <typename BatchNormalizationWorkloadType, typename armnn::DataType DataType>
Nikhil Rajd1340932018-10-18 14:27:50 +0100215static void NeonCreateBatchNormalizationWorkloadTest(DataLayout dataLayout)
telsoa014fcda012018-03-09 14:13:49 +0000216{
Aron Virginas-Tar5caf9072018-11-14 18:35:18 +0000217 Graph graph;
218 NeonWorkloadFactory factory =
219 NeonWorkloadFactoryHelper::GetFactory(NeonWorkloadFactoryHelper::GetMemoryManager());
220
Nikhil Rajd1340932018-10-18 14:27:50 +0100221 auto workload = CreateBatchNormalizationWorkloadTest<BatchNormalizationWorkloadType, DataType>
222 (factory, graph, dataLayout);
telsoa014fcda012018-03-09 14:13:49 +0000223
telsoa01c577f2c2018-08-31 09:22:23 +0100224 // Checks that outputs and inputs are as we expect them (see definition of CreateBatchNormalizationWorkloadTest).
telsoa014fcda012018-03-09 14:13:49 +0000225 BatchNormalizationQueueDescriptor queueDescriptor = workload->GetData();
Derek Lambertic81855f2019-06-13 17:34:19 +0100226 auto inputHandle = boost::polymorphic_downcast<IAclTensorHandle*>(queueDescriptor.m_Inputs[0]);
227 auto outputHandle = boost::polymorphic_downcast<IAclTensorHandle*>(queueDescriptor.m_Outputs[0]);
Nikhil Rajd1340932018-10-18 14:27:50 +0100228
229 TensorShape inputShape = (dataLayout == DataLayout::NCHW) ? TensorShape{2, 3, 4, 4} : TensorShape{2, 4, 4, 3};
230 TensorShape outputShape = (dataLayout == DataLayout::NCHW) ? TensorShape{2, 3, 4, 4} : TensorShape{2, 4, 4, 3};
231
232 BOOST_TEST(TestNeonTensorHandleInfo(inputHandle, TensorInfo(inputShape, DataType)));
233 BOOST_TEST(TestNeonTensorHandleInfo(outputHandle, TensorInfo(outputShape, DataType)));
telsoa014fcda012018-03-09 14:13:49 +0000234}
235
telsoa01c577f2c2018-08-31 09:22:23 +0100236#ifdef __ARM_FEATURE_FP16_VECTOR_ARITHMETIC
Nikhil Rajd1340932018-10-18 14:27:50 +0100237BOOST_AUTO_TEST_CASE(CreateBatchNormalizationFloat16NchwWorkload)
telsoa01c577f2c2018-08-31 09:22:23 +0100238{
Matthew Benthamc48ac8c2018-12-12 16:15:59 +0000239 NeonCreateBatchNormalizationWorkloadTest<NeonBatchNormalizationWorkload, DataType::Float16>(DataLayout::NCHW);
Nikhil Rajd1340932018-10-18 14:27:50 +0100240}
241
242BOOST_AUTO_TEST_CASE(CreateBatchNormalizationFloat16NhwcWorkload)
243{
Matthew Benthamc48ac8c2018-12-12 16:15:59 +0000244 NeonCreateBatchNormalizationWorkloadTest<NeonBatchNormalizationWorkload, DataType::Float16>(DataLayout::NHWC);
telsoa01c577f2c2018-08-31 09:22:23 +0100245}
246#endif
247
Nikhil Rajd1340932018-10-18 14:27:50 +0100248BOOST_AUTO_TEST_CASE(CreateBatchNormalizationFloatNchwWorkload)
telsoa01c577f2c2018-08-31 09:22:23 +0100249{
Matthew Benthamc48ac8c2018-12-12 16:15:59 +0000250 NeonCreateBatchNormalizationWorkloadTest<NeonBatchNormalizationWorkload, DataType::Float32>(DataLayout::NCHW);
Nikhil Rajd1340932018-10-18 14:27:50 +0100251}
252
253BOOST_AUTO_TEST_CASE(CreateBatchNormalizationFloatNhwcWorkload)
254{
Matthew Benthamc48ac8c2018-12-12 16:15:59 +0000255 NeonCreateBatchNormalizationWorkloadTest<NeonBatchNormalizationWorkload, DataType::Float32>(DataLayout::NHWC);
telsoa01c577f2c2018-08-31 09:22:23 +0100256}
257
Nattapat Chaimanowong974b65f2018-10-15 15:07:34 +0100258template <typename armnn::DataType DataType>
Francis Murtagh0d9d4192018-10-09 16:22:33 +0100259static void NeonCreateConvolution2dWorkloadTest(DataLayout dataLayout = DataLayout::NCHW)
telsoa014fcda012018-03-09 14:13:49 +0000260{
Aron Virginas-Tar5caf9072018-11-14 18:35:18 +0000261 Graph graph;
262 NeonWorkloadFactory factory =
263 NeonWorkloadFactoryHelper::GetFactory(NeonWorkloadFactoryHelper::GetMemoryManager());
264
265 auto workload = CreateConvolution2dWorkloadTest<NeonConvolution2dWorkload, DataType>(factory, graph, dataLayout);
Francis Murtagh0d9d4192018-10-09 16:22:33 +0100266
267 TensorShape inputShape = (dataLayout == DataLayout::NCHW) ? TensorShape{2, 3, 8, 16} : TensorShape{2, 8, 16, 3};
268 TensorShape outputShape = (dataLayout == DataLayout::NCHW) ? TensorShape{2, 2, 2, 10} : TensorShape{2, 2, 10, 2};
telsoa014fcda012018-03-09 14:13:49 +0000269
telsoa01c577f2c2018-08-31 09:22:23 +0100270 // Checks that outputs and inputs are as we expect them (see definition of CreateConvolution2dWorkloadTest).
telsoa014fcda012018-03-09 14:13:49 +0000271 Convolution2dQueueDescriptor queueDescriptor = workload->GetData();
Derek Lambertic81855f2019-06-13 17:34:19 +0100272 auto inputHandle = boost::polymorphic_downcast<IAclTensorHandle*>(queueDescriptor.m_Inputs[0]);
273 auto outputHandle = boost::polymorphic_downcast<IAclTensorHandle*>(queueDescriptor.m_Outputs[0]);
Francis Murtagh0d9d4192018-10-09 16:22:33 +0100274 BOOST_TEST(TestNeonTensorHandleInfo(inputHandle, TensorInfo(inputShape, DataType)));
275 BOOST_TEST(TestNeonTensorHandleInfo(outputHandle, TensorInfo(outputShape, DataType)));
telsoa014fcda012018-03-09 14:13:49 +0000276}
277
telsoa01c577f2c2018-08-31 09:22:23 +0100278#ifdef __ARM_FEATURE_FP16_VECTOR_ARITHMETIC
Francis Murtagh0d9d4192018-10-09 16:22:33 +0100279BOOST_AUTO_TEST_CASE(CreateConvolution2dFloat16NchwWorkload)
telsoa01c577f2c2018-08-31 09:22:23 +0100280{
Nattapat Chaimanowong974b65f2018-10-15 15:07:34 +0100281 NeonCreateConvolution2dWorkloadTest<DataType::Float16>();
telsoa01c577f2c2018-08-31 09:22:23 +0100282}
telsoa01c577f2c2018-08-31 09:22:23 +0100283
Francis Murtagh0d9d4192018-10-09 16:22:33 +0100284BOOST_AUTO_TEST_CASE(CreateConvolution2dFloat16NhwcWorkload)
285{
Nattapat Chaimanowong974b65f2018-10-15 15:07:34 +0100286 NeonCreateConvolution2dWorkloadTest<DataType::Float16>(DataLayout::NHWC);
Francis Murtagh0d9d4192018-10-09 16:22:33 +0100287}
288
289#endif
290BOOST_AUTO_TEST_CASE(CreateConvolution2dFloatNchwWorkload)
telsoa01c577f2c2018-08-31 09:22:23 +0100291{
Nattapat Chaimanowong974b65f2018-10-15 15:07:34 +0100292 NeonCreateConvolution2dWorkloadTest<DataType::Float32>();
telsoa01c577f2c2018-08-31 09:22:23 +0100293}
294
Francis Murtagh0d9d4192018-10-09 16:22:33 +0100295BOOST_AUTO_TEST_CASE(CreateConvolution2dFloatNhwcWorkload)
296{
Nattapat Chaimanowong974b65f2018-10-15 15:07:34 +0100297 NeonCreateConvolution2dWorkloadTest<DataType::Float32>(DataLayout::NHWC);
Francis Murtagh0d9d4192018-10-09 16:22:33 +0100298}
299
Nattapat Chaimanowong77140882018-10-17 11:12:19 +0100300template <typename armnn::DataType DataType>
Nikhil Rajcec6b652018-10-12 13:51:57 +0100301static void NeonCreateDepthWiseConvolutionWorkloadTest(DataLayout dataLayout)
302{
303 Graph graph;
Aron Virginas-Tar5caf9072018-11-14 18:35:18 +0000304 NeonWorkloadFactory factory =
305 NeonWorkloadFactoryHelper::GetFactory(NeonWorkloadFactoryHelper::GetMemoryManager());
Nikhil Rajcec6b652018-10-12 13:51:57 +0100306
Nattapat Chaimanowong77140882018-10-17 11:12:19 +0100307 auto workload = CreateDepthwiseConvolution2dWorkloadTest<NeonDepthwiseConvolutionWorkload,
Nikhil Rajcec6b652018-10-12 13:51:57 +0100308 DataType>(factory, graph, dataLayout);
309
310 // Checks that inputs/outputs are as we expect them (see definition of CreateNormalizationWorkloadTest).
311 DepthwiseConvolution2dQueueDescriptor queueDescriptor = workload->GetData();
Derek Lambertic81855f2019-06-13 17:34:19 +0100312 auto inputHandle = boost::polymorphic_downcast<IAclTensorHandle*>(queueDescriptor.m_Inputs[0]);
313 auto outputHandle = boost::polymorphic_downcast<IAclTensorHandle*>(queueDescriptor.m_Outputs[0]);
Nikhil Rajcec6b652018-10-12 13:51:57 +0100314
Mike Kellydb482882019-06-14 12:35:24 +0100315 TensorShape inputShape = (dataLayout == DataLayout::NCHW) ? std::initializer_list<unsigned int>({ 2, 2, 5, 5 })
316 : std::initializer_list<unsigned int>({ 2, 5, 5, 2 });
317 TensorShape outputShape = (dataLayout == DataLayout::NCHW) ? std::initializer_list<unsigned int>({ 2, 2, 5, 5 })
318 : std::initializer_list<unsigned int>({ 2, 5, 5, 2 });
Nikhil Rajcec6b652018-10-12 13:51:57 +0100319
320 BOOST_TEST(TestNeonTensorHandleInfo(inputHandle, TensorInfo(inputShape, DataType)));
321 BOOST_TEST(TestNeonTensorHandleInfo(outputHandle, TensorInfo(outputShape, DataType)));
322}
323
324BOOST_AUTO_TEST_CASE(CreateDepthWiseConvolution2dFloat32NhwcWorkload)
325{
Nattapat Chaimanowong77140882018-10-17 11:12:19 +0100326 NeonCreateDepthWiseConvolutionWorkloadTest<DataType::Float32>(DataLayout::NHWC);
Nikhil Rajcec6b652018-10-12 13:51:57 +0100327}
328
329#ifdef __ARM_FEATURE_FP16_VECTOR_ARITHMETIC
330BOOST_AUTO_TEST_CASE(CreateDepthWiseConvolution2dFloat16NhwcWorkload)
331{
Nattapat Chaimanowong77140882018-10-17 11:12:19 +0100332 NeonCreateDepthWiseConvolutionWorkloadTest<DataType::Float16>(DataLayout::NHWC);
Nikhil Rajcec6b652018-10-12 13:51:57 +0100333}
334#endif
335
telsoa01c577f2c2018-08-31 09:22:23 +0100336template <typename FullyConnectedWorkloadType, typename armnn::DataType DataType>
337static void NeonCreateFullyConnectedWorkloadTest()
telsoa014fcda012018-03-09 14:13:49 +0000338{
Aron Virginas-Tar5caf9072018-11-14 18:35:18 +0000339 Graph graph;
340 NeonWorkloadFactory factory =
341 NeonWorkloadFactoryHelper::GetFactory(NeonWorkloadFactoryHelper::GetMemoryManager());
342
343 auto workload = CreateFullyConnectedWorkloadTest<FullyConnectedWorkloadType, DataType>(factory, graph);
telsoa014fcda012018-03-09 14:13:49 +0000344
telsoa01c577f2c2018-08-31 09:22:23 +0100345 // Checks that outputs and inputs are as we expect them (see definition of CreateFullyConnectedWorkloadTest).
telsoa014fcda012018-03-09 14:13:49 +0000346 FullyConnectedQueueDescriptor queueDescriptor = workload->GetData();
Derek Lambertic81855f2019-06-13 17:34:19 +0100347 auto inputHandle = boost::polymorphic_downcast<IAclTensorHandle*>(queueDescriptor.m_Inputs[0]);
348 auto outputHandle = boost::polymorphic_downcast<IAclTensorHandle*>(queueDescriptor.m_Outputs[0]);
telsoa01c577f2c2018-08-31 09:22:23 +0100349 BOOST_TEST(TestNeonTensorHandleInfo(inputHandle, TensorInfo({3, 1, 4, 5}, DataType)));
350 BOOST_TEST(TestNeonTensorHandleInfo(outputHandle, TensorInfo({3, 7}, DataType)));
telsoa014fcda012018-03-09 14:13:49 +0000351}
352
telsoa01c577f2c2018-08-31 09:22:23 +0100353#ifdef __ARM_FEATURE_FP16_VECTOR_ARITHMETIC
354BOOST_AUTO_TEST_CASE(CreateFullyConnectedFloat16Workload)
355{
kevmay01e448be32018-09-26 10:21:55 +0100356 NeonCreateFullyConnectedWorkloadTest<NeonFullyConnectedWorkload, DataType::Float16>();
telsoa01c577f2c2018-08-31 09:22:23 +0100357}
358#endif
359
arovir019e53a352018-08-31 15:26:35 +0100360BOOST_AUTO_TEST_CASE(CreateFullyConnectedFloatWorkload)
telsoa01c577f2c2018-08-31 09:22:23 +0100361{
kevmay01e448be32018-09-26 10:21:55 +0100362 NeonCreateFullyConnectedWorkloadTest<NeonFullyConnectedWorkload, DataType::Float32>();
telsoa01c577f2c2018-08-31 09:22:23 +0100363}
364
telsoa01c577f2c2018-08-31 09:22:23 +0100365template <typename NormalizationWorkloadType, typename armnn::DataType DataType>
narpra0155a97bc2018-10-02 14:35:53 +0100366static void NeonCreateNormalizationWorkloadTest(DataLayout dataLayout)
telsoa014fcda012018-03-09 14:13:49 +0000367{
narpra0155a97bc2018-10-02 14:35:53 +0100368 Graph graph;
Aron Virginas-Tar5caf9072018-11-14 18:35:18 +0000369 NeonWorkloadFactory factory =
370 NeonWorkloadFactoryHelper::GetFactory(NeonWorkloadFactoryHelper::GetMemoryManager());
371
narpra0155a97bc2018-10-02 14:35:53 +0100372 auto workload = CreateNormalizationWorkloadTest<NormalizationWorkloadType, DataType>(factory, graph, dataLayout);
telsoa014fcda012018-03-09 14:13:49 +0000373
telsoa01c577f2c2018-08-31 09:22:23 +0100374 // Checks that outputs and inputs are as we expect them (see definition of CreateNormalizationWorkloadTest).
telsoa014fcda012018-03-09 14:13:49 +0000375 NormalizationQueueDescriptor queueDescriptor = workload->GetData();
Derek Lambertic81855f2019-06-13 17:34:19 +0100376 auto inputHandle = boost::polymorphic_downcast<IAclTensorHandle*>(queueDescriptor.m_Inputs[0]);
377 auto outputHandle = boost::polymorphic_downcast<IAclTensorHandle*>(queueDescriptor.m_Outputs[0]);
Matteo Martincigha160b242018-10-18 10:33:23 +0100378
379 TensorShape inputShape = (dataLayout == DataLayout::NCHW) ? TensorShape{3, 5, 5, 1} : TensorShape{3, 1, 5, 5};
380 TensorShape outputShape = (dataLayout == DataLayout::NCHW) ? TensorShape{3, 5, 5, 1} : TensorShape{3, 1, 5, 5};
381
382 BOOST_TEST(TestNeonTensorHandleInfo(inputHandle, TensorInfo(inputShape, DataType)));
383 BOOST_TEST(TestNeonTensorHandleInfo(outputHandle, TensorInfo(outputShape, DataType)));
telsoa014fcda012018-03-09 14:13:49 +0000384}
385
telsoa01c577f2c2018-08-31 09:22:23 +0100386#ifdef __ARM_FEATURE_FP16_VECTOR_ARITHMETIC
narpra0155a97bc2018-10-02 14:35:53 +0100387BOOST_AUTO_TEST_CASE(CreateNormalizationFloat16NchwWorkload)
telsoa01c577f2c2018-08-31 09:22:23 +0100388{
narpra0155a97bc2018-10-02 14:35:53 +0100389 NeonCreateNormalizationWorkloadTest<NeonNormalizationFloatWorkload, DataType::Float16>(DataLayout::NCHW);
390}
391
392BOOST_AUTO_TEST_CASE(CreateNormalizationFloat16NhwcWorkload)
393{
394 NeonCreateNormalizationWorkloadTest<NeonNormalizationFloatWorkload, DataType::Float16>(DataLayout::NHWC);
telsoa01c577f2c2018-08-31 09:22:23 +0100395}
396#endif
397
narpra0155a97bc2018-10-02 14:35:53 +0100398BOOST_AUTO_TEST_CASE(CreateNormalizationFloatNchwWorkload)
telsoa01c577f2c2018-08-31 09:22:23 +0100399{
narpra0155a97bc2018-10-02 14:35:53 +0100400 NeonCreateNormalizationWorkloadTest<NeonNormalizationFloatWorkload, DataType::Float32>(DataLayout::NCHW);
telsoa01c577f2c2018-08-31 09:22:23 +0100401}
402
narpra0155a97bc2018-10-02 14:35:53 +0100403BOOST_AUTO_TEST_CASE(CreateNormalizationFloatNhwcWorkload)
404{
405 NeonCreateNormalizationWorkloadTest<NeonNormalizationFloatWorkload, DataType::Float32>(DataLayout::NHWC);
406}
407
408
Nattapat Chaimanowong5d2e7002018-10-12 16:03:56 +0100409template <typename armnn::DataType DataType>
Nina Drozdb48e6862018-10-09 12:09:56 +0100410static void NeonCreatePooling2dWorkloadTest(DataLayout dataLayout = DataLayout::NCHW)
telsoa014fcda012018-03-09 14:13:49 +0000411{
Aron Virginas-Tar5caf9072018-11-14 18:35:18 +0000412 Graph graph;
413 NeonWorkloadFactory factory =
414 NeonWorkloadFactoryHelper::GetFactory(NeonWorkloadFactoryHelper::GetMemoryManager());
415
416 auto workload = CreatePooling2dWorkloadTest<NeonPooling2dWorkload, DataType>(factory, graph, dataLayout);
Nina Drozdb48e6862018-10-09 12:09:56 +0100417
418 TensorShape inputShape = (dataLayout == DataLayout::NCHW) ? TensorShape{3, 2, 5, 5} : TensorShape{3, 5, 5, 2};
419 TensorShape outputShape = (dataLayout == DataLayout::NCHW) ? TensorShape{3, 2, 2, 4} : TensorShape{3, 2, 4, 2};
telsoa014fcda012018-03-09 14:13:49 +0000420
telsoa01c577f2c2018-08-31 09:22:23 +0100421 // Checks that outputs and inputs are as we expect them (see definition of CreatePooling2dWorkloadTest).
telsoa014fcda012018-03-09 14:13:49 +0000422 Pooling2dQueueDescriptor queueDescriptor = workload->GetData();
Derek Lambertic81855f2019-06-13 17:34:19 +0100423 auto inputHandle = boost::polymorphic_downcast<IAclTensorHandle*>(queueDescriptor.m_Inputs[0]);
424 auto outputHandle = boost::polymorphic_downcast<IAclTensorHandle*>(queueDescriptor.m_Outputs[0]);
Nina Drozdb48e6862018-10-09 12:09:56 +0100425 BOOST_TEST(TestNeonTensorHandleInfo(inputHandle, TensorInfo(inputShape, DataType)));
426 BOOST_TEST(TestNeonTensorHandleInfo(outputHandle, TensorInfo(outputShape, DataType)));
telsoa014fcda012018-03-09 14:13:49 +0000427}
428
telsoa01c577f2c2018-08-31 09:22:23 +0100429#ifdef __ARM_FEATURE_FP16_VECTOR_ARITHMETIC
430BOOST_AUTO_TEST_CASE(CreatePooling2dFloat16Workload)
431{
Nattapat Chaimanowong5d2e7002018-10-12 16:03:56 +0100432 NeonCreatePooling2dWorkloadTest<DataType::Float16>();
telsoa01c577f2c2018-08-31 09:22:23 +0100433}
434#endif
435
Nina Drozdb48e6862018-10-09 12:09:56 +0100436BOOST_AUTO_TEST_CASE(CreatePooling2dFloatNchwWorkload)
telsoa01c577f2c2018-08-31 09:22:23 +0100437{
Nattapat Chaimanowong5d2e7002018-10-12 16:03:56 +0100438 NeonCreatePooling2dWorkloadTest<DataType::Float32>(DataLayout::NCHW);
telsoa01c577f2c2018-08-31 09:22:23 +0100439}
440
Nina Drozdb48e6862018-10-09 12:09:56 +0100441BOOST_AUTO_TEST_CASE(CreatePooling2dFloatNhwcWorkload)
telsoa01c577f2c2018-08-31 09:22:23 +0100442{
Nattapat Chaimanowong5d2e7002018-10-12 16:03:56 +0100443 NeonCreatePooling2dWorkloadTest<DataType::Float32>(DataLayout::NHWC);
Nina Drozdb48e6862018-10-09 12:09:56 +0100444}
445
446BOOST_AUTO_TEST_CASE(CreatePooling2dUint8NchwWorkload)
447{
Nattapat Chaimanowong5d2e7002018-10-12 16:03:56 +0100448 NeonCreatePooling2dWorkloadTest<DataType::QuantisedAsymm8>(DataLayout::NCHW);
Nina Drozdb48e6862018-10-09 12:09:56 +0100449}
450
451BOOST_AUTO_TEST_CASE(CreatePooling2dUint8NhwcWorkload)
452{
Nattapat Chaimanowong5d2e7002018-10-12 16:03:56 +0100453 NeonCreatePooling2dWorkloadTest<DataType::QuantisedAsymm8>(DataLayout::NHWC);
telsoa01c577f2c2018-08-31 09:22:23 +0100454}
455
Nikhil Raj9b461482019-07-03 15:58:31 +0100456static void NeonCreatePreluWorkloadTest(const armnn::TensorShape& inputShape,
457 const armnn::TensorShape& alphaShape,
458 const armnn::TensorShape& outputShape,
459 armnn::DataType dataType)
460{
461 Graph graph;
462 NeonWorkloadFactory factory =
463 NeonWorkloadFactoryHelper::GetFactory(NeonWorkloadFactoryHelper::GetMemoryManager());
464
465 auto workload = CreatePreluWorkloadTest<NeonPreluWorkload>(factory,
466 graph,
467 inputShape,
468 alphaShape,
469 outputShape,
470 dataType);
471
472 // Checks that outputs and inputs are as we expect them (see definition of CreateReshapeWorkloadTest).
473 PreluQueueDescriptor queueDescriptor = workload->GetData();
474 auto inputHandle = boost::polymorphic_downcast<IAclTensorHandle*>(queueDescriptor.m_Inputs[0]);
475 auto alphaHandle = boost::polymorphic_downcast<IAclTensorHandle*>(queueDescriptor.m_Inputs[1]);
476 auto outputHandle = boost::polymorphic_downcast<IAclTensorHandle*>(queueDescriptor.m_Outputs[0]);
477 BOOST_TEST(TestNeonTensorHandleInfo(inputHandle, TensorInfo(inputShape, dataType)));
478 BOOST_TEST(TestNeonTensorHandleInfo(alphaHandle, TensorInfo(alphaShape, dataType)));
479 BOOST_TEST(TestNeonTensorHandleInfo(outputHandle, TensorInfo(outputShape, dataType)));
480}
481
482#ifdef __ARM_FEATURE_FP16_VECTOR_ARITHMETIC
483 BOOST_AUTO_TEST_CASE(CreatePreluFloat16Workload)
484{
485 NeonCreatePreluWorkloadTest({ 1, 4, 1, 2 }, { 5, 4, 3, 1 }, { 5, 4, 3, 2 }, DataType::Float16);
486}
487#endif
488
489BOOST_AUTO_TEST_CASE(CreatePreluFloatWorkload)
490{
491 NeonCreatePreluWorkloadTest({ 1, 4, 1, 2 }, { 5, 4, 3, 1 }, { 5, 4, 3, 2 }, DataType::Float32);
492}
493
494BOOST_AUTO_TEST_CASE(CreatePreluUint8Workload)
495{
496 NeonCreatePreluWorkloadTest({ 1, 4, 1, 2 }, { 5, 4, 3, 1 }, { 5, 4, 3, 2 }, DataType::QuantisedAsymm8);
497}
498
Nattapat Chaimanowongcce11fc2018-10-12 16:30:56 +0100499template <typename armnn::DataType DataType>
telsoa01c577f2c2018-08-31 09:22:23 +0100500static void NeonCreateReshapeWorkloadTest()
telsoa014fcda012018-03-09 14:13:49 +0000501{
Aron Virginas-Tar5caf9072018-11-14 18:35:18 +0000502 Graph graph;
503 NeonWorkloadFactory factory =
504 NeonWorkloadFactoryHelper::GetFactory(NeonWorkloadFactoryHelper::GetMemoryManager());
505
506 auto workload = CreateReshapeWorkloadTest<NeonReshapeWorkload, DataType>(factory, graph);
telsoa014fcda012018-03-09 14:13:49 +0000507
telsoa01c577f2c2018-08-31 09:22:23 +0100508 // Checks that outputs and inputs are as we expect them (see definition of CreateReshapeWorkloadTest).
telsoa014fcda012018-03-09 14:13:49 +0000509 ReshapeQueueDescriptor queueDescriptor = workload->GetData();
Derek Lambertic81855f2019-06-13 17:34:19 +0100510 auto inputHandle = boost::polymorphic_downcast<IAclTensorHandle*>(queueDescriptor.m_Inputs[0]);
511 auto outputHandle = boost::polymorphic_downcast<IAclTensorHandle*>(queueDescriptor.m_Outputs[0]);
telsoa01c577f2c2018-08-31 09:22:23 +0100512 BOOST_TEST(TestNeonTensorHandleInfo(inputHandle, TensorInfo({4, 1}, DataType)));
513 BOOST_TEST(TestNeonTensorHandleInfo(outputHandle, TensorInfo({1, 4}, DataType)));
telsoa014fcda012018-03-09 14:13:49 +0000514}
515
telsoa01c577f2c2018-08-31 09:22:23 +0100516#ifdef __ARM_FEATURE_FP16_VECTOR_ARITHMETIC
517BOOST_AUTO_TEST_CASE(CreateReshapeFloat16Workload)
518{
Nattapat Chaimanowongcce11fc2018-10-12 16:30:56 +0100519 NeonCreateReshapeWorkloadTest<DataType::Float16>();
telsoa01c577f2c2018-08-31 09:22:23 +0100520}
521#endif
522
arovir019e53a352018-08-31 15:26:35 +0100523BOOST_AUTO_TEST_CASE(CreateReshapeFloatWorkload)
telsoa014fcda012018-03-09 14:13:49 +0000524{
Nattapat Chaimanowongcce11fc2018-10-12 16:30:56 +0100525 NeonCreateReshapeWorkloadTest<DataType::Float32>();
telsoa014fcda012018-03-09 14:13:49 +0000526}
527
528BOOST_AUTO_TEST_CASE(CreateReshapeUint8Workload)
529{
Nattapat Chaimanowongcce11fc2018-10-12 16:30:56 +0100530 NeonCreateReshapeWorkloadTest<DataType::QuantisedAsymm8>();
telsoa014fcda012018-03-09 14:13:49 +0000531}
532
Ellen Norris-Thompson37e68682019-07-15 14:23:30 +0100533template <typename ResizeWorkloadType, armnn::DataType DataType>
534static void NeonCreateResizeWorkloadTest(DataLayout dataLayout)
535{
536 Graph graph;
537 NeonWorkloadFactory factory =
538 NeonWorkloadFactoryHelper::GetFactory(NeonWorkloadFactoryHelper::GetMemoryManager());
539 auto workload = CreateResizeBilinearWorkloadTest<ResizeWorkloadType, DataType>(factory, graph, dataLayout);
540
541 auto queueDescriptor = workload->GetData();
542
543 auto inputHandle = boost::polymorphic_downcast<IAclTensorHandle*>(queueDescriptor.m_Inputs[0]);
544 auto outputHandle = boost::polymorphic_downcast<IAclTensorHandle*>(queueDescriptor.m_Outputs[0]);
545
546 switch (dataLayout)
547 {
548 case DataLayout::NHWC:
549 BOOST_TEST(CompareIAclTensorHandleShape(inputHandle, { 2, 4, 4, 3 }));
550 BOOST_TEST(CompareIAclTensorHandleShape(outputHandle, { 2, 2, 2, 3 }));
551 break;
552 case DataLayout::NCHW:
553 default:
554 BOOST_TEST(CompareIAclTensorHandleShape(inputHandle, { 2, 3, 4, 4 }));
555 BOOST_TEST(CompareIAclTensorHandleShape(outputHandle, { 2, 3, 2, 2 }));
556 }
557}
558
559BOOST_AUTO_TEST_CASE(CreateResizeFloat32NchwWorkload)
560{
561 NeonCreateResizeWorkloadTest<NeonResizeWorkload, armnn::DataType::Float32>(DataLayout::NCHW);
562}
563
564BOOST_AUTO_TEST_CASE(CreateResizeUint8NchwWorkload)
565{
566 NeonCreateResizeWorkloadTest<NeonResizeWorkload, armnn::DataType::QuantisedAsymm8>(DataLayout::NCHW);
567}
568
569BOOST_AUTO_TEST_CASE(CreateResizeFloat32NhwcWorkload)
570{
571 NeonCreateResizeWorkloadTest<NeonResizeWorkload, armnn::DataType::Float32>(DataLayout::NHWC);
572}
573
574BOOST_AUTO_TEST_CASE(CreateResizeUint8NhwcWorkload)
575{
576 NeonCreateResizeWorkloadTest<NeonResizeWorkload, armnn::DataType::QuantisedAsymm8>(DataLayout::NHWC);
577}
578
telsoa01c577f2c2018-08-31 09:22:23 +0100579template <typename SoftmaxWorkloadType, typename armnn::DataType DataType>
580static void NeonCreateSoftmaxWorkloadTest()
telsoa014fcda012018-03-09 14:13:49 +0000581{
Aron Virginas-Tar5caf9072018-11-14 18:35:18 +0000582 Graph graph;
583 NeonWorkloadFactory factory =
584 NeonWorkloadFactoryHelper::GetFactory(NeonWorkloadFactoryHelper::GetMemoryManager());
585
telsoa01c577f2c2018-08-31 09:22:23 +0100586 auto workload = CreateSoftmaxWorkloadTest<SoftmaxWorkloadType, DataType>(factory, graph);
telsoa014fcda012018-03-09 14:13:49 +0000587
telsoa01c577f2c2018-08-31 09:22:23 +0100588 // Checks that outputs and inputs are as we expect them (see definition of CreateSoftmaxWorkloadTest).
telsoa014fcda012018-03-09 14:13:49 +0000589 SoftmaxQueueDescriptor queueDescriptor = workload->GetData();
Derek Lambertic81855f2019-06-13 17:34:19 +0100590 auto inputHandle = boost::polymorphic_downcast<IAclTensorHandle*>(queueDescriptor.m_Inputs[0]);
591 auto outputHandle = boost::polymorphic_downcast<IAclTensorHandle*>(queueDescriptor.m_Outputs[0]);
telsoa01c577f2c2018-08-31 09:22:23 +0100592 BOOST_TEST(TestNeonTensorHandleInfo(inputHandle, TensorInfo({4, 1}, DataType)));
593 BOOST_TEST(TestNeonTensorHandleInfo(outputHandle, TensorInfo({4, 1}, DataType)));
594}
595
596#ifdef __ARM_FEATURE_FP16_VECTOR_ARITHMETIC
597BOOST_AUTO_TEST_CASE(CreateSoftmaxFloat16Workload)
598{
arovir019e53a352018-08-31 15:26:35 +0100599 NeonCreateSoftmaxWorkloadTest<NeonSoftmaxFloatWorkload, DataType::Float16>();
telsoa01c577f2c2018-08-31 09:22:23 +0100600}
601#endif
602
arovir019e53a352018-08-31 15:26:35 +0100603BOOST_AUTO_TEST_CASE(CreateSoftmaxFloatWorkload)
telsoa01c577f2c2018-08-31 09:22:23 +0100604{
arovir019e53a352018-08-31 15:26:35 +0100605 NeonCreateSoftmaxWorkloadTest<NeonSoftmaxFloatWorkload, DataType::Float32>();
telsoa014fcda012018-03-09 14:13:49 +0000606}
607
Ellen Norris-Thompson29794572019-06-26 16:40:36 +0100608template <typename SpaceToDepthWorkloadType, typename armnn::DataType DataType>
609static void NeonSpaceToDepthWorkloadTest()
610{
611 Graph graph;
612 NeonWorkloadFactory factory =
613 NeonWorkloadFactoryHelper::GetFactory(NeonWorkloadFactoryHelper::GetMemoryManager());
614
615 auto workload = CreateSpaceToDepthWorkloadTest<SpaceToDepthWorkloadType, DataType>(factory, graph);
616
617 SpaceToDepthQueueDescriptor queueDescriptor = workload->GetData();
618 auto inputHandle = boost::polymorphic_downcast<IAclTensorHandle*>(queueDescriptor.m_Inputs[0]);
619 auto outputHandle = boost::polymorphic_downcast<IAclTensorHandle*>(queueDescriptor.m_Outputs[0]);
620
621 BOOST_TEST(TestNeonTensorHandleInfo(inputHandle, TensorInfo({ 1, 2, 2, 1 }, DataType)));
622 BOOST_TEST(TestNeonTensorHandleInfo(outputHandle, TensorInfo({ 1, 1, 1, 4 }, DataType)));
623}
624
625BOOST_AUTO_TEST_CASE(CreateSpaceToDepthFloat32Workload)
626{
627 NeonSpaceToDepthWorkloadTest<NeonSpaceToDepthWorkload, armnn::DataType::Float32>();
628}
629
630BOOST_AUTO_TEST_CASE(CreateSpaceToDepthFloat16Workload)
631{
632 NeonSpaceToDepthWorkloadTest<NeonSpaceToDepthWorkload, armnn::DataType::Float16>();
633}
634
635BOOST_AUTO_TEST_CASE(CreateSpaceToDepthQAsymm8Workload)
636{
637 NeonSpaceToDepthWorkloadTest<NeonSpaceToDepthWorkload, armnn::DataType::QuantisedAsymm8>();
638}
639
640BOOST_AUTO_TEST_CASE(CreateSpaceToDepthQSymm16Workload)
641{
642 NeonSpaceToDepthWorkloadTest<NeonSpaceToDepthWorkload, armnn::DataType::QuantisedSymm16>();
643}
644
telsoa014fcda012018-03-09 14:13:49 +0000645BOOST_AUTO_TEST_CASE(CreateSplitterWorkload)
646{
647 Graph graph;
Aron Virginas-Tar5caf9072018-11-14 18:35:18 +0000648 NeonWorkloadFactory factory =
649 NeonWorkloadFactoryHelper::GetFactory(NeonWorkloadFactoryHelper::GetMemoryManager());
650
Nattapat Chaimanowong14766d72018-10-12 15:09:53 +0100651 auto workload = CreateSplitterWorkloadTest<NeonSplitterWorkload, DataType::Float32>(factory, graph);
telsoa014fcda012018-03-09 14:13:49 +0000652
telsoa01c577f2c2018-08-31 09:22:23 +0100653 // Checks that outputs are as we expect them (see definition of CreateSplitterWorkloadTest).
telsoa014fcda012018-03-09 14:13:49 +0000654 SplitterQueueDescriptor queueDescriptor = workload->GetData();
Derek Lambertic81855f2019-06-13 17:34:19 +0100655 auto inputHandle = boost::polymorphic_downcast<IAclTensorHandle*>(queueDescriptor.m_Inputs[0]);
surmeh013537c2c2018-05-18 16:31:43 +0100656 BOOST_TEST(TestNeonTensorHandleInfo(inputHandle, TensorInfo({5, 7, 7}, DataType::Float32)));
657
Derek Lambertic81855f2019-06-13 17:34:19 +0100658 auto outputHandle0 = boost::polymorphic_downcast<IAclTensorHandle*>(queueDescriptor.m_Outputs[0]);
surmeh013537c2c2018-05-18 16:31:43 +0100659 BOOST_TEST(TestNeonTensorHandleInfo(outputHandle0, TensorInfo({1, 7, 7}, DataType::Float32)));
660
Derek Lambertic81855f2019-06-13 17:34:19 +0100661 auto outputHandle1 = boost::polymorphic_downcast<IAclTensorHandle*>(queueDescriptor.m_Outputs[1]);
surmeh013537c2c2018-05-18 16:31:43 +0100662 BOOST_TEST(TestNeonTensorHandleInfo(outputHandle1, TensorInfo({2, 7, 7}, DataType::Float32)));
663
Derek Lambertic81855f2019-06-13 17:34:19 +0100664 auto outputHandle2 = boost::polymorphic_downcast<IAclTensorHandle*>(queueDescriptor.m_Outputs[2]);
surmeh013537c2c2018-05-18 16:31:43 +0100665 BOOST_TEST(TestNeonTensorHandleInfo(outputHandle2, TensorInfo({2, 7, 7}, DataType::Float32)));
telsoa014fcda012018-03-09 14:13:49 +0000666}
667
Jim Flynne242f2d2019-05-22 14:24:13 +0100668BOOST_AUTO_TEST_CASE(CreateSplitterConcat)
telsoa014fcda012018-03-09 14:13:49 +0000669{
telsoa01c577f2c2018-08-31 09:22:23 +0100670 // Tests that it is possible to decide which output of the splitter layer
Jim Flynne242f2d2019-05-22 14:24:13 +0100671 // should be lined to which input of the concat layer.
telsoa01c577f2c2018-08-31 09:22:23 +0100672 // We tested that is is possible to specify 0th output
Jim Flynne242f2d2019-05-22 14:24:13 +0100673 // of the splitter to be the 1st input to the concat, and the 1st output of the splitter to be 0th input
674 // of the concat.
telsoa014fcda012018-03-09 14:13:49 +0000675
676 Graph graph;
Aron Virginas-Tar5caf9072018-11-14 18:35:18 +0000677 NeonWorkloadFactory factory =
678 NeonWorkloadFactoryHelper::GetFactory(NeonWorkloadFactoryHelper::GetMemoryManager());
telsoa014fcda012018-03-09 14:13:49 +0000679
680 auto workloads =
Jim Flynne242f2d2019-05-22 14:24:13 +0100681 CreateSplitterConcatWorkloadTest<NeonSplitterWorkload, NeonConcatWorkload,
telsoa01c577f2c2018-08-31 09:22:23 +0100682 DataType::Float32>(factory, graph);
telsoa014fcda012018-03-09 14:13:49 +0000683
684 auto wlSplitter = std::move(workloads.first);
Jim Flynne242f2d2019-05-22 14:24:13 +0100685 auto wlConcat = std::move(workloads.second);
telsoa014fcda012018-03-09 14:13:49 +0000686
telsoa01c577f2c2018-08-31 09:22:23 +0100687 //Checks that the index of inputs/outputs matches what we declared on InputDescriptor construction.
Derek Lambertic81855f2019-06-13 17:34:19 +0100688 armnn::IAclTensorHandle* sOut0 = dynamic_cast<armnn::IAclTensorHandle*>(wlSplitter->GetData().m_Outputs[0]);
689 armnn::IAclTensorHandle* sOut1 = dynamic_cast<armnn::IAclTensorHandle*>(wlSplitter->GetData().m_Outputs[1]);
690 armnn::IAclTensorHandle* mIn0 = dynamic_cast<armnn::IAclTensorHandle*>(wlConcat->GetData().m_Inputs[0]);
691 armnn::IAclTensorHandle* mIn1 = dynamic_cast<armnn::IAclTensorHandle*>(wlConcat->GetData().m_Inputs[1]);
telsoa014fcda012018-03-09 14:13:49 +0000692
693 BOOST_TEST(sOut0);
694 BOOST_TEST(sOut1);
695 BOOST_TEST(mIn0);
696 BOOST_TEST(mIn1);
697
698 bool validDataPointers = (sOut0 == mIn1) && (sOut1 == mIn0);
699
700 BOOST_TEST(validDataPointers);
701}
702
703BOOST_AUTO_TEST_CASE(CreateSingleOutputMultipleInputs)
704{
telsoa01c577f2c2018-08-31 09:22:23 +0100705 // Tests that it is possible to assign multiple (two) different layers to each of the outputs of a splitter layer.
706 // 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 +0000707
708 Graph graph;
Aron Virginas-Tar5caf9072018-11-14 18:35:18 +0000709 NeonWorkloadFactory factory =
710 NeonWorkloadFactoryHelper::GetFactory(NeonWorkloadFactoryHelper::GetMemoryManager());
711
Nattapat Chaimanowong14766d72018-10-12 15:09:53 +0100712 std::unique_ptr<NeonSplitterWorkload> wlSplitter;
Nattapat Chaimanowongd4b70592018-10-12 11:21:49 +0100713 std::unique_ptr<NeonActivationWorkload> wlActiv0_0;
714 std::unique_ptr<NeonActivationWorkload> wlActiv0_1;
715 std::unique_ptr<NeonActivationWorkload> wlActiv1_0;
716 std::unique_ptr<NeonActivationWorkload> wlActiv1_1;
telsoa014fcda012018-03-09 14:13:49 +0000717
Nattapat Chaimanowong14766d72018-10-12 15:09:53 +0100718 CreateSplitterMultipleInputsOneOutputWorkloadTest<NeonSplitterWorkload,
Nattapat Chaimanowongd4b70592018-10-12 11:21:49 +0100719 NeonActivationWorkload, DataType::Float32>(factory, graph, wlSplitter, wlActiv0_0, wlActiv0_1,
720 wlActiv1_0, wlActiv1_1);
telsoa014fcda012018-03-09 14:13:49 +0000721
Derek Lambertic81855f2019-06-13 17:34:19 +0100722 armnn::IAclTensorHandle* sOut0 = dynamic_cast<armnn::IAclTensorHandle*>(wlSplitter->GetData().m_Outputs[0]);
723 armnn::IAclTensorHandle* sOut1 = dynamic_cast<armnn::IAclTensorHandle*>(wlSplitter->GetData().m_Outputs[1]);
724 armnn::IAclTensorHandle* activ0_0Im = dynamic_cast<armnn::IAclTensorHandle*>(wlActiv0_0->GetData().m_Inputs[0]);
725 armnn::IAclTensorHandle* activ0_1Im = dynamic_cast<armnn::IAclTensorHandle*>(wlActiv0_1->GetData().m_Inputs[0]);
726 armnn::IAclTensorHandle* activ1_0Im = dynamic_cast<armnn::IAclTensorHandle*>(wlActiv1_0->GetData().m_Inputs[0]);
727 armnn::IAclTensorHandle* activ1_1Im = dynamic_cast<armnn::IAclTensorHandle*>(wlActiv1_1->GetData().m_Inputs[0]);
telsoa014fcda012018-03-09 14:13:49 +0000728
729
730 BOOST_TEST(sOut0);
731 BOOST_TEST(sOut1);
732 BOOST_TEST(activ0_0Im);
733 BOOST_TEST(activ0_1Im);
734 BOOST_TEST(activ1_0Im);
735 BOOST_TEST(activ1_1Im);
736
737 bool validDataPointers = (sOut0 == activ0_0Im) && (sOut0 == activ0_1Im) &&
738 (sOut1 == activ1_0Im) && (sOut1 == activ1_1Im);
739
740 BOOST_TEST(validDataPointers);
741}
742
Matteo Martincighdb16dd32019-08-27 16:41:11 +0100743#if defined(ARMNNREF_ENABLED)
Matteo Martincighe67edb22019-08-14 14:05:46 +0100744
745// This test unit needs the reference backend, it's not available if the reference backend is not built
746
telsoa014fcda012018-03-09 14:13:49 +0000747BOOST_AUTO_TEST_CASE(CreateMemCopyWorkloadsNeon)
748{
Aron Virginas-Tar5caf9072018-11-14 18:35:18 +0000749 NeonWorkloadFactory factory =
750 NeonWorkloadFactoryHelper::GetFactory(NeonWorkloadFactoryHelper::GetMemoryManager());
Derek Lambertic81855f2019-06-13 17:34:19 +0100751 CreateMemCopyWorkloads<IAclTensorHandle>(factory);
telsoa014fcda012018-03-09 14:13:49 +0000752}
753
Matteo Martincighe67edb22019-08-14 14:05:46 +0100754#endif
755
Matteo Martincighbcd3c852018-09-28 14:14:12 +0100756template <typename L2NormalizationWorkloadType, typename armnn::DataType DataType>
757static void NeonCreateL2NormalizationWorkloadTest(DataLayout dataLayout)
758{
Matteo Martincigh2400b6d2018-10-09 18:19:20 +0100759 Graph graph;
Aron Virginas-Tar5caf9072018-11-14 18:35:18 +0000760 NeonWorkloadFactory factory =
761 NeonWorkloadFactoryHelper::GetFactory(NeonWorkloadFactoryHelper::GetMemoryManager());
762
Matteo Martincigh2400b6d2018-10-09 18:19:20 +0100763 auto workload =
764 CreateL2NormalizationWorkloadTest<L2NormalizationWorkloadType, DataType>(factory, graph, dataLayout);
Matteo Martincighbcd3c852018-09-28 14:14:12 +0100765
766 // Checks that inputs/outputs are as we expect them (see definition of CreateNormalizationWorkloadTest).
767 L2NormalizationQueueDescriptor queueDescriptor = workload->GetData();
Derek Lambertic81855f2019-06-13 17:34:19 +0100768 auto inputHandle = boost::polymorphic_downcast<IAclTensorHandle*>(queueDescriptor.m_Inputs[0]);
769 auto outputHandle = boost::polymorphic_downcast<IAclTensorHandle*>(queueDescriptor.m_Outputs[0]);
Matteo Martincigh2400b6d2018-10-09 18:19:20 +0100770
771 TensorShape inputShape = (dataLayout == DataLayout::NCHW) ?
772 TensorShape{ 5, 20, 50, 67 } : TensorShape{ 5, 50, 67, 20 };
773 TensorShape outputShape = (dataLayout == DataLayout::NCHW) ?
774 TensorShape{ 5, 20, 50, 67 } : TensorShape{ 5, 50, 67, 20 };
775
776 BOOST_TEST(TestNeonTensorHandleInfo(inputHandle, TensorInfo(inputShape, DataType)));
777 BOOST_TEST(TestNeonTensorHandleInfo(outputHandle, TensorInfo(outputShape, DataType)));
Matteo Martincighbcd3c852018-09-28 14:14:12 +0100778}
779
780#ifdef __ARM_FEATURE_FP16_VECTOR_ARITHMETIC
781BOOST_AUTO_TEST_CASE(CreateL2NormalizationFloat16NchwWorkload)
782{
783 NeonCreateL2NormalizationWorkloadTest<NeonL2NormalizationFloatWorkload, DataType::Float16>(DataLayout::NCHW);
784}
785
786BOOST_AUTO_TEST_CASE(CreateL2NormalizationFloat16NhwcWorkload)
787{
788 NeonCreateL2NormalizationWorkloadTest<NeonL2NormalizationFloatWorkload, DataType::Float16>(DataLayout::NHWC);
789}
790#endif
791
792BOOST_AUTO_TEST_CASE(CreateL2NormalizationNchwWorkload)
793{
794 NeonCreateL2NormalizationWorkloadTest<NeonL2NormalizationFloatWorkload, DataType::Float32>(DataLayout::NCHW);
795}
796
797BOOST_AUTO_TEST_CASE(CreateL2NormalizationNhwcWorkload)
798{
799 NeonCreateL2NormalizationWorkloadTest<NeonL2NormalizationFloatWorkload, DataType::Float32>(DataLayout::NHWC);
800}
801
Jan Eilersad5293a2019-07-08 09:57:55 +0100802template <typename LstmWorkloadType>
803static void NeonCreateLstmWorkloadTest()
804{
805 Graph graph;
806 NeonWorkloadFactory factory =
807 NeonWorkloadFactoryHelper::GetFactory(NeonWorkloadFactoryHelper::GetMemoryManager());
808
809 auto workload = CreateLstmWorkloadTest<LstmWorkloadType>(factory, graph);
810
811 LstmQueueDescriptor queueDescriptor = workload->GetData();
812
813 auto inputHandle = boost::polymorphic_downcast<IAclTensorHandle*>(queueDescriptor.m_Inputs[0]);
814 auto outputHandle = boost::polymorphic_downcast<IAclTensorHandle*>(queueDescriptor.m_Outputs[1]);
815
816 BOOST_TEST(TestNeonTensorHandleInfo(inputHandle, TensorInfo({ 2, 2 }, DataType::Float32)));
817 BOOST_TEST(TestNeonTensorHandleInfo(outputHandle, TensorInfo({ 2, 4 }, DataType::Float32)));
818}
819
820BOOST_AUTO_TEST_CASE(CreateLSTMWorkloadFloatWorkload)
821{
822 NeonCreateLstmWorkloadTest<NeonLstmFloatWorkload>();
823}
824
Jim Flynne242f2d2019-05-22 14:24:13 +0100825template <typename ConcatWorkloadType, armnn::DataType DataType>
826static void NeonCreateConcatWorkloadTest(std::initializer_list<unsigned int> outputShape,
narpra015cdda352018-11-19 15:30:27 +0000827 unsigned int concatAxis)
828{
829 Graph graph;
830 NeonWorkloadFactory factory =
831 NeonWorkloadFactoryHelper::GetFactory(NeonWorkloadFactoryHelper::GetMemoryManager());
832
Jim Flynne242f2d2019-05-22 14:24:13 +0100833 auto workload = CreateConcatWorkloadTest<ConcatWorkloadType, DataType>(factory, graph, outputShape, concatAxis);
narpra015cdda352018-11-19 15:30:27 +0000834
Jim Flynne242f2d2019-05-22 14:24:13 +0100835 ConcatQueueDescriptor queueDescriptor = workload->GetData();
Derek Lambertic81855f2019-06-13 17:34:19 +0100836 auto inputHandle0 = boost::polymorphic_downcast<IAclTensorHandle*>(queueDescriptor.m_Inputs[0]);
837 auto inputHandle1 = boost::polymorphic_downcast<IAclTensorHandle*>(queueDescriptor.m_Inputs[1]);
838 auto outputHandle = boost::polymorphic_downcast<IAclTensorHandle*>(queueDescriptor.m_Outputs[0]);
narpra015cdda352018-11-19 15:30:27 +0000839
840 BOOST_TEST(TestNeonTensorHandleInfo(inputHandle0, TensorInfo({ 2, 3, 2, 5 }, DataType)));
841 BOOST_TEST(TestNeonTensorHandleInfo(inputHandle1, TensorInfo({ 2, 3, 2, 5 }, DataType)));
842 BOOST_TEST(TestNeonTensorHandleInfo(outputHandle, TensorInfo(outputShape, DataType)));
843}
844
Jim Flynne242f2d2019-05-22 14:24:13 +0100845BOOST_AUTO_TEST_CASE(CreateConcatDim0Float32Workload)
narpra015cdda352018-11-19 15:30:27 +0000846{
Jim Flynne242f2d2019-05-22 14:24:13 +0100847 NeonCreateConcatWorkloadTest<NeonConcatWorkload, armnn::DataType::Float32>({ 4, 3, 2, 5 }, 0);
narpra015cdda352018-11-19 15:30:27 +0000848}
849
Jim Flynne242f2d2019-05-22 14:24:13 +0100850BOOST_AUTO_TEST_CASE(CreateConcatDim1Float32Workload)
narpra015cdda352018-11-19 15:30:27 +0000851{
Jim Flynne242f2d2019-05-22 14:24:13 +0100852 NeonCreateConcatWorkloadTest<NeonConcatWorkload, armnn::DataType::Float32>({ 2, 6, 2, 5 }, 1);
narpra015cdda352018-11-19 15:30:27 +0000853}
854
Jim Flynne242f2d2019-05-22 14:24:13 +0100855BOOST_AUTO_TEST_CASE(CreateConcatDim3Float32Workload)
narpra015cdda352018-11-19 15:30:27 +0000856{
Jim Flynne242f2d2019-05-22 14:24:13 +0100857 NeonCreateConcatWorkloadTest<NeonConcatWorkload, armnn::DataType::Float32>({ 2, 3, 2, 10 }, 3);
narpra015cdda352018-11-19 15:30:27 +0000858}
859
Jim Flynne242f2d2019-05-22 14:24:13 +0100860BOOST_AUTO_TEST_CASE(CreateConcatDim0Uint8Workload)
narpra0163b08822018-11-20 11:29:12 +0000861{
Jim Flynne242f2d2019-05-22 14:24:13 +0100862 NeonCreateConcatWorkloadTest<NeonConcatWorkload, armnn::DataType::QuantisedAsymm8>({ 4, 3, 2, 5 }, 0);
narpra0163b08822018-11-20 11:29:12 +0000863}
864
Jim Flynne242f2d2019-05-22 14:24:13 +0100865BOOST_AUTO_TEST_CASE(CreateConcatDim1Uint8Workload)
narpra0163b08822018-11-20 11:29:12 +0000866{
Jim Flynne242f2d2019-05-22 14:24:13 +0100867 NeonCreateConcatWorkloadTest<NeonConcatWorkload, armnn::DataType::QuantisedAsymm8>({ 2, 6, 2, 5 }, 1);
narpra0163b08822018-11-20 11:29:12 +0000868}
869
Jim Flynne242f2d2019-05-22 14:24:13 +0100870BOOST_AUTO_TEST_CASE(CreateConcatDim3Uint8Workload)
narpra0163b08822018-11-20 11:29:12 +0000871{
Jim Flynne242f2d2019-05-22 14:24:13 +0100872 NeonCreateConcatWorkloadTest<NeonConcatWorkload, armnn::DataType::QuantisedAsymm8>({ 2, 3, 2, 10 }, 3);
narpra0163b08822018-11-20 11:29:12 +0000873}
874
Matthew Jackson87f65ea2019-08-01 10:01:34 +0100875template <armnn::DataType DataType>
876static void NeonCreateStackWorkloadTest(const std::initializer_list<unsigned int>& inputShape,
877 const std::initializer_list<unsigned int>& outputShape,
878 unsigned int axis,
879 unsigned int numInputs)
880{
881 armnn::Graph graph;
882 NeonWorkloadFactory factory =
883 NeonWorkloadFactoryHelper::GetFactory(NeonWorkloadFactoryHelper::GetMemoryManager());
884
885 auto workload = CreateStackWorkloadTest<NeonStackWorkload, DataType>(factory,
886 graph,
887 TensorShape(inputShape),
888 TensorShape(outputShape),
889 axis,
890 numInputs);
891
892 // Check inputs and output are as expected
893 StackQueueDescriptor queueDescriptor = workload->GetData();
894 for (unsigned int i = 0; i < numInputs; ++i)
895 {
896 auto inputHandle = boost::polymorphic_downcast<IAclTensorHandle*>(queueDescriptor.m_Inputs[i]);
897 BOOST_TEST(TestNeonTensorHandleInfo(inputHandle, TensorInfo(inputShape, DataType)));
898 }
899 auto outputHandle = boost::polymorphic_downcast<IAclTensorHandle*>(queueDescriptor.m_Outputs[0]);
900 BOOST_TEST(TestNeonTensorHandleInfo(outputHandle, TensorInfo(outputShape, DataType)));
901}
902
903BOOST_AUTO_TEST_CASE(CreateStackFloat32Workload)
904{
905 NeonCreateStackWorkloadTest<armnn::DataType::Float32>({ 3, 4, 5 }, { 3, 4, 2, 5 }, 2, 2);
906}
907
Matthew Jacksone69c3992019-09-09 14:31:21 +0100908#ifdef __ARM_FEATURE_FP16_VECTOR_ARITHMETIC
909BOOST_AUTO_TEST_CASE(CreateStackFloat16Workload)
910{
911 NeonCreateStackWorkloadTest<armnn::DataType::Float16>({ 3, 4, 5 }, { 3, 4, 2, 5 }, 2, 2);
912}
913#endif
914
Matthew Jackson87f65ea2019-08-01 10:01:34 +0100915BOOST_AUTO_TEST_CASE(CreateStackUint8Workload)
916{
917 NeonCreateStackWorkloadTest<armnn::DataType::QuantisedAsymm8>({ 3, 4, 5 }, { 3, 4, 2, 5 }, 2, 2);
918}
919
Francis Murtagh4fc3c482019-08-02 13:20:54 +0100920template <typename QuantizedLstmWorkloadType>
921static void NeonCreateQuantizedLstmWorkloadTest()
922{
923 using boost::polymorphic_downcast;
924
925 Graph graph;
926 NeonWorkloadFactory factory = NeonWorkloadFactoryHelper::GetFactory(NeonWorkloadFactoryHelper::GetMemoryManager());
927
928 auto workload = CreateQuantizedLstmWorkloadTest<QuantizedLstmWorkloadType>(factory, graph);
929
930 QuantizedLstmQueueDescriptor queueDescriptor = workload->GetData();
931
932 IAclTensorHandle* inputHandle = polymorphic_downcast<IAclTensorHandle*>(queueDescriptor.m_Inputs[0]);
933 BOOST_TEST((inputHandle->GetShape() == TensorShape({2, 2})));
934 BOOST_TEST((inputHandle->GetDataType() == arm_compute::DataType::QASYMM8));
935
936 IAclTensorHandle* cellStateInHandle = polymorphic_downcast<IAclTensorHandle*>(queueDescriptor.m_Inputs[1]);
937 BOOST_TEST((cellStateInHandle->GetShape() == TensorShape({2, 4})));
938 BOOST_TEST((cellStateInHandle->GetDataType() == arm_compute::DataType::QSYMM16));
939
940 IAclTensorHandle* outputStateInHandle = polymorphic_downcast<IAclTensorHandle*>(queueDescriptor.m_Inputs[2]);
941 BOOST_TEST((outputStateInHandle->GetShape() == TensorShape({2, 4})));
942 BOOST_TEST((outputStateInHandle->GetDataType() == arm_compute::DataType::QASYMM8));
943
944 IAclTensorHandle* cellStateOutHandle = polymorphic_downcast<IAclTensorHandle*>(queueDescriptor.m_Outputs[0]);
945 BOOST_TEST((cellStateOutHandle->GetShape() == TensorShape({2, 4})));
946 BOOST_TEST((cellStateOutHandle->GetDataType() == arm_compute::DataType::QSYMM16));
947
948 IAclTensorHandle* outputStateOutHandle = polymorphic_downcast<IAclTensorHandle*>(queueDescriptor.m_Outputs[1]);
949 BOOST_TEST((outputStateOutHandle->GetShape() == TensorShape({2, 4})));
950 BOOST_TEST((outputStateOutHandle->GetDataType() == arm_compute::DataType::QASYMM8));
951}
952
953BOOST_AUTO_TEST_CASE(CreateQuantizedLstmWorkload)
954{
955 NeonCreateQuantizedLstmWorkloadTest<NeonQuantizedLstmWorkload>();
956}
957
telsoa014fcda012018-03-09 14:13:49 +0000958BOOST_AUTO_TEST_SUITE_END()