blob: 63b3d415003ed4ca85fe119168c46ef4a5139808 [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
arovir0143095f32018-10-09 18:04:24 +01006#include <backends/MemCopyWorkload.hpp>
Aron Virginas-Tar3b278e92018-10-12 13:00:55 +01007
8#include <backends/aclCommon/test/CreateWorkloadClNeon.hpp>
9
David Beck0dbe0ee2018-09-24 15:59:27 +010010#include <backends/neon/NeonWorkloadFactory.hpp>
11#include <backends/neon/NeonTensorHandle.hpp>
12#include <backends/neon/workloads/NeonWorkloadUtils.hpp>
13#include <backends/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>
156static void NeonCreateBatchNormalizationWorkloadTest()
telsoa014fcda012018-03-09 14:13:49 +0000157{
158 Graph graph;
159 NeonWorkloadFactory factory;
telsoa01c577f2c2018-08-31 09:22:23 +0100160 auto workload = CreateBatchNormalizationWorkloadTest<BatchNormalizationWorkloadType, DataType>(factory, graph);
telsoa014fcda012018-03-09 14:13:49 +0000161
telsoa01c577f2c2018-08-31 09:22:23 +0100162 // Checks that outputs and inputs are as we expect them (see definition of CreateBatchNormalizationWorkloadTest).
telsoa014fcda012018-03-09 14:13:49 +0000163 BatchNormalizationQueueDescriptor queueDescriptor = workload->GetData();
164 auto inputHandle = boost::polymorphic_downcast<INeonTensorHandle*>(queueDescriptor.m_Inputs[0]);
165 auto outputHandle = boost::polymorphic_downcast<INeonTensorHandle*>(queueDescriptor.m_Outputs[0]);
telsoa01c577f2c2018-08-31 09:22:23 +0100166 BOOST_TEST(TestNeonTensorHandleInfo(inputHandle, TensorInfo({2, 3, 1, 1}, DataType)));
167 BOOST_TEST(TestNeonTensorHandleInfo(outputHandle, TensorInfo({2, 3, 1, 1}, DataType)));
telsoa014fcda012018-03-09 14:13:49 +0000168}
169
telsoa01c577f2c2018-08-31 09:22:23 +0100170#ifdef __ARM_FEATURE_FP16_VECTOR_ARITHMETIC
171BOOST_AUTO_TEST_CASE(CreateBatchNormalizationFloat16Workload)
172{
arovir019e53a352018-08-31 15:26:35 +0100173 NeonCreateBatchNormalizationWorkloadTest<NeonBatchNormalizationFloatWorkload, DataType::Float16>();
telsoa01c577f2c2018-08-31 09:22:23 +0100174}
175#endif
176
arovir019e53a352018-08-31 15:26:35 +0100177BOOST_AUTO_TEST_CASE(CreateBatchNormalizationFloatWorkload)
telsoa01c577f2c2018-08-31 09:22:23 +0100178{
arovir019e53a352018-08-31 15:26:35 +0100179 NeonCreateBatchNormalizationWorkloadTest<NeonBatchNormalizationFloatWorkload, DataType::Float32>();
telsoa01c577f2c2018-08-31 09:22:23 +0100180}
181
Nattapat Chaimanowong974b65f2018-10-15 15:07:34 +0100182template <typename armnn::DataType DataType>
Francis Murtagh0d9d4192018-10-09 16:22:33 +0100183static void NeonCreateConvolution2dWorkloadTest(DataLayout dataLayout = DataLayout::NCHW)
telsoa014fcda012018-03-09 14:13:49 +0000184{
185 Graph graph;
186 NeonWorkloadFactory factory;
Nattapat Chaimanowong974b65f2018-10-15 15:07:34 +0100187 auto workload = CreateConvolution2dWorkloadTest<NeonConvolution2dWorkload,
Francis Murtagh0d9d4192018-10-09 16:22:33 +0100188 DataType>(factory, graph, dataLayout);
189
190 TensorShape inputShape = (dataLayout == DataLayout::NCHW) ? TensorShape{2, 3, 8, 16} : TensorShape{2, 8, 16, 3};
191 TensorShape outputShape = (dataLayout == DataLayout::NCHW) ? TensorShape{2, 2, 2, 10} : TensorShape{2, 2, 10, 2};
telsoa014fcda012018-03-09 14:13:49 +0000192
telsoa01c577f2c2018-08-31 09:22:23 +0100193 // Checks that outputs and inputs are as we expect them (see definition of CreateConvolution2dWorkloadTest).
telsoa014fcda012018-03-09 14:13:49 +0000194 Convolution2dQueueDescriptor queueDescriptor = workload->GetData();
195 auto inputHandle = boost::polymorphic_downcast<INeonTensorHandle*>(queueDescriptor.m_Inputs[0]);
196 auto outputHandle = boost::polymorphic_downcast<INeonTensorHandle*>(queueDescriptor.m_Outputs[0]);
Francis Murtagh0d9d4192018-10-09 16:22:33 +0100197 BOOST_TEST(TestNeonTensorHandleInfo(inputHandle, TensorInfo(inputShape, DataType)));
198 BOOST_TEST(TestNeonTensorHandleInfo(outputHandle, TensorInfo(outputShape, DataType)));
telsoa014fcda012018-03-09 14:13:49 +0000199}
200
telsoa01c577f2c2018-08-31 09:22:23 +0100201#ifdef __ARM_FEATURE_FP16_VECTOR_ARITHMETIC
Francis Murtagh0d9d4192018-10-09 16:22:33 +0100202BOOST_AUTO_TEST_CASE(CreateConvolution2dFloat16NchwWorkload)
telsoa01c577f2c2018-08-31 09:22:23 +0100203{
Nattapat Chaimanowong974b65f2018-10-15 15:07:34 +0100204 NeonCreateConvolution2dWorkloadTest<DataType::Float16>();
telsoa01c577f2c2018-08-31 09:22:23 +0100205}
telsoa01c577f2c2018-08-31 09:22:23 +0100206
Francis Murtagh0d9d4192018-10-09 16:22:33 +0100207BOOST_AUTO_TEST_CASE(CreateConvolution2dFloat16NhwcWorkload)
208{
Nattapat Chaimanowong974b65f2018-10-15 15:07:34 +0100209 NeonCreateConvolution2dWorkloadTest<DataType::Float16>(DataLayout::NHWC);
Francis Murtagh0d9d4192018-10-09 16:22:33 +0100210}
211
212#endif
213BOOST_AUTO_TEST_CASE(CreateConvolution2dFloatNchwWorkload)
telsoa01c577f2c2018-08-31 09:22:23 +0100214{
Nattapat Chaimanowong974b65f2018-10-15 15:07:34 +0100215 NeonCreateConvolution2dWorkloadTest<DataType::Float32>();
telsoa01c577f2c2018-08-31 09:22:23 +0100216}
217
Francis Murtagh0d9d4192018-10-09 16:22:33 +0100218BOOST_AUTO_TEST_CASE(CreateConvolution2dFloatNhwcWorkload)
219{
Nattapat Chaimanowong974b65f2018-10-15 15:07:34 +0100220 NeonCreateConvolution2dWorkloadTest<DataType::Float32>(DataLayout::NHWC);
Francis Murtagh0d9d4192018-10-09 16:22:33 +0100221}
222
Nikhil Rajcec6b652018-10-12 13:51:57 +0100223template <typename DepthwiseConvolution2dFloat32WorkloadType, typename armnn::DataType DataType>
224static void NeonCreateDepthWiseConvolutionWorkloadTest(DataLayout dataLayout)
225{
226 Graph graph;
227 NeonWorkloadFactory factory;
228
229 auto workload = CreateDepthwiseConvolution2dWorkloadTest<DepthwiseConvolution2dFloat32WorkloadType,
230 DataType>(factory, graph, dataLayout);
231
232 // Checks that inputs/outputs are as we expect them (see definition of CreateNormalizationWorkloadTest).
233 DepthwiseConvolution2dQueueDescriptor queueDescriptor = workload->GetData();
234 auto inputHandle = boost::polymorphic_downcast<INeonTensorHandle*>(queueDescriptor.m_Inputs[0]);
235 auto outputHandle = boost::polymorphic_downcast<INeonTensorHandle*>(queueDescriptor.m_Outputs[0]);
236
237 std::initializer_list<unsigned int> inputShape = (dataLayout == DataLayout::NCHW)
238 ? std::initializer_list<unsigned int>({ 2, 2, 5, 5 })
239 : std::initializer_list<unsigned int>({ 2, 5, 5, 2 });
240 std::initializer_list<unsigned int> outputShape = (dataLayout == DataLayout::NCHW)
241 ? std::initializer_list<unsigned int>({ 2, 2, 5, 5 })
242 : std::initializer_list<unsigned int>({ 2, 5, 5, 2 });
243
244 BOOST_TEST(TestNeonTensorHandleInfo(inputHandle, TensorInfo(inputShape, DataType)));
245 BOOST_TEST(TestNeonTensorHandleInfo(outputHandle, TensorInfo(outputShape, DataType)));
246}
247
248BOOST_AUTO_TEST_CASE(CreateDepthWiseConvolution2dFloat32NhwcWorkload)
249{
250 NeonCreateDepthWiseConvolutionWorkloadTest<NeonDepthwiseConvolutionFloatWorkload,
251 DataType::Float32>(DataLayout::NHWC);
252}
253
254#ifdef __ARM_FEATURE_FP16_VECTOR_ARITHMETIC
255BOOST_AUTO_TEST_CASE(CreateDepthWiseConvolution2dFloat16NhwcWorkload)
256{
257 NeonCreateDepthWiseConvolutionWorkloadTest<NeonDepthwiseConvolutionFloatWorkload,
258 DataType::Float16>(DataLayout::NHWC);
259}
260#endif
261
telsoa01c577f2c2018-08-31 09:22:23 +0100262template <typename FullyConnectedWorkloadType, typename armnn::DataType DataType>
263static void NeonCreateFullyConnectedWorkloadTest()
telsoa014fcda012018-03-09 14:13:49 +0000264{
265 Graph graph;
266 NeonWorkloadFactory factory;
telsoa01c577f2c2018-08-31 09:22:23 +0100267 auto workload = CreateFullyConnectedWorkloadTest<FullyConnectedWorkloadType,
268 DataType>(factory, graph);
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 CreateFullyConnectedWorkloadTest).
telsoa014fcda012018-03-09 14:13:49 +0000271 FullyConnectedQueueDescriptor queueDescriptor = workload->GetData();
272 auto inputHandle = boost::polymorphic_downcast<INeonTensorHandle*>(queueDescriptor.m_Inputs[0]);
273 auto outputHandle = boost::polymorphic_downcast<INeonTensorHandle*>(queueDescriptor.m_Outputs[0]);
telsoa01c577f2c2018-08-31 09:22:23 +0100274 BOOST_TEST(TestNeonTensorHandleInfo(inputHandle, TensorInfo({3, 1, 4, 5}, DataType)));
275 BOOST_TEST(TestNeonTensorHandleInfo(outputHandle, TensorInfo({3, 7}, DataType)));
telsoa014fcda012018-03-09 14:13:49 +0000276}
277
telsoa01c577f2c2018-08-31 09:22:23 +0100278#ifdef __ARM_FEATURE_FP16_VECTOR_ARITHMETIC
279BOOST_AUTO_TEST_CASE(CreateFullyConnectedFloat16Workload)
280{
kevmay01e448be32018-09-26 10:21:55 +0100281 NeonCreateFullyConnectedWorkloadTest<NeonFullyConnectedWorkload, DataType::Float16>();
telsoa01c577f2c2018-08-31 09:22:23 +0100282}
283#endif
284
arovir019e53a352018-08-31 15:26:35 +0100285BOOST_AUTO_TEST_CASE(CreateFullyConnectedFloatWorkload)
telsoa01c577f2c2018-08-31 09:22:23 +0100286{
kevmay01e448be32018-09-26 10:21:55 +0100287 NeonCreateFullyConnectedWorkloadTest<NeonFullyConnectedWorkload, DataType::Float32>();
telsoa01c577f2c2018-08-31 09:22:23 +0100288}
289
telsoa01c577f2c2018-08-31 09:22:23 +0100290template <typename NormalizationWorkloadType, typename armnn::DataType DataType>
narpra0155a97bc2018-10-02 14:35:53 +0100291static void NeonCreateNormalizationWorkloadTest(DataLayout dataLayout)
telsoa014fcda012018-03-09 14:13:49 +0000292{
narpra0155a97bc2018-10-02 14:35:53 +0100293 Graph graph;
telsoa014fcda012018-03-09 14:13:49 +0000294 NeonWorkloadFactory factory;
narpra0155a97bc2018-10-02 14:35:53 +0100295 auto workload = CreateNormalizationWorkloadTest<NormalizationWorkloadType, DataType>(factory, graph, dataLayout);
telsoa014fcda012018-03-09 14:13:49 +0000296
telsoa01c577f2c2018-08-31 09:22:23 +0100297 // Checks that outputs and inputs are as we expect them (see definition of CreateNormalizationWorkloadTest).
telsoa014fcda012018-03-09 14:13:49 +0000298 NormalizationQueueDescriptor queueDescriptor = workload->GetData();
299 auto inputHandle = boost::polymorphic_downcast<INeonTensorHandle*>(queueDescriptor.m_Inputs[0]);
300 auto outputHandle = boost::polymorphic_downcast<INeonTensorHandle*>(queueDescriptor.m_Outputs[0]);
telsoa01c577f2c2018-08-31 09:22:23 +0100301 BOOST_TEST(TestNeonTensorHandleInfo(inputHandle, TensorInfo({3, 5, 5, 1}, DataType)));
302 BOOST_TEST(TestNeonTensorHandleInfo(outputHandle, TensorInfo({3, 5, 5, 1}, DataType)));
telsoa014fcda012018-03-09 14:13:49 +0000303}
304
telsoa01c577f2c2018-08-31 09:22:23 +0100305#ifdef __ARM_FEATURE_FP16_VECTOR_ARITHMETIC
narpra0155a97bc2018-10-02 14:35:53 +0100306BOOST_AUTO_TEST_CASE(CreateNormalizationFloat16NchwWorkload)
telsoa01c577f2c2018-08-31 09:22:23 +0100307{
narpra0155a97bc2018-10-02 14:35:53 +0100308 NeonCreateNormalizationWorkloadTest<NeonNormalizationFloatWorkload, DataType::Float16>(DataLayout::NCHW);
309}
310
311BOOST_AUTO_TEST_CASE(CreateNormalizationFloat16NhwcWorkload)
312{
313 NeonCreateNormalizationWorkloadTest<NeonNormalizationFloatWorkload, DataType::Float16>(DataLayout::NHWC);
telsoa01c577f2c2018-08-31 09:22:23 +0100314}
315#endif
316
narpra0155a97bc2018-10-02 14:35:53 +0100317BOOST_AUTO_TEST_CASE(CreateNormalizationFloatNchwWorkload)
telsoa01c577f2c2018-08-31 09:22:23 +0100318{
narpra0155a97bc2018-10-02 14:35:53 +0100319 NeonCreateNormalizationWorkloadTest<NeonNormalizationFloatWorkload, DataType::Float32>(DataLayout::NCHW);
telsoa01c577f2c2018-08-31 09:22:23 +0100320}
321
narpra0155a97bc2018-10-02 14:35:53 +0100322BOOST_AUTO_TEST_CASE(CreateNormalizationFloatNhwcWorkload)
323{
324 NeonCreateNormalizationWorkloadTest<NeonNormalizationFloatWorkload, DataType::Float32>(DataLayout::NHWC);
325}
326
327
Nattapat Chaimanowong5d2e7002018-10-12 16:03:56 +0100328template <typename armnn::DataType DataType>
Nina Drozdb48e6862018-10-09 12:09:56 +0100329static void NeonCreatePooling2dWorkloadTest(DataLayout dataLayout = DataLayout::NCHW)
telsoa014fcda012018-03-09 14:13:49 +0000330{
331 Graph graph;
332 NeonWorkloadFactory factory;
Nattapat Chaimanowong5d2e7002018-10-12 16:03:56 +0100333 auto workload = CreatePooling2dWorkloadTest<NeonPooling2dWorkload, DataType>
Nina Drozdb48e6862018-10-09 12:09:56 +0100334 (factory, graph, dataLayout);
335
336 TensorShape inputShape = (dataLayout == DataLayout::NCHW) ? TensorShape{3, 2, 5, 5} : TensorShape{3, 5, 5, 2};
337 TensorShape outputShape = (dataLayout == DataLayout::NCHW) ? TensorShape{3, 2, 2, 4} : TensorShape{3, 2, 4, 2};
telsoa014fcda012018-03-09 14:13:49 +0000338
telsoa01c577f2c2018-08-31 09:22:23 +0100339 // Checks that outputs and inputs are as we expect them (see definition of CreatePooling2dWorkloadTest).
telsoa014fcda012018-03-09 14:13:49 +0000340 Pooling2dQueueDescriptor queueDescriptor = workload->GetData();
341 auto inputHandle = boost::polymorphic_downcast<INeonTensorHandle*>(queueDescriptor.m_Inputs[0]);
342 auto outputHandle = boost::polymorphic_downcast<INeonTensorHandle*>(queueDescriptor.m_Outputs[0]);
Nina Drozdb48e6862018-10-09 12:09:56 +0100343 BOOST_TEST(TestNeonTensorHandleInfo(inputHandle, TensorInfo(inputShape, DataType)));
344 BOOST_TEST(TestNeonTensorHandleInfo(outputHandle, TensorInfo(outputShape, DataType)));
telsoa014fcda012018-03-09 14:13:49 +0000345}
346
telsoa01c577f2c2018-08-31 09:22:23 +0100347#ifdef __ARM_FEATURE_FP16_VECTOR_ARITHMETIC
348BOOST_AUTO_TEST_CASE(CreatePooling2dFloat16Workload)
349{
Nattapat Chaimanowong5d2e7002018-10-12 16:03:56 +0100350 NeonCreatePooling2dWorkloadTest<DataType::Float16>();
telsoa01c577f2c2018-08-31 09:22:23 +0100351}
352#endif
353
Nina Drozdb48e6862018-10-09 12:09:56 +0100354BOOST_AUTO_TEST_CASE(CreatePooling2dFloatNchwWorkload)
telsoa01c577f2c2018-08-31 09:22:23 +0100355{
Nattapat Chaimanowong5d2e7002018-10-12 16:03:56 +0100356 NeonCreatePooling2dWorkloadTest<DataType::Float32>(DataLayout::NCHW);
telsoa01c577f2c2018-08-31 09:22:23 +0100357}
358
Nina Drozdb48e6862018-10-09 12:09:56 +0100359BOOST_AUTO_TEST_CASE(CreatePooling2dFloatNhwcWorkload)
telsoa01c577f2c2018-08-31 09:22:23 +0100360{
Nattapat Chaimanowong5d2e7002018-10-12 16:03:56 +0100361 NeonCreatePooling2dWorkloadTest<DataType::Float32>(DataLayout::NHWC);
Nina Drozdb48e6862018-10-09 12:09:56 +0100362}
363
364BOOST_AUTO_TEST_CASE(CreatePooling2dUint8NchwWorkload)
365{
Nattapat Chaimanowong5d2e7002018-10-12 16:03:56 +0100366 NeonCreatePooling2dWorkloadTest<DataType::QuantisedAsymm8>(DataLayout::NCHW);
Nina Drozdb48e6862018-10-09 12:09:56 +0100367}
368
369BOOST_AUTO_TEST_CASE(CreatePooling2dUint8NhwcWorkload)
370{
Nattapat Chaimanowong5d2e7002018-10-12 16:03:56 +0100371 NeonCreatePooling2dWorkloadTest<DataType::QuantisedAsymm8>(DataLayout::NHWC);
telsoa01c577f2c2018-08-31 09:22:23 +0100372}
373
Nattapat Chaimanowongcce11fc2018-10-12 16:30:56 +0100374template <typename armnn::DataType DataType>
telsoa01c577f2c2018-08-31 09:22:23 +0100375static void NeonCreateReshapeWorkloadTest()
telsoa014fcda012018-03-09 14:13:49 +0000376{
377 Graph graph;
378 NeonWorkloadFactory factory;
Nattapat Chaimanowongcce11fc2018-10-12 16:30:56 +0100379 auto workload = CreateReshapeWorkloadTest<NeonReshapeWorkload, DataType>(factory, graph);
telsoa014fcda012018-03-09 14:13:49 +0000380
telsoa01c577f2c2018-08-31 09:22:23 +0100381 // Checks that outputs and inputs are as we expect them (see definition of CreateReshapeWorkloadTest).
telsoa014fcda012018-03-09 14:13:49 +0000382 ReshapeQueueDescriptor queueDescriptor = workload->GetData();
383 auto inputHandle = boost::polymorphic_downcast<INeonTensorHandle*>(queueDescriptor.m_Inputs[0]);
384 auto outputHandle = boost::polymorphic_downcast<INeonTensorHandle*>(queueDescriptor.m_Outputs[0]);
telsoa01c577f2c2018-08-31 09:22:23 +0100385 BOOST_TEST(TestNeonTensorHandleInfo(inputHandle, TensorInfo({4, 1}, DataType)));
386 BOOST_TEST(TestNeonTensorHandleInfo(outputHandle, TensorInfo({1, 4}, DataType)));
telsoa014fcda012018-03-09 14:13:49 +0000387}
388
telsoa01c577f2c2018-08-31 09:22:23 +0100389#ifdef __ARM_FEATURE_FP16_VECTOR_ARITHMETIC
390BOOST_AUTO_TEST_CASE(CreateReshapeFloat16Workload)
391{
Nattapat Chaimanowongcce11fc2018-10-12 16:30:56 +0100392 NeonCreateReshapeWorkloadTest<DataType::Float16>();
telsoa01c577f2c2018-08-31 09:22:23 +0100393}
394#endif
395
arovir019e53a352018-08-31 15:26:35 +0100396BOOST_AUTO_TEST_CASE(CreateReshapeFloatWorkload)
telsoa014fcda012018-03-09 14:13:49 +0000397{
Nattapat Chaimanowongcce11fc2018-10-12 16:30:56 +0100398 NeonCreateReshapeWorkloadTest<DataType::Float32>();
telsoa014fcda012018-03-09 14:13:49 +0000399}
400
401BOOST_AUTO_TEST_CASE(CreateReshapeUint8Workload)
402{
Nattapat Chaimanowongcce11fc2018-10-12 16:30:56 +0100403 NeonCreateReshapeWorkloadTest<DataType::QuantisedAsymm8>();
telsoa014fcda012018-03-09 14:13:49 +0000404}
405
telsoa01c577f2c2018-08-31 09:22:23 +0100406template <typename SoftmaxWorkloadType, typename armnn::DataType DataType>
407static void NeonCreateSoftmaxWorkloadTest()
telsoa014fcda012018-03-09 14:13:49 +0000408{
409 Graph graph;
410 NeonWorkloadFactory factory;
telsoa01c577f2c2018-08-31 09:22:23 +0100411 auto workload = CreateSoftmaxWorkloadTest<SoftmaxWorkloadType, DataType>(factory, graph);
telsoa014fcda012018-03-09 14:13:49 +0000412
telsoa01c577f2c2018-08-31 09:22:23 +0100413 // Checks that outputs and inputs are as we expect them (see definition of CreateSoftmaxWorkloadTest).
telsoa014fcda012018-03-09 14:13:49 +0000414 SoftmaxQueueDescriptor queueDescriptor = workload->GetData();
415 auto inputHandle = boost::polymorphic_downcast<INeonTensorHandle*>(queueDescriptor.m_Inputs[0]);
416 auto outputHandle = boost::polymorphic_downcast<INeonTensorHandle*>(queueDescriptor.m_Outputs[0]);
telsoa01c577f2c2018-08-31 09:22:23 +0100417 BOOST_TEST(TestNeonTensorHandleInfo(inputHandle, TensorInfo({4, 1}, DataType)));
418 BOOST_TEST(TestNeonTensorHandleInfo(outputHandle, TensorInfo({4, 1}, DataType)));
419}
420
421#ifdef __ARM_FEATURE_FP16_VECTOR_ARITHMETIC
422BOOST_AUTO_TEST_CASE(CreateSoftmaxFloat16Workload)
423{
arovir019e53a352018-08-31 15:26:35 +0100424 NeonCreateSoftmaxWorkloadTest<NeonSoftmaxFloatWorkload, DataType::Float16>();
telsoa01c577f2c2018-08-31 09:22:23 +0100425}
426#endif
427
arovir019e53a352018-08-31 15:26:35 +0100428BOOST_AUTO_TEST_CASE(CreateSoftmaxFloatWorkload)
telsoa01c577f2c2018-08-31 09:22:23 +0100429{
arovir019e53a352018-08-31 15:26:35 +0100430 NeonCreateSoftmaxWorkloadTest<NeonSoftmaxFloatWorkload, DataType::Float32>();
telsoa014fcda012018-03-09 14:13:49 +0000431}
432
433BOOST_AUTO_TEST_CASE(CreateSplitterWorkload)
434{
435 Graph graph;
436 NeonWorkloadFactory factory;
Nattapat Chaimanowong14766d72018-10-12 15:09:53 +0100437 auto workload = CreateSplitterWorkloadTest<NeonSplitterWorkload, DataType::Float32>(factory, graph);
telsoa014fcda012018-03-09 14:13:49 +0000438
telsoa01c577f2c2018-08-31 09:22:23 +0100439 // Checks that outputs are as we expect them (see definition of CreateSplitterWorkloadTest).
telsoa014fcda012018-03-09 14:13:49 +0000440 SplitterQueueDescriptor queueDescriptor = workload->GetData();
441 auto inputHandle = boost::polymorphic_downcast<INeonTensorHandle*>(queueDescriptor.m_Inputs[0]);
surmeh013537c2c2018-05-18 16:31:43 +0100442 BOOST_TEST(TestNeonTensorHandleInfo(inputHandle, TensorInfo({5, 7, 7}, DataType::Float32)));
443
telsoa014fcda012018-03-09 14:13:49 +0000444 auto outputHandle0 = boost::polymorphic_downcast<INeonTensorHandle*>(queueDescriptor.m_Outputs[0]);
surmeh013537c2c2018-05-18 16:31:43 +0100445 BOOST_TEST(TestNeonTensorHandleInfo(outputHandle0, TensorInfo({1, 7, 7}, DataType::Float32)));
446
telsoa014fcda012018-03-09 14:13:49 +0000447 auto outputHandle1 = boost::polymorphic_downcast<INeonTensorHandle*>(queueDescriptor.m_Outputs[1]);
surmeh013537c2c2018-05-18 16:31:43 +0100448 BOOST_TEST(TestNeonTensorHandleInfo(outputHandle1, TensorInfo({2, 7, 7}, DataType::Float32)));
449
telsoa014fcda012018-03-09 14:13:49 +0000450 auto outputHandle2 = boost::polymorphic_downcast<INeonTensorHandle*>(queueDescriptor.m_Outputs[2]);
surmeh013537c2c2018-05-18 16:31:43 +0100451 BOOST_TEST(TestNeonTensorHandleInfo(outputHandle2, TensorInfo({2, 7, 7}, DataType::Float32)));
telsoa014fcda012018-03-09 14:13:49 +0000452}
453
454BOOST_AUTO_TEST_CASE(CreateSplitterMerger)
455{
telsoa01c577f2c2018-08-31 09:22:23 +0100456 // Tests that it is possible to decide which output of the splitter layer
457 // should be lined to which input of the merger layer.
458 // We tested that is is possible to specify 0th output
459 // 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 +0000460 // of the merger.
461
462 Graph graph;
463 NeonWorkloadFactory factory;
464
465 auto workloads =
Nattapat Chaimanowong14766d72018-10-12 15:09:53 +0100466 CreateSplitterMergerWorkloadTest<NeonSplitterWorkload, NeonMergerWorkload,
telsoa01c577f2c2018-08-31 09:22:23 +0100467 DataType::Float32>(factory, graph);
telsoa014fcda012018-03-09 14:13:49 +0000468
469 auto wlSplitter = std::move(workloads.first);
470 auto wlMerger = std::move(workloads.second);
471
telsoa01c577f2c2018-08-31 09:22:23 +0100472 //Checks that the index of inputs/outputs matches what we declared on InputDescriptor construction.
telsoa014fcda012018-03-09 14:13:49 +0000473 armnn::INeonTensorHandle* sOut0 = dynamic_cast<armnn::INeonTensorHandle*>(wlSplitter->GetData().m_Outputs[0]);
474 armnn::INeonTensorHandle* sOut1 = dynamic_cast<armnn::INeonTensorHandle*>(wlSplitter->GetData().m_Outputs[1]);
475 armnn::INeonTensorHandle* mIn0 = dynamic_cast<armnn::INeonTensorHandle*>(wlMerger->GetData().m_Inputs[0]);
476 armnn::INeonTensorHandle* mIn1 = dynamic_cast<armnn::INeonTensorHandle*>(wlMerger->GetData().m_Inputs[1]);
477
478 BOOST_TEST(sOut0);
479 BOOST_TEST(sOut1);
480 BOOST_TEST(mIn0);
481 BOOST_TEST(mIn1);
482
483 bool validDataPointers = (sOut0 == mIn1) && (sOut1 == mIn0);
484
485 BOOST_TEST(validDataPointers);
486}
487
488BOOST_AUTO_TEST_CASE(CreateSingleOutputMultipleInputs)
489{
telsoa01c577f2c2018-08-31 09:22:23 +0100490 // Tests that it is possible to assign multiple (two) different layers to each of the outputs of a splitter layer.
491 // 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 +0000492
493 Graph graph;
494 NeonWorkloadFactory factory;
Nattapat Chaimanowong14766d72018-10-12 15:09:53 +0100495 std::unique_ptr<NeonSplitterWorkload> wlSplitter;
Nattapat Chaimanowongd4b70592018-10-12 11:21:49 +0100496 std::unique_ptr<NeonActivationWorkload> wlActiv0_0;
497 std::unique_ptr<NeonActivationWorkload> wlActiv0_1;
498 std::unique_ptr<NeonActivationWorkload> wlActiv1_0;
499 std::unique_ptr<NeonActivationWorkload> wlActiv1_1;
telsoa014fcda012018-03-09 14:13:49 +0000500
Nattapat Chaimanowong14766d72018-10-12 15:09:53 +0100501 CreateSplitterMultipleInputsOneOutputWorkloadTest<NeonSplitterWorkload,
Nattapat Chaimanowongd4b70592018-10-12 11:21:49 +0100502 NeonActivationWorkload, DataType::Float32>(factory, graph, wlSplitter, wlActiv0_0, wlActiv0_1,
503 wlActiv1_0, wlActiv1_1);
telsoa014fcda012018-03-09 14:13:49 +0000504
505 armnn::INeonTensorHandle* sOut0 = dynamic_cast<armnn::INeonTensorHandle*>(wlSplitter->GetData().m_Outputs[0]);
506 armnn::INeonTensorHandle* sOut1 = dynamic_cast<armnn::INeonTensorHandle*>(wlSplitter->GetData().m_Outputs[1]);
507 armnn::INeonTensorHandle* activ0_0Im = dynamic_cast<armnn::INeonTensorHandle*>(wlActiv0_0->GetData().m_Inputs[0]);
508 armnn::INeonTensorHandle* activ0_1Im = dynamic_cast<armnn::INeonTensorHandle*>(wlActiv0_1->GetData().m_Inputs[0]);
509 armnn::INeonTensorHandle* activ1_0Im = dynamic_cast<armnn::INeonTensorHandle*>(wlActiv1_0->GetData().m_Inputs[0]);
510 armnn::INeonTensorHandle* activ1_1Im = dynamic_cast<armnn::INeonTensorHandle*>(wlActiv1_1->GetData().m_Inputs[0]);
511
512
513 BOOST_TEST(sOut0);
514 BOOST_TEST(sOut1);
515 BOOST_TEST(activ0_0Im);
516 BOOST_TEST(activ0_1Im);
517 BOOST_TEST(activ1_0Im);
518 BOOST_TEST(activ1_1Im);
519
520 bool validDataPointers = (sOut0 == activ0_0Im) && (sOut0 == activ0_1Im) &&
521 (sOut1 == activ1_0Im) && (sOut1 == activ1_1Im);
522
523 BOOST_TEST(validDataPointers);
524}
525
526BOOST_AUTO_TEST_CASE(CreateMemCopyWorkloadsNeon)
527{
528 NeonWorkloadFactory factory;
telsoa01c577f2c2018-08-31 09:22:23 +0100529 CreateMemCopyWorkloads<INeonTensorHandle>(factory);
telsoa014fcda012018-03-09 14:13:49 +0000530}
531
Matteo Martincighbcd3c852018-09-28 14:14:12 +0100532template <typename L2NormalizationWorkloadType, typename armnn::DataType DataType>
533static void NeonCreateL2NormalizationWorkloadTest(DataLayout dataLayout)
534{
Matteo Martincigh2400b6d2018-10-09 18:19:20 +0100535 Graph graph;
536 NeonWorkloadFactory factory;
537 auto workload =
538 CreateL2NormalizationWorkloadTest<L2NormalizationWorkloadType, DataType>(factory, graph, dataLayout);
Matteo Martincighbcd3c852018-09-28 14:14:12 +0100539
540 // Checks that inputs/outputs are as we expect them (see definition of CreateNormalizationWorkloadTest).
541 L2NormalizationQueueDescriptor queueDescriptor = workload->GetData();
542 auto inputHandle = boost::polymorphic_downcast<INeonTensorHandle*>(queueDescriptor.m_Inputs[0]);
543 auto outputHandle = boost::polymorphic_downcast<INeonTensorHandle*>(queueDescriptor.m_Outputs[0]);
Matteo Martincigh2400b6d2018-10-09 18:19:20 +0100544
545 TensorShape inputShape = (dataLayout == DataLayout::NCHW) ?
546 TensorShape{ 5, 20, 50, 67 } : TensorShape{ 5, 50, 67, 20 };
547 TensorShape outputShape = (dataLayout == DataLayout::NCHW) ?
548 TensorShape{ 5, 20, 50, 67 } : TensorShape{ 5, 50, 67, 20 };
549
550 BOOST_TEST(TestNeonTensorHandleInfo(inputHandle, TensorInfo(inputShape, DataType)));
551 BOOST_TEST(TestNeonTensorHandleInfo(outputHandle, TensorInfo(outputShape, DataType)));
Matteo Martincighbcd3c852018-09-28 14:14:12 +0100552}
553
554#ifdef __ARM_FEATURE_FP16_VECTOR_ARITHMETIC
555BOOST_AUTO_TEST_CASE(CreateL2NormalizationFloat16NchwWorkload)
556{
557 NeonCreateL2NormalizationWorkloadTest<NeonL2NormalizationFloatWorkload, DataType::Float16>(DataLayout::NCHW);
558}
559
560BOOST_AUTO_TEST_CASE(CreateL2NormalizationFloat16NhwcWorkload)
561{
562 NeonCreateL2NormalizationWorkloadTest<NeonL2NormalizationFloatWorkload, DataType::Float16>(DataLayout::NHWC);
563}
564#endif
565
566BOOST_AUTO_TEST_CASE(CreateL2NormalizationNchwWorkload)
567{
568 NeonCreateL2NormalizationWorkloadTest<NeonL2NormalizationFloatWorkload, DataType::Float32>(DataLayout::NCHW);
569}
570
571BOOST_AUTO_TEST_CASE(CreateL2NormalizationNhwcWorkload)
572{
573 NeonCreateL2NormalizationWorkloadTest<NeonL2NormalizationFloatWorkload, DataType::Float32>(DataLayout::NHWC);
574}
575
telsoa014fcda012018-03-09 14:13:49 +0000576BOOST_AUTO_TEST_SUITE_END()