blob: e9fcb56d1770252783425ef484f91f3d808c947b [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>
238static void NeonCreateNormalizationWorkloadTest()
telsoa014fcda012018-03-09 14:13:49 +0000239{
240 Graph graph;
241 NeonWorkloadFactory factory;
telsoa01c577f2c2018-08-31 09:22:23 +0100242 auto workload = CreateNormalizationWorkloadTest<NormalizationWorkloadType, DataType>(factory, graph);
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
253BOOST_AUTO_TEST_CASE(CreateNormalizationFloat16Workload)
254{
arovir019e53a352018-08-31 15:26:35 +0100255 NeonCreateNormalizationWorkloadTest<NeonNormalizationFloatWorkload, DataType::Float16>();
telsoa01c577f2c2018-08-31 09:22:23 +0100256}
257#endif
258
arovir019e53a352018-08-31 15:26:35 +0100259BOOST_AUTO_TEST_CASE(CreateNormalizationFloatWorkload)
telsoa01c577f2c2018-08-31 09:22:23 +0100260{
arovir019e53a352018-08-31 15:26:35 +0100261 NeonCreateNormalizationWorkloadTest<NeonNormalizationFloatWorkload, DataType::Float32>();
telsoa01c577f2c2018-08-31 09:22:23 +0100262}
263
264template <typename Pooling2dWorkloadType, typename armnn::DataType DataType>
265static void NeonCreatePooling2dWorkloadTest()
telsoa014fcda012018-03-09 14:13:49 +0000266{
267 Graph graph;
268 NeonWorkloadFactory factory;
telsoa01c577f2c2018-08-31 09:22:23 +0100269 auto workload = CreatePooling2dWorkloadTest<Pooling2dWorkloadType, DataType>
270 (factory, graph);
telsoa014fcda012018-03-09 14:13:49 +0000271
telsoa01c577f2c2018-08-31 09:22:23 +0100272 // Checks that outputs and inputs are as we expect them (see definition of CreatePooling2dWorkloadTest).
telsoa014fcda012018-03-09 14:13:49 +0000273 Pooling2dQueueDescriptor queueDescriptor = workload->GetData();
274 auto inputHandle = boost::polymorphic_downcast<INeonTensorHandle*>(queueDescriptor.m_Inputs[0]);
275 auto outputHandle = boost::polymorphic_downcast<INeonTensorHandle*>(queueDescriptor.m_Outputs[0]);
telsoa01c577f2c2018-08-31 09:22:23 +0100276 BOOST_TEST(TestNeonTensorHandleInfo(inputHandle, TensorInfo({3, 2, 5, 5}, DataType)));
277 BOOST_TEST(TestNeonTensorHandleInfo(outputHandle, TensorInfo({3, 2, 2, 4}, DataType)));
telsoa014fcda012018-03-09 14:13:49 +0000278}
279
telsoa01c577f2c2018-08-31 09:22:23 +0100280#ifdef __ARM_FEATURE_FP16_VECTOR_ARITHMETIC
281BOOST_AUTO_TEST_CASE(CreatePooling2dFloat16Workload)
282{
arovir019e53a352018-08-31 15:26:35 +0100283 NeonCreatePooling2dWorkloadTest<NeonPooling2dFloatWorkload, DataType::Float16>();
telsoa01c577f2c2018-08-31 09:22:23 +0100284}
285#endif
286
arovir019e53a352018-08-31 15:26:35 +0100287BOOST_AUTO_TEST_CASE(CreatePooling2dFloatWorkload)
telsoa01c577f2c2018-08-31 09:22:23 +0100288{
arovir019e53a352018-08-31 15:26:35 +0100289 NeonCreatePooling2dWorkloadTest<NeonPooling2dFloatWorkload, DataType::Float32>();
telsoa01c577f2c2018-08-31 09:22:23 +0100290}
291
292BOOST_AUTO_TEST_CASE(CreatePooling2dUint8Workload)
293{
294 NeonCreatePooling2dWorkloadTest<NeonPooling2dUint8Workload, DataType::QuantisedAsymm8>();
295}
296
297template <typename ReshapeWorkloadType, typename armnn::DataType DataType>
298static void NeonCreateReshapeWorkloadTest()
telsoa014fcda012018-03-09 14:13:49 +0000299{
300 Graph graph;
301 NeonWorkloadFactory factory;
telsoa01c577f2c2018-08-31 09:22:23 +0100302 auto workload = CreateReshapeWorkloadTest<ReshapeWorkloadType, DataType>(factory, graph);
telsoa014fcda012018-03-09 14:13:49 +0000303
telsoa01c577f2c2018-08-31 09:22:23 +0100304 // Checks that outputs and inputs are as we expect them (see definition of CreateReshapeWorkloadTest).
telsoa014fcda012018-03-09 14:13:49 +0000305 ReshapeQueueDescriptor queueDescriptor = workload->GetData();
306 auto inputHandle = boost::polymorphic_downcast<INeonTensorHandle*>(queueDescriptor.m_Inputs[0]);
307 auto outputHandle = boost::polymorphic_downcast<INeonTensorHandle*>(queueDescriptor.m_Outputs[0]);
telsoa01c577f2c2018-08-31 09:22:23 +0100308 BOOST_TEST(TestNeonTensorHandleInfo(inputHandle, TensorInfo({4, 1}, DataType)));
309 BOOST_TEST(TestNeonTensorHandleInfo(outputHandle, TensorInfo({1, 4}, DataType)));
telsoa014fcda012018-03-09 14:13:49 +0000310}
311
telsoa01c577f2c2018-08-31 09:22:23 +0100312#ifdef __ARM_FEATURE_FP16_VECTOR_ARITHMETIC
313BOOST_AUTO_TEST_CASE(CreateReshapeFloat16Workload)
314{
arovir019e53a352018-08-31 15:26:35 +0100315 NeonCreateReshapeWorkloadTest<NeonReshapeFloatWorkload, DataType::Float16>();
telsoa01c577f2c2018-08-31 09:22:23 +0100316}
317#endif
318
arovir019e53a352018-08-31 15:26:35 +0100319BOOST_AUTO_TEST_CASE(CreateReshapeFloatWorkload)
telsoa014fcda012018-03-09 14:13:49 +0000320{
arovir019e53a352018-08-31 15:26:35 +0100321 NeonCreateReshapeWorkloadTest<NeonReshapeFloatWorkload, DataType::Float32>();
telsoa014fcda012018-03-09 14:13:49 +0000322}
323
324BOOST_AUTO_TEST_CASE(CreateReshapeUint8Workload)
325{
telsoa01c577f2c2018-08-31 09:22:23 +0100326 NeonCreateReshapeWorkloadTest<NeonReshapeUint8Workload, DataType::QuantisedAsymm8>();
telsoa014fcda012018-03-09 14:13:49 +0000327}
328
telsoa01c577f2c2018-08-31 09:22:23 +0100329template <typename SoftmaxWorkloadType, typename armnn::DataType DataType>
330static void NeonCreateSoftmaxWorkloadTest()
telsoa014fcda012018-03-09 14:13:49 +0000331{
332 Graph graph;
333 NeonWorkloadFactory factory;
telsoa01c577f2c2018-08-31 09:22:23 +0100334 auto workload = CreateSoftmaxWorkloadTest<SoftmaxWorkloadType, DataType>(factory, graph);
telsoa014fcda012018-03-09 14:13:49 +0000335
telsoa01c577f2c2018-08-31 09:22:23 +0100336 // Checks that outputs and inputs are as we expect them (see definition of CreateSoftmaxWorkloadTest).
telsoa014fcda012018-03-09 14:13:49 +0000337 SoftmaxQueueDescriptor queueDescriptor = workload->GetData();
338 auto inputHandle = boost::polymorphic_downcast<INeonTensorHandle*>(queueDescriptor.m_Inputs[0]);
339 auto outputHandle = boost::polymorphic_downcast<INeonTensorHandle*>(queueDescriptor.m_Outputs[0]);
telsoa01c577f2c2018-08-31 09:22:23 +0100340 BOOST_TEST(TestNeonTensorHandleInfo(inputHandle, TensorInfo({4, 1}, DataType)));
341 BOOST_TEST(TestNeonTensorHandleInfo(outputHandle, TensorInfo({4, 1}, DataType)));
342}
343
344#ifdef __ARM_FEATURE_FP16_VECTOR_ARITHMETIC
345BOOST_AUTO_TEST_CASE(CreateSoftmaxFloat16Workload)
346{
arovir019e53a352018-08-31 15:26:35 +0100347 NeonCreateSoftmaxWorkloadTest<NeonSoftmaxFloatWorkload, DataType::Float16>();
telsoa01c577f2c2018-08-31 09:22:23 +0100348}
349#endif
350
arovir019e53a352018-08-31 15:26:35 +0100351BOOST_AUTO_TEST_CASE(CreateSoftmaxFloatWorkload)
telsoa01c577f2c2018-08-31 09:22:23 +0100352{
arovir019e53a352018-08-31 15:26:35 +0100353 NeonCreateSoftmaxWorkloadTest<NeonSoftmaxFloatWorkload, DataType::Float32>();
telsoa014fcda012018-03-09 14:13:49 +0000354}
355
356BOOST_AUTO_TEST_CASE(CreateSplitterWorkload)
357{
358 Graph graph;
359 NeonWorkloadFactory factory;
arovir019e53a352018-08-31 15:26:35 +0100360 auto workload = CreateSplitterWorkloadTest<NeonSplitterFloatWorkload, DataType::Float32>(factory, graph);
telsoa014fcda012018-03-09 14:13:49 +0000361
telsoa01c577f2c2018-08-31 09:22:23 +0100362 // Checks that outputs are as we expect them (see definition of CreateSplitterWorkloadTest).
telsoa014fcda012018-03-09 14:13:49 +0000363 SplitterQueueDescriptor queueDescriptor = workload->GetData();
364 auto inputHandle = boost::polymorphic_downcast<INeonTensorHandle*>(queueDescriptor.m_Inputs[0]);
surmeh013537c2c2018-05-18 16:31:43 +0100365 BOOST_TEST(TestNeonTensorHandleInfo(inputHandle, TensorInfo({5, 7, 7}, DataType::Float32)));
366
telsoa014fcda012018-03-09 14:13:49 +0000367 auto outputHandle0 = boost::polymorphic_downcast<INeonTensorHandle*>(queueDescriptor.m_Outputs[0]);
surmeh013537c2c2018-05-18 16:31:43 +0100368 BOOST_TEST(TestNeonTensorHandleInfo(outputHandle0, TensorInfo({1, 7, 7}, DataType::Float32)));
369
telsoa014fcda012018-03-09 14:13:49 +0000370 auto outputHandle1 = boost::polymorphic_downcast<INeonTensorHandle*>(queueDescriptor.m_Outputs[1]);
surmeh013537c2c2018-05-18 16:31:43 +0100371 BOOST_TEST(TestNeonTensorHandleInfo(outputHandle1, TensorInfo({2, 7, 7}, DataType::Float32)));
372
telsoa014fcda012018-03-09 14:13:49 +0000373 auto outputHandle2 = boost::polymorphic_downcast<INeonTensorHandle*>(queueDescriptor.m_Outputs[2]);
surmeh013537c2c2018-05-18 16:31:43 +0100374 BOOST_TEST(TestNeonTensorHandleInfo(outputHandle2, TensorInfo({2, 7, 7}, DataType::Float32)));
telsoa014fcda012018-03-09 14:13:49 +0000375}
376
377BOOST_AUTO_TEST_CASE(CreateSplitterMerger)
378{
telsoa01c577f2c2018-08-31 09:22:23 +0100379 // Tests that it is possible to decide which output of the splitter layer
380 // should be lined to which input of the merger layer.
381 // We tested that is is possible to specify 0th output
382 // 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 +0000383 // of the merger.
384
385 Graph graph;
386 NeonWorkloadFactory factory;
387
388 auto workloads =
arovir019e53a352018-08-31 15:26:35 +0100389 CreateSplitterMergerWorkloadTest<NeonSplitterFloatWorkload, NeonMergerFloatWorkload,
telsoa01c577f2c2018-08-31 09:22:23 +0100390 DataType::Float32>(factory, graph);
telsoa014fcda012018-03-09 14:13:49 +0000391
392 auto wlSplitter = std::move(workloads.first);
393 auto wlMerger = std::move(workloads.second);
394
telsoa01c577f2c2018-08-31 09:22:23 +0100395 //Checks that the index of inputs/outputs matches what we declared on InputDescriptor construction.
telsoa014fcda012018-03-09 14:13:49 +0000396 armnn::INeonTensorHandle* sOut0 = dynamic_cast<armnn::INeonTensorHandle*>(wlSplitter->GetData().m_Outputs[0]);
397 armnn::INeonTensorHandle* sOut1 = dynamic_cast<armnn::INeonTensorHandle*>(wlSplitter->GetData().m_Outputs[1]);
398 armnn::INeonTensorHandle* mIn0 = dynamic_cast<armnn::INeonTensorHandle*>(wlMerger->GetData().m_Inputs[0]);
399 armnn::INeonTensorHandle* mIn1 = dynamic_cast<armnn::INeonTensorHandle*>(wlMerger->GetData().m_Inputs[1]);
400
401 BOOST_TEST(sOut0);
402 BOOST_TEST(sOut1);
403 BOOST_TEST(mIn0);
404 BOOST_TEST(mIn1);
405
406 bool validDataPointers = (sOut0 == mIn1) && (sOut1 == mIn0);
407
408 BOOST_TEST(validDataPointers);
409}
410
411BOOST_AUTO_TEST_CASE(CreateSingleOutputMultipleInputs)
412{
telsoa01c577f2c2018-08-31 09:22:23 +0100413 // Tests that it is possible to assign multiple (two) different layers to each of the outputs of a splitter layer.
414 // 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 +0000415
416 Graph graph;
417 NeonWorkloadFactory factory;
arovir019e53a352018-08-31 15:26:35 +0100418 std::unique_ptr<NeonSplitterFloatWorkload> wlSplitter;
419 std::unique_ptr<NeonActivationFloatWorkload> wlActiv0_0;
420 std::unique_ptr<NeonActivationFloatWorkload> wlActiv0_1;
421 std::unique_ptr<NeonActivationFloatWorkload> wlActiv1_0;
422 std::unique_ptr<NeonActivationFloatWorkload> wlActiv1_1;
telsoa014fcda012018-03-09 14:13:49 +0000423
arovir019e53a352018-08-31 15:26:35 +0100424 CreateSplitterMultipleInputsOneOutputWorkloadTest<NeonSplitterFloatWorkload,
425 NeonActivationFloatWorkload, DataType::Float32>(factory, graph, wlSplitter, wlActiv0_0, wlActiv0_1,
telsoa01c577f2c2018-08-31 09:22:23 +0100426 wlActiv1_0, wlActiv1_1);
telsoa014fcda012018-03-09 14:13:49 +0000427
428 armnn::INeonTensorHandle* sOut0 = dynamic_cast<armnn::INeonTensorHandle*>(wlSplitter->GetData().m_Outputs[0]);
429 armnn::INeonTensorHandle* sOut1 = dynamic_cast<armnn::INeonTensorHandle*>(wlSplitter->GetData().m_Outputs[1]);
430 armnn::INeonTensorHandle* activ0_0Im = dynamic_cast<armnn::INeonTensorHandle*>(wlActiv0_0->GetData().m_Inputs[0]);
431 armnn::INeonTensorHandle* activ0_1Im = dynamic_cast<armnn::INeonTensorHandle*>(wlActiv0_1->GetData().m_Inputs[0]);
432 armnn::INeonTensorHandle* activ1_0Im = dynamic_cast<armnn::INeonTensorHandle*>(wlActiv1_0->GetData().m_Inputs[0]);
433 armnn::INeonTensorHandle* activ1_1Im = dynamic_cast<armnn::INeonTensorHandle*>(wlActiv1_1->GetData().m_Inputs[0]);
434
435
436 BOOST_TEST(sOut0);
437 BOOST_TEST(sOut1);
438 BOOST_TEST(activ0_0Im);
439 BOOST_TEST(activ0_1Im);
440 BOOST_TEST(activ1_0Im);
441 BOOST_TEST(activ1_1Im);
442
443 bool validDataPointers = (sOut0 == activ0_0Im) && (sOut0 == activ0_1Im) &&
444 (sOut1 == activ1_0Im) && (sOut1 == activ1_1Im);
445
446 BOOST_TEST(validDataPointers);
447}
448
449BOOST_AUTO_TEST_CASE(CreateMemCopyWorkloadsNeon)
450{
451 NeonWorkloadFactory factory;
telsoa01c577f2c2018-08-31 09:22:23 +0100452 CreateMemCopyWorkloads<INeonTensorHandle>(factory);
telsoa014fcda012018-03-09 14:13:49 +0000453}
454
Matteo Martincighbcd3c852018-09-28 14:14:12 +0100455template <typename L2NormalizationWorkloadType, typename armnn::DataType DataType>
456static void NeonCreateL2NormalizationWorkloadTest(DataLayout dataLayout)
457{
458 Graph graph;
459 NeonWorkloadFactory factory;
460 auto workload = CreateL2NormalizationWorkloadTest<L2NormalizationWorkloadType,
461 DataType>(factory, graph, dataLayout);
462
463 // Checks that inputs/outputs are as we expect them (see definition of CreateNormalizationWorkloadTest).
464 L2NormalizationQueueDescriptor queueDescriptor = workload->GetData();
465 auto inputHandle = boost::polymorphic_downcast<INeonTensorHandle*>(queueDescriptor.m_Inputs[0]);
466 auto outputHandle = boost::polymorphic_downcast<INeonTensorHandle*>(queueDescriptor.m_Outputs[0]);
467 BOOST_TEST(TestNeonTensorHandleInfo(inputHandle, TensorInfo({ 5, 20, 50, 67 }, DataType)));
468 BOOST_TEST(TestNeonTensorHandleInfo(outputHandle, TensorInfo({ 5, 20, 50, 67 }, DataType)));
469}
470
471#ifdef __ARM_FEATURE_FP16_VECTOR_ARITHMETIC
472BOOST_AUTO_TEST_CASE(CreateL2NormalizationFloat16NchwWorkload)
473{
474 NeonCreateL2NormalizationWorkloadTest<NeonL2NormalizationFloatWorkload, DataType::Float16>(DataLayout::NCHW);
475}
476
477BOOST_AUTO_TEST_CASE(CreateL2NormalizationFloat16NhwcWorkload)
478{
479 NeonCreateL2NormalizationWorkloadTest<NeonL2NormalizationFloatWorkload, DataType::Float16>(DataLayout::NHWC);
480}
481#endif
482
483BOOST_AUTO_TEST_CASE(CreateL2NormalizationNchwWorkload)
484{
485 NeonCreateL2NormalizationWorkloadTest<NeonL2NormalizationFloatWorkload, DataType::Float32>(DataLayout::NCHW);
486}
487
488BOOST_AUTO_TEST_CASE(CreateL2NormalizationNhwcWorkload)
489{
490 NeonCreateL2NormalizationWorkloadTest<NeonL2NormalizationFloatWorkload, DataType::Float32>(DataLayout::NHWC);
491}
492
telsoa014fcda012018-03-09 14:13:49 +0000493BOOST_AUTO_TEST_SUITE_END()