blob: 07953bf86f991c40e323ecf9f53a73f612db620e [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
Aron Virginas-Tarc9cc8042018-11-01 16:15:57 +00008#include <backendsCommon/MemCopyWorkload.hpp>
Aron Virginas-Tar3b278e92018-10-12 13:00:55 +01009
Aron Virginas-Tarc9cc8042018-11-01 16:15:57 +000010#include <aclCommon/test/CreateWorkloadClNeon.hpp>
Aron Virginas-Tar3b278e92018-10-12 13:00:55 +010011
Aron Virginas-Tarc9cc8042018-11-01 16:15:57 +000012#include <neon/NeonWorkloadFactory.hpp>
13#include <neon/NeonTensorHandle.hpp>
14#include <neon/workloads/NeonWorkloadUtils.hpp>
15#include <neon/workloads/NeonWorkloads.hpp>
telsoa014fcda012018-03-09 14:13:49 +000016
17BOOST_AUTO_TEST_SUITE(CreateWorkloadNeon)
18
19namespace
20{
21
22bool TestNeonTensorHandleInfo(armnn::INeonTensorHandle* handle, const armnn::TensorInfo& expectedInfo)
23{
24 using namespace armnn::armcomputetensorutils;
25
26 const arm_compute::ITensorInfo* handleInfo = handle->GetTensor().info();
27 const arm_compute::TensorInfo expectedAclInfo = BuildArmComputeTensorInfo(expectedInfo);
28
29 if (handleInfo->data_type() != expectedAclInfo.data_type())
30 {
31 return false;
32 }
33
34 if (handleInfo->num_dimensions() != expectedAclInfo.num_dimensions())
35 {
36 return false;
37 }
38
39 if (handleInfo->quantization_info() != expectedAclInfo.quantization_info())
40 {
41 return false;
42 }
43
44 for (std::size_t d = 0; d < expectedAclInfo.num_dimensions(); ++d)
45 {
46 if (handleInfo->dimension(d) != expectedAclInfo.dimension(d))
47 {
48 return false;
49 }
50 }
51
52 return true;
53}
54
55} // namespace
56
Nattapat Chaimanowongd4b70592018-10-12 11:21:49 +010057template <typename armnn::DataType DataType>
telsoa01c577f2c2018-08-31 09:22:23 +010058static void NeonCreateActivationWorkloadTest()
telsoa014fcda012018-03-09 14:13:49 +000059{
60 Graph graph;
Aron Virginas-Tar56055192018-11-12 18:10:43 +000061 NeonWorkloadFactory factory = NeonWorkloadFactoryHelper::GetFactory();
Nattapat Chaimanowongd4b70592018-10-12 11:21:49 +010062 auto workload = CreateActivationWorkloadTest<NeonActivationWorkload, DataType>(factory, graph);
telsoa014fcda012018-03-09 14:13:49 +000063
telsoa01c577f2c2018-08-31 09:22:23 +010064 // Checks that inputs/outputs are as we expect them (see definition of CreateActivationWorkloadTest).
telsoa014fcda012018-03-09 14:13:49 +000065 ActivationQueueDescriptor queueDescriptor = workload->GetData();
66 auto inputHandle = boost::polymorphic_downcast<INeonTensorHandle*>(queueDescriptor.m_Inputs[0]);
67 auto outputHandle = boost::polymorphic_downcast<INeonTensorHandle*>(queueDescriptor.m_Outputs[0]);
telsoa01c577f2c2018-08-31 09:22:23 +010068 BOOST_TEST(TestNeonTensorHandleInfo(inputHandle, TensorInfo({1, 1}, DataType)));
69 BOOST_TEST(TestNeonTensorHandleInfo(outputHandle, TensorInfo({1, 1}, DataType)));
telsoa014fcda012018-03-09 14:13:49 +000070}
71
telsoa01c577f2c2018-08-31 09:22:23 +010072#ifdef __ARM_FEATURE_FP16_VECTOR_ARITHMETIC
73BOOST_AUTO_TEST_CASE(CreateActivationFloat16Workload)
74{
Nattapat Chaimanowongd4b70592018-10-12 11:21:49 +010075 NeonCreateActivationWorkloadTest<DataType::Float16>();
telsoa01c577f2c2018-08-31 09:22:23 +010076}
77#endif
78
arovir019e53a352018-08-31 15:26:35 +010079BOOST_AUTO_TEST_CASE(CreateActivationFloatWorkload)
telsoa01c577f2c2018-08-31 09:22:23 +010080{
Nattapat Chaimanowongd4b70592018-10-12 11:21:49 +010081 NeonCreateActivationWorkloadTest<DataType::Float32>();
telsoa01c577f2c2018-08-31 09:22:23 +010082}
83
David Beckbc392452018-09-10 14:47:28 +010084template <typename WorkloadType,
85 typename DescriptorType,
86 typename LayerType,
87 armnn::DataType DataType>
88static void NeonCreateArithmethicWorkloadTest()
telsoa014fcda012018-03-09 14:13:49 +000089{
David Beckbc392452018-09-10 14:47:28 +010090 Graph graph;
Aron Virginas-Tar56055192018-11-12 18:10:43 +000091 NeonWorkloadFactory factory = NeonWorkloadFactoryHelper::GetFactory();
David Beckbc392452018-09-10 14:47:28 +010092 auto workload = CreateArithmeticWorkloadTest<WorkloadType, DescriptorType, LayerType, DataType>(factory, graph);
telsoa014fcda012018-03-09 14:13:49 +000093
David Beckbc392452018-09-10 14:47:28 +010094 DescriptorType queueDescriptor = workload->GetData();
telsoa014fcda012018-03-09 14:13:49 +000095 auto inputHandle1 = boost::polymorphic_downcast<INeonTensorHandle*>(queueDescriptor.m_Inputs[0]);
96 auto inputHandle2 = boost::polymorphic_downcast<INeonTensorHandle*>(queueDescriptor.m_Inputs[1]);
97 auto outputHandle = boost::polymorphic_downcast<INeonTensorHandle*>(queueDescriptor.m_Outputs[0]);
telsoa01c577f2c2018-08-31 09:22:23 +010098 BOOST_TEST(TestNeonTensorHandleInfo(inputHandle1, TensorInfo({2, 3}, DataType)));
99 BOOST_TEST(TestNeonTensorHandleInfo(inputHandle2, TensorInfo({2, 3}, DataType)));
100 BOOST_TEST(TestNeonTensorHandleInfo(outputHandle, TensorInfo({2, 3}, DataType)));
telsoa014fcda012018-03-09 14:13:49 +0000101}
102
telsoa01c577f2c2018-08-31 09:22:23 +0100103#ifdef __ARM_FEATURE_FP16_VECTOR_ARITHMETIC
104BOOST_AUTO_TEST_CASE(CreateAdditionFloat16Workload)
105{
David Beckbc392452018-09-10 14:47:28 +0100106 NeonCreateArithmethicWorkloadTest<NeonAdditionFloatWorkload,
107 AdditionQueueDescriptor,
108 AdditionLayer,
109 DataType::Float16>();
telsoa01c577f2c2018-08-31 09:22:23 +0100110}
111#endif
112
arovir019e53a352018-08-31 15:26:35 +0100113BOOST_AUTO_TEST_CASE(CreateAdditionFloatWorkload)
telsoa01c577f2c2018-08-31 09:22:23 +0100114{
David Beckbc392452018-09-10 14:47:28 +0100115 NeonCreateArithmethicWorkloadTest<NeonAdditionFloatWorkload,
116 AdditionQueueDescriptor,
117 AdditionLayer,
118 DataType::Float32>();
119}
120
121#ifdef __ARM_FEATURE_FP16_VECTOR_ARITHMETIC
122BOOST_AUTO_TEST_CASE(CreateSubtractionFloat16Workload)
123{
124 NeonCreateArithmethicWorkloadTest<NeonSubtractionFloatWorkload,
125 SubtractionQueueDescriptor,
126 SubtractionLayer,
127 DataType::Float16>();
128}
129#endif
130
131BOOST_AUTO_TEST_CASE(CreateSubtractionFloatWorkload)
132{
133 NeonCreateArithmethicWorkloadTest<NeonSubtractionFloatWorkload,
134 SubtractionQueueDescriptor,
135 SubtractionLayer,
136 DataType::Float32>();
137}
138
139#ifdef __ARM_FEATURE_FP16_VECTOR_ARITHMETIC
140BOOST_AUTO_TEST_CASE(CreateMultiplicationFloat16Workload)
141{
142 NeonCreateArithmethicWorkloadTest<NeonMultiplicationFloatWorkload,
143 MultiplicationQueueDescriptor,
144 MultiplicationLayer,
145 DataType::Float16>();
146}
147#endif
148
149BOOST_AUTO_TEST_CASE(CreateMultiplicationFloatWorkload)
150{
151 NeonCreateArithmethicWorkloadTest<NeonMultiplicationFloatWorkload,
152 MultiplicationQueueDescriptor,
153 MultiplicationLayer,
154 DataType::Float32>();
telsoa01c577f2c2018-08-31 09:22:23 +0100155}
156
157template <typename BatchNormalizationWorkloadType, typename armnn::DataType DataType>
Nikhil Rajd1340932018-10-18 14:27:50 +0100158static void NeonCreateBatchNormalizationWorkloadTest(DataLayout dataLayout)
telsoa014fcda012018-03-09 14:13:49 +0000159{
160 Graph graph;
Aron Virginas-Tar56055192018-11-12 18:10:43 +0000161 NeonWorkloadFactory factory = NeonWorkloadFactoryHelper::GetFactory();
Nikhil Rajd1340932018-10-18 14:27:50 +0100162 auto workload = CreateBatchNormalizationWorkloadTest<BatchNormalizationWorkloadType, DataType>
163 (factory, graph, dataLayout);
telsoa014fcda012018-03-09 14:13:49 +0000164
telsoa01c577f2c2018-08-31 09:22:23 +0100165 // Checks that outputs and inputs are as we expect them (see definition of CreateBatchNormalizationWorkloadTest).
telsoa014fcda012018-03-09 14:13:49 +0000166 BatchNormalizationQueueDescriptor queueDescriptor = workload->GetData();
167 auto inputHandle = boost::polymorphic_downcast<INeonTensorHandle*>(queueDescriptor.m_Inputs[0]);
168 auto outputHandle = boost::polymorphic_downcast<INeonTensorHandle*>(queueDescriptor.m_Outputs[0]);
Nikhil Rajd1340932018-10-18 14:27:50 +0100169
170 TensorShape inputShape = (dataLayout == DataLayout::NCHW) ? TensorShape{2, 3, 4, 4} : TensorShape{2, 4, 4, 3};
171 TensorShape outputShape = (dataLayout == DataLayout::NCHW) ? TensorShape{2, 3, 4, 4} : TensorShape{2, 4, 4, 3};
172
173 BOOST_TEST(TestNeonTensorHandleInfo(inputHandle, TensorInfo(inputShape, DataType)));
174 BOOST_TEST(TestNeonTensorHandleInfo(outputHandle, TensorInfo(outputShape, DataType)));
telsoa014fcda012018-03-09 14:13:49 +0000175}
176
telsoa01c577f2c2018-08-31 09:22:23 +0100177#ifdef __ARM_FEATURE_FP16_VECTOR_ARITHMETIC
Nikhil Rajd1340932018-10-18 14:27:50 +0100178BOOST_AUTO_TEST_CASE(CreateBatchNormalizationFloat16NchwWorkload)
telsoa01c577f2c2018-08-31 09:22:23 +0100179{
Nikhil Rajd1340932018-10-18 14:27:50 +0100180 NeonCreateBatchNormalizationWorkloadTest<NeonBatchNormalizationFloatWorkload, DataType::Float16>(DataLayout::NCHW);
181}
182
183BOOST_AUTO_TEST_CASE(CreateBatchNormalizationFloat16NhwcWorkload)
184{
185 NeonCreateBatchNormalizationWorkloadTest<NeonBatchNormalizationFloatWorkload, DataType::Float16>(DataLayout::NHWC);
telsoa01c577f2c2018-08-31 09:22:23 +0100186}
187#endif
188
Nikhil Rajd1340932018-10-18 14:27:50 +0100189BOOST_AUTO_TEST_CASE(CreateBatchNormalizationFloatNchwWorkload)
telsoa01c577f2c2018-08-31 09:22:23 +0100190{
Nikhil Rajd1340932018-10-18 14:27:50 +0100191 NeonCreateBatchNormalizationWorkloadTest<NeonBatchNormalizationFloatWorkload, DataType::Float32>(DataLayout::NCHW);
192}
193
194BOOST_AUTO_TEST_CASE(CreateBatchNormalizationFloatNhwcWorkload)
195{
196 NeonCreateBatchNormalizationWorkloadTest<NeonBatchNormalizationFloatWorkload, DataType::Float32>(DataLayout::NHWC);
telsoa01c577f2c2018-08-31 09:22:23 +0100197}
198
Nattapat Chaimanowong974b65f2018-10-15 15:07:34 +0100199template <typename armnn::DataType DataType>
Francis Murtagh0d9d4192018-10-09 16:22:33 +0100200static void NeonCreateConvolution2dWorkloadTest(DataLayout dataLayout = DataLayout::NCHW)
telsoa014fcda012018-03-09 14:13:49 +0000201{
202 Graph graph;
Aron Virginas-Tar56055192018-11-12 18:10:43 +0000203 NeonWorkloadFactory factory = NeonWorkloadFactoryHelper::GetFactory();
Nattapat Chaimanowong974b65f2018-10-15 15:07:34 +0100204 auto workload = CreateConvolution2dWorkloadTest<NeonConvolution2dWorkload,
Francis Murtagh0d9d4192018-10-09 16:22:33 +0100205 DataType>(factory, graph, dataLayout);
206
207 TensorShape inputShape = (dataLayout == DataLayout::NCHW) ? TensorShape{2, 3, 8, 16} : TensorShape{2, 8, 16, 3};
208 TensorShape outputShape = (dataLayout == DataLayout::NCHW) ? TensorShape{2, 2, 2, 10} : TensorShape{2, 2, 10, 2};
telsoa014fcda012018-03-09 14:13:49 +0000209
telsoa01c577f2c2018-08-31 09:22:23 +0100210 // Checks that outputs and inputs are as we expect them (see definition of CreateConvolution2dWorkloadTest).
telsoa014fcda012018-03-09 14:13:49 +0000211 Convolution2dQueueDescriptor queueDescriptor = workload->GetData();
212 auto inputHandle = boost::polymorphic_downcast<INeonTensorHandle*>(queueDescriptor.m_Inputs[0]);
213 auto outputHandle = boost::polymorphic_downcast<INeonTensorHandle*>(queueDescriptor.m_Outputs[0]);
Francis Murtagh0d9d4192018-10-09 16:22:33 +0100214 BOOST_TEST(TestNeonTensorHandleInfo(inputHandle, TensorInfo(inputShape, DataType)));
215 BOOST_TEST(TestNeonTensorHandleInfo(outputHandle, TensorInfo(outputShape, DataType)));
telsoa014fcda012018-03-09 14:13:49 +0000216}
217
telsoa01c577f2c2018-08-31 09:22:23 +0100218#ifdef __ARM_FEATURE_FP16_VECTOR_ARITHMETIC
Francis Murtagh0d9d4192018-10-09 16:22:33 +0100219BOOST_AUTO_TEST_CASE(CreateConvolution2dFloat16NchwWorkload)
telsoa01c577f2c2018-08-31 09:22:23 +0100220{
Nattapat Chaimanowong974b65f2018-10-15 15:07:34 +0100221 NeonCreateConvolution2dWorkloadTest<DataType::Float16>();
telsoa01c577f2c2018-08-31 09:22:23 +0100222}
telsoa01c577f2c2018-08-31 09:22:23 +0100223
Francis Murtagh0d9d4192018-10-09 16:22:33 +0100224BOOST_AUTO_TEST_CASE(CreateConvolution2dFloat16NhwcWorkload)
225{
Nattapat Chaimanowong974b65f2018-10-15 15:07:34 +0100226 NeonCreateConvolution2dWorkloadTest<DataType::Float16>(DataLayout::NHWC);
Francis Murtagh0d9d4192018-10-09 16:22:33 +0100227}
228
229#endif
230BOOST_AUTO_TEST_CASE(CreateConvolution2dFloatNchwWorkload)
telsoa01c577f2c2018-08-31 09:22:23 +0100231{
Nattapat Chaimanowong974b65f2018-10-15 15:07:34 +0100232 NeonCreateConvolution2dWorkloadTest<DataType::Float32>();
telsoa01c577f2c2018-08-31 09:22:23 +0100233}
234
Francis Murtagh0d9d4192018-10-09 16:22:33 +0100235BOOST_AUTO_TEST_CASE(CreateConvolution2dFloatNhwcWorkload)
236{
Nattapat Chaimanowong974b65f2018-10-15 15:07:34 +0100237 NeonCreateConvolution2dWorkloadTest<DataType::Float32>(DataLayout::NHWC);
Francis Murtagh0d9d4192018-10-09 16:22:33 +0100238}
239
Nattapat Chaimanowong77140882018-10-17 11:12:19 +0100240template <typename armnn::DataType DataType>
Nikhil Rajcec6b652018-10-12 13:51:57 +0100241static void NeonCreateDepthWiseConvolutionWorkloadTest(DataLayout dataLayout)
242{
243 Graph graph;
Aron Virginas-Tar56055192018-11-12 18:10:43 +0000244 NeonWorkloadFactory factory = NeonWorkloadFactoryHelper::GetFactory();
Nikhil Rajcec6b652018-10-12 13:51:57 +0100245
Nattapat Chaimanowong77140882018-10-17 11:12:19 +0100246 auto workload = CreateDepthwiseConvolution2dWorkloadTest<NeonDepthwiseConvolutionWorkload,
Nikhil Rajcec6b652018-10-12 13:51:57 +0100247 DataType>(factory, graph, dataLayout);
248
249 // Checks that inputs/outputs are as we expect them (see definition of CreateNormalizationWorkloadTest).
250 DepthwiseConvolution2dQueueDescriptor queueDescriptor = workload->GetData();
251 auto inputHandle = boost::polymorphic_downcast<INeonTensorHandle*>(queueDescriptor.m_Inputs[0]);
252 auto outputHandle = boost::polymorphic_downcast<INeonTensorHandle*>(queueDescriptor.m_Outputs[0]);
253
254 std::initializer_list<unsigned int> inputShape = (dataLayout == DataLayout::NCHW)
255 ? std::initializer_list<unsigned int>({ 2, 2, 5, 5 })
256 : std::initializer_list<unsigned int>({ 2, 5, 5, 2 });
257 std::initializer_list<unsigned int> outputShape = (dataLayout == DataLayout::NCHW)
258 ? std::initializer_list<unsigned int>({ 2, 2, 5, 5 })
259 : std::initializer_list<unsigned int>({ 2, 5, 5, 2 });
260
261 BOOST_TEST(TestNeonTensorHandleInfo(inputHandle, TensorInfo(inputShape, DataType)));
262 BOOST_TEST(TestNeonTensorHandleInfo(outputHandle, TensorInfo(outputShape, DataType)));
263}
264
265BOOST_AUTO_TEST_CASE(CreateDepthWiseConvolution2dFloat32NhwcWorkload)
266{
Nattapat Chaimanowong77140882018-10-17 11:12:19 +0100267 NeonCreateDepthWiseConvolutionWorkloadTest<DataType::Float32>(DataLayout::NHWC);
Nikhil Rajcec6b652018-10-12 13:51:57 +0100268}
269
270#ifdef __ARM_FEATURE_FP16_VECTOR_ARITHMETIC
271BOOST_AUTO_TEST_CASE(CreateDepthWiseConvolution2dFloat16NhwcWorkload)
272{
Nattapat Chaimanowong77140882018-10-17 11:12:19 +0100273 NeonCreateDepthWiseConvolutionWorkloadTest<DataType::Float16>(DataLayout::NHWC);
Nikhil Rajcec6b652018-10-12 13:51:57 +0100274}
275#endif
276
telsoa01c577f2c2018-08-31 09:22:23 +0100277template <typename FullyConnectedWorkloadType, typename armnn::DataType DataType>
278static void NeonCreateFullyConnectedWorkloadTest()
telsoa014fcda012018-03-09 14:13:49 +0000279{
280 Graph graph;
Aron Virginas-Tar56055192018-11-12 18:10:43 +0000281 NeonWorkloadFactory factory = NeonWorkloadFactoryHelper::GetFactory();
telsoa01c577f2c2018-08-31 09:22:23 +0100282 auto workload = CreateFullyConnectedWorkloadTest<FullyConnectedWorkloadType,
283 DataType>(factory, graph);
telsoa014fcda012018-03-09 14:13:49 +0000284
telsoa01c577f2c2018-08-31 09:22:23 +0100285 // Checks that outputs and inputs are as we expect them (see definition of CreateFullyConnectedWorkloadTest).
telsoa014fcda012018-03-09 14:13:49 +0000286 FullyConnectedQueueDescriptor queueDescriptor = workload->GetData();
287 auto inputHandle = boost::polymorphic_downcast<INeonTensorHandle*>(queueDescriptor.m_Inputs[0]);
288 auto outputHandle = boost::polymorphic_downcast<INeonTensorHandle*>(queueDescriptor.m_Outputs[0]);
telsoa01c577f2c2018-08-31 09:22:23 +0100289 BOOST_TEST(TestNeonTensorHandleInfo(inputHandle, TensorInfo({3, 1, 4, 5}, DataType)));
290 BOOST_TEST(TestNeonTensorHandleInfo(outputHandle, TensorInfo({3, 7}, DataType)));
telsoa014fcda012018-03-09 14:13:49 +0000291}
292
telsoa01c577f2c2018-08-31 09:22:23 +0100293#ifdef __ARM_FEATURE_FP16_VECTOR_ARITHMETIC
294BOOST_AUTO_TEST_CASE(CreateFullyConnectedFloat16Workload)
295{
kevmay01e448be32018-09-26 10:21:55 +0100296 NeonCreateFullyConnectedWorkloadTest<NeonFullyConnectedWorkload, DataType::Float16>();
telsoa01c577f2c2018-08-31 09:22:23 +0100297}
298#endif
299
arovir019e53a352018-08-31 15:26:35 +0100300BOOST_AUTO_TEST_CASE(CreateFullyConnectedFloatWorkload)
telsoa01c577f2c2018-08-31 09:22:23 +0100301{
kevmay01e448be32018-09-26 10:21:55 +0100302 NeonCreateFullyConnectedWorkloadTest<NeonFullyConnectedWorkload, DataType::Float32>();
telsoa01c577f2c2018-08-31 09:22:23 +0100303}
304
telsoa01c577f2c2018-08-31 09:22:23 +0100305template <typename NormalizationWorkloadType, typename armnn::DataType DataType>
narpra0155a97bc2018-10-02 14:35:53 +0100306static void NeonCreateNormalizationWorkloadTest(DataLayout dataLayout)
telsoa014fcda012018-03-09 14:13:49 +0000307{
narpra0155a97bc2018-10-02 14:35:53 +0100308 Graph graph;
Aron Virginas-Tar56055192018-11-12 18:10:43 +0000309 NeonWorkloadFactory factory = NeonWorkloadFactoryHelper::GetFactory();
narpra0155a97bc2018-10-02 14:35:53 +0100310 auto workload = CreateNormalizationWorkloadTest<NormalizationWorkloadType, DataType>(factory, graph, dataLayout);
telsoa014fcda012018-03-09 14:13:49 +0000311
telsoa01c577f2c2018-08-31 09:22:23 +0100312 // Checks that outputs and inputs are as we expect them (see definition of CreateNormalizationWorkloadTest).
telsoa014fcda012018-03-09 14:13:49 +0000313 NormalizationQueueDescriptor queueDescriptor = workload->GetData();
314 auto inputHandle = boost::polymorphic_downcast<INeonTensorHandle*>(queueDescriptor.m_Inputs[0]);
315 auto outputHandle = boost::polymorphic_downcast<INeonTensorHandle*>(queueDescriptor.m_Outputs[0]);
Matteo Martincigha160b242018-10-18 10:33:23 +0100316
317 TensorShape inputShape = (dataLayout == DataLayout::NCHW) ? TensorShape{3, 5, 5, 1} : TensorShape{3, 1, 5, 5};
318 TensorShape outputShape = (dataLayout == DataLayout::NCHW) ? TensorShape{3, 5, 5, 1} : TensorShape{3, 1, 5, 5};
319
320 BOOST_TEST(TestNeonTensorHandleInfo(inputHandle, TensorInfo(inputShape, DataType)));
321 BOOST_TEST(TestNeonTensorHandleInfo(outputHandle, TensorInfo(outputShape, DataType)));
telsoa014fcda012018-03-09 14:13:49 +0000322}
323
telsoa01c577f2c2018-08-31 09:22:23 +0100324#ifdef __ARM_FEATURE_FP16_VECTOR_ARITHMETIC
narpra0155a97bc2018-10-02 14:35:53 +0100325BOOST_AUTO_TEST_CASE(CreateNormalizationFloat16NchwWorkload)
telsoa01c577f2c2018-08-31 09:22:23 +0100326{
narpra0155a97bc2018-10-02 14:35:53 +0100327 NeonCreateNormalizationWorkloadTest<NeonNormalizationFloatWorkload, DataType::Float16>(DataLayout::NCHW);
328}
329
330BOOST_AUTO_TEST_CASE(CreateNormalizationFloat16NhwcWorkload)
331{
332 NeonCreateNormalizationWorkloadTest<NeonNormalizationFloatWorkload, DataType::Float16>(DataLayout::NHWC);
telsoa01c577f2c2018-08-31 09:22:23 +0100333}
334#endif
335
narpra0155a97bc2018-10-02 14:35:53 +0100336BOOST_AUTO_TEST_CASE(CreateNormalizationFloatNchwWorkload)
telsoa01c577f2c2018-08-31 09:22:23 +0100337{
narpra0155a97bc2018-10-02 14:35:53 +0100338 NeonCreateNormalizationWorkloadTest<NeonNormalizationFloatWorkload, DataType::Float32>(DataLayout::NCHW);
telsoa01c577f2c2018-08-31 09:22:23 +0100339}
340
narpra0155a97bc2018-10-02 14:35:53 +0100341BOOST_AUTO_TEST_CASE(CreateNormalizationFloatNhwcWorkload)
342{
343 NeonCreateNormalizationWorkloadTest<NeonNormalizationFloatWorkload, DataType::Float32>(DataLayout::NHWC);
344}
345
346
Nattapat Chaimanowong5d2e7002018-10-12 16:03:56 +0100347template <typename armnn::DataType DataType>
Nina Drozdb48e6862018-10-09 12:09:56 +0100348static void NeonCreatePooling2dWorkloadTest(DataLayout dataLayout = DataLayout::NCHW)
telsoa014fcda012018-03-09 14:13:49 +0000349{
350 Graph graph;
Aron Virginas-Tar56055192018-11-12 18:10:43 +0000351 NeonWorkloadFactory factory = NeonWorkloadFactoryHelper::GetFactory();
Nattapat Chaimanowong5d2e7002018-10-12 16:03:56 +0100352 auto workload = CreatePooling2dWorkloadTest<NeonPooling2dWorkload, DataType>
Nina Drozdb48e6862018-10-09 12:09:56 +0100353 (factory, graph, dataLayout);
354
355 TensorShape inputShape = (dataLayout == DataLayout::NCHW) ? TensorShape{3, 2, 5, 5} : TensorShape{3, 5, 5, 2};
356 TensorShape outputShape = (dataLayout == DataLayout::NCHW) ? TensorShape{3, 2, 2, 4} : TensorShape{3, 2, 4, 2};
telsoa014fcda012018-03-09 14:13:49 +0000357
telsoa01c577f2c2018-08-31 09:22:23 +0100358 // Checks that outputs and inputs are as we expect them (see definition of CreatePooling2dWorkloadTest).
telsoa014fcda012018-03-09 14:13:49 +0000359 Pooling2dQueueDescriptor queueDescriptor = workload->GetData();
360 auto inputHandle = boost::polymorphic_downcast<INeonTensorHandle*>(queueDescriptor.m_Inputs[0]);
361 auto outputHandle = boost::polymorphic_downcast<INeonTensorHandle*>(queueDescriptor.m_Outputs[0]);
Nina Drozdb48e6862018-10-09 12:09:56 +0100362 BOOST_TEST(TestNeonTensorHandleInfo(inputHandle, TensorInfo(inputShape, DataType)));
363 BOOST_TEST(TestNeonTensorHandleInfo(outputHandle, TensorInfo(outputShape, DataType)));
telsoa014fcda012018-03-09 14:13:49 +0000364}
365
telsoa01c577f2c2018-08-31 09:22:23 +0100366#ifdef __ARM_FEATURE_FP16_VECTOR_ARITHMETIC
367BOOST_AUTO_TEST_CASE(CreatePooling2dFloat16Workload)
368{
Nattapat Chaimanowong5d2e7002018-10-12 16:03:56 +0100369 NeonCreatePooling2dWorkloadTest<DataType::Float16>();
telsoa01c577f2c2018-08-31 09:22:23 +0100370}
371#endif
372
Nina Drozdb48e6862018-10-09 12:09:56 +0100373BOOST_AUTO_TEST_CASE(CreatePooling2dFloatNchwWorkload)
telsoa01c577f2c2018-08-31 09:22:23 +0100374{
Nattapat Chaimanowong5d2e7002018-10-12 16:03:56 +0100375 NeonCreatePooling2dWorkloadTest<DataType::Float32>(DataLayout::NCHW);
telsoa01c577f2c2018-08-31 09:22:23 +0100376}
377
Nina Drozdb48e6862018-10-09 12:09:56 +0100378BOOST_AUTO_TEST_CASE(CreatePooling2dFloatNhwcWorkload)
telsoa01c577f2c2018-08-31 09:22:23 +0100379{
Nattapat Chaimanowong5d2e7002018-10-12 16:03:56 +0100380 NeonCreatePooling2dWorkloadTest<DataType::Float32>(DataLayout::NHWC);
Nina Drozdb48e6862018-10-09 12:09:56 +0100381}
382
383BOOST_AUTO_TEST_CASE(CreatePooling2dUint8NchwWorkload)
384{
Nattapat Chaimanowong5d2e7002018-10-12 16:03:56 +0100385 NeonCreatePooling2dWorkloadTest<DataType::QuantisedAsymm8>(DataLayout::NCHW);
Nina Drozdb48e6862018-10-09 12:09:56 +0100386}
387
388BOOST_AUTO_TEST_CASE(CreatePooling2dUint8NhwcWorkload)
389{
Nattapat Chaimanowong5d2e7002018-10-12 16:03:56 +0100390 NeonCreatePooling2dWorkloadTest<DataType::QuantisedAsymm8>(DataLayout::NHWC);
telsoa01c577f2c2018-08-31 09:22:23 +0100391}
392
Nattapat Chaimanowongcce11fc2018-10-12 16:30:56 +0100393template <typename armnn::DataType DataType>
telsoa01c577f2c2018-08-31 09:22:23 +0100394static void NeonCreateReshapeWorkloadTest()
telsoa014fcda012018-03-09 14:13:49 +0000395{
396 Graph graph;
Aron Virginas-Tar56055192018-11-12 18:10:43 +0000397 NeonWorkloadFactory factory = NeonWorkloadFactoryHelper::GetFactory();
Nattapat Chaimanowongcce11fc2018-10-12 16:30:56 +0100398 auto workload = CreateReshapeWorkloadTest<NeonReshapeWorkload, DataType>(factory, graph);
telsoa014fcda012018-03-09 14:13:49 +0000399
telsoa01c577f2c2018-08-31 09:22:23 +0100400 // Checks that outputs and inputs are as we expect them (see definition of CreateReshapeWorkloadTest).
telsoa014fcda012018-03-09 14:13:49 +0000401 ReshapeQueueDescriptor queueDescriptor = workload->GetData();
402 auto inputHandle = boost::polymorphic_downcast<INeonTensorHandle*>(queueDescriptor.m_Inputs[0]);
403 auto outputHandle = boost::polymorphic_downcast<INeonTensorHandle*>(queueDescriptor.m_Outputs[0]);
telsoa01c577f2c2018-08-31 09:22:23 +0100404 BOOST_TEST(TestNeonTensorHandleInfo(inputHandle, TensorInfo({4, 1}, DataType)));
405 BOOST_TEST(TestNeonTensorHandleInfo(outputHandle, TensorInfo({1, 4}, DataType)));
telsoa014fcda012018-03-09 14:13:49 +0000406}
407
telsoa01c577f2c2018-08-31 09:22:23 +0100408#ifdef __ARM_FEATURE_FP16_VECTOR_ARITHMETIC
409BOOST_AUTO_TEST_CASE(CreateReshapeFloat16Workload)
410{
Nattapat Chaimanowongcce11fc2018-10-12 16:30:56 +0100411 NeonCreateReshapeWorkloadTest<DataType::Float16>();
telsoa01c577f2c2018-08-31 09:22:23 +0100412}
413#endif
414
arovir019e53a352018-08-31 15:26:35 +0100415BOOST_AUTO_TEST_CASE(CreateReshapeFloatWorkload)
telsoa014fcda012018-03-09 14:13:49 +0000416{
Nattapat Chaimanowongcce11fc2018-10-12 16:30:56 +0100417 NeonCreateReshapeWorkloadTest<DataType::Float32>();
telsoa014fcda012018-03-09 14:13:49 +0000418}
419
420BOOST_AUTO_TEST_CASE(CreateReshapeUint8Workload)
421{
Nattapat Chaimanowongcce11fc2018-10-12 16:30:56 +0100422 NeonCreateReshapeWorkloadTest<DataType::QuantisedAsymm8>();
telsoa014fcda012018-03-09 14:13:49 +0000423}
424
telsoa01c577f2c2018-08-31 09:22:23 +0100425template <typename SoftmaxWorkloadType, typename armnn::DataType DataType>
426static void NeonCreateSoftmaxWorkloadTest()
telsoa014fcda012018-03-09 14:13:49 +0000427{
428 Graph graph;
Aron Virginas-Tar56055192018-11-12 18:10:43 +0000429 NeonWorkloadFactory factory = NeonWorkloadFactoryHelper::GetFactory();
telsoa01c577f2c2018-08-31 09:22:23 +0100430 auto workload = CreateSoftmaxWorkloadTest<SoftmaxWorkloadType, DataType>(factory, graph);
telsoa014fcda012018-03-09 14:13:49 +0000431
telsoa01c577f2c2018-08-31 09:22:23 +0100432 // Checks that outputs and inputs are as we expect them (see definition of CreateSoftmaxWorkloadTest).
telsoa014fcda012018-03-09 14:13:49 +0000433 SoftmaxQueueDescriptor queueDescriptor = workload->GetData();
434 auto inputHandle = boost::polymorphic_downcast<INeonTensorHandle*>(queueDescriptor.m_Inputs[0]);
435 auto outputHandle = boost::polymorphic_downcast<INeonTensorHandle*>(queueDescriptor.m_Outputs[0]);
telsoa01c577f2c2018-08-31 09:22:23 +0100436 BOOST_TEST(TestNeonTensorHandleInfo(inputHandle, TensorInfo({4, 1}, DataType)));
437 BOOST_TEST(TestNeonTensorHandleInfo(outputHandle, TensorInfo({4, 1}, DataType)));
438}
439
440#ifdef __ARM_FEATURE_FP16_VECTOR_ARITHMETIC
441BOOST_AUTO_TEST_CASE(CreateSoftmaxFloat16Workload)
442{
arovir019e53a352018-08-31 15:26:35 +0100443 NeonCreateSoftmaxWorkloadTest<NeonSoftmaxFloatWorkload, DataType::Float16>();
telsoa01c577f2c2018-08-31 09:22:23 +0100444}
445#endif
446
arovir019e53a352018-08-31 15:26:35 +0100447BOOST_AUTO_TEST_CASE(CreateSoftmaxFloatWorkload)
telsoa01c577f2c2018-08-31 09:22:23 +0100448{
arovir019e53a352018-08-31 15:26:35 +0100449 NeonCreateSoftmaxWorkloadTest<NeonSoftmaxFloatWorkload, DataType::Float32>();
telsoa014fcda012018-03-09 14:13:49 +0000450}
451
452BOOST_AUTO_TEST_CASE(CreateSplitterWorkload)
453{
454 Graph graph;
Aron Virginas-Tar56055192018-11-12 18:10:43 +0000455 NeonWorkloadFactory factory = NeonWorkloadFactoryHelper::GetFactory();
Nattapat Chaimanowong14766d72018-10-12 15:09:53 +0100456 auto workload = CreateSplitterWorkloadTest<NeonSplitterWorkload, DataType::Float32>(factory, graph);
telsoa014fcda012018-03-09 14:13:49 +0000457
telsoa01c577f2c2018-08-31 09:22:23 +0100458 // Checks that outputs are as we expect them (see definition of CreateSplitterWorkloadTest).
telsoa014fcda012018-03-09 14:13:49 +0000459 SplitterQueueDescriptor queueDescriptor = workload->GetData();
460 auto inputHandle = boost::polymorphic_downcast<INeonTensorHandle*>(queueDescriptor.m_Inputs[0]);
surmeh013537c2c2018-05-18 16:31:43 +0100461 BOOST_TEST(TestNeonTensorHandleInfo(inputHandle, TensorInfo({5, 7, 7}, DataType::Float32)));
462
telsoa014fcda012018-03-09 14:13:49 +0000463 auto outputHandle0 = boost::polymorphic_downcast<INeonTensorHandle*>(queueDescriptor.m_Outputs[0]);
surmeh013537c2c2018-05-18 16:31:43 +0100464 BOOST_TEST(TestNeonTensorHandleInfo(outputHandle0, TensorInfo({1, 7, 7}, DataType::Float32)));
465
telsoa014fcda012018-03-09 14:13:49 +0000466 auto outputHandle1 = boost::polymorphic_downcast<INeonTensorHandle*>(queueDescriptor.m_Outputs[1]);
surmeh013537c2c2018-05-18 16:31:43 +0100467 BOOST_TEST(TestNeonTensorHandleInfo(outputHandle1, TensorInfo({2, 7, 7}, DataType::Float32)));
468
telsoa014fcda012018-03-09 14:13:49 +0000469 auto outputHandle2 = boost::polymorphic_downcast<INeonTensorHandle*>(queueDescriptor.m_Outputs[2]);
surmeh013537c2c2018-05-18 16:31:43 +0100470 BOOST_TEST(TestNeonTensorHandleInfo(outputHandle2, TensorInfo({2, 7, 7}, DataType::Float32)));
telsoa014fcda012018-03-09 14:13:49 +0000471}
472
473BOOST_AUTO_TEST_CASE(CreateSplitterMerger)
474{
telsoa01c577f2c2018-08-31 09:22:23 +0100475 // Tests that it is possible to decide which output of the splitter layer
476 // should be lined to which input of the merger layer.
477 // We tested that is is possible to specify 0th output
478 // 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 +0000479 // of the merger.
480
481 Graph graph;
Aron Virginas-Tar56055192018-11-12 18:10:43 +0000482 NeonWorkloadFactory factory = NeonWorkloadFactoryHelper::GetFactory();
telsoa014fcda012018-03-09 14:13:49 +0000483
484 auto workloads =
Nattapat Chaimanowong14766d72018-10-12 15:09:53 +0100485 CreateSplitterMergerWorkloadTest<NeonSplitterWorkload, NeonMergerWorkload,
telsoa01c577f2c2018-08-31 09:22:23 +0100486 DataType::Float32>(factory, graph);
telsoa014fcda012018-03-09 14:13:49 +0000487
488 auto wlSplitter = std::move(workloads.first);
489 auto wlMerger = std::move(workloads.second);
490
telsoa01c577f2c2018-08-31 09:22:23 +0100491 //Checks that the index of inputs/outputs matches what we declared on InputDescriptor construction.
telsoa014fcda012018-03-09 14:13:49 +0000492 armnn::INeonTensorHandle* sOut0 = dynamic_cast<armnn::INeonTensorHandle*>(wlSplitter->GetData().m_Outputs[0]);
493 armnn::INeonTensorHandle* sOut1 = dynamic_cast<armnn::INeonTensorHandle*>(wlSplitter->GetData().m_Outputs[1]);
494 armnn::INeonTensorHandle* mIn0 = dynamic_cast<armnn::INeonTensorHandle*>(wlMerger->GetData().m_Inputs[0]);
495 armnn::INeonTensorHandle* mIn1 = dynamic_cast<armnn::INeonTensorHandle*>(wlMerger->GetData().m_Inputs[1]);
496
497 BOOST_TEST(sOut0);
498 BOOST_TEST(sOut1);
499 BOOST_TEST(mIn0);
500 BOOST_TEST(mIn1);
501
502 bool validDataPointers = (sOut0 == mIn1) && (sOut1 == mIn0);
503
504 BOOST_TEST(validDataPointers);
505}
506
507BOOST_AUTO_TEST_CASE(CreateSingleOutputMultipleInputs)
508{
telsoa01c577f2c2018-08-31 09:22:23 +0100509 // Tests that it is possible to assign multiple (two) different layers to each of the outputs of a splitter layer.
510 // 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 +0000511
512 Graph graph;
Aron Virginas-Tar56055192018-11-12 18:10:43 +0000513 NeonWorkloadFactory factory = NeonWorkloadFactoryHelper::GetFactory();
Nattapat Chaimanowong14766d72018-10-12 15:09:53 +0100514 std::unique_ptr<NeonSplitterWorkload> wlSplitter;
Nattapat Chaimanowongd4b70592018-10-12 11:21:49 +0100515 std::unique_ptr<NeonActivationWorkload> wlActiv0_0;
516 std::unique_ptr<NeonActivationWorkload> wlActiv0_1;
517 std::unique_ptr<NeonActivationWorkload> wlActiv1_0;
518 std::unique_ptr<NeonActivationWorkload> wlActiv1_1;
telsoa014fcda012018-03-09 14:13:49 +0000519
Nattapat Chaimanowong14766d72018-10-12 15:09:53 +0100520 CreateSplitterMultipleInputsOneOutputWorkloadTest<NeonSplitterWorkload,
Nattapat Chaimanowongd4b70592018-10-12 11:21:49 +0100521 NeonActivationWorkload, DataType::Float32>(factory, graph, wlSplitter, wlActiv0_0, wlActiv0_1,
522 wlActiv1_0, wlActiv1_1);
telsoa014fcda012018-03-09 14:13:49 +0000523
524 armnn::INeonTensorHandle* sOut0 = dynamic_cast<armnn::INeonTensorHandle*>(wlSplitter->GetData().m_Outputs[0]);
525 armnn::INeonTensorHandle* sOut1 = dynamic_cast<armnn::INeonTensorHandle*>(wlSplitter->GetData().m_Outputs[1]);
526 armnn::INeonTensorHandle* activ0_0Im = dynamic_cast<armnn::INeonTensorHandle*>(wlActiv0_0->GetData().m_Inputs[0]);
527 armnn::INeonTensorHandle* activ0_1Im = dynamic_cast<armnn::INeonTensorHandle*>(wlActiv0_1->GetData().m_Inputs[0]);
528 armnn::INeonTensorHandle* activ1_0Im = dynamic_cast<armnn::INeonTensorHandle*>(wlActiv1_0->GetData().m_Inputs[0]);
529 armnn::INeonTensorHandle* activ1_1Im = dynamic_cast<armnn::INeonTensorHandle*>(wlActiv1_1->GetData().m_Inputs[0]);
530
531
532 BOOST_TEST(sOut0);
533 BOOST_TEST(sOut1);
534 BOOST_TEST(activ0_0Im);
535 BOOST_TEST(activ0_1Im);
536 BOOST_TEST(activ1_0Im);
537 BOOST_TEST(activ1_1Im);
538
539 bool validDataPointers = (sOut0 == activ0_0Im) && (sOut0 == activ0_1Im) &&
540 (sOut1 == activ1_0Im) && (sOut1 == activ1_1Im);
541
542 BOOST_TEST(validDataPointers);
543}
544
545BOOST_AUTO_TEST_CASE(CreateMemCopyWorkloadsNeon)
546{
Aron Virginas-Tar56055192018-11-12 18:10:43 +0000547 NeonWorkloadFactory factory = NeonWorkloadFactoryHelper::GetFactory();
telsoa01c577f2c2018-08-31 09:22:23 +0100548 CreateMemCopyWorkloads<INeonTensorHandle>(factory);
telsoa014fcda012018-03-09 14:13:49 +0000549}
550
Matteo Martincighbcd3c852018-09-28 14:14:12 +0100551template <typename L2NormalizationWorkloadType, typename armnn::DataType DataType>
552static void NeonCreateL2NormalizationWorkloadTest(DataLayout dataLayout)
553{
Matteo Martincigh2400b6d2018-10-09 18:19:20 +0100554 Graph graph;
Aron Virginas-Tar56055192018-11-12 18:10:43 +0000555 NeonWorkloadFactory factory = NeonWorkloadFactoryHelper::GetFactory();
Matteo Martincigh2400b6d2018-10-09 18:19:20 +0100556 auto workload =
557 CreateL2NormalizationWorkloadTest<L2NormalizationWorkloadType, DataType>(factory, graph, dataLayout);
Matteo Martincighbcd3c852018-09-28 14:14:12 +0100558
559 // Checks that inputs/outputs are as we expect them (see definition of CreateNormalizationWorkloadTest).
560 L2NormalizationQueueDescriptor queueDescriptor = workload->GetData();
561 auto inputHandle = boost::polymorphic_downcast<INeonTensorHandle*>(queueDescriptor.m_Inputs[0]);
562 auto outputHandle = boost::polymorphic_downcast<INeonTensorHandle*>(queueDescriptor.m_Outputs[0]);
Matteo Martincigh2400b6d2018-10-09 18:19:20 +0100563
564 TensorShape inputShape = (dataLayout == DataLayout::NCHW) ?
565 TensorShape{ 5, 20, 50, 67 } : TensorShape{ 5, 50, 67, 20 };
566 TensorShape outputShape = (dataLayout == DataLayout::NCHW) ?
567 TensorShape{ 5, 20, 50, 67 } : TensorShape{ 5, 50, 67, 20 };
568
569 BOOST_TEST(TestNeonTensorHandleInfo(inputHandle, TensorInfo(inputShape, DataType)));
570 BOOST_TEST(TestNeonTensorHandleInfo(outputHandle, TensorInfo(outputShape, DataType)));
Matteo Martincighbcd3c852018-09-28 14:14:12 +0100571}
572
573#ifdef __ARM_FEATURE_FP16_VECTOR_ARITHMETIC
574BOOST_AUTO_TEST_CASE(CreateL2NormalizationFloat16NchwWorkload)
575{
576 NeonCreateL2NormalizationWorkloadTest<NeonL2NormalizationFloatWorkload, DataType::Float16>(DataLayout::NCHW);
577}
578
579BOOST_AUTO_TEST_CASE(CreateL2NormalizationFloat16NhwcWorkload)
580{
581 NeonCreateL2NormalizationWorkloadTest<NeonL2NormalizationFloatWorkload, DataType::Float16>(DataLayout::NHWC);
582}
583#endif
584
585BOOST_AUTO_TEST_CASE(CreateL2NormalizationNchwWorkload)
586{
587 NeonCreateL2NormalizationWorkloadTest<NeonL2NormalizationFloatWorkload, DataType::Float32>(DataLayout::NCHW);
588}
589
590BOOST_AUTO_TEST_CASE(CreateL2NormalizationNhwcWorkload)
591{
592 NeonCreateL2NormalizationWorkloadTest<NeonL2NormalizationFloatWorkload, DataType::Float32>(DataLayout::NHWC);
593}
594
telsoa014fcda012018-03-09 14:13:49 +0000595BOOST_AUTO_TEST_SUITE_END()