blob: 99ff9ae8b82106085b94c5131dfeb83b9f714f25 [file] [log] [blame]
telsoa014fcda012018-03-09 14:13:49 +00001//
Keith Davis69e653f2020-07-02 11:49:26 +01002// Copyright © 2017 Arm Ltd and Contributors. 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
Francis Murtagh4fc3c482019-08-02 13:20:54 +01008#include <aclCommon/ArmComputeTensorUtils.hpp>
Sadik Armagan04a72972020-09-14 15:44:18 +01009#include <armnn/utility/Assert.hpp>
10#include <armnn/utility/IgnoreUnused.hpp>
Jan Eilersbb446e52020-04-02 13:56:54 +010011#include <armnn/utility/PolymorphicDowncast.hpp>
Aron Virginas-Tarc9cc8042018-11-01 16:15:57 +000012#include <backendsCommon/MemCopyWorkload.hpp>
Aron Virginas-Tar3b278e92018-10-12 13:00:55 +010013
Aron Virginas-Tarc9cc8042018-11-01 16:15:57 +000014#include <aclCommon/test/CreateWorkloadClNeon.hpp>
Aron Virginas-Tar3b278e92018-10-12 13:00:55 +010015
Aron Virginas-Tarc9cc8042018-11-01 16:15:57 +000016#include <neon/NeonWorkloadFactory.hpp>
17#include <neon/NeonTensorHandle.hpp>
18#include <neon/workloads/NeonWorkloadUtils.hpp>
19#include <neon/workloads/NeonWorkloads.hpp>
telsoa014fcda012018-03-09 14:13:49 +000020
21BOOST_AUTO_TEST_SUITE(CreateWorkloadNeon)
22
23namespace
24{
25
Ellen Norris-Thompson37e68682019-07-15 14:23:30 +010026boost::test_tools::predicate_result CompareIAclTensorHandleShape(IAclTensorHandle* tensorHandle,
27 std::initializer_list<unsigned int> expectedDimensions)
28{
29 return CompareTensorHandleShape<IAclTensorHandle>(tensorHandle, expectedDimensions);
30}
31
Derek Lambertic81855f2019-06-13 17:34:19 +010032bool TestNeonTensorHandleInfo(armnn::IAclTensorHandle* handle, const armnn::TensorInfo& expectedInfo)
telsoa014fcda012018-03-09 14:13:49 +000033{
34 using namespace armnn::armcomputetensorutils;
35
36 const arm_compute::ITensorInfo* handleInfo = handle->GetTensor().info();
37 const arm_compute::TensorInfo expectedAclInfo = BuildArmComputeTensorInfo(expectedInfo);
38
39 if (handleInfo->data_type() != expectedAclInfo.data_type())
40 {
41 return false;
42 }
43
44 if (handleInfo->num_dimensions() != expectedAclInfo.num_dimensions())
45 {
46 return false;
47 }
48
49 if (handleInfo->quantization_info() != expectedAclInfo.quantization_info())
50 {
51 return false;
52 }
53
54 for (std::size_t d = 0; d < expectedAclInfo.num_dimensions(); ++d)
55 {
56 if (handleInfo->dimension(d) != expectedAclInfo.dimension(d))
57 {
58 return false;
59 }
60 }
61
62 return true;
63}
64
65} // namespace
66
Nattapat Chaimanowongd4b70592018-10-12 11:21:49 +010067template <typename armnn::DataType DataType>
telsoa01c577f2c2018-08-31 09:22:23 +010068static void NeonCreateActivationWorkloadTest()
telsoa014fcda012018-03-09 14:13:49 +000069{
70 Graph graph;
Aron Virginas-Tar5caf9072018-11-14 18:35:18 +000071 NeonWorkloadFactory factory =
72 NeonWorkloadFactoryHelper::GetFactory(NeonWorkloadFactoryHelper::GetMemoryManager());
73
Nattapat Chaimanowongd4b70592018-10-12 11:21:49 +010074 auto workload = CreateActivationWorkloadTest<NeonActivationWorkload, DataType>(factory, graph);
telsoa014fcda012018-03-09 14:13:49 +000075
telsoa01c577f2c2018-08-31 09:22:23 +010076 // Checks that inputs/outputs are as we expect them (see definition of CreateActivationWorkloadTest).
telsoa014fcda012018-03-09 14:13:49 +000077 ActivationQueueDescriptor queueDescriptor = workload->GetData();
Jan Eilersbb446e52020-04-02 13:56:54 +010078 auto inputHandle = PolymorphicDowncast<IAclTensorHandle*>(queueDescriptor.m_Inputs[0]);
79 auto outputHandle = PolymorphicDowncast<IAclTensorHandle*>(queueDescriptor.m_Outputs[0]);
telsoa01c577f2c2018-08-31 09:22:23 +010080 BOOST_TEST(TestNeonTensorHandleInfo(inputHandle, TensorInfo({1, 1}, DataType)));
81 BOOST_TEST(TestNeonTensorHandleInfo(outputHandle, TensorInfo({1, 1}, DataType)));
telsoa014fcda012018-03-09 14:13:49 +000082}
83
telsoa01c577f2c2018-08-31 09:22:23 +010084#ifdef __ARM_FEATURE_FP16_VECTOR_ARITHMETIC
85BOOST_AUTO_TEST_CASE(CreateActivationFloat16Workload)
86{
Nattapat Chaimanowongd4b70592018-10-12 11:21:49 +010087 NeonCreateActivationWorkloadTest<DataType::Float16>();
telsoa01c577f2c2018-08-31 09:22:23 +010088}
89#endif
90
arovir019e53a352018-08-31 15:26:35 +010091BOOST_AUTO_TEST_CASE(CreateActivationFloatWorkload)
telsoa01c577f2c2018-08-31 09:22:23 +010092{
Nattapat Chaimanowongd4b70592018-10-12 11:21:49 +010093 NeonCreateActivationWorkloadTest<DataType::Float32>();
telsoa01c577f2c2018-08-31 09:22:23 +010094}
95
David Beckbc392452018-09-10 14:47:28 +010096template <typename WorkloadType,
97 typename DescriptorType,
98 typename LayerType,
99 armnn::DataType DataType>
Éanna Ó Catháind57415d2018-11-28 16:24:38 +0000100static void NeonCreateElementwiseWorkloadTest()
telsoa014fcda012018-03-09 14:13:49 +0000101{
David Beckbc392452018-09-10 14:47:28 +0100102 Graph graph;
Aron Virginas-Tar5caf9072018-11-14 18:35:18 +0000103 NeonWorkloadFactory factory =
104 NeonWorkloadFactoryHelper::GetFactory(NeonWorkloadFactoryHelper::GetMemoryManager());
105
Éanna Ó Catháind57415d2018-11-28 16:24:38 +0000106 auto workload = CreateElementwiseWorkloadTest<WorkloadType, DescriptorType, LayerType, DataType>(factory, graph);
telsoa014fcda012018-03-09 14:13:49 +0000107
David Beckbc392452018-09-10 14:47:28 +0100108 DescriptorType queueDescriptor = workload->GetData();
Jan Eilersbb446e52020-04-02 13:56:54 +0100109 auto inputHandle1 = PolymorphicDowncast<IAclTensorHandle*>(queueDescriptor.m_Inputs[0]);
110 auto inputHandle2 = PolymorphicDowncast<IAclTensorHandle*>(queueDescriptor.m_Inputs[1]);
111 auto outputHandle = PolymorphicDowncast<IAclTensorHandle*>(queueDescriptor.m_Outputs[0]);
telsoa01c577f2c2018-08-31 09:22:23 +0100112 BOOST_TEST(TestNeonTensorHandleInfo(inputHandle1, TensorInfo({2, 3}, DataType)));
113 BOOST_TEST(TestNeonTensorHandleInfo(inputHandle2, TensorInfo({2, 3}, DataType)));
114 BOOST_TEST(TestNeonTensorHandleInfo(outputHandle, TensorInfo({2, 3}, DataType)));
telsoa014fcda012018-03-09 14:13:49 +0000115}
116
telsoa01c577f2c2018-08-31 09:22:23 +0100117#ifdef __ARM_FEATURE_FP16_VECTOR_ARITHMETIC
118BOOST_AUTO_TEST_CASE(CreateAdditionFloat16Workload)
119{
Matthew Bentham955258d2018-12-10 10:48:52 +0000120 NeonCreateElementwiseWorkloadTest<NeonAdditionWorkload,
David Beckbc392452018-09-10 14:47:28 +0100121 AdditionQueueDescriptor,
122 AdditionLayer,
123 DataType::Float16>();
telsoa01c577f2c2018-08-31 09:22:23 +0100124}
125#endif
126
arovir019e53a352018-08-31 15:26:35 +0100127BOOST_AUTO_TEST_CASE(CreateAdditionFloatWorkload)
telsoa01c577f2c2018-08-31 09:22:23 +0100128{
Matthew Bentham955258d2018-12-10 10:48:52 +0000129 NeonCreateElementwiseWorkloadTest<NeonAdditionWorkload,
David Beckbc392452018-09-10 14:47:28 +0100130 AdditionQueueDescriptor,
131 AdditionLayer,
132 DataType::Float32>();
133}
134
135#ifdef __ARM_FEATURE_FP16_VECTOR_ARITHMETIC
136BOOST_AUTO_TEST_CASE(CreateSubtractionFloat16Workload)
137{
Conor Kennedyb99480b2019-03-08 08:24:41 +0000138 NeonCreateElementwiseWorkloadTest<NeonSubtractionWorkload,
David Beckbc392452018-09-10 14:47:28 +0100139 SubtractionQueueDescriptor,
140 SubtractionLayer,
141 DataType::Float16>();
142}
143#endif
144
145BOOST_AUTO_TEST_CASE(CreateSubtractionFloatWorkload)
146{
Conor Kennedyb99480b2019-03-08 08:24:41 +0000147 NeonCreateElementwiseWorkloadTest<NeonSubtractionWorkload,
David Beckbc392452018-09-10 14:47:28 +0100148 SubtractionQueueDescriptor,
149 SubtractionLayer,
150 DataType::Float32>();
151}
152
Conor Kennedyb99480b2019-03-08 08:24:41 +0000153BOOST_AUTO_TEST_CASE(CreateSubtractionUint8Workload)
154{
155 NeonCreateElementwiseWorkloadTest<NeonSubtractionWorkload,
156 SubtractionQueueDescriptor,
157 SubtractionLayer,
Derek Lambertif90c56d2020-01-10 17:14:08 +0000158 DataType::QAsymmU8>();
Conor Kennedyb99480b2019-03-08 08:24:41 +0000159}
160
David Beckbc392452018-09-10 14:47:28 +0100161#ifdef __ARM_FEATURE_FP16_VECTOR_ARITHMETIC
162BOOST_AUTO_TEST_CASE(CreateMultiplicationFloat16Workload)
163{
Conor Kennedyb99480b2019-03-08 08:24:41 +0000164 NeonCreateElementwiseWorkloadTest<NeonMultiplicationWorkload,
David Beckbc392452018-09-10 14:47:28 +0100165 MultiplicationQueueDescriptor,
166 MultiplicationLayer,
167 DataType::Float16>();
168}
169#endif
170
171BOOST_AUTO_TEST_CASE(CreateMultiplicationFloatWorkload)
172{
Conor Kennedyb99480b2019-03-08 08:24:41 +0000173 NeonCreateElementwiseWorkloadTest<NeonMultiplicationWorkload,
David Beckbc392452018-09-10 14:47:28 +0100174 MultiplicationQueueDescriptor,
175 MultiplicationLayer,
176 DataType::Float32>();
telsoa01c577f2c2018-08-31 09:22:23 +0100177}
178
Conor Kennedyb99480b2019-03-08 08:24:41 +0000179BOOST_AUTO_TEST_CASE(CreateMultiplicationUint8Workload)
180{
181 NeonCreateElementwiseWorkloadTest<NeonMultiplicationWorkload,
182 MultiplicationQueueDescriptor,
183 MultiplicationLayer,
Derek Lambertif90c56d2020-01-10 17:14:08 +0000184 DataType::QAsymmU8>();
Conor Kennedyb99480b2019-03-08 08:24:41 +0000185}
186
Pablo Telloe61f0712020-01-23 10:37:17 +0000187BOOST_AUTO_TEST_CASE(CreateDivisionFloatWorkloadTest)
188{
189 NeonCreateElementwiseWorkloadTest<NeonDivisionWorkload,
190 DivisionQueueDescriptor,
191 DivisionLayer,
192 armnn::DataType::Float32>();
193}
194
telsoa01c577f2c2018-08-31 09:22:23 +0100195template <typename BatchNormalizationWorkloadType, typename armnn::DataType DataType>
Nikhil Rajd1340932018-10-18 14:27:50 +0100196static void NeonCreateBatchNormalizationWorkloadTest(DataLayout dataLayout)
telsoa014fcda012018-03-09 14:13:49 +0000197{
Aron Virginas-Tar5caf9072018-11-14 18:35:18 +0000198 Graph graph;
199 NeonWorkloadFactory factory =
200 NeonWorkloadFactoryHelper::GetFactory(NeonWorkloadFactoryHelper::GetMemoryManager());
201
Nikhil Rajd1340932018-10-18 14:27:50 +0100202 auto workload = CreateBatchNormalizationWorkloadTest<BatchNormalizationWorkloadType, DataType>
203 (factory, graph, dataLayout);
telsoa014fcda012018-03-09 14:13:49 +0000204
telsoa01c577f2c2018-08-31 09:22:23 +0100205 // Checks that outputs and inputs are as we expect them (see definition of CreateBatchNormalizationWorkloadTest).
telsoa014fcda012018-03-09 14:13:49 +0000206 BatchNormalizationQueueDescriptor queueDescriptor = workload->GetData();
Jan Eilersbb446e52020-04-02 13:56:54 +0100207 auto inputHandle = PolymorphicDowncast<IAclTensorHandle*>(queueDescriptor.m_Inputs[0]);
208 auto outputHandle = PolymorphicDowncast<IAclTensorHandle*>(queueDescriptor.m_Outputs[0]);
Nikhil Rajd1340932018-10-18 14:27:50 +0100209
210 TensorShape inputShape = (dataLayout == DataLayout::NCHW) ? TensorShape{2, 3, 4, 4} : TensorShape{2, 4, 4, 3};
211 TensorShape outputShape = (dataLayout == DataLayout::NCHW) ? TensorShape{2, 3, 4, 4} : TensorShape{2, 4, 4, 3};
212
213 BOOST_TEST(TestNeonTensorHandleInfo(inputHandle, TensorInfo(inputShape, DataType)));
214 BOOST_TEST(TestNeonTensorHandleInfo(outputHandle, TensorInfo(outputShape, DataType)));
telsoa014fcda012018-03-09 14:13:49 +0000215}
216
telsoa01c577f2c2018-08-31 09:22:23 +0100217#ifdef __ARM_FEATURE_FP16_VECTOR_ARITHMETIC
Nikhil Rajd1340932018-10-18 14:27:50 +0100218BOOST_AUTO_TEST_CASE(CreateBatchNormalizationFloat16NchwWorkload)
telsoa01c577f2c2018-08-31 09:22:23 +0100219{
Matthew Benthamc48ac8c2018-12-12 16:15:59 +0000220 NeonCreateBatchNormalizationWorkloadTest<NeonBatchNormalizationWorkload, DataType::Float16>(DataLayout::NCHW);
Nikhil Rajd1340932018-10-18 14:27:50 +0100221}
222
223BOOST_AUTO_TEST_CASE(CreateBatchNormalizationFloat16NhwcWorkload)
224{
Matthew Benthamc48ac8c2018-12-12 16:15:59 +0000225 NeonCreateBatchNormalizationWorkloadTest<NeonBatchNormalizationWorkload, DataType::Float16>(DataLayout::NHWC);
telsoa01c577f2c2018-08-31 09:22:23 +0100226}
227#endif
228
Nikhil Rajd1340932018-10-18 14:27:50 +0100229BOOST_AUTO_TEST_CASE(CreateBatchNormalizationFloatNchwWorkload)
telsoa01c577f2c2018-08-31 09:22:23 +0100230{
Matthew Benthamc48ac8c2018-12-12 16:15:59 +0000231 NeonCreateBatchNormalizationWorkloadTest<NeonBatchNormalizationWorkload, DataType::Float32>(DataLayout::NCHW);
Nikhil Rajd1340932018-10-18 14:27:50 +0100232}
233
234BOOST_AUTO_TEST_CASE(CreateBatchNormalizationFloatNhwcWorkload)
235{
Matthew Benthamc48ac8c2018-12-12 16:15:59 +0000236 NeonCreateBatchNormalizationWorkloadTest<NeonBatchNormalizationWorkload, DataType::Float32>(DataLayout::NHWC);
telsoa01c577f2c2018-08-31 09:22:23 +0100237}
238
Nattapat Chaimanowong974b65f2018-10-15 15:07:34 +0100239template <typename armnn::DataType DataType>
Francis Murtagh0d9d4192018-10-09 16:22:33 +0100240static void NeonCreateConvolution2dWorkloadTest(DataLayout dataLayout = DataLayout::NCHW)
telsoa014fcda012018-03-09 14:13:49 +0000241{
Aron Virginas-Tar5caf9072018-11-14 18:35:18 +0000242 Graph graph;
243 NeonWorkloadFactory factory =
244 NeonWorkloadFactoryHelper::GetFactory(NeonWorkloadFactoryHelper::GetMemoryManager());
245
246 auto workload = CreateConvolution2dWorkloadTest<NeonConvolution2dWorkload, DataType>(factory, graph, dataLayout);
Francis Murtagh0d9d4192018-10-09 16:22:33 +0100247
248 TensorShape inputShape = (dataLayout == DataLayout::NCHW) ? TensorShape{2, 3, 8, 16} : TensorShape{2, 8, 16, 3};
249 TensorShape outputShape = (dataLayout == DataLayout::NCHW) ? TensorShape{2, 2, 2, 10} : TensorShape{2, 2, 10, 2};
telsoa014fcda012018-03-09 14:13:49 +0000250
telsoa01c577f2c2018-08-31 09:22:23 +0100251 // Checks that outputs and inputs are as we expect them (see definition of CreateConvolution2dWorkloadTest).
telsoa014fcda012018-03-09 14:13:49 +0000252 Convolution2dQueueDescriptor queueDescriptor = workload->GetData();
Jan Eilersbb446e52020-04-02 13:56:54 +0100253 auto inputHandle = PolymorphicDowncast<IAclTensorHandle*>(queueDescriptor.m_Inputs[0]);
254 auto outputHandle = PolymorphicDowncast<IAclTensorHandle*>(queueDescriptor.m_Outputs[0]);
Francis Murtagh0d9d4192018-10-09 16:22:33 +0100255 BOOST_TEST(TestNeonTensorHandleInfo(inputHandle, TensorInfo(inputShape, DataType)));
256 BOOST_TEST(TestNeonTensorHandleInfo(outputHandle, TensorInfo(outputShape, DataType)));
telsoa014fcda012018-03-09 14:13:49 +0000257}
258
telsoa01c577f2c2018-08-31 09:22:23 +0100259#ifdef __ARM_FEATURE_FP16_VECTOR_ARITHMETIC
Francis Murtagh0d9d4192018-10-09 16:22:33 +0100260BOOST_AUTO_TEST_CASE(CreateConvolution2dFloat16NchwWorkload)
telsoa01c577f2c2018-08-31 09:22:23 +0100261{
Nattapat Chaimanowong974b65f2018-10-15 15:07:34 +0100262 NeonCreateConvolution2dWorkloadTest<DataType::Float16>();
telsoa01c577f2c2018-08-31 09:22:23 +0100263}
telsoa01c577f2c2018-08-31 09:22:23 +0100264
Francis Murtagh0d9d4192018-10-09 16:22:33 +0100265BOOST_AUTO_TEST_CASE(CreateConvolution2dFloat16NhwcWorkload)
266{
Nattapat Chaimanowong974b65f2018-10-15 15:07:34 +0100267 NeonCreateConvolution2dWorkloadTest<DataType::Float16>(DataLayout::NHWC);
Francis Murtagh0d9d4192018-10-09 16:22:33 +0100268}
269
270#endif
271BOOST_AUTO_TEST_CASE(CreateConvolution2dFloatNchwWorkload)
telsoa01c577f2c2018-08-31 09:22:23 +0100272{
Nattapat Chaimanowong974b65f2018-10-15 15:07:34 +0100273 NeonCreateConvolution2dWorkloadTest<DataType::Float32>();
telsoa01c577f2c2018-08-31 09:22:23 +0100274}
275
Francis Murtagh0d9d4192018-10-09 16:22:33 +0100276BOOST_AUTO_TEST_CASE(CreateConvolution2dFloatNhwcWorkload)
277{
Nattapat Chaimanowong974b65f2018-10-15 15:07:34 +0100278 NeonCreateConvolution2dWorkloadTest<DataType::Float32>(DataLayout::NHWC);
Francis Murtagh0d9d4192018-10-09 16:22:33 +0100279}
280
Sadik Armagan04a72972020-09-14 15:44:18 +0100281BOOST_AUTO_TEST_CASE(CreateConvolution2dFastMathEnabledWorkload)
282{
283 Graph graph;
284 using ModelOptions = std::vector<BackendOptions>;
285 ModelOptions modelOptions = {};
286 BackendOptions cpuAcc("CpuAcc",
287 {
288 { "FastMathEnabled", true }
289 });
290 modelOptions.push_back(cpuAcc);
291 NeonWorkloadFactory factory =
292 NeonWorkloadFactoryHelper::GetFactory(NeonWorkloadFactoryHelper::GetMemoryManager(), modelOptions);
293
294 auto workload =
295 CreateConvolution2dWorkloadTest<NeonConvolution2dWorkload, armnn::DataType::Float32>(factory,
296 graph,
297 DataLayout::NCHW,
298 modelOptions);
299
300 ARMNN_ASSERT(workload != nullptr);
301 auto conv2dWorkload = PolymorphicDowncast<NeonConvolution2dWorkload*>(workload.get());
302 IgnoreUnused(conv2dWorkload);
303 ARMNN_ASSERT(conv2dWorkload != nullptr);
304 // fast_math enabled but configuration does not match with WINOGRAD
305 ARMNN_ASSERT(conv2dWorkload->GetConvolutionMethod() == arm_compute::ConvolutionMethod::GEMM);
306}
307
Nattapat Chaimanowong77140882018-10-17 11:12:19 +0100308template <typename armnn::DataType DataType>
Nikhil Rajcec6b652018-10-12 13:51:57 +0100309static void NeonCreateDepthWiseConvolutionWorkloadTest(DataLayout dataLayout)
310{
311 Graph graph;
Aron Virginas-Tar5caf9072018-11-14 18:35:18 +0000312 NeonWorkloadFactory factory =
313 NeonWorkloadFactoryHelper::GetFactory(NeonWorkloadFactoryHelper::GetMemoryManager());
Nikhil Rajcec6b652018-10-12 13:51:57 +0100314
Nattapat Chaimanowong77140882018-10-17 11:12:19 +0100315 auto workload = CreateDepthwiseConvolution2dWorkloadTest<NeonDepthwiseConvolutionWorkload,
Nikhil Rajcec6b652018-10-12 13:51:57 +0100316 DataType>(factory, graph, dataLayout);
317
318 // Checks that inputs/outputs are as we expect them (see definition of CreateNormalizationWorkloadTest).
319 DepthwiseConvolution2dQueueDescriptor queueDescriptor = workload->GetData();
Jan Eilersbb446e52020-04-02 13:56:54 +0100320 auto inputHandle = PolymorphicDowncast<IAclTensorHandle*>(queueDescriptor.m_Inputs[0]);
321 auto outputHandle = PolymorphicDowncast<IAclTensorHandle*>(queueDescriptor.m_Outputs[0]);
Nikhil Rajcec6b652018-10-12 13:51:57 +0100322
Mike Kellydb482882019-06-14 12:35:24 +0100323 TensorShape inputShape = (dataLayout == DataLayout::NCHW) ? std::initializer_list<unsigned int>({ 2, 2, 5, 5 })
324 : std::initializer_list<unsigned int>({ 2, 5, 5, 2 });
325 TensorShape outputShape = (dataLayout == DataLayout::NCHW) ? std::initializer_list<unsigned int>({ 2, 2, 5, 5 })
326 : std::initializer_list<unsigned int>({ 2, 5, 5, 2 });
Nikhil Rajcec6b652018-10-12 13:51:57 +0100327
328 BOOST_TEST(TestNeonTensorHandleInfo(inputHandle, TensorInfo(inputShape, DataType)));
329 BOOST_TEST(TestNeonTensorHandleInfo(outputHandle, TensorInfo(outputShape, DataType)));
330}
331
332BOOST_AUTO_TEST_CASE(CreateDepthWiseConvolution2dFloat32NhwcWorkload)
333{
Nattapat Chaimanowong77140882018-10-17 11:12:19 +0100334 NeonCreateDepthWiseConvolutionWorkloadTest<DataType::Float32>(DataLayout::NHWC);
Nikhil Rajcec6b652018-10-12 13:51:57 +0100335}
336
337#ifdef __ARM_FEATURE_FP16_VECTOR_ARITHMETIC
338BOOST_AUTO_TEST_CASE(CreateDepthWiseConvolution2dFloat16NhwcWorkload)
339{
Nattapat Chaimanowong77140882018-10-17 11:12:19 +0100340 NeonCreateDepthWiseConvolutionWorkloadTest<DataType::Float16>(DataLayout::NHWC);
Nikhil Rajcec6b652018-10-12 13:51:57 +0100341}
342#endif
343
telsoa01c577f2c2018-08-31 09:22:23 +0100344template <typename FullyConnectedWorkloadType, typename armnn::DataType DataType>
345static void NeonCreateFullyConnectedWorkloadTest()
telsoa014fcda012018-03-09 14:13:49 +0000346{
Aron Virginas-Tar5caf9072018-11-14 18:35:18 +0000347 Graph graph;
348 NeonWorkloadFactory factory =
349 NeonWorkloadFactoryHelper::GetFactory(NeonWorkloadFactoryHelper::GetMemoryManager());
350
351 auto workload = CreateFullyConnectedWorkloadTest<FullyConnectedWorkloadType, DataType>(factory, graph);
telsoa014fcda012018-03-09 14:13:49 +0000352
telsoa01c577f2c2018-08-31 09:22:23 +0100353 // Checks that outputs and inputs are as we expect them (see definition of CreateFullyConnectedWorkloadTest).
telsoa014fcda012018-03-09 14:13:49 +0000354 FullyConnectedQueueDescriptor queueDescriptor = workload->GetData();
Jan Eilersbb446e52020-04-02 13:56:54 +0100355 auto inputHandle = PolymorphicDowncast<IAclTensorHandle*>(queueDescriptor.m_Inputs[0]);
356 auto outputHandle = PolymorphicDowncast<IAclTensorHandle*>(queueDescriptor.m_Outputs[0]);
Kevin Maybe7e35c2020-04-29 17:05:05 +0100357
358 // Checks that outputs and inputs are as we expect them (see definition of CreateFullyConnectedWorkloadTest).
359 float inputsQScale = DataType == armnn::DataType::QAsymmU8 ? 1.0f : 0.0;
360 float outputQScale = DataType == armnn::DataType::QAsymmU8 ? 2.0f : 0.0;
361 BOOST_TEST(TestNeonTensorHandleInfo(inputHandle, TensorInfo({3, 1, 4, 5}, DataType, inputsQScale)));
362 BOOST_TEST(TestNeonTensorHandleInfo(outputHandle, TensorInfo({3, 7}, DataType, outputQScale)));
telsoa014fcda012018-03-09 14:13:49 +0000363}
364
telsoa01c577f2c2018-08-31 09:22:23 +0100365#ifdef __ARM_FEATURE_FP16_VECTOR_ARITHMETIC
366BOOST_AUTO_TEST_CASE(CreateFullyConnectedFloat16Workload)
367{
kevmay01e448be32018-09-26 10:21:55 +0100368 NeonCreateFullyConnectedWorkloadTest<NeonFullyConnectedWorkload, DataType::Float16>();
telsoa01c577f2c2018-08-31 09:22:23 +0100369}
370#endif
371
arovir019e53a352018-08-31 15:26:35 +0100372BOOST_AUTO_TEST_CASE(CreateFullyConnectedFloatWorkload)
telsoa01c577f2c2018-08-31 09:22:23 +0100373{
kevmay01e448be32018-09-26 10:21:55 +0100374 NeonCreateFullyConnectedWorkloadTest<NeonFullyConnectedWorkload, DataType::Float32>();
telsoa01c577f2c2018-08-31 09:22:23 +0100375}
376
Kevin Maybe7e35c2020-04-29 17:05:05 +0100377BOOST_AUTO_TEST_CASE(CreateFullyConnectedQAsymmU8Workload)
378{
379 NeonCreateFullyConnectedWorkloadTest<NeonFullyConnectedWorkload, DataType::QAsymmU8>();
380}
381
382BOOST_AUTO_TEST_CASE(CreateFullyConnectedQAsymmS8Workload)
383{
384 NeonCreateFullyConnectedWorkloadTest<NeonFullyConnectedWorkload, DataType::QAsymmS8>();
385}
386
telsoa01c577f2c2018-08-31 09:22:23 +0100387template <typename NormalizationWorkloadType, typename armnn::DataType DataType>
narpra0155a97bc2018-10-02 14:35:53 +0100388static void NeonCreateNormalizationWorkloadTest(DataLayout dataLayout)
telsoa014fcda012018-03-09 14:13:49 +0000389{
narpra0155a97bc2018-10-02 14:35:53 +0100390 Graph graph;
Aron Virginas-Tar5caf9072018-11-14 18:35:18 +0000391 NeonWorkloadFactory factory =
392 NeonWorkloadFactoryHelper::GetFactory(NeonWorkloadFactoryHelper::GetMemoryManager());
393
narpra0155a97bc2018-10-02 14:35:53 +0100394 auto workload = CreateNormalizationWorkloadTest<NormalizationWorkloadType, DataType>(factory, graph, dataLayout);
telsoa014fcda012018-03-09 14:13:49 +0000395
telsoa01c577f2c2018-08-31 09:22:23 +0100396 // Checks that outputs and inputs are as we expect them (see definition of CreateNormalizationWorkloadTest).
telsoa014fcda012018-03-09 14:13:49 +0000397 NormalizationQueueDescriptor queueDescriptor = workload->GetData();
Jan Eilersbb446e52020-04-02 13:56:54 +0100398 auto inputHandle = PolymorphicDowncast<IAclTensorHandle*>(queueDescriptor.m_Inputs[0]);
399 auto outputHandle = PolymorphicDowncast<IAclTensorHandle*>(queueDescriptor.m_Outputs[0]);
Matteo Martincigha160b242018-10-18 10:33:23 +0100400
401 TensorShape inputShape = (dataLayout == DataLayout::NCHW) ? TensorShape{3, 5, 5, 1} : TensorShape{3, 1, 5, 5};
402 TensorShape outputShape = (dataLayout == DataLayout::NCHW) ? TensorShape{3, 5, 5, 1} : TensorShape{3, 1, 5, 5};
403
404 BOOST_TEST(TestNeonTensorHandleInfo(inputHandle, TensorInfo(inputShape, DataType)));
405 BOOST_TEST(TestNeonTensorHandleInfo(outputHandle, TensorInfo(outputShape, DataType)));
telsoa014fcda012018-03-09 14:13:49 +0000406}
407
telsoa01c577f2c2018-08-31 09:22:23 +0100408#ifdef __ARM_FEATURE_FP16_VECTOR_ARITHMETIC
narpra0155a97bc2018-10-02 14:35:53 +0100409BOOST_AUTO_TEST_CASE(CreateNormalizationFloat16NchwWorkload)
telsoa01c577f2c2018-08-31 09:22:23 +0100410{
narpra0155a97bc2018-10-02 14:35:53 +0100411 NeonCreateNormalizationWorkloadTest<NeonNormalizationFloatWorkload, DataType::Float16>(DataLayout::NCHW);
412}
413
414BOOST_AUTO_TEST_CASE(CreateNormalizationFloat16NhwcWorkload)
415{
416 NeonCreateNormalizationWorkloadTest<NeonNormalizationFloatWorkload, DataType::Float16>(DataLayout::NHWC);
telsoa01c577f2c2018-08-31 09:22:23 +0100417}
418#endif
419
narpra0155a97bc2018-10-02 14:35:53 +0100420BOOST_AUTO_TEST_CASE(CreateNormalizationFloatNchwWorkload)
telsoa01c577f2c2018-08-31 09:22:23 +0100421{
narpra0155a97bc2018-10-02 14:35:53 +0100422 NeonCreateNormalizationWorkloadTest<NeonNormalizationFloatWorkload, DataType::Float32>(DataLayout::NCHW);
telsoa01c577f2c2018-08-31 09:22:23 +0100423}
424
narpra0155a97bc2018-10-02 14:35:53 +0100425BOOST_AUTO_TEST_CASE(CreateNormalizationFloatNhwcWorkload)
426{
427 NeonCreateNormalizationWorkloadTest<NeonNormalizationFloatWorkload, DataType::Float32>(DataLayout::NHWC);
428}
429
430
Nattapat Chaimanowong5d2e7002018-10-12 16:03:56 +0100431template <typename armnn::DataType DataType>
Nina Drozdb48e6862018-10-09 12:09:56 +0100432static void NeonCreatePooling2dWorkloadTest(DataLayout dataLayout = DataLayout::NCHW)
telsoa014fcda012018-03-09 14:13:49 +0000433{
Aron Virginas-Tar5caf9072018-11-14 18:35:18 +0000434 Graph graph;
435 NeonWorkloadFactory factory =
436 NeonWorkloadFactoryHelper::GetFactory(NeonWorkloadFactoryHelper::GetMemoryManager());
437
438 auto workload = CreatePooling2dWorkloadTest<NeonPooling2dWorkload, DataType>(factory, graph, dataLayout);
Nina Drozdb48e6862018-10-09 12:09:56 +0100439
440 TensorShape inputShape = (dataLayout == DataLayout::NCHW) ? TensorShape{3, 2, 5, 5} : TensorShape{3, 5, 5, 2};
441 TensorShape outputShape = (dataLayout == DataLayout::NCHW) ? TensorShape{3, 2, 2, 4} : TensorShape{3, 2, 4, 2};
telsoa014fcda012018-03-09 14:13:49 +0000442
telsoa01c577f2c2018-08-31 09:22:23 +0100443 // Checks that outputs and inputs are as we expect them (see definition of CreatePooling2dWorkloadTest).
telsoa014fcda012018-03-09 14:13:49 +0000444 Pooling2dQueueDescriptor queueDescriptor = workload->GetData();
Jan Eilersbb446e52020-04-02 13:56:54 +0100445 auto inputHandle = PolymorphicDowncast<IAclTensorHandle*>(queueDescriptor.m_Inputs[0]);
446 auto outputHandle = PolymorphicDowncast<IAclTensorHandle*>(queueDescriptor.m_Outputs[0]);
Nina Drozdb48e6862018-10-09 12:09:56 +0100447 BOOST_TEST(TestNeonTensorHandleInfo(inputHandle, TensorInfo(inputShape, DataType)));
448 BOOST_TEST(TestNeonTensorHandleInfo(outputHandle, TensorInfo(outputShape, DataType)));
telsoa014fcda012018-03-09 14:13:49 +0000449}
450
telsoa01c577f2c2018-08-31 09:22:23 +0100451#ifdef __ARM_FEATURE_FP16_VECTOR_ARITHMETIC
452BOOST_AUTO_TEST_CASE(CreatePooling2dFloat16Workload)
453{
Nattapat Chaimanowong5d2e7002018-10-12 16:03:56 +0100454 NeonCreatePooling2dWorkloadTest<DataType::Float16>();
telsoa01c577f2c2018-08-31 09:22:23 +0100455}
456#endif
457
Nina Drozdb48e6862018-10-09 12:09:56 +0100458BOOST_AUTO_TEST_CASE(CreatePooling2dFloatNchwWorkload)
telsoa01c577f2c2018-08-31 09:22:23 +0100459{
Nattapat Chaimanowong5d2e7002018-10-12 16:03:56 +0100460 NeonCreatePooling2dWorkloadTest<DataType::Float32>(DataLayout::NCHW);
telsoa01c577f2c2018-08-31 09:22:23 +0100461}
462
Nina Drozdb48e6862018-10-09 12:09:56 +0100463BOOST_AUTO_TEST_CASE(CreatePooling2dFloatNhwcWorkload)
telsoa01c577f2c2018-08-31 09:22:23 +0100464{
Nattapat Chaimanowong5d2e7002018-10-12 16:03:56 +0100465 NeonCreatePooling2dWorkloadTest<DataType::Float32>(DataLayout::NHWC);
Nina Drozdb48e6862018-10-09 12:09:56 +0100466}
467
468BOOST_AUTO_TEST_CASE(CreatePooling2dUint8NchwWorkload)
469{
Derek Lambertif90c56d2020-01-10 17:14:08 +0000470 NeonCreatePooling2dWorkloadTest<DataType::QAsymmU8>(DataLayout::NCHW);
Nina Drozdb48e6862018-10-09 12:09:56 +0100471}
472
473BOOST_AUTO_TEST_CASE(CreatePooling2dUint8NhwcWorkload)
474{
Derek Lambertif90c56d2020-01-10 17:14:08 +0000475 NeonCreatePooling2dWorkloadTest<DataType::QAsymmU8>(DataLayout::NHWC);
telsoa01c577f2c2018-08-31 09:22:23 +0100476}
477
Nikhil Raj9b461482019-07-03 15:58:31 +0100478static void NeonCreatePreluWorkloadTest(const armnn::TensorShape& inputShape,
479 const armnn::TensorShape& alphaShape,
480 const armnn::TensorShape& outputShape,
481 armnn::DataType dataType)
482{
483 Graph graph;
484 NeonWorkloadFactory factory =
485 NeonWorkloadFactoryHelper::GetFactory(NeonWorkloadFactoryHelper::GetMemoryManager());
486
487 auto workload = CreatePreluWorkloadTest<NeonPreluWorkload>(factory,
488 graph,
489 inputShape,
490 alphaShape,
491 outputShape,
492 dataType);
493
494 // Checks that outputs and inputs are as we expect them (see definition of CreateReshapeWorkloadTest).
495 PreluQueueDescriptor queueDescriptor = workload->GetData();
Jan Eilersbb446e52020-04-02 13:56:54 +0100496 auto inputHandle = PolymorphicDowncast<IAclTensorHandle*>(queueDescriptor.m_Inputs[0]);
497 auto alphaHandle = PolymorphicDowncast<IAclTensorHandle*>(queueDescriptor.m_Inputs[1]);
498 auto outputHandle = PolymorphicDowncast<IAclTensorHandle*>(queueDescriptor.m_Outputs[0]);
Nikhil Raj9b461482019-07-03 15:58:31 +0100499 BOOST_TEST(TestNeonTensorHandleInfo(inputHandle, TensorInfo(inputShape, dataType)));
500 BOOST_TEST(TestNeonTensorHandleInfo(alphaHandle, TensorInfo(alphaShape, dataType)));
501 BOOST_TEST(TestNeonTensorHandleInfo(outputHandle, TensorInfo(outputShape, dataType)));
502}
503
504#ifdef __ARM_FEATURE_FP16_VECTOR_ARITHMETIC
505 BOOST_AUTO_TEST_CASE(CreatePreluFloat16Workload)
506{
507 NeonCreatePreluWorkloadTest({ 1, 4, 1, 2 }, { 5, 4, 3, 1 }, { 5, 4, 3, 2 }, DataType::Float16);
508}
509#endif
510
511BOOST_AUTO_TEST_CASE(CreatePreluFloatWorkload)
512{
513 NeonCreatePreluWorkloadTest({ 1, 4, 1, 2 }, { 5, 4, 3, 1 }, { 5, 4, 3, 2 }, DataType::Float32);
514}
515
516BOOST_AUTO_TEST_CASE(CreatePreluUint8Workload)
517{
Derek Lambertif90c56d2020-01-10 17:14:08 +0000518 NeonCreatePreluWorkloadTest({ 1, 4, 1, 2 }, { 5, 4, 3, 1 }, { 5, 4, 3, 2 }, DataType::QAsymmU8);
Nikhil Raj9b461482019-07-03 15:58:31 +0100519}
520
Nattapat Chaimanowongcce11fc2018-10-12 16:30:56 +0100521template <typename armnn::DataType DataType>
telsoa01c577f2c2018-08-31 09:22:23 +0100522static void NeonCreateReshapeWorkloadTest()
telsoa014fcda012018-03-09 14:13:49 +0000523{
Aron Virginas-Tar5caf9072018-11-14 18:35:18 +0000524 Graph graph;
525 NeonWorkloadFactory factory =
526 NeonWorkloadFactoryHelper::GetFactory(NeonWorkloadFactoryHelper::GetMemoryManager());
527
528 auto workload = CreateReshapeWorkloadTest<NeonReshapeWorkload, DataType>(factory, graph);
telsoa014fcda012018-03-09 14:13:49 +0000529
telsoa01c577f2c2018-08-31 09:22:23 +0100530 // Checks that outputs and inputs are as we expect them (see definition of CreateReshapeWorkloadTest).
telsoa014fcda012018-03-09 14:13:49 +0000531 ReshapeQueueDescriptor queueDescriptor = workload->GetData();
Jan Eilersbb446e52020-04-02 13:56:54 +0100532 auto inputHandle = PolymorphicDowncast<IAclTensorHandle*>(queueDescriptor.m_Inputs[0]);
533 auto outputHandle = PolymorphicDowncast<IAclTensorHandle*>(queueDescriptor.m_Outputs[0]);
telsoa01c577f2c2018-08-31 09:22:23 +0100534 BOOST_TEST(TestNeonTensorHandleInfo(inputHandle, TensorInfo({4, 1}, DataType)));
535 BOOST_TEST(TestNeonTensorHandleInfo(outputHandle, TensorInfo({1, 4}, DataType)));
telsoa014fcda012018-03-09 14:13:49 +0000536}
537
telsoa01c577f2c2018-08-31 09:22:23 +0100538#ifdef __ARM_FEATURE_FP16_VECTOR_ARITHMETIC
539BOOST_AUTO_TEST_CASE(CreateReshapeFloat16Workload)
540{
Nattapat Chaimanowongcce11fc2018-10-12 16:30:56 +0100541 NeonCreateReshapeWorkloadTest<DataType::Float16>();
telsoa01c577f2c2018-08-31 09:22:23 +0100542}
543#endif
544
arovir019e53a352018-08-31 15:26:35 +0100545BOOST_AUTO_TEST_CASE(CreateReshapeFloatWorkload)
telsoa014fcda012018-03-09 14:13:49 +0000546{
Nattapat Chaimanowongcce11fc2018-10-12 16:30:56 +0100547 NeonCreateReshapeWorkloadTest<DataType::Float32>();
telsoa014fcda012018-03-09 14:13:49 +0000548}
549
550BOOST_AUTO_TEST_CASE(CreateReshapeUint8Workload)
551{
Derek Lambertif90c56d2020-01-10 17:14:08 +0000552 NeonCreateReshapeWorkloadTest<DataType::QAsymmU8>();
telsoa014fcda012018-03-09 14:13:49 +0000553}
554
Ellen Norris-Thompson37e68682019-07-15 14:23:30 +0100555template <typename ResizeWorkloadType, armnn::DataType DataType>
556static void NeonCreateResizeWorkloadTest(DataLayout dataLayout)
557{
558 Graph graph;
559 NeonWorkloadFactory factory =
560 NeonWorkloadFactoryHelper::GetFactory(NeonWorkloadFactoryHelper::GetMemoryManager());
561 auto workload = CreateResizeBilinearWorkloadTest<ResizeWorkloadType, DataType>(factory, graph, dataLayout);
562
563 auto queueDescriptor = workload->GetData();
564
Jan Eilersbb446e52020-04-02 13:56:54 +0100565 auto inputHandle = PolymorphicDowncast<IAclTensorHandle*>(queueDescriptor.m_Inputs[0]);
566 auto outputHandle = PolymorphicDowncast<IAclTensorHandle*>(queueDescriptor.m_Outputs[0]);
Ellen Norris-Thompson37e68682019-07-15 14:23:30 +0100567
568 switch (dataLayout)
569 {
570 case DataLayout::NHWC:
571 BOOST_TEST(CompareIAclTensorHandleShape(inputHandle, { 2, 4, 4, 3 }));
572 BOOST_TEST(CompareIAclTensorHandleShape(outputHandle, { 2, 2, 2, 3 }));
573 break;
574 case DataLayout::NCHW:
575 default:
576 BOOST_TEST(CompareIAclTensorHandleShape(inputHandle, { 2, 3, 4, 4 }));
577 BOOST_TEST(CompareIAclTensorHandleShape(outputHandle, { 2, 3, 2, 2 }));
578 }
579}
580
581BOOST_AUTO_TEST_CASE(CreateResizeFloat32NchwWorkload)
582{
583 NeonCreateResizeWorkloadTest<NeonResizeWorkload, armnn::DataType::Float32>(DataLayout::NCHW);
584}
585
586BOOST_AUTO_TEST_CASE(CreateResizeUint8NchwWorkload)
587{
Derek Lambertif90c56d2020-01-10 17:14:08 +0000588 NeonCreateResizeWorkloadTest<NeonResizeWorkload, armnn::DataType::QAsymmU8>(DataLayout::NCHW);
Ellen Norris-Thompson37e68682019-07-15 14:23:30 +0100589}
590
591BOOST_AUTO_TEST_CASE(CreateResizeFloat32NhwcWorkload)
592{
593 NeonCreateResizeWorkloadTest<NeonResizeWorkload, armnn::DataType::Float32>(DataLayout::NHWC);
594}
595
596BOOST_AUTO_TEST_CASE(CreateResizeUint8NhwcWorkload)
597{
Derek Lambertif90c56d2020-01-10 17:14:08 +0000598 NeonCreateResizeWorkloadTest<NeonResizeWorkload, armnn::DataType::QAsymmU8>(DataLayout::NHWC);
Ellen Norris-Thompson37e68682019-07-15 14:23:30 +0100599}
600
telsoa01c577f2c2018-08-31 09:22:23 +0100601template <typename SoftmaxWorkloadType, typename armnn::DataType DataType>
602static void NeonCreateSoftmaxWorkloadTest()
telsoa014fcda012018-03-09 14:13:49 +0000603{
Aron Virginas-Tar5caf9072018-11-14 18:35:18 +0000604 Graph graph;
605 NeonWorkloadFactory factory =
606 NeonWorkloadFactoryHelper::GetFactory(NeonWorkloadFactoryHelper::GetMemoryManager());
607
telsoa01c577f2c2018-08-31 09:22:23 +0100608 auto workload = CreateSoftmaxWorkloadTest<SoftmaxWorkloadType, DataType>(factory, graph);
telsoa014fcda012018-03-09 14:13:49 +0000609
telsoa01c577f2c2018-08-31 09:22:23 +0100610 // Checks that outputs and inputs are as we expect them (see definition of CreateSoftmaxWorkloadTest).
telsoa014fcda012018-03-09 14:13:49 +0000611 SoftmaxQueueDescriptor queueDescriptor = workload->GetData();
Jan Eilersbb446e52020-04-02 13:56:54 +0100612 auto inputHandle = PolymorphicDowncast<IAclTensorHandle*>(queueDescriptor.m_Inputs[0]);
613 auto outputHandle = PolymorphicDowncast<IAclTensorHandle*>(queueDescriptor.m_Outputs[0]);
Sadik Armaganbe88a572020-04-30 11:39:37 +0100614 armnn::TensorInfo tensorInfo({4, 1}, DataType);
615 if (DataType == armnn::DataType::QAsymmU8)
616 {
617 tensorInfo.SetQuantizationOffset(0);
618 tensorInfo.SetQuantizationScale(1.f / 256);
619 }
620 else if (DataType == armnn::DataType::QAsymmS8)
621 {
622 tensorInfo.SetQuantizationOffset(-128);
623 tensorInfo.SetQuantizationScale(1.f / 256);
624 }
625 BOOST_TEST(TestNeonTensorHandleInfo(inputHandle, tensorInfo));
626 BOOST_TEST(TestNeonTensorHandleInfo(outputHandle, tensorInfo));
telsoa01c577f2c2018-08-31 09:22:23 +0100627}
628
629#ifdef __ARM_FEATURE_FP16_VECTOR_ARITHMETIC
630BOOST_AUTO_TEST_CASE(CreateSoftmaxFloat16Workload)
631{
Sadik Armaganbe88a572020-04-30 11:39:37 +0100632 NeonCreateSoftmaxWorkloadTest<NeonSoftmaxWorkload, DataType::Float16>();
telsoa01c577f2c2018-08-31 09:22:23 +0100633}
634#endif
635
arovir019e53a352018-08-31 15:26:35 +0100636BOOST_AUTO_TEST_CASE(CreateSoftmaxFloatWorkload)
telsoa01c577f2c2018-08-31 09:22:23 +0100637{
Sadik Armaganbe88a572020-04-30 11:39:37 +0100638 NeonCreateSoftmaxWorkloadTest<NeonSoftmaxWorkload, DataType::Float32>();
639}
640
641BOOST_AUTO_TEST_CASE(CreateSoftmaxQAsymmU8Workload)
642{
643 NeonCreateSoftmaxWorkloadTest<NeonSoftmaxWorkload, DataType::QAsymmU8>();
644}
645
646BOOST_AUTO_TEST_CASE(CreateSoftmaxQAsymmS8Workload)
647{
648 NeonCreateSoftmaxWorkloadTest<NeonSoftmaxWorkload, DataType::QAsymmS8>();
telsoa014fcda012018-03-09 14:13:49 +0000649}
650
Ellen Norris-Thompson29794572019-06-26 16:40:36 +0100651template <typename SpaceToDepthWorkloadType, typename armnn::DataType DataType>
652static void NeonSpaceToDepthWorkloadTest()
653{
654 Graph graph;
655 NeonWorkloadFactory factory =
656 NeonWorkloadFactoryHelper::GetFactory(NeonWorkloadFactoryHelper::GetMemoryManager());
657
658 auto workload = CreateSpaceToDepthWorkloadTest<SpaceToDepthWorkloadType, DataType>(factory, graph);
659
660 SpaceToDepthQueueDescriptor queueDescriptor = workload->GetData();
Jan Eilersbb446e52020-04-02 13:56:54 +0100661 auto inputHandle = PolymorphicDowncast<IAclTensorHandle*>(queueDescriptor.m_Inputs[0]);
662 auto outputHandle = PolymorphicDowncast<IAclTensorHandle*>(queueDescriptor.m_Outputs[0]);
Ellen Norris-Thompson29794572019-06-26 16:40:36 +0100663
664 BOOST_TEST(TestNeonTensorHandleInfo(inputHandle, TensorInfo({ 1, 2, 2, 1 }, DataType)));
665 BOOST_TEST(TestNeonTensorHandleInfo(outputHandle, TensorInfo({ 1, 1, 1, 4 }, DataType)));
666}
667
668BOOST_AUTO_TEST_CASE(CreateSpaceToDepthFloat32Workload)
669{
670 NeonSpaceToDepthWorkloadTest<NeonSpaceToDepthWorkload, armnn::DataType::Float32>();
671}
672
673BOOST_AUTO_TEST_CASE(CreateSpaceToDepthFloat16Workload)
674{
675 NeonSpaceToDepthWorkloadTest<NeonSpaceToDepthWorkload, armnn::DataType::Float16>();
676}
677
678BOOST_AUTO_TEST_CASE(CreateSpaceToDepthQAsymm8Workload)
679{
Derek Lambertif90c56d2020-01-10 17:14:08 +0000680 NeonSpaceToDepthWorkloadTest<NeonSpaceToDepthWorkload, armnn::DataType::QAsymmU8>();
Ellen Norris-Thompson29794572019-06-26 16:40:36 +0100681}
682
683BOOST_AUTO_TEST_CASE(CreateSpaceToDepthQSymm16Workload)
684{
Derek Lambertif90c56d2020-01-10 17:14:08 +0000685 NeonSpaceToDepthWorkloadTest<NeonSpaceToDepthWorkload, armnn::DataType::QSymmS16>();
Ellen Norris-Thompson29794572019-06-26 16:40:36 +0100686}
687
telsoa014fcda012018-03-09 14:13:49 +0000688BOOST_AUTO_TEST_CASE(CreateSplitterWorkload)
689{
690 Graph graph;
Aron Virginas-Tar5caf9072018-11-14 18:35:18 +0000691 NeonWorkloadFactory factory =
692 NeonWorkloadFactoryHelper::GetFactory(NeonWorkloadFactoryHelper::GetMemoryManager());
693
Nattapat Chaimanowong14766d72018-10-12 15:09:53 +0100694 auto workload = CreateSplitterWorkloadTest<NeonSplitterWorkload, DataType::Float32>(factory, graph);
telsoa014fcda012018-03-09 14:13:49 +0000695
telsoa01c577f2c2018-08-31 09:22:23 +0100696 // Checks that outputs are as we expect them (see definition of CreateSplitterWorkloadTest).
telsoa014fcda012018-03-09 14:13:49 +0000697 SplitterQueueDescriptor queueDescriptor = workload->GetData();
Jan Eilersbb446e52020-04-02 13:56:54 +0100698 auto inputHandle = PolymorphicDowncast<IAclTensorHandle*>(queueDescriptor.m_Inputs[0]);
surmeh013537c2c2018-05-18 16:31:43 +0100699 BOOST_TEST(TestNeonTensorHandleInfo(inputHandle, TensorInfo({5, 7, 7}, DataType::Float32)));
700
Jan Eilersbb446e52020-04-02 13:56:54 +0100701 auto outputHandle0 = PolymorphicDowncast<IAclTensorHandle*>(queueDescriptor.m_Outputs[0]);
surmeh013537c2c2018-05-18 16:31:43 +0100702 BOOST_TEST(TestNeonTensorHandleInfo(outputHandle0, TensorInfo({1, 7, 7}, DataType::Float32)));
703
Jan Eilersbb446e52020-04-02 13:56:54 +0100704 auto outputHandle1 = PolymorphicDowncast<IAclTensorHandle*>(queueDescriptor.m_Outputs[1]);
surmeh013537c2c2018-05-18 16:31:43 +0100705 BOOST_TEST(TestNeonTensorHandleInfo(outputHandle1, TensorInfo({2, 7, 7}, DataType::Float32)));
706
Jan Eilersbb446e52020-04-02 13:56:54 +0100707 auto outputHandle2 = PolymorphicDowncast<IAclTensorHandle*>(queueDescriptor.m_Outputs[2]);
surmeh013537c2c2018-05-18 16:31:43 +0100708 BOOST_TEST(TestNeonTensorHandleInfo(outputHandle2, TensorInfo({2, 7, 7}, DataType::Float32)));
telsoa014fcda012018-03-09 14:13:49 +0000709}
710
Jim Flynne242f2d2019-05-22 14:24:13 +0100711BOOST_AUTO_TEST_CASE(CreateSplitterConcat)
telsoa014fcda012018-03-09 14:13:49 +0000712{
telsoa01c577f2c2018-08-31 09:22:23 +0100713 // Tests that it is possible to decide which output of the splitter layer
Jim Flynne242f2d2019-05-22 14:24:13 +0100714 // should be lined to which input of the concat layer.
telsoa01c577f2c2018-08-31 09:22:23 +0100715 // We tested that is is possible to specify 0th output
Jim Flynne242f2d2019-05-22 14:24:13 +0100716 // of the splitter to be the 1st input to the concat, and the 1st output of the splitter to be 0th input
717 // of the concat.
telsoa014fcda012018-03-09 14:13:49 +0000718
719 Graph graph;
Aron Virginas-Tar5caf9072018-11-14 18:35:18 +0000720 NeonWorkloadFactory factory =
721 NeonWorkloadFactoryHelper::GetFactory(NeonWorkloadFactoryHelper::GetMemoryManager());
telsoa014fcda012018-03-09 14:13:49 +0000722
723 auto workloads =
Jim Flynne242f2d2019-05-22 14:24:13 +0100724 CreateSplitterConcatWorkloadTest<NeonSplitterWorkload, NeonConcatWorkload,
telsoa01c577f2c2018-08-31 09:22:23 +0100725 DataType::Float32>(factory, graph);
telsoa014fcda012018-03-09 14:13:49 +0000726
727 auto wlSplitter = std::move(workloads.first);
Jim Flynne242f2d2019-05-22 14:24:13 +0100728 auto wlConcat = std::move(workloads.second);
telsoa014fcda012018-03-09 14:13:49 +0000729
telsoa01c577f2c2018-08-31 09:22:23 +0100730 //Checks that the index of inputs/outputs matches what we declared on InputDescriptor construction.
Derek Lambertic81855f2019-06-13 17:34:19 +0100731 armnn::IAclTensorHandle* sOut0 = dynamic_cast<armnn::IAclTensorHandle*>(wlSplitter->GetData().m_Outputs[0]);
732 armnn::IAclTensorHandle* sOut1 = dynamic_cast<armnn::IAclTensorHandle*>(wlSplitter->GetData().m_Outputs[1]);
733 armnn::IAclTensorHandle* mIn0 = dynamic_cast<armnn::IAclTensorHandle*>(wlConcat->GetData().m_Inputs[0]);
734 armnn::IAclTensorHandle* mIn1 = dynamic_cast<armnn::IAclTensorHandle*>(wlConcat->GetData().m_Inputs[1]);
telsoa014fcda012018-03-09 14:13:49 +0000735
736 BOOST_TEST(sOut0);
737 BOOST_TEST(sOut1);
738 BOOST_TEST(mIn0);
739 BOOST_TEST(mIn1);
740
741 bool validDataPointers = (sOut0 == mIn1) && (sOut1 == mIn0);
742
743 BOOST_TEST(validDataPointers);
744}
745
746BOOST_AUTO_TEST_CASE(CreateSingleOutputMultipleInputs)
747{
telsoa01c577f2c2018-08-31 09:22:23 +0100748 // Tests that it is possible to assign multiple (two) different layers to each of the outputs of a splitter layer.
749 // 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 +0000750
751 Graph graph;
Aron Virginas-Tar5caf9072018-11-14 18:35:18 +0000752 NeonWorkloadFactory factory =
753 NeonWorkloadFactoryHelper::GetFactory(NeonWorkloadFactoryHelper::GetMemoryManager());
754
Nattapat Chaimanowong14766d72018-10-12 15:09:53 +0100755 std::unique_ptr<NeonSplitterWorkload> wlSplitter;
Nattapat Chaimanowongd4b70592018-10-12 11:21:49 +0100756 std::unique_ptr<NeonActivationWorkload> wlActiv0_0;
757 std::unique_ptr<NeonActivationWorkload> wlActiv0_1;
758 std::unique_ptr<NeonActivationWorkload> wlActiv1_0;
759 std::unique_ptr<NeonActivationWorkload> wlActiv1_1;
telsoa014fcda012018-03-09 14:13:49 +0000760
Nattapat Chaimanowong14766d72018-10-12 15:09:53 +0100761 CreateSplitterMultipleInputsOneOutputWorkloadTest<NeonSplitterWorkload,
Nattapat Chaimanowongd4b70592018-10-12 11:21:49 +0100762 NeonActivationWorkload, DataType::Float32>(factory, graph, wlSplitter, wlActiv0_0, wlActiv0_1,
763 wlActiv1_0, wlActiv1_1);
telsoa014fcda012018-03-09 14:13:49 +0000764
Derek Lambertic81855f2019-06-13 17:34:19 +0100765 armnn::IAclTensorHandle* sOut0 = dynamic_cast<armnn::IAclTensorHandle*>(wlSplitter->GetData().m_Outputs[0]);
766 armnn::IAclTensorHandle* sOut1 = dynamic_cast<armnn::IAclTensorHandle*>(wlSplitter->GetData().m_Outputs[1]);
767 armnn::IAclTensorHandle* activ0_0Im = dynamic_cast<armnn::IAclTensorHandle*>(wlActiv0_0->GetData().m_Inputs[0]);
768 armnn::IAclTensorHandle* activ0_1Im = dynamic_cast<armnn::IAclTensorHandle*>(wlActiv0_1->GetData().m_Inputs[0]);
769 armnn::IAclTensorHandle* activ1_0Im = dynamic_cast<armnn::IAclTensorHandle*>(wlActiv1_0->GetData().m_Inputs[0]);
770 armnn::IAclTensorHandle* activ1_1Im = dynamic_cast<armnn::IAclTensorHandle*>(wlActiv1_1->GetData().m_Inputs[0]);
telsoa014fcda012018-03-09 14:13:49 +0000771
772
773 BOOST_TEST(sOut0);
774 BOOST_TEST(sOut1);
775 BOOST_TEST(activ0_0Im);
776 BOOST_TEST(activ0_1Im);
777 BOOST_TEST(activ1_0Im);
778 BOOST_TEST(activ1_1Im);
779
780 bool validDataPointers = (sOut0 == activ0_0Im) && (sOut0 == activ0_1Im) &&
781 (sOut1 == activ1_0Im) && (sOut1 == activ1_1Im);
782
783 BOOST_TEST(validDataPointers);
784}
785
Matteo Martincighdb16dd32019-08-27 16:41:11 +0100786#if defined(ARMNNREF_ENABLED)
Matteo Martincighe67edb22019-08-14 14:05:46 +0100787
788// This test unit needs the reference backend, it's not available if the reference backend is not built
789
telsoa014fcda012018-03-09 14:13:49 +0000790BOOST_AUTO_TEST_CASE(CreateMemCopyWorkloadsNeon)
791{
Aron Virginas-Tar5caf9072018-11-14 18:35:18 +0000792 NeonWorkloadFactory factory =
793 NeonWorkloadFactoryHelper::GetFactory(NeonWorkloadFactoryHelper::GetMemoryManager());
Derek Lambertic81855f2019-06-13 17:34:19 +0100794 CreateMemCopyWorkloads<IAclTensorHandle>(factory);
telsoa014fcda012018-03-09 14:13:49 +0000795}
796
Matteo Martincighe67edb22019-08-14 14:05:46 +0100797#endif
798
Matteo Martincighbcd3c852018-09-28 14:14:12 +0100799template <typename L2NormalizationWorkloadType, typename armnn::DataType DataType>
800static void NeonCreateL2NormalizationWorkloadTest(DataLayout dataLayout)
801{
Matteo Martincigh2400b6d2018-10-09 18:19:20 +0100802 Graph graph;
Aron Virginas-Tar5caf9072018-11-14 18:35:18 +0000803 NeonWorkloadFactory factory =
804 NeonWorkloadFactoryHelper::GetFactory(NeonWorkloadFactoryHelper::GetMemoryManager());
805
Matteo Martincigh2400b6d2018-10-09 18:19:20 +0100806 auto workload =
807 CreateL2NormalizationWorkloadTest<L2NormalizationWorkloadType, DataType>(factory, graph, dataLayout);
Matteo Martincighbcd3c852018-09-28 14:14:12 +0100808
809 // Checks that inputs/outputs are as we expect them (see definition of CreateNormalizationWorkloadTest).
810 L2NormalizationQueueDescriptor queueDescriptor = workload->GetData();
Jan Eilersbb446e52020-04-02 13:56:54 +0100811 auto inputHandle = PolymorphicDowncast<IAclTensorHandle*>(queueDescriptor.m_Inputs[0]);
812 auto outputHandle = PolymorphicDowncast<IAclTensorHandle*>(queueDescriptor.m_Outputs[0]);
Matteo Martincigh2400b6d2018-10-09 18:19:20 +0100813
814 TensorShape inputShape = (dataLayout == DataLayout::NCHW) ?
815 TensorShape{ 5, 20, 50, 67 } : TensorShape{ 5, 50, 67, 20 };
816 TensorShape outputShape = (dataLayout == DataLayout::NCHW) ?
817 TensorShape{ 5, 20, 50, 67 } : TensorShape{ 5, 50, 67, 20 };
818
819 BOOST_TEST(TestNeonTensorHandleInfo(inputHandle, TensorInfo(inputShape, DataType)));
820 BOOST_TEST(TestNeonTensorHandleInfo(outputHandle, TensorInfo(outputShape, DataType)));
Matteo Martincighbcd3c852018-09-28 14:14:12 +0100821}
822
823#ifdef __ARM_FEATURE_FP16_VECTOR_ARITHMETIC
824BOOST_AUTO_TEST_CASE(CreateL2NormalizationFloat16NchwWorkload)
825{
826 NeonCreateL2NormalizationWorkloadTest<NeonL2NormalizationFloatWorkload, DataType::Float16>(DataLayout::NCHW);
827}
828
829BOOST_AUTO_TEST_CASE(CreateL2NormalizationFloat16NhwcWorkload)
830{
831 NeonCreateL2NormalizationWorkloadTest<NeonL2NormalizationFloatWorkload, DataType::Float16>(DataLayout::NHWC);
832}
833#endif
834
835BOOST_AUTO_TEST_CASE(CreateL2NormalizationNchwWorkload)
836{
837 NeonCreateL2NormalizationWorkloadTest<NeonL2NormalizationFloatWorkload, DataType::Float32>(DataLayout::NCHW);
838}
839
840BOOST_AUTO_TEST_CASE(CreateL2NormalizationNhwcWorkload)
841{
842 NeonCreateL2NormalizationWorkloadTest<NeonL2NormalizationFloatWorkload, DataType::Float32>(DataLayout::NHWC);
843}
844
Keith Davis69e653f2020-07-02 11:49:26 +0100845template <typename LogSoftmaxWorkloadType, typename armnn::DataType DataType>
846static void NeonCreateLogSoftmaxWorkloadTest()
847{
848 Graph graph;
849 NeonWorkloadFactory factory =
850 NeonWorkloadFactoryHelper::GetFactory(NeonWorkloadFactoryHelper::GetMemoryManager());
851
852 auto workload = CreateLogSoftmaxWorkloadTest<LogSoftmaxWorkloadType, DataType>(factory, graph);
853
854 // Checks that outputs and inputs are as we expect them (see definition of CreateLogSoftmaxWorkloadTest).
855 LogSoftmaxQueueDescriptor queueDescriptor = workload->GetData();
856 auto inputHandle = PolymorphicDowncast<IAclTensorHandle*>(queueDescriptor.m_Inputs[0]);
857 auto outputHandle = PolymorphicDowncast<IAclTensorHandle*>(queueDescriptor.m_Outputs[0]);
858 armnn::TensorInfo tensorInfo({4, 1}, DataType);
859
860 BOOST_TEST(TestNeonTensorHandleInfo(inputHandle, tensorInfo));
861 BOOST_TEST(TestNeonTensorHandleInfo(outputHandle, tensorInfo));
862}
863
864#ifdef __ARM_FEATURE_FP16_VECTOR_ARITHMETIC
865BOOST_AUTO_TEST_CASE(CreateLogSoftmaxFloat16Workload)
866{
867 NeonCreateLogSoftmaxWorkloadTest<NeonLogSoftmaxWorkload, DataType::Float16>();
868}
869#endif
870
871BOOST_AUTO_TEST_CASE(CreateLogSoftmaxFloatWorkload)
872{
873 NeonCreateLogSoftmaxWorkloadTest<NeonLogSoftmaxWorkload, DataType::Float32>();
874}
875
Jan Eilersad5293a2019-07-08 09:57:55 +0100876template <typename LstmWorkloadType>
877static void NeonCreateLstmWorkloadTest()
878{
879 Graph graph;
880 NeonWorkloadFactory factory =
881 NeonWorkloadFactoryHelper::GetFactory(NeonWorkloadFactoryHelper::GetMemoryManager());
882
883 auto workload = CreateLstmWorkloadTest<LstmWorkloadType>(factory, graph);
884
885 LstmQueueDescriptor queueDescriptor = workload->GetData();
886
Jan Eilersbb446e52020-04-02 13:56:54 +0100887 auto inputHandle = PolymorphicDowncast<IAclTensorHandle*>(queueDescriptor.m_Inputs[0]);
888 auto outputHandle = PolymorphicDowncast<IAclTensorHandle*>(queueDescriptor.m_Outputs[1]);
Jan Eilersad5293a2019-07-08 09:57:55 +0100889
890 BOOST_TEST(TestNeonTensorHandleInfo(inputHandle, TensorInfo({ 2, 2 }, DataType::Float32)));
891 BOOST_TEST(TestNeonTensorHandleInfo(outputHandle, TensorInfo({ 2, 4 }, DataType::Float32)));
892}
893
894BOOST_AUTO_TEST_CASE(CreateLSTMWorkloadFloatWorkload)
895{
896 NeonCreateLstmWorkloadTest<NeonLstmFloatWorkload>();
897}
898
Jim Flynne242f2d2019-05-22 14:24:13 +0100899template <typename ConcatWorkloadType, armnn::DataType DataType>
900static void NeonCreateConcatWorkloadTest(std::initializer_list<unsigned int> outputShape,
narpra015cdda352018-11-19 15:30:27 +0000901 unsigned int concatAxis)
902{
903 Graph graph;
904 NeonWorkloadFactory factory =
905 NeonWorkloadFactoryHelper::GetFactory(NeonWorkloadFactoryHelper::GetMemoryManager());
906
Jim Flynne242f2d2019-05-22 14:24:13 +0100907 auto workload = CreateConcatWorkloadTest<ConcatWorkloadType, DataType>(factory, graph, outputShape, concatAxis);
narpra015cdda352018-11-19 15:30:27 +0000908
Jim Flynne242f2d2019-05-22 14:24:13 +0100909 ConcatQueueDescriptor queueDescriptor = workload->GetData();
Jan Eilersbb446e52020-04-02 13:56:54 +0100910 auto inputHandle0 = PolymorphicDowncast<IAclTensorHandle*>(queueDescriptor.m_Inputs[0]);
911 auto inputHandle1 = PolymorphicDowncast<IAclTensorHandle*>(queueDescriptor.m_Inputs[1]);
912 auto outputHandle = PolymorphicDowncast<IAclTensorHandle*>(queueDescriptor.m_Outputs[0]);
narpra015cdda352018-11-19 15:30:27 +0000913
914 BOOST_TEST(TestNeonTensorHandleInfo(inputHandle0, TensorInfo({ 2, 3, 2, 5 }, DataType)));
915 BOOST_TEST(TestNeonTensorHandleInfo(inputHandle1, TensorInfo({ 2, 3, 2, 5 }, DataType)));
916 BOOST_TEST(TestNeonTensorHandleInfo(outputHandle, TensorInfo(outputShape, DataType)));
917}
918
Jim Flynne242f2d2019-05-22 14:24:13 +0100919BOOST_AUTO_TEST_CASE(CreateConcatDim0Float32Workload)
narpra015cdda352018-11-19 15:30:27 +0000920{
Jim Flynne242f2d2019-05-22 14:24:13 +0100921 NeonCreateConcatWorkloadTest<NeonConcatWorkload, armnn::DataType::Float32>({ 4, 3, 2, 5 }, 0);
narpra015cdda352018-11-19 15:30:27 +0000922}
923
Jim Flynne242f2d2019-05-22 14:24:13 +0100924BOOST_AUTO_TEST_CASE(CreateConcatDim1Float32Workload)
narpra015cdda352018-11-19 15:30:27 +0000925{
Jim Flynne242f2d2019-05-22 14:24:13 +0100926 NeonCreateConcatWorkloadTest<NeonConcatWorkload, armnn::DataType::Float32>({ 2, 6, 2, 5 }, 1);
narpra015cdda352018-11-19 15:30:27 +0000927}
928
Jim Flynne242f2d2019-05-22 14:24:13 +0100929BOOST_AUTO_TEST_CASE(CreateConcatDim3Float32Workload)
narpra015cdda352018-11-19 15:30:27 +0000930{
Jim Flynne242f2d2019-05-22 14:24:13 +0100931 NeonCreateConcatWorkloadTest<NeonConcatWorkload, armnn::DataType::Float32>({ 2, 3, 2, 10 }, 3);
narpra015cdda352018-11-19 15:30:27 +0000932}
933
Jim Flynne242f2d2019-05-22 14:24:13 +0100934BOOST_AUTO_TEST_CASE(CreateConcatDim0Uint8Workload)
narpra0163b08822018-11-20 11:29:12 +0000935{
Derek Lambertif90c56d2020-01-10 17:14:08 +0000936 NeonCreateConcatWorkloadTest<NeonConcatWorkload, armnn::DataType::QAsymmU8>({ 4, 3, 2, 5 }, 0);
narpra0163b08822018-11-20 11:29:12 +0000937}
938
Jim Flynne242f2d2019-05-22 14:24:13 +0100939BOOST_AUTO_TEST_CASE(CreateConcatDim1Uint8Workload)
narpra0163b08822018-11-20 11:29:12 +0000940{
Derek Lambertif90c56d2020-01-10 17:14:08 +0000941 NeonCreateConcatWorkloadTest<NeonConcatWorkload, armnn::DataType::QAsymmU8>({ 2, 6, 2, 5 }, 1);
narpra0163b08822018-11-20 11:29:12 +0000942}
943
Jim Flynne242f2d2019-05-22 14:24:13 +0100944BOOST_AUTO_TEST_CASE(CreateConcatDim3Uint8Workload)
narpra0163b08822018-11-20 11:29:12 +0000945{
Derek Lambertif90c56d2020-01-10 17:14:08 +0000946 NeonCreateConcatWorkloadTest<NeonConcatWorkload, armnn::DataType::QAsymmU8>({ 2, 3, 2, 10 }, 3);
narpra0163b08822018-11-20 11:29:12 +0000947}
948
Matthew Jackson87f65ea2019-08-01 10:01:34 +0100949template <armnn::DataType DataType>
950static void NeonCreateStackWorkloadTest(const std::initializer_list<unsigned int>& inputShape,
951 const std::initializer_list<unsigned int>& outputShape,
952 unsigned int axis,
953 unsigned int numInputs)
954{
955 armnn::Graph graph;
956 NeonWorkloadFactory factory =
957 NeonWorkloadFactoryHelper::GetFactory(NeonWorkloadFactoryHelper::GetMemoryManager());
958
959 auto workload = CreateStackWorkloadTest<NeonStackWorkload, DataType>(factory,
960 graph,
961 TensorShape(inputShape),
962 TensorShape(outputShape),
963 axis,
964 numInputs);
965
966 // Check inputs and output are as expected
967 StackQueueDescriptor queueDescriptor = workload->GetData();
968 for (unsigned int i = 0; i < numInputs; ++i)
969 {
Jan Eilersbb446e52020-04-02 13:56:54 +0100970 auto inputHandle = PolymorphicDowncast<IAclTensorHandle*>(queueDescriptor.m_Inputs[i]);
Matthew Jackson87f65ea2019-08-01 10:01:34 +0100971 BOOST_TEST(TestNeonTensorHandleInfo(inputHandle, TensorInfo(inputShape, DataType)));
972 }
Jan Eilersbb446e52020-04-02 13:56:54 +0100973 auto outputHandle = PolymorphicDowncast<IAclTensorHandle*>(queueDescriptor.m_Outputs[0]);
Matthew Jackson87f65ea2019-08-01 10:01:34 +0100974 BOOST_TEST(TestNeonTensorHandleInfo(outputHandle, TensorInfo(outputShape, DataType)));
975}
976
977BOOST_AUTO_TEST_CASE(CreateStackFloat32Workload)
978{
979 NeonCreateStackWorkloadTest<armnn::DataType::Float32>({ 3, 4, 5 }, { 3, 4, 2, 5 }, 2, 2);
980}
981
Matthew Jacksone69c3992019-09-09 14:31:21 +0100982#ifdef __ARM_FEATURE_FP16_VECTOR_ARITHMETIC
983BOOST_AUTO_TEST_CASE(CreateStackFloat16Workload)
984{
985 NeonCreateStackWorkloadTest<armnn::DataType::Float16>({ 3, 4, 5 }, { 3, 4, 2, 5 }, 2, 2);
986}
987#endif
988
Matthew Jackson87f65ea2019-08-01 10:01:34 +0100989BOOST_AUTO_TEST_CASE(CreateStackUint8Workload)
990{
Derek Lambertif90c56d2020-01-10 17:14:08 +0000991 NeonCreateStackWorkloadTest<armnn::DataType::QAsymmU8>({ 3, 4, 5 }, { 3, 4, 2, 5 }, 2, 2);
Matthew Jackson87f65ea2019-08-01 10:01:34 +0100992}
993
Francis Murtagh4fc3c482019-08-02 13:20:54 +0100994template <typename QuantizedLstmWorkloadType>
995static void NeonCreateQuantizedLstmWorkloadTest()
996{
Francis Murtagh4fc3c482019-08-02 13:20:54 +0100997 Graph graph;
998 NeonWorkloadFactory factory = NeonWorkloadFactoryHelper::GetFactory(NeonWorkloadFactoryHelper::GetMemoryManager());
999
1000 auto workload = CreateQuantizedLstmWorkloadTest<QuantizedLstmWorkloadType>(factory, graph);
1001
1002 QuantizedLstmQueueDescriptor queueDescriptor = workload->GetData();
1003
Jan Eilersbb446e52020-04-02 13:56:54 +01001004 IAclTensorHandle* inputHandle = PolymorphicDowncast<IAclTensorHandle*>(queueDescriptor.m_Inputs[0]);
Francis Murtagh4fc3c482019-08-02 13:20:54 +01001005 BOOST_TEST((inputHandle->GetShape() == TensorShape({2, 2})));
1006 BOOST_TEST((inputHandle->GetDataType() == arm_compute::DataType::QASYMM8));
1007
Jan Eilersbb446e52020-04-02 13:56:54 +01001008 IAclTensorHandle* cellStateInHandle = PolymorphicDowncast<IAclTensorHandle*>(queueDescriptor.m_Inputs[1]);
Francis Murtagh4fc3c482019-08-02 13:20:54 +01001009 BOOST_TEST((cellStateInHandle->GetShape() == TensorShape({2, 4})));
1010 BOOST_TEST((cellStateInHandle->GetDataType() == arm_compute::DataType::QSYMM16));
1011
Jan Eilersbb446e52020-04-02 13:56:54 +01001012 IAclTensorHandle* outputStateInHandle = PolymorphicDowncast<IAclTensorHandle*>(queueDescriptor.m_Inputs[2]);
Francis Murtagh4fc3c482019-08-02 13:20:54 +01001013 BOOST_TEST((outputStateInHandle->GetShape() == TensorShape({2, 4})));
1014 BOOST_TEST((outputStateInHandle->GetDataType() == arm_compute::DataType::QASYMM8));
1015
Jan Eilersbb446e52020-04-02 13:56:54 +01001016 IAclTensorHandle* cellStateOutHandle = PolymorphicDowncast<IAclTensorHandle*>(queueDescriptor.m_Outputs[0]);
Francis Murtagh4fc3c482019-08-02 13:20:54 +01001017 BOOST_TEST((cellStateOutHandle->GetShape() == TensorShape({2, 4})));
1018 BOOST_TEST((cellStateOutHandle->GetDataType() == arm_compute::DataType::QSYMM16));
1019
Jan Eilersbb446e52020-04-02 13:56:54 +01001020 IAclTensorHandle* outputStateOutHandle = PolymorphicDowncast<IAclTensorHandle*>(queueDescriptor.m_Outputs[1]);
Francis Murtagh4fc3c482019-08-02 13:20:54 +01001021 BOOST_TEST((outputStateOutHandle->GetShape() == TensorShape({2, 4})));
1022 BOOST_TEST((outputStateOutHandle->GetDataType() == arm_compute::DataType::QASYMM8));
1023}
1024
1025BOOST_AUTO_TEST_CASE(CreateQuantizedLstmWorkload)
1026{
1027 NeonCreateQuantizedLstmWorkloadTest<NeonQuantizedLstmWorkload>();
1028}
1029
James Conroycc340932020-05-12 18:08:52 +01001030template <typename QLstmWorkloadType>
1031static void NeonCreateQLstmWorkloadTest()
1032{
1033 Graph graph;
1034 NeonWorkloadFactory factory = NeonWorkloadFactoryHelper::GetFactory(NeonWorkloadFactoryHelper::GetMemoryManager());
1035
1036 auto workload = CreateQLstmWorkloadTest<QLstmWorkloadType>(factory, graph);
1037 QLstmQueueDescriptor queueDescriptor = workload->GetData();
1038
1039 IAclTensorHandle* inputHandle = PolymorphicDowncast<IAclTensorHandle*>(queueDescriptor.m_Inputs[0]);
1040 BOOST_TEST((inputHandle->GetShape() == TensorShape({2, 4})));
1041 BOOST_TEST((inputHandle->GetDataType() == arm_compute::DataType::QASYMM8_SIGNED));
1042
1043 IAclTensorHandle* cellStateOutHandle = PolymorphicDowncast<IAclTensorHandle*>(queueDescriptor.m_Outputs[1]);
1044 BOOST_TEST((cellStateOutHandle->GetShape() == TensorShape({2, 4})));
1045 BOOST_TEST((cellStateOutHandle->GetDataType() == arm_compute::DataType::QSYMM16));
1046
1047 IAclTensorHandle* outputHandle = PolymorphicDowncast<IAclTensorHandle*>(queueDescriptor.m_Outputs[2]);
1048 BOOST_TEST((outputHandle->GetShape() == TensorShape({2, 4})));
1049 BOOST_TEST((outputHandle->GetDataType() == arm_compute::DataType::QASYMM8_SIGNED));
1050}
1051
1052BOOST_AUTO_TEST_CASE(CreateQLstmWorkloadTest)
1053{
1054 NeonCreateQLstmWorkloadTest<NeonQLstmWorkload>();
1055}
1056
telsoa014fcda012018-03-09 14:13:49 +00001057BOOST_AUTO_TEST_SUITE_END()