blob: 5cd305c8ac81de92d5687bc081f4eeda806f526d [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-Tarc9cc8042018-11-01 16:15:57 +00006#include <backendsCommon/MemCopyWorkload.hpp>
Aron Virginas-Tar3b278e92018-10-12 13:00:55 +01007
Aron Virginas-Tarc9cc8042018-11-01 16:15:57 +00008#include <aclCommon/test/CreateWorkloadClNeon.hpp>
Aron Virginas-Tar3b278e92018-10-12 13:00:55 +01009
Aron Virginas-Tarc9cc8042018-11-01 16:15:57 +000010#include <neon/NeonWorkloadFactory.hpp>
11#include <neon/NeonTensorHandle.hpp>
12#include <neon/workloads/NeonWorkloadUtils.hpp>
13#include <neon/workloads/NeonWorkloads.hpp>
telsoa014fcda012018-03-09 14:13:49 +000014
15BOOST_AUTO_TEST_SUITE(CreateWorkloadNeon)
16
17namespace
18{
19
20bool TestNeonTensorHandleInfo(armnn::INeonTensorHandle* handle, const armnn::TensorInfo& expectedInfo)
21{
22 using namespace armnn::armcomputetensorutils;
23
24 const arm_compute::ITensorInfo* handleInfo = handle->GetTensor().info();
25 const arm_compute::TensorInfo expectedAclInfo = BuildArmComputeTensorInfo(expectedInfo);
26
27 if (handleInfo->data_type() != expectedAclInfo.data_type())
28 {
29 return false;
30 }
31
32 if (handleInfo->num_dimensions() != expectedAclInfo.num_dimensions())
33 {
34 return false;
35 }
36
37 if (handleInfo->quantization_info() != expectedAclInfo.quantization_info())
38 {
39 return false;
40 }
41
42 for (std::size_t d = 0; d < expectedAclInfo.num_dimensions(); ++d)
43 {
44 if (handleInfo->dimension(d) != expectedAclInfo.dimension(d))
45 {
46 return false;
47 }
48 }
49
50 return true;
51}
52
53} // namespace
54
Nattapat Chaimanowongd4b70592018-10-12 11:21:49 +010055template <typename armnn::DataType DataType>
telsoa01c577f2c2018-08-31 09:22:23 +010056static void NeonCreateActivationWorkloadTest()
telsoa014fcda012018-03-09 14:13:49 +000057{
58 Graph graph;
59 NeonWorkloadFactory factory;
Nattapat Chaimanowongd4b70592018-10-12 11:21:49 +010060 auto workload = CreateActivationWorkloadTest<NeonActivationWorkload, DataType>(factory, graph);
telsoa014fcda012018-03-09 14:13:49 +000061
telsoa01c577f2c2018-08-31 09:22:23 +010062 // Checks that inputs/outputs are as we expect them (see definition of CreateActivationWorkloadTest).
telsoa014fcda012018-03-09 14:13:49 +000063 ActivationQueueDescriptor queueDescriptor = workload->GetData();
64 auto inputHandle = boost::polymorphic_downcast<INeonTensorHandle*>(queueDescriptor.m_Inputs[0]);
65 auto outputHandle = boost::polymorphic_downcast<INeonTensorHandle*>(queueDescriptor.m_Outputs[0]);
telsoa01c577f2c2018-08-31 09:22:23 +010066 BOOST_TEST(TestNeonTensorHandleInfo(inputHandle, TensorInfo({1, 1}, DataType)));
67 BOOST_TEST(TestNeonTensorHandleInfo(outputHandle, TensorInfo({1, 1}, DataType)));
telsoa014fcda012018-03-09 14:13:49 +000068}
69
telsoa01c577f2c2018-08-31 09:22:23 +010070#ifdef __ARM_FEATURE_FP16_VECTOR_ARITHMETIC
71BOOST_AUTO_TEST_CASE(CreateActivationFloat16Workload)
72{
Nattapat Chaimanowongd4b70592018-10-12 11:21:49 +010073 NeonCreateActivationWorkloadTest<DataType::Float16>();
telsoa01c577f2c2018-08-31 09:22:23 +010074}
75#endif
76
arovir019e53a352018-08-31 15:26:35 +010077BOOST_AUTO_TEST_CASE(CreateActivationFloatWorkload)
telsoa01c577f2c2018-08-31 09:22:23 +010078{
Nattapat Chaimanowongd4b70592018-10-12 11:21:49 +010079 NeonCreateActivationWorkloadTest<DataType::Float32>();
telsoa01c577f2c2018-08-31 09:22:23 +010080}
81
David Beckbc392452018-09-10 14:47:28 +010082template <typename WorkloadType,
83 typename DescriptorType,
84 typename LayerType,
85 armnn::DataType DataType>
86static void NeonCreateArithmethicWorkloadTest()
telsoa014fcda012018-03-09 14:13:49 +000087{
David Beckbc392452018-09-10 14:47:28 +010088 Graph graph;
telsoa014fcda012018-03-09 14:13:49 +000089 NeonWorkloadFactory factory;
David Beckbc392452018-09-10 14:47:28 +010090 auto workload = CreateArithmeticWorkloadTest<WorkloadType, DescriptorType, LayerType, DataType>(factory, graph);
telsoa014fcda012018-03-09 14:13:49 +000091
David Beckbc392452018-09-10 14:47:28 +010092 DescriptorType queueDescriptor = workload->GetData();
telsoa014fcda012018-03-09 14:13:49 +000093 auto inputHandle1 = boost::polymorphic_downcast<INeonTensorHandle*>(queueDescriptor.m_Inputs[0]);
94 auto inputHandle2 = boost::polymorphic_downcast<INeonTensorHandle*>(queueDescriptor.m_Inputs[1]);
95 auto outputHandle = boost::polymorphic_downcast<INeonTensorHandle*>(queueDescriptor.m_Outputs[0]);
telsoa01c577f2c2018-08-31 09:22:23 +010096 BOOST_TEST(TestNeonTensorHandleInfo(inputHandle1, TensorInfo({2, 3}, DataType)));
97 BOOST_TEST(TestNeonTensorHandleInfo(inputHandle2, TensorInfo({2, 3}, DataType)));
98 BOOST_TEST(TestNeonTensorHandleInfo(outputHandle, TensorInfo({2, 3}, DataType)));
telsoa014fcda012018-03-09 14:13:49 +000099}
100
telsoa01c577f2c2018-08-31 09:22:23 +0100101#ifdef __ARM_FEATURE_FP16_VECTOR_ARITHMETIC
102BOOST_AUTO_TEST_CASE(CreateAdditionFloat16Workload)
103{
David Beckbc392452018-09-10 14:47:28 +0100104 NeonCreateArithmethicWorkloadTest<NeonAdditionFloatWorkload,
105 AdditionQueueDescriptor,
106 AdditionLayer,
107 DataType::Float16>();
telsoa01c577f2c2018-08-31 09:22:23 +0100108}
109#endif
110
arovir019e53a352018-08-31 15:26:35 +0100111BOOST_AUTO_TEST_CASE(CreateAdditionFloatWorkload)
telsoa01c577f2c2018-08-31 09:22:23 +0100112{
David Beckbc392452018-09-10 14:47:28 +0100113 NeonCreateArithmethicWorkloadTest<NeonAdditionFloatWorkload,
114 AdditionQueueDescriptor,
115 AdditionLayer,
116 DataType::Float32>();
117}
118
119#ifdef __ARM_FEATURE_FP16_VECTOR_ARITHMETIC
120BOOST_AUTO_TEST_CASE(CreateSubtractionFloat16Workload)
121{
122 NeonCreateArithmethicWorkloadTest<NeonSubtractionFloatWorkload,
123 SubtractionQueueDescriptor,
124 SubtractionLayer,
125 DataType::Float16>();
126}
127#endif
128
129BOOST_AUTO_TEST_CASE(CreateSubtractionFloatWorkload)
130{
131 NeonCreateArithmethicWorkloadTest<NeonSubtractionFloatWorkload,
132 SubtractionQueueDescriptor,
133 SubtractionLayer,
134 DataType::Float32>();
135}
136
137#ifdef __ARM_FEATURE_FP16_VECTOR_ARITHMETIC
138BOOST_AUTO_TEST_CASE(CreateMultiplicationFloat16Workload)
139{
140 NeonCreateArithmethicWorkloadTest<NeonMultiplicationFloatWorkload,
141 MultiplicationQueueDescriptor,
142 MultiplicationLayer,
143 DataType::Float16>();
144}
145#endif
146
147BOOST_AUTO_TEST_CASE(CreateMultiplicationFloatWorkload)
148{
149 NeonCreateArithmethicWorkloadTest<NeonMultiplicationFloatWorkload,
150 MultiplicationQueueDescriptor,
151 MultiplicationLayer,
152 DataType::Float32>();
telsoa01c577f2c2018-08-31 09:22:23 +0100153}
154
155template <typename BatchNormalizationWorkloadType, typename armnn::DataType DataType>
Nikhil Rajd1340932018-10-18 14:27:50 +0100156static void NeonCreateBatchNormalizationWorkloadTest(DataLayout dataLayout)
telsoa014fcda012018-03-09 14:13:49 +0000157{
158 Graph graph;
159 NeonWorkloadFactory factory;
Nikhil Rajd1340932018-10-18 14:27:50 +0100160 auto workload = CreateBatchNormalizationWorkloadTest<BatchNormalizationWorkloadType, DataType>
161 (factory, graph, dataLayout);
telsoa014fcda012018-03-09 14:13:49 +0000162
telsoa01c577f2c2018-08-31 09:22:23 +0100163 // Checks that outputs and inputs are as we expect them (see definition of CreateBatchNormalizationWorkloadTest).
telsoa014fcda012018-03-09 14:13:49 +0000164 BatchNormalizationQueueDescriptor queueDescriptor = workload->GetData();
165 auto inputHandle = boost::polymorphic_downcast<INeonTensorHandle*>(queueDescriptor.m_Inputs[0]);
166 auto outputHandle = boost::polymorphic_downcast<INeonTensorHandle*>(queueDescriptor.m_Outputs[0]);
Nikhil Rajd1340932018-10-18 14:27:50 +0100167
168 TensorShape inputShape = (dataLayout == DataLayout::NCHW) ? TensorShape{2, 3, 4, 4} : TensorShape{2, 4, 4, 3};
169 TensorShape outputShape = (dataLayout == DataLayout::NCHW) ? TensorShape{2, 3, 4, 4} : TensorShape{2, 4, 4, 3};
170
171 BOOST_TEST(TestNeonTensorHandleInfo(inputHandle, TensorInfo(inputShape, DataType)));
172 BOOST_TEST(TestNeonTensorHandleInfo(outputHandle, TensorInfo(outputShape, DataType)));
telsoa014fcda012018-03-09 14:13:49 +0000173}
174
telsoa01c577f2c2018-08-31 09:22:23 +0100175#ifdef __ARM_FEATURE_FP16_VECTOR_ARITHMETIC
Nikhil Rajd1340932018-10-18 14:27:50 +0100176BOOST_AUTO_TEST_CASE(CreateBatchNormalizationFloat16NchwWorkload)
telsoa01c577f2c2018-08-31 09:22:23 +0100177{
Nikhil Rajd1340932018-10-18 14:27:50 +0100178 NeonCreateBatchNormalizationWorkloadTest<NeonBatchNormalizationFloatWorkload, DataType::Float16>(DataLayout::NCHW);
179}
180
181BOOST_AUTO_TEST_CASE(CreateBatchNormalizationFloat16NhwcWorkload)
182{
183 NeonCreateBatchNormalizationWorkloadTest<NeonBatchNormalizationFloatWorkload, DataType::Float16>(DataLayout::NHWC);
telsoa01c577f2c2018-08-31 09:22:23 +0100184}
185#endif
186
Nikhil Rajd1340932018-10-18 14:27:50 +0100187BOOST_AUTO_TEST_CASE(CreateBatchNormalizationFloatNchwWorkload)
telsoa01c577f2c2018-08-31 09:22:23 +0100188{
Nikhil Rajd1340932018-10-18 14:27:50 +0100189 NeonCreateBatchNormalizationWorkloadTest<NeonBatchNormalizationFloatWorkload, DataType::Float32>(DataLayout::NCHW);
190}
191
192BOOST_AUTO_TEST_CASE(CreateBatchNormalizationFloatNhwcWorkload)
193{
194 NeonCreateBatchNormalizationWorkloadTest<NeonBatchNormalizationFloatWorkload, DataType::Float32>(DataLayout::NHWC);
telsoa01c577f2c2018-08-31 09:22:23 +0100195}
196
Nattapat Chaimanowong974b65f2018-10-15 15:07:34 +0100197template <typename armnn::DataType DataType>
Francis Murtagh0d9d4192018-10-09 16:22:33 +0100198static void NeonCreateConvolution2dWorkloadTest(DataLayout dataLayout = DataLayout::NCHW)
telsoa014fcda012018-03-09 14:13:49 +0000199{
200 Graph graph;
201 NeonWorkloadFactory factory;
Nattapat Chaimanowong974b65f2018-10-15 15:07:34 +0100202 auto workload = CreateConvolution2dWorkloadTest<NeonConvolution2dWorkload,
Francis Murtagh0d9d4192018-10-09 16:22:33 +0100203 DataType>(factory, graph, dataLayout);
204
205 TensorShape inputShape = (dataLayout == DataLayout::NCHW) ? TensorShape{2, 3, 8, 16} : TensorShape{2, 8, 16, 3};
206 TensorShape outputShape = (dataLayout == DataLayout::NCHW) ? TensorShape{2, 2, 2, 10} : TensorShape{2, 2, 10, 2};
telsoa014fcda012018-03-09 14:13:49 +0000207
telsoa01c577f2c2018-08-31 09:22:23 +0100208 // Checks that outputs and inputs are as we expect them (see definition of CreateConvolution2dWorkloadTest).
telsoa014fcda012018-03-09 14:13:49 +0000209 Convolution2dQueueDescriptor queueDescriptor = workload->GetData();
210 auto inputHandle = boost::polymorphic_downcast<INeonTensorHandle*>(queueDescriptor.m_Inputs[0]);
211 auto outputHandle = boost::polymorphic_downcast<INeonTensorHandle*>(queueDescriptor.m_Outputs[0]);
Francis Murtagh0d9d4192018-10-09 16:22:33 +0100212 BOOST_TEST(TestNeonTensorHandleInfo(inputHandle, TensorInfo(inputShape, DataType)));
213 BOOST_TEST(TestNeonTensorHandleInfo(outputHandle, TensorInfo(outputShape, DataType)));
telsoa014fcda012018-03-09 14:13:49 +0000214}
215
telsoa01c577f2c2018-08-31 09:22:23 +0100216#ifdef __ARM_FEATURE_FP16_VECTOR_ARITHMETIC
Francis Murtagh0d9d4192018-10-09 16:22:33 +0100217BOOST_AUTO_TEST_CASE(CreateConvolution2dFloat16NchwWorkload)
telsoa01c577f2c2018-08-31 09:22:23 +0100218{
Nattapat Chaimanowong974b65f2018-10-15 15:07:34 +0100219 NeonCreateConvolution2dWorkloadTest<DataType::Float16>();
telsoa01c577f2c2018-08-31 09:22:23 +0100220}
telsoa01c577f2c2018-08-31 09:22:23 +0100221
Francis Murtagh0d9d4192018-10-09 16:22:33 +0100222BOOST_AUTO_TEST_CASE(CreateConvolution2dFloat16NhwcWorkload)
223{
Nattapat Chaimanowong974b65f2018-10-15 15:07:34 +0100224 NeonCreateConvolution2dWorkloadTest<DataType::Float16>(DataLayout::NHWC);
Francis Murtagh0d9d4192018-10-09 16:22:33 +0100225}
226
227#endif
228BOOST_AUTO_TEST_CASE(CreateConvolution2dFloatNchwWorkload)
telsoa01c577f2c2018-08-31 09:22:23 +0100229{
Nattapat Chaimanowong974b65f2018-10-15 15:07:34 +0100230 NeonCreateConvolution2dWorkloadTest<DataType::Float32>();
telsoa01c577f2c2018-08-31 09:22:23 +0100231}
232
Francis Murtagh0d9d4192018-10-09 16:22:33 +0100233BOOST_AUTO_TEST_CASE(CreateConvolution2dFloatNhwcWorkload)
234{
Nattapat Chaimanowong974b65f2018-10-15 15:07:34 +0100235 NeonCreateConvolution2dWorkloadTest<DataType::Float32>(DataLayout::NHWC);
Francis Murtagh0d9d4192018-10-09 16:22:33 +0100236}
237
Nattapat Chaimanowong77140882018-10-17 11:12:19 +0100238template <typename armnn::DataType DataType>
Nikhil Rajcec6b652018-10-12 13:51:57 +0100239static void NeonCreateDepthWiseConvolutionWorkloadTest(DataLayout dataLayout)
240{
241 Graph graph;
242 NeonWorkloadFactory factory;
243
Nattapat Chaimanowong77140882018-10-17 11:12:19 +0100244 auto workload = CreateDepthwiseConvolution2dWorkloadTest<NeonDepthwiseConvolutionWorkload,
Nikhil Rajcec6b652018-10-12 13:51:57 +0100245 DataType>(factory, graph, dataLayout);
246
247 // Checks that inputs/outputs are as we expect them (see definition of CreateNormalizationWorkloadTest).
248 DepthwiseConvolution2dQueueDescriptor queueDescriptor = workload->GetData();
249 auto inputHandle = boost::polymorphic_downcast<INeonTensorHandle*>(queueDescriptor.m_Inputs[0]);
250 auto outputHandle = boost::polymorphic_downcast<INeonTensorHandle*>(queueDescriptor.m_Outputs[0]);
251
252 std::initializer_list<unsigned int> inputShape = (dataLayout == DataLayout::NCHW)
253 ? std::initializer_list<unsigned int>({ 2, 2, 5, 5 })
254 : std::initializer_list<unsigned int>({ 2, 5, 5, 2 });
255 std::initializer_list<unsigned int> outputShape = (dataLayout == DataLayout::NCHW)
256 ? std::initializer_list<unsigned int>({ 2, 2, 5, 5 })
257 : std::initializer_list<unsigned int>({ 2, 5, 5, 2 });
258
259 BOOST_TEST(TestNeonTensorHandleInfo(inputHandle, TensorInfo(inputShape, DataType)));
260 BOOST_TEST(TestNeonTensorHandleInfo(outputHandle, TensorInfo(outputShape, DataType)));
261}
262
263BOOST_AUTO_TEST_CASE(CreateDepthWiseConvolution2dFloat32NhwcWorkload)
264{
Nattapat Chaimanowong77140882018-10-17 11:12:19 +0100265 NeonCreateDepthWiseConvolutionWorkloadTest<DataType::Float32>(DataLayout::NHWC);
Nikhil Rajcec6b652018-10-12 13:51:57 +0100266}
267
268#ifdef __ARM_FEATURE_FP16_VECTOR_ARITHMETIC
269BOOST_AUTO_TEST_CASE(CreateDepthWiseConvolution2dFloat16NhwcWorkload)
270{
Nattapat Chaimanowong77140882018-10-17 11:12:19 +0100271 NeonCreateDepthWiseConvolutionWorkloadTest<DataType::Float16>(DataLayout::NHWC);
Nikhil Rajcec6b652018-10-12 13:51:57 +0100272}
273#endif
274
telsoa01c577f2c2018-08-31 09:22:23 +0100275template <typename FullyConnectedWorkloadType, typename armnn::DataType DataType>
276static void NeonCreateFullyConnectedWorkloadTest()
telsoa014fcda012018-03-09 14:13:49 +0000277{
278 Graph graph;
279 NeonWorkloadFactory factory;
telsoa01c577f2c2018-08-31 09:22:23 +0100280 auto workload = CreateFullyConnectedWorkloadTest<FullyConnectedWorkloadType,
281 DataType>(factory, graph);
telsoa014fcda012018-03-09 14:13:49 +0000282
telsoa01c577f2c2018-08-31 09:22:23 +0100283 // Checks that outputs and inputs are as we expect them (see definition of CreateFullyConnectedWorkloadTest).
telsoa014fcda012018-03-09 14:13:49 +0000284 FullyConnectedQueueDescriptor queueDescriptor = workload->GetData();
285 auto inputHandle = boost::polymorphic_downcast<INeonTensorHandle*>(queueDescriptor.m_Inputs[0]);
286 auto outputHandle = boost::polymorphic_downcast<INeonTensorHandle*>(queueDescriptor.m_Outputs[0]);
telsoa01c577f2c2018-08-31 09:22:23 +0100287 BOOST_TEST(TestNeonTensorHandleInfo(inputHandle, TensorInfo({3, 1, 4, 5}, DataType)));
288 BOOST_TEST(TestNeonTensorHandleInfo(outputHandle, TensorInfo({3, 7}, DataType)));
telsoa014fcda012018-03-09 14:13:49 +0000289}
290
telsoa01c577f2c2018-08-31 09:22:23 +0100291#ifdef __ARM_FEATURE_FP16_VECTOR_ARITHMETIC
292BOOST_AUTO_TEST_CASE(CreateFullyConnectedFloat16Workload)
293{
kevmay01e448be32018-09-26 10:21:55 +0100294 NeonCreateFullyConnectedWorkloadTest<NeonFullyConnectedWorkload, DataType::Float16>();
telsoa01c577f2c2018-08-31 09:22:23 +0100295}
296#endif
297
arovir019e53a352018-08-31 15:26:35 +0100298BOOST_AUTO_TEST_CASE(CreateFullyConnectedFloatWorkload)
telsoa01c577f2c2018-08-31 09:22:23 +0100299{
kevmay01e448be32018-09-26 10:21:55 +0100300 NeonCreateFullyConnectedWorkloadTest<NeonFullyConnectedWorkload, DataType::Float32>();
telsoa01c577f2c2018-08-31 09:22:23 +0100301}
302
telsoa01c577f2c2018-08-31 09:22:23 +0100303template <typename NormalizationWorkloadType, typename armnn::DataType DataType>
narpra0155a97bc2018-10-02 14:35:53 +0100304static void NeonCreateNormalizationWorkloadTest(DataLayout dataLayout)
telsoa014fcda012018-03-09 14:13:49 +0000305{
narpra0155a97bc2018-10-02 14:35:53 +0100306 Graph graph;
telsoa014fcda012018-03-09 14:13:49 +0000307 NeonWorkloadFactory factory;
narpra0155a97bc2018-10-02 14:35:53 +0100308 auto workload = CreateNormalizationWorkloadTest<NormalizationWorkloadType, DataType>(factory, graph, dataLayout);
telsoa014fcda012018-03-09 14:13:49 +0000309
telsoa01c577f2c2018-08-31 09:22:23 +0100310 // Checks that outputs and inputs are as we expect them (see definition of CreateNormalizationWorkloadTest).
telsoa014fcda012018-03-09 14:13:49 +0000311 NormalizationQueueDescriptor queueDescriptor = workload->GetData();
312 auto inputHandle = boost::polymorphic_downcast<INeonTensorHandle*>(queueDescriptor.m_Inputs[0]);
313 auto outputHandle = boost::polymorphic_downcast<INeonTensorHandle*>(queueDescriptor.m_Outputs[0]);
Matteo Martincigha160b242018-10-18 10:33:23 +0100314
315 TensorShape inputShape = (dataLayout == DataLayout::NCHW) ? TensorShape{3, 5, 5, 1} : TensorShape{3, 1, 5, 5};
316 TensorShape outputShape = (dataLayout == DataLayout::NCHW) ? TensorShape{3, 5, 5, 1} : TensorShape{3, 1, 5, 5};
317
318 BOOST_TEST(TestNeonTensorHandleInfo(inputHandle, TensorInfo(inputShape, DataType)));
319 BOOST_TEST(TestNeonTensorHandleInfo(outputHandle, TensorInfo(outputShape, DataType)));
telsoa014fcda012018-03-09 14:13:49 +0000320}
321
telsoa01c577f2c2018-08-31 09:22:23 +0100322#ifdef __ARM_FEATURE_FP16_VECTOR_ARITHMETIC
narpra0155a97bc2018-10-02 14:35:53 +0100323BOOST_AUTO_TEST_CASE(CreateNormalizationFloat16NchwWorkload)
telsoa01c577f2c2018-08-31 09:22:23 +0100324{
narpra0155a97bc2018-10-02 14:35:53 +0100325 NeonCreateNormalizationWorkloadTest<NeonNormalizationFloatWorkload, DataType::Float16>(DataLayout::NCHW);
326}
327
328BOOST_AUTO_TEST_CASE(CreateNormalizationFloat16NhwcWorkload)
329{
330 NeonCreateNormalizationWorkloadTest<NeonNormalizationFloatWorkload, DataType::Float16>(DataLayout::NHWC);
telsoa01c577f2c2018-08-31 09:22:23 +0100331}
332#endif
333
narpra0155a97bc2018-10-02 14:35:53 +0100334BOOST_AUTO_TEST_CASE(CreateNormalizationFloatNchwWorkload)
telsoa01c577f2c2018-08-31 09:22:23 +0100335{
narpra0155a97bc2018-10-02 14:35:53 +0100336 NeonCreateNormalizationWorkloadTest<NeonNormalizationFloatWorkload, DataType::Float32>(DataLayout::NCHW);
telsoa01c577f2c2018-08-31 09:22:23 +0100337}
338
narpra0155a97bc2018-10-02 14:35:53 +0100339BOOST_AUTO_TEST_CASE(CreateNormalizationFloatNhwcWorkload)
340{
341 NeonCreateNormalizationWorkloadTest<NeonNormalizationFloatWorkload, DataType::Float32>(DataLayout::NHWC);
342}
343
344
Nattapat Chaimanowong5d2e7002018-10-12 16:03:56 +0100345template <typename armnn::DataType DataType>
Nina Drozdb48e6862018-10-09 12:09:56 +0100346static void NeonCreatePooling2dWorkloadTest(DataLayout dataLayout = DataLayout::NCHW)
telsoa014fcda012018-03-09 14:13:49 +0000347{
348 Graph graph;
349 NeonWorkloadFactory factory;
Nattapat Chaimanowong5d2e7002018-10-12 16:03:56 +0100350 auto workload = CreatePooling2dWorkloadTest<NeonPooling2dWorkload, DataType>
Nina Drozdb48e6862018-10-09 12:09:56 +0100351 (factory, graph, dataLayout);
352
353 TensorShape inputShape = (dataLayout == DataLayout::NCHW) ? TensorShape{3, 2, 5, 5} : TensorShape{3, 5, 5, 2};
354 TensorShape outputShape = (dataLayout == DataLayout::NCHW) ? TensorShape{3, 2, 2, 4} : TensorShape{3, 2, 4, 2};
telsoa014fcda012018-03-09 14:13:49 +0000355
telsoa01c577f2c2018-08-31 09:22:23 +0100356 // Checks that outputs and inputs are as we expect them (see definition of CreatePooling2dWorkloadTest).
telsoa014fcda012018-03-09 14:13:49 +0000357 Pooling2dQueueDescriptor queueDescriptor = workload->GetData();
358 auto inputHandle = boost::polymorphic_downcast<INeonTensorHandle*>(queueDescriptor.m_Inputs[0]);
359 auto outputHandle = boost::polymorphic_downcast<INeonTensorHandle*>(queueDescriptor.m_Outputs[0]);
Nina Drozdb48e6862018-10-09 12:09:56 +0100360 BOOST_TEST(TestNeonTensorHandleInfo(inputHandle, TensorInfo(inputShape, DataType)));
361 BOOST_TEST(TestNeonTensorHandleInfo(outputHandle, TensorInfo(outputShape, DataType)));
telsoa014fcda012018-03-09 14:13:49 +0000362}
363
telsoa01c577f2c2018-08-31 09:22:23 +0100364#ifdef __ARM_FEATURE_FP16_VECTOR_ARITHMETIC
365BOOST_AUTO_TEST_CASE(CreatePooling2dFloat16Workload)
366{
Nattapat Chaimanowong5d2e7002018-10-12 16:03:56 +0100367 NeonCreatePooling2dWorkloadTest<DataType::Float16>();
telsoa01c577f2c2018-08-31 09:22:23 +0100368}
369#endif
370
Nina Drozdb48e6862018-10-09 12:09:56 +0100371BOOST_AUTO_TEST_CASE(CreatePooling2dFloatNchwWorkload)
telsoa01c577f2c2018-08-31 09:22:23 +0100372{
Nattapat Chaimanowong5d2e7002018-10-12 16:03:56 +0100373 NeonCreatePooling2dWorkloadTest<DataType::Float32>(DataLayout::NCHW);
telsoa01c577f2c2018-08-31 09:22:23 +0100374}
375
Nina Drozdb48e6862018-10-09 12:09:56 +0100376BOOST_AUTO_TEST_CASE(CreatePooling2dFloatNhwcWorkload)
telsoa01c577f2c2018-08-31 09:22:23 +0100377{
Nattapat Chaimanowong5d2e7002018-10-12 16:03:56 +0100378 NeonCreatePooling2dWorkloadTest<DataType::Float32>(DataLayout::NHWC);
Nina Drozdb48e6862018-10-09 12:09:56 +0100379}
380
381BOOST_AUTO_TEST_CASE(CreatePooling2dUint8NchwWorkload)
382{
Nattapat Chaimanowong5d2e7002018-10-12 16:03:56 +0100383 NeonCreatePooling2dWorkloadTest<DataType::QuantisedAsymm8>(DataLayout::NCHW);
Nina Drozdb48e6862018-10-09 12:09:56 +0100384}
385
386BOOST_AUTO_TEST_CASE(CreatePooling2dUint8NhwcWorkload)
387{
Nattapat Chaimanowong5d2e7002018-10-12 16:03:56 +0100388 NeonCreatePooling2dWorkloadTest<DataType::QuantisedAsymm8>(DataLayout::NHWC);
telsoa01c577f2c2018-08-31 09:22:23 +0100389}
390
Nattapat Chaimanowongcce11fc2018-10-12 16:30:56 +0100391template <typename armnn::DataType DataType>
telsoa01c577f2c2018-08-31 09:22:23 +0100392static void NeonCreateReshapeWorkloadTest()
telsoa014fcda012018-03-09 14:13:49 +0000393{
394 Graph graph;
395 NeonWorkloadFactory factory;
Nattapat Chaimanowongcce11fc2018-10-12 16:30:56 +0100396 auto workload = CreateReshapeWorkloadTest<NeonReshapeWorkload, DataType>(factory, graph);
telsoa014fcda012018-03-09 14:13:49 +0000397
telsoa01c577f2c2018-08-31 09:22:23 +0100398 // Checks that outputs and inputs are as we expect them (see definition of CreateReshapeWorkloadTest).
telsoa014fcda012018-03-09 14:13:49 +0000399 ReshapeQueueDescriptor queueDescriptor = workload->GetData();
400 auto inputHandle = boost::polymorphic_downcast<INeonTensorHandle*>(queueDescriptor.m_Inputs[0]);
401 auto outputHandle = boost::polymorphic_downcast<INeonTensorHandle*>(queueDescriptor.m_Outputs[0]);
telsoa01c577f2c2018-08-31 09:22:23 +0100402 BOOST_TEST(TestNeonTensorHandleInfo(inputHandle, TensorInfo({4, 1}, DataType)));
403 BOOST_TEST(TestNeonTensorHandleInfo(outputHandle, TensorInfo({1, 4}, DataType)));
telsoa014fcda012018-03-09 14:13:49 +0000404}
405
telsoa01c577f2c2018-08-31 09:22:23 +0100406#ifdef __ARM_FEATURE_FP16_VECTOR_ARITHMETIC
407BOOST_AUTO_TEST_CASE(CreateReshapeFloat16Workload)
408{
Nattapat Chaimanowongcce11fc2018-10-12 16:30:56 +0100409 NeonCreateReshapeWorkloadTest<DataType::Float16>();
telsoa01c577f2c2018-08-31 09:22:23 +0100410}
411#endif
412
arovir019e53a352018-08-31 15:26:35 +0100413BOOST_AUTO_TEST_CASE(CreateReshapeFloatWorkload)
telsoa014fcda012018-03-09 14:13:49 +0000414{
Nattapat Chaimanowongcce11fc2018-10-12 16:30:56 +0100415 NeonCreateReshapeWorkloadTest<DataType::Float32>();
telsoa014fcda012018-03-09 14:13:49 +0000416}
417
418BOOST_AUTO_TEST_CASE(CreateReshapeUint8Workload)
419{
Nattapat Chaimanowongcce11fc2018-10-12 16:30:56 +0100420 NeonCreateReshapeWorkloadTest<DataType::QuantisedAsymm8>();
telsoa014fcda012018-03-09 14:13:49 +0000421}
422
telsoa01c577f2c2018-08-31 09:22:23 +0100423template <typename SoftmaxWorkloadType, typename armnn::DataType DataType>
424static void NeonCreateSoftmaxWorkloadTest()
telsoa014fcda012018-03-09 14:13:49 +0000425{
426 Graph graph;
427 NeonWorkloadFactory factory;
telsoa01c577f2c2018-08-31 09:22:23 +0100428 auto workload = CreateSoftmaxWorkloadTest<SoftmaxWorkloadType, DataType>(factory, graph);
telsoa014fcda012018-03-09 14:13:49 +0000429
telsoa01c577f2c2018-08-31 09:22:23 +0100430 // Checks that outputs and inputs are as we expect them (see definition of CreateSoftmaxWorkloadTest).
telsoa014fcda012018-03-09 14:13:49 +0000431 SoftmaxQueueDescriptor queueDescriptor = workload->GetData();
432 auto inputHandle = boost::polymorphic_downcast<INeonTensorHandle*>(queueDescriptor.m_Inputs[0]);
433 auto outputHandle = boost::polymorphic_downcast<INeonTensorHandle*>(queueDescriptor.m_Outputs[0]);
telsoa01c577f2c2018-08-31 09:22:23 +0100434 BOOST_TEST(TestNeonTensorHandleInfo(inputHandle, TensorInfo({4, 1}, DataType)));
435 BOOST_TEST(TestNeonTensorHandleInfo(outputHandle, TensorInfo({4, 1}, DataType)));
436}
437
438#ifdef __ARM_FEATURE_FP16_VECTOR_ARITHMETIC
439BOOST_AUTO_TEST_CASE(CreateSoftmaxFloat16Workload)
440{
arovir019e53a352018-08-31 15:26:35 +0100441 NeonCreateSoftmaxWorkloadTest<NeonSoftmaxFloatWorkload, DataType::Float16>();
telsoa01c577f2c2018-08-31 09:22:23 +0100442}
443#endif
444
arovir019e53a352018-08-31 15:26:35 +0100445BOOST_AUTO_TEST_CASE(CreateSoftmaxFloatWorkload)
telsoa01c577f2c2018-08-31 09:22:23 +0100446{
arovir019e53a352018-08-31 15:26:35 +0100447 NeonCreateSoftmaxWorkloadTest<NeonSoftmaxFloatWorkload, DataType::Float32>();
telsoa014fcda012018-03-09 14:13:49 +0000448}
449
450BOOST_AUTO_TEST_CASE(CreateSplitterWorkload)
451{
452 Graph graph;
453 NeonWorkloadFactory factory;
Nattapat Chaimanowong14766d72018-10-12 15:09:53 +0100454 auto workload = CreateSplitterWorkloadTest<NeonSplitterWorkload, DataType::Float32>(factory, graph);
telsoa014fcda012018-03-09 14:13:49 +0000455
telsoa01c577f2c2018-08-31 09:22:23 +0100456 // Checks that outputs are as we expect them (see definition of CreateSplitterWorkloadTest).
telsoa014fcda012018-03-09 14:13:49 +0000457 SplitterQueueDescriptor queueDescriptor = workload->GetData();
458 auto inputHandle = boost::polymorphic_downcast<INeonTensorHandle*>(queueDescriptor.m_Inputs[0]);
surmeh013537c2c2018-05-18 16:31:43 +0100459 BOOST_TEST(TestNeonTensorHandleInfo(inputHandle, TensorInfo({5, 7, 7}, DataType::Float32)));
460
telsoa014fcda012018-03-09 14:13:49 +0000461 auto outputHandle0 = boost::polymorphic_downcast<INeonTensorHandle*>(queueDescriptor.m_Outputs[0]);
surmeh013537c2c2018-05-18 16:31:43 +0100462 BOOST_TEST(TestNeonTensorHandleInfo(outputHandle0, TensorInfo({1, 7, 7}, DataType::Float32)));
463
telsoa014fcda012018-03-09 14:13:49 +0000464 auto outputHandle1 = boost::polymorphic_downcast<INeonTensorHandle*>(queueDescriptor.m_Outputs[1]);
surmeh013537c2c2018-05-18 16:31:43 +0100465 BOOST_TEST(TestNeonTensorHandleInfo(outputHandle1, TensorInfo({2, 7, 7}, DataType::Float32)));
466
telsoa014fcda012018-03-09 14:13:49 +0000467 auto outputHandle2 = boost::polymorphic_downcast<INeonTensorHandle*>(queueDescriptor.m_Outputs[2]);
surmeh013537c2c2018-05-18 16:31:43 +0100468 BOOST_TEST(TestNeonTensorHandleInfo(outputHandle2, TensorInfo({2, 7, 7}, DataType::Float32)));
telsoa014fcda012018-03-09 14:13:49 +0000469}
470
471BOOST_AUTO_TEST_CASE(CreateSplitterMerger)
472{
telsoa01c577f2c2018-08-31 09:22:23 +0100473 // Tests that it is possible to decide which output of the splitter layer
474 // should be lined to which input of the merger layer.
475 // We tested that is is possible to specify 0th output
476 // of the splitter to be the 1st input to the merger, and the 1st output of the splitter to be 0th input
telsoa014fcda012018-03-09 14:13:49 +0000477 // of the merger.
478
479 Graph graph;
480 NeonWorkloadFactory factory;
481
482 auto workloads =
Nattapat Chaimanowong14766d72018-10-12 15:09:53 +0100483 CreateSplitterMergerWorkloadTest<NeonSplitterWorkload, NeonMergerWorkload,
telsoa01c577f2c2018-08-31 09:22:23 +0100484 DataType::Float32>(factory, graph);
telsoa014fcda012018-03-09 14:13:49 +0000485
486 auto wlSplitter = std::move(workloads.first);
487 auto wlMerger = std::move(workloads.second);
488
telsoa01c577f2c2018-08-31 09:22:23 +0100489 //Checks that the index of inputs/outputs matches what we declared on InputDescriptor construction.
telsoa014fcda012018-03-09 14:13:49 +0000490 armnn::INeonTensorHandle* sOut0 = dynamic_cast<armnn::INeonTensorHandle*>(wlSplitter->GetData().m_Outputs[0]);
491 armnn::INeonTensorHandle* sOut1 = dynamic_cast<armnn::INeonTensorHandle*>(wlSplitter->GetData().m_Outputs[1]);
492 armnn::INeonTensorHandle* mIn0 = dynamic_cast<armnn::INeonTensorHandle*>(wlMerger->GetData().m_Inputs[0]);
493 armnn::INeonTensorHandle* mIn1 = dynamic_cast<armnn::INeonTensorHandle*>(wlMerger->GetData().m_Inputs[1]);
494
495 BOOST_TEST(sOut0);
496 BOOST_TEST(sOut1);
497 BOOST_TEST(mIn0);
498 BOOST_TEST(mIn1);
499
500 bool validDataPointers = (sOut0 == mIn1) && (sOut1 == mIn0);
501
502 BOOST_TEST(validDataPointers);
503}
504
505BOOST_AUTO_TEST_CASE(CreateSingleOutputMultipleInputs)
506{
telsoa01c577f2c2018-08-31 09:22:23 +0100507 // Tests that it is possible to assign multiple (two) different layers to each of the outputs of a splitter layer.
508 // 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 +0000509
510 Graph graph;
511 NeonWorkloadFactory factory;
Nattapat Chaimanowong14766d72018-10-12 15:09:53 +0100512 std::unique_ptr<NeonSplitterWorkload> wlSplitter;
Nattapat Chaimanowongd4b70592018-10-12 11:21:49 +0100513 std::unique_ptr<NeonActivationWorkload> wlActiv0_0;
514 std::unique_ptr<NeonActivationWorkload> wlActiv0_1;
515 std::unique_ptr<NeonActivationWorkload> wlActiv1_0;
516 std::unique_ptr<NeonActivationWorkload> wlActiv1_1;
telsoa014fcda012018-03-09 14:13:49 +0000517
Nattapat Chaimanowong14766d72018-10-12 15:09:53 +0100518 CreateSplitterMultipleInputsOneOutputWorkloadTest<NeonSplitterWorkload,
Nattapat Chaimanowongd4b70592018-10-12 11:21:49 +0100519 NeonActivationWorkload, DataType::Float32>(factory, graph, wlSplitter, wlActiv0_0, wlActiv0_1,
520 wlActiv1_0, wlActiv1_1);
telsoa014fcda012018-03-09 14:13:49 +0000521
522 armnn::INeonTensorHandle* sOut0 = dynamic_cast<armnn::INeonTensorHandle*>(wlSplitter->GetData().m_Outputs[0]);
523 armnn::INeonTensorHandle* sOut1 = dynamic_cast<armnn::INeonTensorHandle*>(wlSplitter->GetData().m_Outputs[1]);
524 armnn::INeonTensorHandle* activ0_0Im = dynamic_cast<armnn::INeonTensorHandle*>(wlActiv0_0->GetData().m_Inputs[0]);
525 armnn::INeonTensorHandle* activ0_1Im = dynamic_cast<armnn::INeonTensorHandle*>(wlActiv0_1->GetData().m_Inputs[0]);
526 armnn::INeonTensorHandle* activ1_0Im = dynamic_cast<armnn::INeonTensorHandle*>(wlActiv1_0->GetData().m_Inputs[0]);
527 armnn::INeonTensorHandle* activ1_1Im = dynamic_cast<armnn::INeonTensorHandle*>(wlActiv1_1->GetData().m_Inputs[0]);
528
529
530 BOOST_TEST(sOut0);
531 BOOST_TEST(sOut1);
532 BOOST_TEST(activ0_0Im);
533 BOOST_TEST(activ0_1Im);
534 BOOST_TEST(activ1_0Im);
535 BOOST_TEST(activ1_1Im);
536
537 bool validDataPointers = (sOut0 == activ0_0Im) && (sOut0 == activ0_1Im) &&
538 (sOut1 == activ1_0Im) && (sOut1 == activ1_1Im);
539
540 BOOST_TEST(validDataPointers);
541}
542
543BOOST_AUTO_TEST_CASE(CreateMemCopyWorkloadsNeon)
544{
545 NeonWorkloadFactory factory;
telsoa01c577f2c2018-08-31 09:22:23 +0100546 CreateMemCopyWorkloads<INeonTensorHandle>(factory);
telsoa014fcda012018-03-09 14:13:49 +0000547}
548
Matteo Martincighbcd3c852018-09-28 14:14:12 +0100549template <typename L2NormalizationWorkloadType, typename armnn::DataType DataType>
550static void NeonCreateL2NormalizationWorkloadTest(DataLayout dataLayout)
551{
Matteo Martincigh2400b6d2018-10-09 18:19:20 +0100552 Graph graph;
553 NeonWorkloadFactory factory;
554 auto workload =
555 CreateL2NormalizationWorkloadTest<L2NormalizationWorkloadType, DataType>(factory, graph, dataLayout);
Matteo Martincighbcd3c852018-09-28 14:14:12 +0100556
557 // Checks that inputs/outputs are as we expect them (see definition of CreateNormalizationWorkloadTest).
558 L2NormalizationQueueDescriptor queueDescriptor = workload->GetData();
559 auto inputHandle = boost::polymorphic_downcast<INeonTensorHandle*>(queueDescriptor.m_Inputs[0]);
560 auto outputHandle = boost::polymorphic_downcast<INeonTensorHandle*>(queueDescriptor.m_Outputs[0]);
Matteo Martincigh2400b6d2018-10-09 18:19:20 +0100561
562 TensorShape inputShape = (dataLayout == DataLayout::NCHW) ?
563 TensorShape{ 5, 20, 50, 67 } : TensorShape{ 5, 50, 67, 20 };
564 TensorShape outputShape = (dataLayout == DataLayout::NCHW) ?
565 TensorShape{ 5, 20, 50, 67 } : TensorShape{ 5, 50, 67, 20 };
566
567 BOOST_TEST(TestNeonTensorHandleInfo(inputHandle, TensorInfo(inputShape, DataType)));
568 BOOST_TEST(TestNeonTensorHandleInfo(outputHandle, TensorInfo(outputShape, DataType)));
Matteo Martincighbcd3c852018-09-28 14:14:12 +0100569}
570
571#ifdef __ARM_FEATURE_FP16_VECTOR_ARITHMETIC
572BOOST_AUTO_TEST_CASE(CreateL2NormalizationFloat16NchwWorkload)
573{
574 NeonCreateL2NormalizationWorkloadTest<NeonL2NormalizationFloatWorkload, DataType::Float16>(DataLayout::NCHW);
575}
576
577BOOST_AUTO_TEST_CASE(CreateL2NormalizationFloat16NhwcWorkload)
578{
579 NeonCreateL2NormalizationWorkloadTest<NeonL2NormalizationFloatWorkload, DataType::Float16>(DataLayout::NHWC);
580}
581#endif
582
583BOOST_AUTO_TEST_CASE(CreateL2NormalizationNchwWorkload)
584{
585 NeonCreateL2NormalizationWorkloadTest<NeonL2NormalizationFloatWorkload, DataType::Float32>(DataLayout::NCHW);
586}
587
588BOOST_AUTO_TEST_CASE(CreateL2NormalizationNhwcWorkload)
589{
590 NeonCreateL2NormalizationWorkloadTest<NeonL2NormalizationFloatWorkload, DataType::Float32>(DataLayout::NHWC);
591}
592
telsoa014fcda012018-03-09 14:13:49 +0000593BOOST_AUTO_TEST_SUITE_END()