blob: 85999203f87c279be419cf6aaee7ff6c4a1d7c10 [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 Beckac42efd2018-09-26 17:41:13 +01005#include <backends/cl/ClWorkloadFactory.hpp>
David Beckb4540be2018-09-24 13:18:27 +01006#include <backends/reference/RefWorkloadFactory.hpp>
7#include <backends/MemCopyWorkload.hpp>
David Beckac42efd2018-09-26 17:41:13 +01008#include <backends/cl/workloads/ClWorkloadUtils.hpp>
9#include <backends/cl/workloads/ClWorkloads.hpp>
10#include <backends/cl/ClTensorHandle.hpp>
telsoa01c577f2c2018-08-31 09:22:23 +010011#include "ClContextControlFixture.hpp"
telsoa014fcda012018-03-09 14:13:49 +000012
David Beckac42efd2018-09-26 17:41:13 +010013#include <test/CreateWorkloadClNeon.hpp>
telsoa014fcda012018-03-09 14:13:49 +000014
15boost::test_tools::predicate_result CompareIClTensorHandleShape(IClTensorHandle* tensorHandle,
16 std::initializer_list<unsigned int> expectedDimensions)
17{
18 return CompareTensorHandleShape<IClTensorHandle>(tensorHandle, expectedDimensions);
19}
20
telsoa01c577f2c2018-08-31 09:22:23 +010021BOOST_FIXTURE_TEST_SUITE(CreateWorkloadCl, ClContextControlFixture)
telsoa014fcda012018-03-09 14:13:49 +000022
telsoa01c577f2c2018-08-31 09:22:23 +010023template <typename ActivationWorkloadType, armnn::DataType DataType>
24static void ClCreateActivationWorkloadTest()
telsoa014fcda012018-03-09 14:13:49 +000025{
26 Graph graph;
27 ClWorkloadFactory factory;
telsoa014fcda012018-03-09 14:13:49 +000028
telsoa01c577f2c2018-08-31 09:22:23 +010029 auto workload = CreateActivationWorkloadTest<ActivationWorkloadType, DataType>(factory, graph);
telsoa014fcda012018-03-09 14:13:49 +000030
telsoa01c577f2c2018-08-31 09:22:23 +010031 // Checks that inputs/outputs are as we expect them (see definition of CreateActivationWorkloadTest).
telsoa014fcda012018-03-09 14:13:49 +000032 ActivationQueueDescriptor queueDescriptor = workload->GetData();
33 auto inputHandle = boost::polymorphic_downcast<IClTensorHandle*>(queueDescriptor.m_Inputs[0]);
34 auto outputHandle = boost::polymorphic_downcast<IClTensorHandle*>(queueDescriptor.m_Outputs[0]);
35
36 BOOST_TEST(CompareIClTensorHandleShape(inputHandle, {1}));
37 BOOST_TEST(CompareIClTensorHandleShape(outputHandle, {1}));
38}
39
arovir019e53a352018-08-31 15:26:35 +010040BOOST_AUTO_TEST_CASE(CreateActivationFloatWorkload)
telsoa01c577f2c2018-08-31 09:22:23 +010041{
arovir019e53a352018-08-31 15:26:35 +010042 ClCreateActivationWorkloadTest<ClActivationFloatWorkload, armnn::DataType::Float32>();
telsoa01c577f2c2018-08-31 09:22:23 +010043}
44
45BOOST_AUTO_TEST_CASE(CreateActivationFloat16Workload)
46{
arovir019e53a352018-08-31 15:26:35 +010047 ClCreateActivationWorkloadTest<ClActivationFloatWorkload, armnn::DataType::Float16>();
telsoa01c577f2c2018-08-31 09:22:23 +010048}
49
David Beck4a8692c2018-09-07 16:19:24 +010050template <typename WorkloadType,
51 typename DescriptorType,
52 typename LayerType,
53 armnn::DataType DataType>
54static void ClCreateArithmethicWorkloadTest()
telsoa014fcda012018-03-09 14:13:49 +000055{
56 Graph graph;
57 ClWorkloadFactory factory;
David Beck4a8692c2018-09-07 16:19:24 +010058 auto workload = CreateArithmeticWorkloadTest<WorkloadType, DescriptorType, LayerType, DataType>(factory, graph);
telsoa014fcda012018-03-09 14:13:49 +000059
James Conroyb9bf9462018-09-19 11:58:44 +010060 // Checks that inputs/outputs are as we expect them (see definition of CreateArithmeticWorkloadTest).
David Beck4a8692c2018-09-07 16:19:24 +010061 DescriptorType queueDescriptor = workload->GetData();
telsoa014fcda012018-03-09 14:13:49 +000062 auto inputHandle1 = boost::polymorphic_downcast<IClTensorHandle*>(queueDescriptor.m_Inputs[0]);
63 auto inputHandle2 = boost::polymorphic_downcast<IClTensorHandle*>(queueDescriptor.m_Inputs[1]);
64 auto outputHandle = boost::polymorphic_downcast<IClTensorHandle*>(queueDescriptor.m_Outputs[0]);
65 BOOST_TEST(CompareIClTensorHandleShape(inputHandle1, {2, 3}));
66 BOOST_TEST(CompareIClTensorHandleShape(inputHandle2, {2, 3}));
67 BOOST_TEST(CompareIClTensorHandleShape(outputHandle, {2, 3}));
68}
69
arovir019e53a352018-08-31 15:26:35 +010070BOOST_AUTO_TEST_CASE(CreateAdditionFloatWorkload)
telsoa014fcda012018-03-09 14:13:49 +000071{
David Beck0a710c42018-09-11 15:21:14 +010072 ClCreateArithmethicWorkloadTest<ClAdditionWorkload<armnn::DataType::Float16, armnn::DataType::Float32>,
David Beck4a8692c2018-09-07 16:19:24 +010073 AdditionQueueDescriptor,
74 AdditionLayer,
75 armnn::DataType::Float32>();
telsoa01c577f2c2018-08-31 09:22:23 +010076}
77
78BOOST_AUTO_TEST_CASE(CreateAdditionFloat16Workload)
79{
David Beck0a710c42018-09-11 15:21:14 +010080 ClCreateArithmethicWorkloadTest<ClAdditionWorkload<armnn::DataType::Float16, armnn::DataType::Float32>,
David Beck4a8692c2018-09-07 16:19:24 +010081 AdditionQueueDescriptor,
82 AdditionLayer,
83 armnn::DataType::Float16>();
84}
85
86BOOST_AUTO_TEST_CASE(CreateSubtractionFloatWorkload)
87{
Matthew Bentham092b3042018-10-01 16:39:28 +010088 ClCreateArithmethicWorkloadTest<ClSubtractionWorkload,
David Beck4a8692c2018-09-07 16:19:24 +010089 SubtractionQueueDescriptor,
90 SubtractionLayer,
91 armnn::DataType::Float32>();
92}
93
94BOOST_AUTO_TEST_CASE(CreateSubtractionFloat16Workload)
95{
Matthew Bentham092b3042018-10-01 16:39:28 +010096 ClCreateArithmethicWorkloadTest<ClSubtractionWorkload,
David Beck4a8692c2018-09-07 16:19:24 +010097 SubtractionQueueDescriptor,
98 SubtractionLayer,
99 armnn::DataType::Float16>();
100}
101
102BOOST_AUTO_TEST_CASE(CreateMultiplicationFloatWorkloadTest)
103{
Matthew Benthame2ec3302018-10-01 11:32:48 +0100104 ClCreateArithmethicWorkloadTest<ClMultiplicationWorkload,
David Beck4a8692c2018-09-07 16:19:24 +0100105 MultiplicationQueueDescriptor,
106 MultiplicationLayer,
107 armnn::DataType::Float32>();
108}
109
110BOOST_AUTO_TEST_CASE(CreateMultiplicationFloat16WorkloadTest)
111{
Matthew Benthame2ec3302018-10-01 11:32:48 +0100112 ClCreateArithmethicWorkloadTest<ClMultiplicationWorkload,
David Beck4a8692c2018-09-07 16:19:24 +0100113 MultiplicationQueueDescriptor,
114 MultiplicationLayer,
115 armnn::DataType::Float16>();
116}
117
Matthew Benthame2ec3302018-10-01 11:32:48 +0100118BOOST_AUTO_TEST_CASE(CreateMultiplicationUint8WorkloadTest)
119{
120 ClCreateArithmethicWorkloadTest<ClMultiplicationWorkload,
121 MultiplicationQueueDescriptor,
122 MultiplicationLayer,
123 armnn::DataType::QuantisedAsymm8>();
124}
125
David Beck4a8692c2018-09-07 16:19:24 +0100126BOOST_AUTO_TEST_CASE(CreateDivisionFloatWorkloadTest)
127{
128 ClCreateArithmethicWorkloadTest<ClDivisionFloatWorkload,
129 DivisionQueueDescriptor,
130 DivisionLayer,
131 armnn::DataType::Float32>();
132}
133
134BOOST_AUTO_TEST_CASE(CreateDivisionFloat16WorkloadTest)
135{
136 ClCreateArithmethicWorkloadTest<ClDivisionFloatWorkload,
137 DivisionQueueDescriptor,
138 DivisionLayer,
139 armnn::DataType::Float16>();
telsoa01c577f2c2018-08-31 09:22:23 +0100140}
141
142template <typename BatchNormalizationWorkloadType, armnn::DataType DataType>
143static void ClCreateBatchNormalizationWorkloadTest()
144{
145 Graph graph;
telsoa014fcda012018-03-09 14:13:49 +0000146 ClWorkloadFactory factory;
telsoa014fcda012018-03-09 14:13:49 +0000147
telsoa01c577f2c2018-08-31 09:22:23 +0100148 auto workload = CreateBatchNormalizationWorkloadTest<BatchNormalizationWorkloadType, DataType>
149 (factory, graph);
telsoa014fcda012018-03-09 14:13:49 +0000150
telsoa01c577f2c2018-08-31 09:22:23 +0100151 // Checks that inputs/outputs are as we expect them (see definition of CreateBatchNormalizationWorkloadTest).
telsoa014fcda012018-03-09 14:13:49 +0000152 BatchNormalizationQueueDescriptor queueDescriptor = workload->GetData();
153 auto inputHandle = boost::polymorphic_downcast<IClTensorHandle*>(queueDescriptor.m_Inputs[0]);
154 auto outputHandle = boost::polymorphic_downcast<IClTensorHandle*>(queueDescriptor.m_Outputs[0]);
155
156 BOOST_TEST(CompareIClTensorHandleShape(inputHandle, {2, 3, 1, 1}));
157 BOOST_TEST(CompareIClTensorHandleShape(outputHandle, {2, 3, 1, 1}));
158}
159
arovir019e53a352018-08-31 15:26:35 +0100160BOOST_AUTO_TEST_CASE(CreateBatchNormalizationFloatWorkload)
telsoa014fcda012018-03-09 14:13:49 +0000161{
arovir019e53a352018-08-31 15:26:35 +0100162 ClCreateBatchNormalizationWorkloadTest<ClBatchNormalizationFloatWorkload, armnn::DataType::Float32>();
telsoa01c577f2c2018-08-31 09:22:23 +0100163}
telsoa014fcda012018-03-09 14:13:49 +0000164
telsoa01c577f2c2018-08-31 09:22:23 +0100165BOOST_AUTO_TEST_CASE(CreateBatchNormalizationFloat16Workload)
166{
arovir019e53a352018-08-31 15:26:35 +0100167 ClCreateBatchNormalizationWorkloadTest<ClBatchNormalizationFloatWorkload, armnn::DataType::Float16>();
telsoa01c577f2c2018-08-31 09:22:23 +0100168}
169
170BOOST_AUTO_TEST_CASE(CreateConvertFp16ToFp32Workload)
171{
172 Graph graph;
173 ClWorkloadFactory factory;
174 auto workload = CreateConvertFp16ToFp32WorkloadTest<ClConvertFp16ToFp32Workload>(factory, graph);
175
176 ConvertFp16ToFp32QueueDescriptor queueDescriptor = workload->GetData();
177 auto inputHandle = boost::polymorphic_downcast<IClTensorHandle*>(queueDescriptor.m_Inputs[0]);
178 auto outputHandle = boost::polymorphic_downcast<IClTensorHandle*>(queueDescriptor.m_Outputs[0]);
179
180 BOOST_TEST(CompareIClTensorHandleShape(inputHandle, {3, 2, 3}));
181 BOOST_TEST(CompareIClTensorHandleShape(outputHandle, {3, 2, 3}));
182 BOOST_TEST((inputHandle->GetTensor().info()->data_type() == arm_compute::DataType::F16));
183 BOOST_TEST((outputHandle->GetTensor().info()->data_type() == arm_compute::DataType::F32));
184}
185
186BOOST_AUTO_TEST_CASE(CreateConvertFp32ToFp16Workload)
187{
188 Graph graph;
189 ClWorkloadFactory factory;
190 auto workload = CreateConvertFp32ToFp16WorkloadTest<ClConvertFp32ToFp16Workload>(factory, graph);
191
192 ConvertFp32ToFp16QueueDescriptor queueDescriptor = workload->GetData();
193 auto inputHandle = boost::polymorphic_downcast<IClTensorHandle*>(queueDescriptor.m_Inputs[0]);
194 auto outputHandle = boost::polymorphic_downcast<IClTensorHandle*>(queueDescriptor.m_Outputs[0]);
195
196 BOOST_TEST(CompareIClTensorHandleShape(inputHandle, {3, 2, 3}));
197 BOOST_TEST(CompareIClTensorHandleShape(outputHandle, {3, 2, 3}));
198 BOOST_TEST((inputHandle->GetTensor().info()->data_type() == arm_compute::DataType::F32));
199 BOOST_TEST((outputHandle->GetTensor().info()->data_type() == arm_compute::DataType::F16));
200}
201
202template <typename Convolution2dWorkloadType, typename armnn::DataType DataType>
203static void ClConvolution2dWorkloadTest()
204{
205 Graph graph;
206 ClWorkloadFactory factory;
207 auto workload = CreateConvolution2dWorkloadTest<Convolution2dWorkloadType, DataType>
208 (factory, graph);
209
210 // Checks that outputs and inputs are as we expect them (see definition of CreateConvolution2dWorkloadTest).
telsoa014fcda012018-03-09 14:13:49 +0000211 Convolution2dQueueDescriptor queueDescriptor = workload->GetData();
212 auto inputHandle = boost::polymorphic_downcast<IClTensorHandle*>(queueDescriptor.m_Inputs[0]);
213 auto outputHandle = boost::polymorphic_downcast<IClTensorHandle*>(queueDescriptor.m_Outputs[0]);
214 BOOST_TEST(CompareIClTensorHandleShape(inputHandle, {2, 3, 8, 16}));
215 BOOST_TEST(CompareIClTensorHandleShape(outputHandle, {2, 2, 2, 10}));
216}
217
arovir019e53a352018-08-31 15:26:35 +0100218BOOST_AUTO_TEST_CASE(CreateConvolution2dFloatWorkload)
telsoa014fcda012018-03-09 14:13:49 +0000219{
arovir019e53a352018-08-31 15:26:35 +0100220 ClConvolution2dWorkloadTest<ClConvolution2dFloatWorkload, armnn::DataType::Float32>();
telsoa01c577f2c2018-08-31 09:22:23 +0100221}
222
223BOOST_AUTO_TEST_CASE(CreateConvolution2dFloat16Workload)
224{
arovir019e53a352018-08-31 15:26:35 +0100225 ClConvolution2dWorkloadTest<ClConvolution2dFloatWorkload, armnn::DataType::Float16>();
telsoa014fcda012018-03-09 14:13:49 +0000226}
227
228
telsoa01c577f2c2018-08-31 09:22:23 +0100229template <typename Convolution2dWorkloadType, typename armnn::DataType DataType>
230static void ClDirectConvolution2dWorkloadTest()
telsoa014fcda012018-03-09 14:13:49 +0000231{
telsoa01c577f2c2018-08-31 09:22:23 +0100232 Graph graph;
233 ClWorkloadFactory factory;
234 auto workload = CreateDirectConvolution2dWorkloadTest<Convolution2dWorkloadType, DataType>(
235 factory, graph);
telsoa014fcda012018-03-09 14:13:49 +0000236
telsoa01c577f2c2018-08-31 09:22:23 +0100237 // Checks that outputs and inputs are as we expect them (see definition of CreateDirectConvolution2dWorkloadTest).
telsoa014fcda012018-03-09 14:13:49 +0000238 Convolution2dQueueDescriptor queueDescriptor = workload->GetData();
239 auto inputHandle = boost::polymorphic_downcast<IClTensorHandle*>(queueDescriptor.m_Inputs[0]);
240 auto outputHandle = boost::polymorphic_downcast<IClTensorHandle*>(queueDescriptor.m_Outputs[0]);
241 BOOST_TEST(CompareIClTensorHandleShape(inputHandle, {2, 3, 6, 6}));
242 BOOST_TEST(CompareIClTensorHandleShape(outputHandle, {2, 2, 6, 6}));
243}
244
arovir019e53a352018-08-31 15:26:35 +0100245BOOST_AUTO_TEST_CASE(CreateDirectConvolution2dFloatWorkload)
telsoa014fcda012018-03-09 14:13:49 +0000246{
arovir019e53a352018-08-31 15:26:35 +0100247 ClDirectConvolution2dWorkloadTest<ClConvolution2dFloatWorkload, armnn::DataType::Float32>();
telsoa01c577f2c2018-08-31 09:22:23 +0100248}
249
250BOOST_AUTO_TEST_CASE(CreateDirectConvolution2dFloat16Workload)
251{
arovir019e53a352018-08-31 15:26:35 +0100252 ClDirectConvolution2dWorkloadTest<ClConvolution2dFloatWorkload, armnn::DataType::Float16>();
telsoa014fcda012018-03-09 14:13:49 +0000253}
254
255BOOST_AUTO_TEST_CASE(CreateDirectConvolution2dUint8Workload)
256{
telsoa01c577f2c2018-08-31 09:22:23 +0100257 ClDirectConvolution2dWorkloadTest<ClConvolution2dUint8Workload, armnn::DataType::QuantisedAsymm8>();
telsoa014fcda012018-03-09 14:13:49 +0000258}
259
telsoa01c577f2c2018-08-31 09:22:23 +0100260template <typename FullyConnectedWorkloadType, typename armnn::DataType DataType>
261static void ClCreateFullyConnectedWorkloadTest()
telsoa014fcda012018-03-09 14:13:49 +0000262{
telsoa01c577f2c2018-08-31 09:22:23 +0100263 Graph graph;
telsoa014fcda012018-03-09 14:13:49 +0000264 ClWorkloadFactory factory;
telsoa01c577f2c2018-08-31 09:22:23 +0100265 auto workload =
266 CreateFullyConnectedWorkloadTest<FullyConnectedWorkloadType, DataType>(factory, graph);
telsoa014fcda012018-03-09 14:13:49 +0000267
telsoa01c577f2c2018-08-31 09:22:23 +0100268 // Checks that outputs and inputs are as we expect them (see definition of CreateFullyConnectedWorkloadTest).
telsoa014fcda012018-03-09 14:13:49 +0000269 FullyConnectedQueueDescriptor queueDescriptor = workload->GetData();
270 auto inputHandle = boost::polymorphic_downcast<IClTensorHandle*>(queueDescriptor.m_Inputs[0]);
271 auto outputHandle = boost::polymorphic_downcast<IClTensorHandle*>(queueDescriptor.m_Outputs[0]);
272 BOOST_TEST(CompareIClTensorHandleShape(inputHandle, {3, 1, 4, 5}));
273 BOOST_TEST(CompareIClTensorHandleShape(outputHandle, {3, 7}));
274}
275
telsoa01c577f2c2018-08-31 09:22:23 +0100276
arovir019e53a352018-08-31 15:26:35 +0100277BOOST_AUTO_TEST_CASE(CreateFullyConnectedFloatWorkloadTest)
telsoa014fcda012018-03-09 14:13:49 +0000278{
Matthew Benthamab8cdc12018-09-17 11:17:41 +0100279 ClCreateFullyConnectedWorkloadTest<ClFullyConnectedWorkload, armnn::DataType::Float32>();
telsoa01c577f2c2018-08-31 09:22:23 +0100280}
281
282BOOST_AUTO_TEST_CASE(CreateFullyConnectedFloat16WorkloadTest)
283{
Matthew Benthamab8cdc12018-09-17 11:17:41 +0100284 ClCreateFullyConnectedWorkloadTest<ClFullyConnectedWorkload, armnn::DataType::Float16>();
telsoa01c577f2c2018-08-31 09:22:23 +0100285}
286
telsoa01c577f2c2018-08-31 09:22:23 +0100287template <typename NormalizationWorkloadType, typename armnn::DataType DataType>
288static void ClNormalizationWorkloadTest()
289{
290 Graph graph;
telsoa014fcda012018-03-09 14:13:49 +0000291 ClWorkloadFactory factory;
telsoa014fcda012018-03-09 14:13:49 +0000292
telsoa01c577f2c2018-08-31 09:22:23 +0100293 auto workload = CreateNormalizationWorkloadTest<NormalizationWorkloadType, DataType>
294 (factory, graph);
telsoa014fcda012018-03-09 14:13:49 +0000295
telsoa01c577f2c2018-08-31 09:22:23 +0100296 // Checks that inputs/outputs are as we expect them (see definition of CreateNormalizationWorkloadTest).
telsoa014fcda012018-03-09 14:13:49 +0000297 NormalizationQueueDescriptor queueDescriptor = workload->GetData();
298 auto inputHandle = boost::polymorphic_downcast<IClTensorHandle*>(queueDescriptor.m_Inputs[0]);
299 auto outputHandle = boost::polymorphic_downcast<IClTensorHandle*>(queueDescriptor.m_Outputs[0]);
300
301 BOOST_TEST(CompareIClTensorHandleShape(inputHandle, {3, 5, 5, 1}));
302 BOOST_TEST(CompareIClTensorHandleShape(outputHandle, {3, 5, 5, 1}));
303}
304
arovir019e53a352018-08-31 15:26:35 +0100305BOOST_AUTO_TEST_CASE(CreateNormalizationFloatWorkload)
telsoa014fcda012018-03-09 14:13:49 +0000306{
arovir019e53a352018-08-31 15:26:35 +0100307 ClNormalizationWorkloadTest<ClNormalizationFloatWorkload, armnn::DataType::Float32>();
telsoa01c577f2c2018-08-31 09:22:23 +0100308}
309
310BOOST_AUTO_TEST_CASE(CreateNormalizationFloat16Workload)
311{
arovir019e53a352018-08-31 15:26:35 +0100312 ClNormalizationWorkloadTest<ClNormalizationFloatWorkload, armnn::DataType::Float16>();
telsoa01c577f2c2018-08-31 09:22:23 +0100313}
314
315template <typename Pooling2dWorkloadType, typename armnn::DataType DataType>
316static void ClPooling2dWorkloadTest()
317{
318 Graph graph;
telsoa014fcda012018-03-09 14:13:49 +0000319 ClWorkloadFactory factory;
telsoa014fcda012018-03-09 14:13:49 +0000320
telsoa01c577f2c2018-08-31 09:22:23 +0100321 auto workload = CreatePooling2dWorkloadTest<Pooling2dWorkloadType, DataType>(factory, graph);
telsoa014fcda012018-03-09 14:13:49 +0000322
telsoa01c577f2c2018-08-31 09:22:23 +0100323 // Check that inputs/outputs are as we expect them (see definition of CreatePooling2dWorkloadTest).
telsoa014fcda012018-03-09 14:13:49 +0000324 Pooling2dQueueDescriptor queueDescriptor = workload->GetData();
325 auto inputHandle = boost::polymorphic_downcast<IClTensorHandle*>(queueDescriptor.m_Inputs[0]);
326 auto outputHandle = boost::polymorphic_downcast<IClTensorHandle*>(queueDescriptor.m_Outputs[0]);
327
328 BOOST_TEST(CompareIClTensorHandleShape(inputHandle, {3, 2, 5, 5}));
329 BOOST_TEST(CompareIClTensorHandleShape(outputHandle, {3, 2, 2, 4}));
330}
331
arovir019e53a352018-08-31 15:26:35 +0100332BOOST_AUTO_TEST_CASE(CreatePooling2dFloatWorkload)
telsoa01c577f2c2018-08-31 09:22:23 +0100333{
arovir019e53a352018-08-31 15:26:35 +0100334 ClPooling2dWorkloadTest<ClPooling2dFloatWorkload, armnn::DataType::Float32>();
telsoa01c577f2c2018-08-31 09:22:23 +0100335}
336
337BOOST_AUTO_TEST_CASE(CreatePooling2dFloat16Workload)
338{
arovir019e53a352018-08-31 15:26:35 +0100339 ClPooling2dWorkloadTest<ClPooling2dFloatWorkload, armnn::DataType::Float16>();
telsoa01c577f2c2018-08-31 09:22:23 +0100340}
341
342template <typename ReshapeWorkloadType, typename armnn::DataType DataType>
telsoa014fcda012018-03-09 14:13:49 +0000343static void ClCreateReshapeWorkloadTest()
344{
telsoa01c577f2c2018-08-31 09:22:23 +0100345 Graph graph;
telsoa014fcda012018-03-09 14:13:49 +0000346 ClWorkloadFactory factory;
telsoa014fcda012018-03-09 14:13:49 +0000347
telsoa01c577f2c2018-08-31 09:22:23 +0100348 auto workload = CreateReshapeWorkloadTest<ReshapeWorkloadType, DataType>(factory, graph);
telsoa014fcda012018-03-09 14:13:49 +0000349
telsoa01c577f2c2018-08-31 09:22:23 +0100350 // Checks that outputs and inputs are as we expect them (see definition of CreateReshapeWorkloadTest).
telsoa014fcda012018-03-09 14:13:49 +0000351 ReshapeQueueDescriptor queueDescriptor = workload->GetData();
telsoa01c577f2c2018-08-31 09:22:23 +0100352 auto inputHandle = boost::polymorphic_downcast<IClTensorHandle*>(queueDescriptor.m_Inputs[0]);
353 auto outputHandle = boost::polymorphic_downcast<IClTensorHandle*>(queueDescriptor.m_Outputs[0]);
telsoa014fcda012018-03-09 14:13:49 +0000354
355 BOOST_TEST(CompareIClTensorHandleShape(inputHandle, {4, 1}));
356 BOOST_TEST(CompareIClTensorHandleShape(outputHandle, {4})); // Leading size 1 dimensions are collapsed by ACL.
357}
358
arovir019e53a352018-08-31 15:26:35 +0100359BOOST_AUTO_TEST_CASE(CreateReshapeFloatWorkload)
telsoa014fcda012018-03-09 14:13:49 +0000360{
arovir019e53a352018-08-31 15:26:35 +0100361 ClCreateReshapeWorkloadTest<ClReshapeFloatWorkload, armnn::DataType::Float32>();
telsoa01c577f2c2018-08-31 09:22:23 +0100362}
363
364BOOST_AUTO_TEST_CASE(CreateReshapeFloat16Workload)
365{
arovir019e53a352018-08-31 15:26:35 +0100366 ClCreateReshapeWorkloadTest<ClReshapeFloatWorkload, armnn::DataType::Float16>();
telsoa014fcda012018-03-09 14:13:49 +0000367}
368
369BOOST_AUTO_TEST_CASE(CreateReshapeUint8Workload)
370{
telsoa01c577f2c2018-08-31 09:22:23 +0100371 ClCreateReshapeWorkloadTest<ClReshapeUint8Workload, armnn::DataType::QuantisedAsymm8>();
telsoa014fcda012018-03-09 14:13:49 +0000372}
373
telsoa01c577f2c2018-08-31 09:22:23 +0100374template <typename SoftmaxWorkloadType, typename armnn::DataType DataType>
375static void ClSoftmaxWorkloadTest()
telsoa014fcda012018-03-09 14:13:49 +0000376{
telsoa01c577f2c2018-08-31 09:22:23 +0100377 Graph graph;
telsoa014fcda012018-03-09 14:13:49 +0000378 ClWorkloadFactory factory;
telsoa014fcda012018-03-09 14:13:49 +0000379
telsoa01c577f2c2018-08-31 09:22:23 +0100380 auto workload = CreateSoftmaxWorkloadTest<SoftmaxWorkloadType, DataType>(factory, graph);
telsoa014fcda012018-03-09 14:13:49 +0000381
arovir019e53a352018-08-31 15:26:35 +0100382 // Checks that inputs/outputs are as we expect them (see definition of ClSoftmaxFloatWorkload).
telsoa014fcda012018-03-09 14:13:49 +0000383 SoftmaxQueueDescriptor queueDescriptor = workload->GetData();
telsoa01c577f2c2018-08-31 09:22:23 +0100384 auto inputHandle = boost::polymorphic_downcast<IClTensorHandle*>(queueDescriptor.m_Inputs[0]);
385 auto outputHandle = boost::polymorphic_downcast<IClTensorHandle*>(queueDescriptor.m_Outputs[0]);
telsoa014fcda012018-03-09 14:13:49 +0000386
387 BOOST_TEST(CompareIClTensorHandleShape(inputHandle, {4, 1}));
388 BOOST_TEST(CompareIClTensorHandleShape(outputHandle, {4, 1}));
389}
390
telsoa01c577f2c2018-08-31 09:22:23 +0100391
arovir019e53a352018-08-31 15:26:35 +0100392BOOST_AUTO_TEST_CASE(CreateSoftmaxFloatWorkloadTest)
telsoa01c577f2c2018-08-31 09:22:23 +0100393{
arovir019e53a352018-08-31 15:26:35 +0100394 ClSoftmaxWorkloadTest<ClSoftmaxFloatWorkload, armnn::DataType::Float32>();
telsoa01c577f2c2018-08-31 09:22:23 +0100395}
396
397BOOST_AUTO_TEST_CASE(CreateSoftmaxFloat16WorkloadTest)
398{
arovir019e53a352018-08-31 15:26:35 +0100399 ClSoftmaxWorkloadTest<ClSoftmaxFloatWorkload, armnn::DataType::Float16>();
telsoa01c577f2c2018-08-31 09:22:23 +0100400}
401
Matthew Bentham29cadb32018-10-01 17:22:32 +0100402template <typename armnn::DataType DataType>
telsoa01c577f2c2018-08-31 09:22:23 +0100403static void ClSplitterWorkloadTest()
telsoa014fcda012018-03-09 14:13:49 +0000404{
405 Graph graph;
406 ClWorkloadFactory factory;
telsoa014fcda012018-03-09 14:13:49 +0000407
Matthew Bentham29cadb32018-10-01 17:22:32 +0100408 auto workload = CreateSplitterWorkloadTest<ClSplitterWorkload, DataType>(factory, graph);
telsoa014fcda012018-03-09 14:13:49 +0000409
telsoa01c577f2c2018-08-31 09:22:23 +0100410 // Checks that outputs are as we expect them (see definition of CreateSplitterWorkloadTest).
telsoa014fcda012018-03-09 14:13:49 +0000411 SplitterQueueDescriptor queueDescriptor = workload->GetData();
412 auto inputHandle = boost::polymorphic_downcast<IClTensorHandle*>(queueDescriptor.m_Inputs[0]);
surmeh013537c2c2018-05-18 16:31:43 +0100413 BOOST_TEST(CompareIClTensorHandleShape(inputHandle, {5, 7, 7}));
414
telsoa014fcda012018-03-09 14:13:49 +0000415 auto outputHandle1 = boost::polymorphic_downcast<IClTensorHandle*>(queueDescriptor.m_Outputs[1]);
surmeh013537c2c2018-05-18 16:31:43 +0100416 BOOST_TEST(CompareIClTensorHandleShape(outputHandle1, {2, 7, 7}));
417
telsoa014fcda012018-03-09 14:13:49 +0000418 auto outputHandle2 = boost::polymorphic_downcast<IClTensorHandle*>(queueDescriptor.m_Outputs[2]);
surmeh013537c2c2018-05-18 16:31:43 +0100419 BOOST_TEST(CompareIClTensorHandleShape(outputHandle2, {2, 7, 7}));
420
421 auto outputHandle0 = boost::polymorphic_downcast<IClTensorHandle*>(queueDescriptor.m_Outputs[0]);
422 // NOTE: At the moment the CL collapses the tensor to a 2 dim when dimension zero = 1
telsoa01c577f2c2018-08-31 09:22:23 +0100423 // we are raising this difference between the NEON and CL libs as an issue with the compute library team.
surmeh013537c2c2018-05-18 16:31:43 +0100424 BOOST_TEST(CompareIClTensorHandleShape(outputHandle0, {7, 7}));
telsoa014fcda012018-03-09 14:13:49 +0000425}
426
arovir019e53a352018-08-31 15:26:35 +0100427BOOST_AUTO_TEST_CASE(CreateSplitterFloatWorkload)
telsoa014fcda012018-03-09 14:13:49 +0000428{
Matthew Bentham29cadb32018-10-01 17:22:32 +0100429 ClSplitterWorkloadTest<armnn::DataType::Float32>();
telsoa01c577f2c2018-08-31 09:22:23 +0100430}
431
432BOOST_AUTO_TEST_CASE(CreateSplitterFloat16Workload)
433{
Matthew Bentham29cadb32018-10-01 17:22:32 +0100434 ClSplitterWorkloadTest<armnn::DataType::Float16>();
telsoa01c577f2c2018-08-31 09:22:23 +0100435}
436
Matthew Bentham29cadb32018-10-01 17:22:32 +0100437template <typename MergerWorkloadType, typename armnn::DataType DataType>
telsoa01c577f2c2018-08-31 09:22:23 +0100438static void ClSplitterMergerTest()
439{
440 // Tests that it is possible to decide which output of the splitter layer
441 // should be lined to which input of the merger layer.
telsoa014fcda012018-03-09 14:13:49 +0000442 // We test that is is possible to specify 0th output
443 // of the splitter to be the 1st input to the merger and the 1st output of the splitter to be 0th input
444 // of the merger.
445
446 Graph graph;
447 ClWorkloadFactory factory;
telsoa014fcda012018-03-09 14:13:49 +0000448
449 auto workloads =
Matthew Bentham29cadb32018-10-01 17:22:32 +0100450 CreateSplitterMergerWorkloadTest<ClSplitterWorkload, MergerWorkloadType, DataType>
telsoa01c577f2c2018-08-31 09:22:23 +0100451 (factory, graph);
telsoa014fcda012018-03-09 14:13:49 +0000452
453 auto wlSplitter = std::move(workloads.first);
454 auto wlMerger = std::move(workloads.second);
455
telsoa01c577f2c2018-08-31 09:22:23 +0100456 //Checks that the index of inputs/outputs matches what we declared on InputDescriptor construction.
telsoa014fcda012018-03-09 14:13:49 +0000457 armnn::ClSubTensorHandle* sOut0 = dynamic_cast<armnn::ClSubTensorHandle*>(wlSplitter->GetData().m_Outputs[0]);
458 armnn::ClSubTensorHandle* sOut1 = dynamic_cast<armnn::ClSubTensorHandle*>(wlSplitter->GetData().m_Outputs[1]);
459 armnn::ClSubTensorHandle* mIn0 = dynamic_cast<armnn::ClSubTensorHandle*>(wlMerger->GetData().m_Inputs[0]);
460 armnn::ClSubTensorHandle* mIn1 = dynamic_cast<armnn::ClSubTensorHandle*>(wlMerger->GetData().m_Inputs[1]);
461
462 BOOST_TEST(sOut0);
463 BOOST_TEST(sOut1);
464 BOOST_TEST(mIn0);
465 BOOST_TEST(mIn1);
466
telsoa01c577f2c2018-08-31 09:22:23 +0100467 //Fliped order of inputs/outputs.
telsoa014fcda012018-03-09 14:13:49 +0000468 bool validDataPointers = (sOut0 == mIn1) && (sOut1 == mIn0);
469 BOOST_TEST(validDataPointers);
470
471
telsoa01c577f2c2018-08-31 09:22:23 +0100472 //Also make sure that the inputs are subtensors of one tensor and outputs are sub tensors of another tensor.
telsoa014fcda012018-03-09 14:13:49 +0000473 bool validSubTensorParents = (mIn0->GetTensor().parent() == mIn1->GetTensor().parent())
474 && (sOut0->GetTensor().parent() == sOut1->GetTensor().parent());
475
476 BOOST_TEST(validSubTensorParents);
477}
478
arovir019e53a352018-08-31 15:26:35 +0100479BOOST_AUTO_TEST_CASE(CreateSplitterMergerFloatWorkload)
telsoa01c577f2c2018-08-31 09:22:23 +0100480{
Matthew Bentham29cadb32018-10-01 17:22:32 +0100481 ClSplitterMergerTest<ClMergerFloatWorkload, armnn::DataType::Float32>();
telsoa01c577f2c2018-08-31 09:22:23 +0100482}
483
484BOOST_AUTO_TEST_CASE(CreateSplitterMergerFloat16Workload)
485{
Matthew Bentham29cadb32018-10-01 17:22:32 +0100486 ClSplitterMergerTest<ClMergerFloatWorkload, armnn::DataType::Float16>();
telsoa01c577f2c2018-08-31 09:22:23 +0100487}
488
489
telsoa014fcda012018-03-09 14:13:49 +0000490BOOST_AUTO_TEST_CASE(CreateSingleOutputMultipleInputs)
491{
492 // Test that it is possible to assign multiple (two) different layers to each of the outputs of a splitter layer.
telsoa01c577f2c2018-08-31 09:22:23 +0100493 // We create a splitter with two outputs. That each of those outputs is used by two different activation layers.
telsoa014fcda012018-03-09 14:13:49 +0000494
495 Graph graph;
496 ClWorkloadFactory factory;
Matthew Bentham29cadb32018-10-01 17:22:32 +0100497 std::unique_ptr<ClSplitterWorkload> wlSplitter;
arovir019e53a352018-08-31 15:26:35 +0100498 std::unique_ptr<ClActivationFloatWorkload> wlActiv0_0;
499 std::unique_ptr<ClActivationFloatWorkload> wlActiv0_1;
500 std::unique_ptr<ClActivationFloatWorkload> wlActiv1_0;
501 std::unique_ptr<ClActivationFloatWorkload> wlActiv1_1;
telsoa014fcda012018-03-09 14:13:49 +0000502
Matthew Bentham29cadb32018-10-01 17:22:32 +0100503 CreateSplitterMultipleInputsOneOutputWorkloadTest<ClSplitterWorkload,
arovir019e53a352018-08-31 15:26:35 +0100504 ClActivationFloatWorkload, armnn::DataType::Float32>(factory, graph, wlSplitter, wlActiv0_0, wlActiv0_1,
telsoa01c577f2c2018-08-31 09:22:23 +0100505 wlActiv1_0, wlActiv1_1);
telsoa014fcda012018-03-09 14:13:49 +0000506
telsoa01c577f2c2018-08-31 09:22:23 +0100507 //Checks that the index of inputs/outputs matches what we declared on InputDescriptor construction.
telsoa014fcda012018-03-09 14:13:49 +0000508 armnn::ClSubTensorHandle* sOut0 = dynamic_cast<armnn::ClSubTensorHandle*>(wlSplitter->GetData().m_Outputs[0]);
509 armnn::ClSubTensorHandle* sOut1 = dynamic_cast<armnn::ClSubTensorHandle*>(wlSplitter->GetData().m_Outputs[1]);
510 armnn::ClSubTensorHandle* activ0_0Im = dynamic_cast<armnn::ClSubTensorHandle*>(wlActiv0_0->GetData().m_Inputs[0]);
511 armnn::ClSubTensorHandle* activ0_1Im = dynamic_cast<armnn::ClSubTensorHandle*>(wlActiv0_1->GetData().m_Inputs[0]);
512 armnn::ClSubTensorHandle* activ1_0Im = dynamic_cast<armnn::ClSubTensorHandle*>(wlActiv1_0->GetData().m_Inputs[0]);
513 armnn::ClSubTensorHandle* activ1_1Im = dynamic_cast<armnn::ClSubTensorHandle*>(wlActiv1_1->GetData().m_Inputs[0]);
514
515
516 BOOST_TEST(sOut0);
517 BOOST_TEST(sOut1);
518 BOOST_TEST(activ0_0Im);
519 BOOST_TEST(activ0_1Im);
520 BOOST_TEST(activ1_0Im);
521 BOOST_TEST(activ1_1Im);
522
523 bool validDataPointers = (sOut0 == activ0_0Im) && (sOut0 == activ0_1Im) &&
524 (sOut1 == activ1_0Im) && (sOut1 == activ1_1Im);
525
526 BOOST_TEST(validDataPointers);
527}
528
529BOOST_AUTO_TEST_CASE(CreateMemCopyWorkloadsCl)
530{
531 ClWorkloadFactory factory;
telsoa01c577f2c2018-08-31 09:22:23 +0100532 CreateMemCopyWorkloads<IClTensorHandle>(factory);
telsoa014fcda012018-03-09 14:13:49 +0000533}
534
Matteo Martincighbcd3c852018-09-28 14:14:12 +0100535template <typename L2NormalizationWorkloadType, typename armnn::DataType DataType>
536static void ClL2NormalizationWorkloadTest(DataLayout dataLayout)
telsoa014fcda012018-03-09 14:13:49 +0000537{
telsoa01c577f2c2018-08-31 09:22:23 +0100538 Graph graph;
telsoa014fcda012018-03-09 14:13:49 +0000539 ClWorkloadFactory factory;
telsoa014fcda012018-03-09 14:13:49 +0000540
Matteo Martincighbcd3c852018-09-28 14:14:12 +0100541 auto workload = CreateL2NormalizationWorkloadTest<L2NormalizationWorkloadType, DataType>
542 (factory, graph, dataLayout);
telsoa014fcda012018-03-09 14:13:49 +0000543
telsoa01c577f2c2018-08-31 09:22:23 +0100544 // Checks that inputs/outputs are as we expect them (see definition of CreateNormalizationWorkloadTest).
telsoa014fcda012018-03-09 14:13:49 +0000545 L2NormalizationQueueDescriptor queueDescriptor = workload->GetData();
546 auto inputHandle = boost::polymorphic_downcast<IClTensorHandle*>(queueDescriptor.m_Inputs[0]);
547 auto outputHandle = boost::polymorphic_downcast<IClTensorHandle*>(queueDescriptor.m_Outputs[0]);
548
549 BOOST_TEST(CompareIClTensorHandleShape(inputHandle, { 5, 20, 50, 67 }));
550 BOOST_TEST(CompareIClTensorHandleShape(outputHandle, { 5, 20, 50, 67 }));
551}
552
Matteo Martincighbcd3c852018-09-28 14:14:12 +0100553BOOST_AUTO_TEST_CASE(CreateL2NormalizationFloatNchwWorkload)
554{
555 ClL2NormalizationWorkloadTest<ClL2NormalizationFloatWorkload, armnn::DataType::Float32>(DataLayout::NCHW);
556}
557
558BOOST_AUTO_TEST_CASE(CreateL2NormalizationFloatNhwcWorkload)
559{
560 ClL2NormalizationWorkloadTest<ClL2NormalizationFloatWorkload, armnn::DataType::Float32>(DataLayout::NHWC);
561}
562
563BOOST_AUTO_TEST_CASE(CreateL2NormalizationFloat16NchwWorkload)
564{
565 ClL2NormalizationWorkloadTest<ClL2NormalizationFloatWorkload, armnn::DataType::Float16>(DataLayout::NCHW);
566}
567
568BOOST_AUTO_TEST_CASE(CreateL2NormalizationFloat16NhwcWorkload)
569{
570 ClL2NormalizationWorkloadTest<ClL2NormalizationFloatWorkload, armnn::DataType::Float16>(DataLayout::NHWC);
571}
572
telsoa01c577f2c2018-08-31 09:22:23 +0100573template <typename LstmWorkloadType>
574static void ClCreateLstmWorkloadTest()
575{
576 Graph graph;
577 ClWorkloadFactory factory;
578 auto workload = CreateLstmWorkloadTest<LstmWorkloadType>(factory, graph);
579
580 LstmQueueDescriptor queueDescriptor = workload->GetData();
581 auto inputHandle = boost::polymorphic_downcast<IClTensorHandle*>(queueDescriptor.m_Inputs[0]);
582 auto outputHandle = boost::polymorphic_downcast<IClTensorHandle*>(queueDescriptor.m_Outputs[1]);
583 BOOST_TEST(CompareIClTensorHandleShape(inputHandle, { 2, 2 }));
584 BOOST_TEST(CompareIClTensorHandleShape(outputHandle, { 2, 4 }));
585}
586
arovir019e53a352018-08-31 15:26:35 +0100587BOOST_AUTO_TEST_CASE(CreateLSTMWorkloadFloatWorkload)
telsoa01c577f2c2018-08-31 09:22:23 +0100588{
arovir019e53a352018-08-31 15:26:35 +0100589 ClCreateLstmWorkloadTest<ClLstmFloatWorkload>();
telsoa01c577f2c2018-08-31 09:22:23 +0100590}
591
592
telsoa014fcda012018-03-09 14:13:49 +0000593BOOST_AUTO_TEST_SUITE_END()