blob: a6f3540994503e6947b2933d865dd59ccb277df1 [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//
David Beck0dbe0ee2018-09-24 15:59:27 +01005#include <backends/neon/NeonWorkloadFactory.hpp>
6#include <backends/neon/NeonTensorHandle.hpp>
7#include <backends/neon/workloads/NeonWorkloadUtils.hpp>
8#include <backends/neon/workloads/NeonWorkloads.hpp>
9#include <backends/MemCopyWorkload.hpp>
telsoa014fcda012018-03-09 14:13:49 +000010
11#include "test/CreateWorkloadClNeon.hpp"
12
13BOOST_AUTO_TEST_SUITE(CreateWorkloadNeon)
14
15namespace
16{
17
18bool TestNeonTensorHandleInfo(armnn::INeonTensorHandle* handle, const armnn::TensorInfo& expectedInfo)
19{
20 using namespace armnn::armcomputetensorutils;
21
22 const arm_compute::ITensorInfo* handleInfo = handle->GetTensor().info();
23 const arm_compute::TensorInfo expectedAclInfo = BuildArmComputeTensorInfo(expectedInfo);
24
25 if (handleInfo->data_type() != expectedAclInfo.data_type())
26 {
27 return false;
28 }
29
30 if (handleInfo->num_dimensions() != expectedAclInfo.num_dimensions())
31 {
32 return false;
33 }
34
35 if (handleInfo->quantization_info() != expectedAclInfo.quantization_info())
36 {
37 return false;
38 }
39
40 for (std::size_t d = 0; d < expectedAclInfo.num_dimensions(); ++d)
41 {
42 if (handleInfo->dimension(d) != expectedAclInfo.dimension(d))
43 {
44 return false;
45 }
46 }
47
48 return true;
49}
50
51} // namespace
52
telsoa01c577f2c2018-08-31 09:22:23 +010053template <typename ActivationWorkloadType, typename armnn::DataType DataType>
54static void NeonCreateActivationWorkloadTest()
telsoa014fcda012018-03-09 14:13:49 +000055{
56 Graph graph;
57 NeonWorkloadFactory factory;
telsoa01c577f2c2018-08-31 09:22:23 +010058 auto workload = CreateActivationWorkloadTest<ActivationWorkloadType, DataType>
59 (factory, graph);
telsoa014fcda012018-03-09 14:13:49 +000060
telsoa01c577f2c2018-08-31 09:22:23 +010061 // Checks that inputs/outputs are as we expect them (see definition of CreateActivationWorkloadTest).
telsoa014fcda012018-03-09 14:13:49 +000062 ActivationQueueDescriptor queueDescriptor = workload->GetData();
63 auto inputHandle = boost::polymorphic_downcast<INeonTensorHandle*>(queueDescriptor.m_Inputs[0]);
64 auto outputHandle = boost::polymorphic_downcast<INeonTensorHandle*>(queueDescriptor.m_Outputs[0]);
telsoa01c577f2c2018-08-31 09:22:23 +010065 BOOST_TEST(TestNeonTensorHandleInfo(inputHandle, TensorInfo({1, 1}, DataType)));
66 BOOST_TEST(TestNeonTensorHandleInfo(outputHandle, TensorInfo({1, 1}, DataType)));
telsoa014fcda012018-03-09 14:13:49 +000067}
68
telsoa01c577f2c2018-08-31 09:22:23 +010069#ifdef __ARM_FEATURE_FP16_VECTOR_ARITHMETIC
70BOOST_AUTO_TEST_CASE(CreateActivationFloat16Workload)
71{
arovir019e53a352018-08-31 15:26:35 +010072 NeonCreateActivationWorkloadTest<NeonActivationFloatWorkload, DataType::Float16>();
telsoa01c577f2c2018-08-31 09:22:23 +010073}
74#endif
75
arovir019e53a352018-08-31 15:26:35 +010076BOOST_AUTO_TEST_CASE(CreateActivationFloatWorkload)
telsoa01c577f2c2018-08-31 09:22:23 +010077{
arovir019e53a352018-08-31 15:26:35 +010078 NeonCreateActivationWorkloadTest<NeonActivationFloatWorkload, DataType::Float32>();
telsoa01c577f2c2018-08-31 09:22:23 +010079}
80
David Beckbc392452018-09-10 14:47:28 +010081template <typename WorkloadType,
82 typename DescriptorType,
83 typename LayerType,
84 armnn::DataType DataType>
85static void NeonCreateArithmethicWorkloadTest()
telsoa014fcda012018-03-09 14:13:49 +000086{
David Beckbc392452018-09-10 14:47:28 +010087 Graph graph;
telsoa014fcda012018-03-09 14:13:49 +000088 NeonWorkloadFactory factory;
David Beckbc392452018-09-10 14:47:28 +010089 auto workload = CreateArithmeticWorkloadTest<WorkloadType, DescriptorType, LayerType, DataType>(factory, graph);
telsoa014fcda012018-03-09 14:13:49 +000090
David Beckbc392452018-09-10 14:47:28 +010091 DescriptorType queueDescriptor = workload->GetData();
telsoa014fcda012018-03-09 14:13:49 +000092 auto inputHandle1 = boost::polymorphic_downcast<INeonTensorHandle*>(queueDescriptor.m_Inputs[0]);
93 auto inputHandle2 = boost::polymorphic_downcast<INeonTensorHandle*>(queueDescriptor.m_Inputs[1]);
94 auto outputHandle = boost::polymorphic_downcast<INeonTensorHandle*>(queueDescriptor.m_Outputs[0]);
telsoa01c577f2c2018-08-31 09:22:23 +010095 BOOST_TEST(TestNeonTensorHandleInfo(inputHandle1, TensorInfo({2, 3}, DataType)));
96 BOOST_TEST(TestNeonTensorHandleInfo(inputHandle2, TensorInfo({2, 3}, DataType)));
97 BOOST_TEST(TestNeonTensorHandleInfo(outputHandle, TensorInfo({2, 3}, DataType)));
telsoa014fcda012018-03-09 14:13:49 +000098}
99
telsoa01c577f2c2018-08-31 09:22:23 +0100100#ifdef __ARM_FEATURE_FP16_VECTOR_ARITHMETIC
101BOOST_AUTO_TEST_CASE(CreateAdditionFloat16Workload)
102{
David Beckbc392452018-09-10 14:47:28 +0100103 NeonCreateArithmethicWorkloadTest<NeonAdditionFloatWorkload,
104 AdditionQueueDescriptor,
105 AdditionLayer,
106 DataType::Float16>();
telsoa01c577f2c2018-08-31 09:22:23 +0100107}
108#endif
109
arovir019e53a352018-08-31 15:26:35 +0100110BOOST_AUTO_TEST_CASE(CreateAdditionFloatWorkload)
telsoa01c577f2c2018-08-31 09:22:23 +0100111{
David Beckbc392452018-09-10 14:47:28 +0100112 NeonCreateArithmethicWorkloadTest<NeonAdditionFloatWorkload,
113 AdditionQueueDescriptor,
114 AdditionLayer,
115 DataType::Float32>();
116}
117
118#ifdef __ARM_FEATURE_FP16_VECTOR_ARITHMETIC
119BOOST_AUTO_TEST_CASE(CreateSubtractionFloat16Workload)
120{
121 NeonCreateArithmethicWorkloadTest<NeonSubtractionFloatWorkload,
122 SubtractionQueueDescriptor,
123 SubtractionLayer,
124 DataType::Float16>();
125}
126#endif
127
128BOOST_AUTO_TEST_CASE(CreateSubtractionFloatWorkload)
129{
130 NeonCreateArithmethicWorkloadTest<NeonSubtractionFloatWorkload,
131 SubtractionQueueDescriptor,
132 SubtractionLayer,
133 DataType::Float32>();
134}
135
136#ifdef __ARM_FEATURE_FP16_VECTOR_ARITHMETIC
137BOOST_AUTO_TEST_CASE(CreateMultiplicationFloat16Workload)
138{
139 NeonCreateArithmethicWorkloadTest<NeonMultiplicationFloatWorkload,
140 MultiplicationQueueDescriptor,
141 MultiplicationLayer,
142 DataType::Float16>();
143}
144#endif
145
146BOOST_AUTO_TEST_CASE(CreateMultiplicationFloatWorkload)
147{
148 NeonCreateArithmethicWorkloadTest<NeonMultiplicationFloatWorkload,
149 MultiplicationQueueDescriptor,
150 MultiplicationLayer,
151 DataType::Float32>();
telsoa01c577f2c2018-08-31 09:22:23 +0100152}
153
154template <typename BatchNormalizationWorkloadType, typename armnn::DataType DataType>
155static void NeonCreateBatchNormalizationWorkloadTest()
telsoa014fcda012018-03-09 14:13:49 +0000156{
157 Graph graph;
158 NeonWorkloadFactory factory;
telsoa01c577f2c2018-08-31 09:22:23 +0100159 auto workload = CreateBatchNormalizationWorkloadTest<BatchNormalizationWorkloadType, DataType>(factory, graph);
telsoa014fcda012018-03-09 14:13:49 +0000160
telsoa01c577f2c2018-08-31 09:22:23 +0100161 // Checks that outputs and inputs are as we expect them (see definition of CreateBatchNormalizationWorkloadTest).
telsoa014fcda012018-03-09 14:13:49 +0000162 BatchNormalizationQueueDescriptor queueDescriptor = workload->GetData();
163 auto inputHandle = boost::polymorphic_downcast<INeonTensorHandle*>(queueDescriptor.m_Inputs[0]);
164 auto outputHandle = boost::polymorphic_downcast<INeonTensorHandle*>(queueDescriptor.m_Outputs[0]);
telsoa01c577f2c2018-08-31 09:22:23 +0100165 BOOST_TEST(TestNeonTensorHandleInfo(inputHandle, TensorInfo({2, 3, 1, 1}, DataType)));
166 BOOST_TEST(TestNeonTensorHandleInfo(outputHandle, TensorInfo({2, 3, 1, 1}, DataType)));
telsoa014fcda012018-03-09 14:13:49 +0000167}
168
telsoa01c577f2c2018-08-31 09:22:23 +0100169#ifdef __ARM_FEATURE_FP16_VECTOR_ARITHMETIC
170BOOST_AUTO_TEST_CASE(CreateBatchNormalizationFloat16Workload)
171{
arovir019e53a352018-08-31 15:26:35 +0100172 NeonCreateBatchNormalizationWorkloadTest<NeonBatchNormalizationFloatWorkload, DataType::Float16>();
telsoa01c577f2c2018-08-31 09:22:23 +0100173}
174#endif
175
arovir019e53a352018-08-31 15:26:35 +0100176BOOST_AUTO_TEST_CASE(CreateBatchNormalizationFloatWorkload)
telsoa01c577f2c2018-08-31 09:22:23 +0100177{
arovir019e53a352018-08-31 15:26:35 +0100178 NeonCreateBatchNormalizationWorkloadTest<NeonBatchNormalizationFloatWorkload, DataType::Float32>();
telsoa01c577f2c2018-08-31 09:22:23 +0100179}
180
181template <typename Convolution2dWorkloadType, typename armnn::DataType DataType>
182static void NeonCreateConvolution2dWorkloadTest()
telsoa014fcda012018-03-09 14:13:49 +0000183{
184 Graph graph;
185 NeonWorkloadFactory factory;
telsoa01c577f2c2018-08-31 09:22:23 +0100186 auto workload = CreateConvolution2dWorkloadTest<Convolution2dWorkloadType,
187 DataType>(factory, graph);
telsoa014fcda012018-03-09 14:13:49 +0000188
telsoa01c577f2c2018-08-31 09:22:23 +0100189 // Checks that outputs and inputs are as we expect them (see definition of CreateConvolution2dWorkloadTest).
telsoa014fcda012018-03-09 14:13:49 +0000190 Convolution2dQueueDescriptor queueDescriptor = workload->GetData();
191 auto inputHandle = boost::polymorphic_downcast<INeonTensorHandle*>(queueDescriptor.m_Inputs[0]);
192 auto outputHandle = boost::polymorphic_downcast<INeonTensorHandle*>(queueDescriptor.m_Outputs[0]);
telsoa01c577f2c2018-08-31 09:22:23 +0100193 BOOST_TEST(TestNeonTensorHandleInfo(inputHandle, TensorInfo({2, 3, 8, 16}, DataType)));
194 BOOST_TEST(TestNeonTensorHandleInfo(outputHandle, TensorInfo({2, 2, 2, 10}, DataType)));
telsoa014fcda012018-03-09 14:13:49 +0000195}
196
telsoa01c577f2c2018-08-31 09:22:23 +0100197#ifdef __ARM_FEATURE_FP16_VECTOR_ARITHMETIC
198BOOST_AUTO_TEST_CASE(CreateConvolution2dFloat16Workload)
199{
arovir019e53a352018-08-31 15:26:35 +0100200 NeonCreateConvolution2dWorkloadTest<NeonConvolution2dFloatWorkload, DataType::Float16>();
telsoa01c577f2c2018-08-31 09:22:23 +0100201}
202#endif
203
arovir019e53a352018-08-31 15:26:35 +0100204BOOST_AUTO_TEST_CASE(CreateConvolution2dFloatWorkload)
telsoa01c577f2c2018-08-31 09:22:23 +0100205{
arovir019e53a352018-08-31 15:26:35 +0100206 NeonCreateConvolution2dWorkloadTest<NeonConvolution2dFloatWorkload, DataType::Float32>();
telsoa01c577f2c2018-08-31 09:22:23 +0100207}
208
209template <typename FullyConnectedWorkloadType, typename armnn::DataType DataType>
210static void NeonCreateFullyConnectedWorkloadTest()
telsoa014fcda012018-03-09 14:13:49 +0000211{
212 Graph graph;
213 NeonWorkloadFactory factory;
telsoa01c577f2c2018-08-31 09:22:23 +0100214 auto workload = CreateFullyConnectedWorkloadTest<FullyConnectedWorkloadType,
215 DataType>(factory, graph);
telsoa014fcda012018-03-09 14:13:49 +0000216
telsoa01c577f2c2018-08-31 09:22:23 +0100217 // Checks that outputs and inputs are as we expect them (see definition of CreateFullyConnectedWorkloadTest).
telsoa014fcda012018-03-09 14:13:49 +0000218 FullyConnectedQueueDescriptor queueDescriptor = workload->GetData();
219 auto inputHandle = boost::polymorphic_downcast<INeonTensorHandle*>(queueDescriptor.m_Inputs[0]);
220 auto outputHandle = boost::polymorphic_downcast<INeonTensorHandle*>(queueDescriptor.m_Outputs[0]);
telsoa01c577f2c2018-08-31 09:22:23 +0100221 BOOST_TEST(TestNeonTensorHandleInfo(inputHandle, TensorInfo({3, 1, 4, 5}, DataType)));
222 BOOST_TEST(TestNeonTensorHandleInfo(outputHandle, TensorInfo({3, 7}, DataType)));
telsoa014fcda012018-03-09 14:13:49 +0000223}
224
telsoa01c577f2c2018-08-31 09:22:23 +0100225#ifdef __ARM_FEATURE_FP16_VECTOR_ARITHMETIC
226BOOST_AUTO_TEST_CASE(CreateFullyConnectedFloat16Workload)
227{
kevmay01e448be32018-09-26 10:21:55 +0100228 NeonCreateFullyConnectedWorkloadTest<NeonFullyConnectedWorkload, DataType::Float16>();
telsoa01c577f2c2018-08-31 09:22:23 +0100229}
230#endif
231
arovir019e53a352018-08-31 15:26:35 +0100232BOOST_AUTO_TEST_CASE(CreateFullyConnectedFloatWorkload)
telsoa01c577f2c2018-08-31 09:22:23 +0100233{
kevmay01e448be32018-09-26 10:21:55 +0100234 NeonCreateFullyConnectedWorkloadTest<NeonFullyConnectedWorkload, DataType::Float32>();
telsoa01c577f2c2018-08-31 09:22:23 +0100235}
236
telsoa01c577f2c2018-08-31 09:22:23 +0100237template <typename NormalizationWorkloadType, typename armnn::DataType DataType>
narpra0155a97bc2018-10-02 14:35:53 +0100238static void NeonCreateNormalizationWorkloadTest(DataLayout dataLayout)
telsoa014fcda012018-03-09 14:13:49 +0000239{
narpra0155a97bc2018-10-02 14:35:53 +0100240 Graph graph;
telsoa014fcda012018-03-09 14:13:49 +0000241 NeonWorkloadFactory factory;
narpra0155a97bc2018-10-02 14:35:53 +0100242 auto workload = CreateNormalizationWorkloadTest<NormalizationWorkloadType, DataType>(factory, graph, dataLayout);
telsoa014fcda012018-03-09 14:13:49 +0000243
telsoa01c577f2c2018-08-31 09:22:23 +0100244 // Checks that outputs and inputs are as we expect them (see definition of CreateNormalizationWorkloadTest).
telsoa014fcda012018-03-09 14:13:49 +0000245 NormalizationQueueDescriptor queueDescriptor = workload->GetData();
246 auto inputHandle = boost::polymorphic_downcast<INeonTensorHandle*>(queueDescriptor.m_Inputs[0]);
247 auto outputHandle = boost::polymorphic_downcast<INeonTensorHandle*>(queueDescriptor.m_Outputs[0]);
telsoa01c577f2c2018-08-31 09:22:23 +0100248 BOOST_TEST(TestNeonTensorHandleInfo(inputHandle, TensorInfo({3, 5, 5, 1}, DataType)));
249 BOOST_TEST(TestNeonTensorHandleInfo(outputHandle, TensorInfo({3, 5, 5, 1}, DataType)));
telsoa014fcda012018-03-09 14:13:49 +0000250}
251
telsoa01c577f2c2018-08-31 09:22:23 +0100252#ifdef __ARM_FEATURE_FP16_VECTOR_ARITHMETIC
narpra0155a97bc2018-10-02 14:35:53 +0100253BOOST_AUTO_TEST_CASE(CreateNormalizationFloat16NchwWorkload)
telsoa01c577f2c2018-08-31 09:22:23 +0100254{
narpra0155a97bc2018-10-02 14:35:53 +0100255 NeonCreateNormalizationWorkloadTest<NeonNormalizationFloatWorkload, DataType::Float16>(DataLayout::NCHW);
256}
257
258BOOST_AUTO_TEST_CASE(CreateNormalizationFloat16NhwcWorkload)
259{
260 NeonCreateNormalizationWorkloadTest<NeonNormalizationFloatWorkload, DataType::Float16>(DataLayout::NHWC);
telsoa01c577f2c2018-08-31 09:22:23 +0100261}
262#endif
263
narpra0155a97bc2018-10-02 14:35:53 +0100264BOOST_AUTO_TEST_CASE(CreateNormalizationFloatNchwWorkload)
telsoa01c577f2c2018-08-31 09:22:23 +0100265{
narpra0155a97bc2018-10-02 14:35:53 +0100266 NeonCreateNormalizationWorkloadTest<NeonNormalizationFloatWorkload, DataType::Float32>(DataLayout::NCHW);
telsoa01c577f2c2018-08-31 09:22:23 +0100267}
268
narpra0155a97bc2018-10-02 14:35:53 +0100269BOOST_AUTO_TEST_CASE(CreateNormalizationFloatNhwcWorkload)
270{
271 NeonCreateNormalizationWorkloadTest<NeonNormalizationFloatWorkload, DataType::Float32>(DataLayout::NHWC);
272}
273
274
telsoa01c577f2c2018-08-31 09:22:23 +0100275template <typename Pooling2dWorkloadType, typename armnn::DataType DataType>
276static void NeonCreatePooling2dWorkloadTest()
telsoa014fcda012018-03-09 14:13:49 +0000277{
278 Graph graph;
279 NeonWorkloadFactory factory;
telsoa01c577f2c2018-08-31 09:22:23 +0100280 auto workload = CreatePooling2dWorkloadTest<Pooling2dWorkloadType, DataType>
281 (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 CreatePooling2dWorkloadTest).
telsoa014fcda012018-03-09 14:13:49 +0000284 Pooling2dQueueDescriptor 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, 2, 5, 5}, DataType)));
288 BOOST_TEST(TestNeonTensorHandleInfo(outputHandle, TensorInfo({3, 2, 2, 4}, 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(CreatePooling2dFloat16Workload)
293{
arovir019e53a352018-08-31 15:26:35 +0100294 NeonCreatePooling2dWorkloadTest<NeonPooling2dFloatWorkload, DataType::Float16>();
telsoa01c577f2c2018-08-31 09:22:23 +0100295}
296#endif
297
arovir019e53a352018-08-31 15:26:35 +0100298BOOST_AUTO_TEST_CASE(CreatePooling2dFloatWorkload)
telsoa01c577f2c2018-08-31 09:22:23 +0100299{
arovir019e53a352018-08-31 15:26:35 +0100300 NeonCreatePooling2dWorkloadTest<NeonPooling2dFloatWorkload, DataType::Float32>();
telsoa01c577f2c2018-08-31 09:22:23 +0100301}
302
303BOOST_AUTO_TEST_CASE(CreatePooling2dUint8Workload)
304{
305 NeonCreatePooling2dWorkloadTest<NeonPooling2dUint8Workload, DataType::QuantisedAsymm8>();
306}
307
308template <typename ReshapeWorkloadType, typename armnn::DataType DataType>
309static void NeonCreateReshapeWorkloadTest()
telsoa014fcda012018-03-09 14:13:49 +0000310{
311 Graph graph;
312 NeonWorkloadFactory factory;
telsoa01c577f2c2018-08-31 09:22:23 +0100313 auto workload = CreateReshapeWorkloadTest<ReshapeWorkloadType, DataType>(factory, graph);
telsoa014fcda012018-03-09 14:13:49 +0000314
telsoa01c577f2c2018-08-31 09:22:23 +0100315 // Checks that outputs and inputs are as we expect them (see definition of CreateReshapeWorkloadTest).
telsoa014fcda012018-03-09 14:13:49 +0000316 ReshapeQueueDescriptor queueDescriptor = workload->GetData();
317 auto inputHandle = boost::polymorphic_downcast<INeonTensorHandle*>(queueDescriptor.m_Inputs[0]);
318 auto outputHandle = boost::polymorphic_downcast<INeonTensorHandle*>(queueDescriptor.m_Outputs[0]);
telsoa01c577f2c2018-08-31 09:22:23 +0100319 BOOST_TEST(TestNeonTensorHandleInfo(inputHandle, TensorInfo({4, 1}, DataType)));
320 BOOST_TEST(TestNeonTensorHandleInfo(outputHandle, TensorInfo({1, 4}, DataType)));
telsoa014fcda012018-03-09 14:13:49 +0000321}
322
telsoa01c577f2c2018-08-31 09:22:23 +0100323#ifdef __ARM_FEATURE_FP16_VECTOR_ARITHMETIC
324BOOST_AUTO_TEST_CASE(CreateReshapeFloat16Workload)
325{
arovir019e53a352018-08-31 15:26:35 +0100326 NeonCreateReshapeWorkloadTest<NeonReshapeFloatWorkload, DataType::Float16>();
telsoa01c577f2c2018-08-31 09:22:23 +0100327}
328#endif
329
arovir019e53a352018-08-31 15:26:35 +0100330BOOST_AUTO_TEST_CASE(CreateReshapeFloatWorkload)
telsoa014fcda012018-03-09 14:13:49 +0000331{
arovir019e53a352018-08-31 15:26:35 +0100332 NeonCreateReshapeWorkloadTest<NeonReshapeFloatWorkload, DataType::Float32>();
telsoa014fcda012018-03-09 14:13:49 +0000333}
334
335BOOST_AUTO_TEST_CASE(CreateReshapeUint8Workload)
336{
telsoa01c577f2c2018-08-31 09:22:23 +0100337 NeonCreateReshapeWorkloadTest<NeonReshapeUint8Workload, DataType::QuantisedAsymm8>();
telsoa014fcda012018-03-09 14:13:49 +0000338}
339
telsoa01c577f2c2018-08-31 09:22:23 +0100340template <typename SoftmaxWorkloadType, typename armnn::DataType DataType>
341static void NeonCreateSoftmaxWorkloadTest()
telsoa014fcda012018-03-09 14:13:49 +0000342{
343 Graph graph;
344 NeonWorkloadFactory factory;
telsoa01c577f2c2018-08-31 09:22:23 +0100345 auto workload = CreateSoftmaxWorkloadTest<SoftmaxWorkloadType, DataType>(factory, graph);
telsoa014fcda012018-03-09 14:13:49 +0000346
telsoa01c577f2c2018-08-31 09:22:23 +0100347 // Checks that outputs and inputs are as we expect them (see definition of CreateSoftmaxWorkloadTest).
telsoa014fcda012018-03-09 14:13:49 +0000348 SoftmaxQueueDescriptor queueDescriptor = workload->GetData();
349 auto inputHandle = boost::polymorphic_downcast<INeonTensorHandle*>(queueDescriptor.m_Inputs[0]);
350 auto outputHandle = boost::polymorphic_downcast<INeonTensorHandle*>(queueDescriptor.m_Outputs[0]);
telsoa01c577f2c2018-08-31 09:22:23 +0100351 BOOST_TEST(TestNeonTensorHandleInfo(inputHandle, TensorInfo({4, 1}, DataType)));
352 BOOST_TEST(TestNeonTensorHandleInfo(outputHandle, TensorInfo({4, 1}, DataType)));
353}
354
355#ifdef __ARM_FEATURE_FP16_VECTOR_ARITHMETIC
356BOOST_AUTO_TEST_CASE(CreateSoftmaxFloat16Workload)
357{
arovir019e53a352018-08-31 15:26:35 +0100358 NeonCreateSoftmaxWorkloadTest<NeonSoftmaxFloatWorkload, DataType::Float16>();
telsoa01c577f2c2018-08-31 09:22:23 +0100359}
360#endif
361
arovir019e53a352018-08-31 15:26:35 +0100362BOOST_AUTO_TEST_CASE(CreateSoftmaxFloatWorkload)
telsoa01c577f2c2018-08-31 09:22:23 +0100363{
arovir019e53a352018-08-31 15:26:35 +0100364 NeonCreateSoftmaxWorkloadTest<NeonSoftmaxFloatWorkload, DataType::Float32>();
telsoa014fcda012018-03-09 14:13:49 +0000365}
366
367BOOST_AUTO_TEST_CASE(CreateSplitterWorkload)
368{
369 Graph graph;
370 NeonWorkloadFactory factory;
arovir019e53a352018-08-31 15:26:35 +0100371 auto workload = CreateSplitterWorkloadTest<NeonSplitterFloatWorkload, DataType::Float32>(factory, graph);
telsoa014fcda012018-03-09 14:13:49 +0000372
telsoa01c577f2c2018-08-31 09:22:23 +0100373 // Checks that outputs are as we expect them (see definition of CreateSplitterWorkloadTest).
telsoa014fcda012018-03-09 14:13:49 +0000374 SplitterQueueDescriptor queueDescriptor = workload->GetData();
375 auto inputHandle = boost::polymorphic_downcast<INeonTensorHandle*>(queueDescriptor.m_Inputs[0]);
surmeh013537c2c2018-05-18 16:31:43 +0100376 BOOST_TEST(TestNeonTensorHandleInfo(inputHandle, TensorInfo({5, 7, 7}, DataType::Float32)));
377
telsoa014fcda012018-03-09 14:13:49 +0000378 auto outputHandle0 = boost::polymorphic_downcast<INeonTensorHandle*>(queueDescriptor.m_Outputs[0]);
surmeh013537c2c2018-05-18 16:31:43 +0100379 BOOST_TEST(TestNeonTensorHandleInfo(outputHandle0, TensorInfo({1, 7, 7}, DataType::Float32)));
380
telsoa014fcda012018-03-09 14:13:49 +0000381 auto outputHandle1 = boost::polymorphic_downcast<INeonTensorHandle*>(queueDescriptor.m_Outputs[1]);
surmeh013537c2c2018-05-18 16:31:43 +0100382 BOOST_TEST(TestNeonTensorHandleInfo(outputHandle1, TensorInfo({2, 7, 7}, DataType::Float32)));
383
telsoa014fcda012018-03-09 14:13:49 +0000384 auto outputHandle2 = boost::polymorphic_downcast<INeonTensorHandle*>(queueDescriptor.m_Outputs[2]);
surmeh013537c2c2018-05-18 16:31:43 +0100385 BOOST_TEST(TestNeonTensorHandleInfo(outputHandle2, TensorInfo({2, 7, 7}, DataType::Float32)));
telsoa014fcda012018-03-09 14:13:49 +0000386}
387
388BOOST_AUTO_TEST_CASE(CreateSplitterMerger)
389{
telsoa01c577f2c2018-08-31 09:22:23 +0100390 // Tests that it is possible to decide which output of the splitter layer
391 // should be lined to which input of the merger layer.
392 // We tested that is is possible to specify 0th output
393 // 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 +0000394 // of the merger.
395
396 Graph graph;
397 NeonWorkloadFactory factory;
398
399 auto workloads =
arovir019e53a352018-08-31 15:26:35 +0100400 CreateSplitterMergerWorkloadTest<NeonSplitterFloatWorkload, NeonMergerFloatWorkload,
telsoa01c577f2c2018-08-31 09:22:23 +0100401 DataType::Float32>(factory, graph);
telsoa014fcda012018-03-09 14:13:49 +0000402
403 auto wlSplitter = std::move(workloads.first);
404 auto wlMerger = std::move(workloads.second);
405
telsoa01c577f2c2018-08-31 09:22:23 +0100406 //Checks that the index of inputs/outputs matches what we declared on InputDescriptor construction.
telsoa014fcda012018-03-09 14:13:49 +0000407 armnn::INeonTensorHandle* sOut0 = dynamic_cast<armnn::INeonTensorHandle*>(wlSplitter->GetData().m_Outputs[0]);
408 armnn::INeonTensorHandle* sOut1 = dynamic_cast<armnn::INeonTensorHandle*>(wlSplitter->GetData().m_Outputs[1]);
409 armnn::INeonTensorHandle* mIn0 = dynamic_cast<armnn::INeonTensorHandle*>(wlMerger->GetData().m_Inputs[0]);
410 armnn::INeonTensorHandle* mIn1 = dynamic_cast<armnn::INeonTensorHandle*>(wlMerger->GetData().m_Inputs[1]);
411
412 BOOST_TEST(sOut0);
413 BOOST_TEST(sOut1);
414 BOOST_TEST(mIn0);
415 BOOST_TEST(mIn1);
416
417 bool validDataPointers = (sOut0 == mIn1) && (sOut1 == mIn0);
418
419 BOOST_TEST(validDataPointers);
420}
421
422BOOST_AUTO_TEST_CASE(CreateSingleOutputMultipleInputs)
423{
telsoa01c577f2c2018-08-31 09:22:23 +0100424 // Tests that it is possible to assign multiple (two) different layers to each of the outputs of a splitter layer.
425 // 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 +0000426
427 Graph graph;
428 NeonWorkloadFactory factory;
arovir019e53a352018-08-31 15:26:35 +0100429 std::unique_ptr<NeonSplitterFloatWorkload> wlSplitter;
430 std::unique_ptr<NeonActivationFloatWorkload> wlActiv0_0;
431 std::unique_ptr<NeonActivationFloatWorkload> wlActiv0_1;
432 std::unique_ptr<NeonActivationFloatWorkload> wlActiv1_0;
433 std::unique_ptr<NeonActivationFloatWorkload> wlActiv1_1;
telsoa014fcda012018-03-09 14:13:49 +0000434
arovir019e53a352018-08-31 15:26:35 +0100435 CreateSplitterMultipleInputsOneOutputWorkloadTest<NeonSplitterFloatWorkload,
436 NeonActivationFloatWorkload, DataType::Float32>(factory, graph, wlSplitter, wlActiv0_0, wlActiv0_1,
telsoa01c577f2c2018-08-31 09:22:23 +0100437 wlActiv1_0, wlActiv1_1);
telsoa014fcda012018-03-09 14:13:49 +0000438
439 armnn::INeonTensorHandle* sOut0 = dynamic_cast<armnn::INeonTensorHandle*>(wlSplitter->GetData().m_Outputs[0]);
440 armnn::INeonTensorHandle* sOut1 = dynamic_cast<armnn::INeonTensorHandle*>(wlSplitter->GetData().m_Outputs[1]);
441 armnn::INeonTensorHandle* activ0_0Im = dynamic_cast<armnn::INeonTensorHandle*>(wlActiv0_0->GetData().m_Inputs[0]);
442 armnn::INeonTensorHandle* activ0_1Im = dynamic_cast<armnn::INeonTensorHandle*>(wlActiv0_1->GetData().m_Inputs[0]);
443 armnn::INeonTensorHandle* activ1_0Im = dynamic_cast<armnn::INeonTensorHandle*>(wlActiv1_0->GetData().m_Inputs[0]);
444 armnn::INeonTensorHandle* activ1_1Im = dynamic_cast<armnn::INeonTensorHandle*>(wlActiv1_1->GetData().m_Inputs[0]);
445
446
447 BOOST_TEST(sOut0);
448 BOOST_TEST(sOut1);
449 BOOST_TEST(activ0_0Im);
450 BOOST_TEST(activ0_1Im);
451 BOOST_TEST(activ1_0Im);
452 BOOST_TEST(activ1_1Im);
453
454 bool validDataPointers = (sOut0 == activ0_0Im) && (sOut0 == activ0_1Im) &&
455 (sOut1 == activ1_0Im) && (sOut1 == activ1_1Im);
456
457 BOOST_TEST(validDataPointers);
458}
459
460BOOST_AUTO_TEST_CASE(CreateMemCopyWorkloadsNeon)
461{
462 NeonWorkloadFactory factory;
telsoa01c577f2c2018-08-31 09:22:23 +0100463 CreateMemCopyWorkloads<INeonTensorHandle>(factory);
telsoa014fcda012018-03-09 14:13:49 +0000464}
465
Matteo Martincighbcd3c852018-09-28 14:14:12 +0100466template <typename L2NormalizationWorkloadType, typename armnn::DataType DataType>
467static void NeonCreateL2NormalizationWorkloadTest(DataLayout dataLayout)
468{
469 Graph graph;
470 NeonWorkloadFactory factory;
471 auto workload = CreateL2NormalizationWorkloadTest<L2NormalizationWorkloadType,
472 DataType>(factory, graph, dataLayout);
473
474 // Checks that inputs/outputs are as we expect them (see definition of CreateNormalizationWorkloadTest).
475 L2NormalizationQueueDescriptor queueDescriptor = workload->GetData();
476 auto inputHandle = boost::polymorphic_downcast<INeonTensorHandle*>(queueDescriptor.m_Inputs[0]);
477 auto outputHandle = boost::polymorphic_downcast<INeonTensorHandle*>(queueDescriptor.m_Outputs[0]);
478 BOOST_TEST(TestNeonTensorHandleInfo(inputHandle, TensorInfo({ 5, 20, 50, 67 }, DataType)));
479 BOOST_TEST(TestNeonTensorHandleInfo(outputHandle, TensorInfo({ 5, 20, 50, 67 }, DataType)));
480}
481
482#ifdef __ARM_FEATURE_FP16_VECTOR_ARITHMETIC
483BOOST_AUTO_TEST_CASE(CreateL2NormalizationFloat16NchwWorkload)
484{
485 NeonCreateL2NormalizationWorkloadTest<NeonL2NormalizationFloatWorkload, DataType::Float16>(DataLayout::NCHW);
486}
487
488BOOST_AUTO_TEST_CASE(CreateL2NormalizationFloat16NhwcWorkload)
489{
490 NeonCreateL2NormalizationWorkloadTest<NeonL2NormalizationFloatWorkload, DataType::Float16>(DataLayout::NHWC);
491}
492#endif
493
494BOOST_AUTO_TEST_CASE(CreateL2NormalizationNchwWorkload)
495{
496 NeonCreateL2NormalizationWorkloadTest<NeonL2NormalizationFloatWorkload, DataType::Float32>(DataLayout::NCHW);
497}
498
499BOOST_AUTO_TEST_CASE(CreateL2NormalizationNhwcWorkload)
500{
501 NeonCreateL2NormalizationWorkloadTest<NeonL2NormalizationFloatWorkload, DataType::Float32>(DataLayout::NHWC);
502}
503
telsoa014fcda012018-03-09 14:13:49 +0000504BOOST_AUTO_TEST_SUITE_END()