blob: 078ef8c52de9da31d8eeb04550d82ef28161fd82 [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{
David Beck0a710c42018-09-11 15:21:14 +010088 ClCreateArithmethicWorkloadTest<ClSubtractionWorkload<armnn::DataType::Float16, armnn::DataType::Float32>,
David Beck4a8692c2018-09-07 16:19:24 +010089 SubtractionQueueDescriptor,
90 SubtractionLayer,
91 armnn::DataType::Float32>();
92}
93
94BOOST_AUTO_TEST_CASE(CreateSubtractionFloat16Workload)
95{
David Beck0a710c42018-09-11 15:21:14 +010096 ClCreateArithmethicWorkloadTest<ClSubtractionWorkload<armnn::DataType::Float16, armnn::DataType::Float32>,
David Beck4a8692c2018-09-07 16:19:24 +010097 SubtractionQueueDescriptor,
98 SubtractionLayer,
99 armnn::DataType::Float16>();
100}
101
102BOOST_AUTO_TEST_CASE(CreateMultiplicationFloatWorkloadTest)
103{
104 ClCreateArithmethicWorkloadTest<ClMultiplicationFloatWorkload,
105 MultiplicationQueueDescriptor,
106 MultiplicationLayer,
107 armnn::DataType::Float32>();
108}
109
110BOOST_AUTO_TEST_CASE(CreateMultiplicationFloat16WorkloadTest)
111{
112 ClCreateArithmethicWorkloadTest<ClMultiplicationFloatWorkload,
113 MultiplicationQueueDescriptor,
114 MultiplicationLayer,
115 armnn::DataType::Float16>();
116}
117
118BOOST_AUTO_TEST_CASE(CreateDivisionFloatWorkloadTest)
119{
120 ClCreateArithmethicWorkloadTest<ClDivisionFloatWorkload,
121 DivisionQueueDescriptor,
122 DivisionLayer,
123 armnn::DataType::Float32>();
124}
125
126BOOST_AUTO_TEST_CASE(CreateDivisionFloat16WorkloadTest)
127{
128 ClCreateArithmethicWorkloadTest<ClDivisionFloatWorkload,
129 DivisionQueueDescriptor,
130 DivisionLayer,
131 armnn::DataType::Float16>();
telsoa01c577f2c2018-08-31 09:22:23 +0100132}
133
134template <typename BatchNormalizationWorkloadType, armnn::DataType DataType>
135static void ClCreateBatchNormalizationWorkloadTest()
136{
137 Graph graph;
telsoa014fcda012018-03-09 14:13:49 +0000138 ClWorkloadFactory factory;
telsoa014fcda012018-03-09 14:13:49 +0000139
telsoa01c577f2c2018-08-31 09:22:23 +0100140 auto workload = CreateBatchNormalizationWorkloadTest<BatchNormalizationWorkloadType, DataType>
141 (factory, graph);
telsoa014fcda012018-03-09 14:13:49 +0000142
telsoa01c577f2c2018-08-31 09:22:23 +0100143 // Checks that inputs/outputs are as we expect them (see definition of CreateBatchNormalizationWorkloadTest).
telsoa014fcda012018-03-09 14:13:49 +0000144 BatchNormalizationQueueDescriptor queueDescriptor = workload->GetData();
145 auto inputHandle = boost::polymorphic_downcast<IClTensorHandle*>(queueDescriptor.m_Inputs[0]);
146 auto outputHandle = boost::polymorphic_downcast<IClTensorHandle*>(queueDescriptor.m_Outputs[0]);
147
148 BOOST_TEST(CompareIClTensorHandleShape(inputHandle, {2, 3, 1, 1}));
149 BOOST_TEST(CompareIClTensorHandleShape(outputHandle, {2, 3, 1, 1}));
150}
151
arovir019e53a352018-08-31 15:26:35 +0100152BOOST_AUTO_TEST_CASE(CreateBatchNormalizationFloatWorkload)
telsoa014fcda012018-03-09 14:13:49 +0000153{
arovir019e53a352018-08-31 15:26:35 +0100154 ClCreateBatchNormalizationWorkloadTest<ClBatchNormalizationFloatWorkload, armnn::DataType::Float32>();
telsoa01c577f2c2018-08-31 09:22:23 +0100155}
telsoa014fcda012018-03-09 14:13:49 +0000156
telsoa01c577f2c2018-08-31 09:22:23 +0100157BOOST_AUTO_TEST_CASE(CreateBatchNormalizationFloat16Workload)
158{
arovir019e53a352018-08-31 15:26:35 +0100159 ClCreateBatchNormalizationWorkloadTest<ClBatchNormalizationFloatWorkload, armnn::DataType::Float16>();
telsoa01c577f2c2018-08-31 09:22:23 +0100160}
161
162BOOST_AUTO_TEST_CASE(CreateConvertFp16ToFp32Workload)
163{
164 Graph graph;
165 ClWorkloadFactory factory;
166 auto workload = CreateConvertFp16ToFp32WorkloadTest<ClConvertFp16ToFp32Workload>(factory, graph);
167
168 ConvertFp16ToFp32QueueDescriptor queueDescriptor = workload->GetData();
169 auto inputHandle = boost::polymorphic_downcast<IClTensorHandle*>(queueDescriptor.m_Inputs[0]);
170 auto outputHandle = boost::polymorphic_downcast<IClTensorHandle*>(queueDescriptor.m_Outputs[0]);
171
172 BOOST_TEST(CompareIClTensorHandleShape(inputHandle, {3, 2, 3}));
173 BOOST_TEST(CompareIClTensorHandleShape(outputHandle, {3, 2, 3}));
174 BOOST_TEST((inputHandle->GetTensor().info()->data_type() == arm_compute::DataType::F16));
175 BOOST_TEST((outputHandle->GetTensor().info()->data_type() == arm_compute::DataType::F32));
176}
177
178BOOST_AUTO_TEST_CASE(CreateConvertFp32ToFp16Workload)
179{
180 Graph graph;
181 ClWorkloadFactory factory;
182 auto workload = CreateConvertFp32ToFp16WorkloadTest<ClConvertFp32ToFp16Workload>(factory, graph);
183
184 ConvertFp32ToFp16QueueDescriptor queueDescriptor = workload->GetData();
185 auto inputHandle = boost::polymorphic_downcast<IClTensorHandle*>(queueDescriptor.m_Inputs[0]);
186 auto outputHandle = boost::polymorphic_downcast<IClTensorHandle*>(queueDescriptor.m_Outputs[0]);
187
188 BOOST_TEST(CompareIClTensorHandleShape(inputHandle, {3, 2, 3}));
189 BOOST_TEST(CompareIClTensorHandleShape(outputHandle, {3, 2, 3}));
190 BOOST_TEST((inputHandle->GetTensor().info()->data_type() == arm_compute::DataType::F32));
191 BOOST_TEST((outputHandle->GetTensor().info()->data_type() == arm_compute::DataType::F16));
192}
193
194template <typename Convolution2dWorkloadType, typename armnn::DataType DataType>
195static void ClConvolution2dWorkloadTest()
196{
197 Graph graph;
198 ClWorkloadFactory factory;
199 auto workload = CreateConvolution2dWorkloadTest<Convolution2dWorkloadType, DataType>
200 (factory, graph);
201
202 // Checks that outputs and inputs are as we expect them (see definition of CreateConvolution2dWorkloadTest).
telsoa014fcda012018-03-09 14:13:49 +0000203 Convolution2dQueueDescriptor queueDescriptor = workload->GetData();
204 auto inputHandle = boost::polymorphic_downcast<IClTensorHandle*>(queueDescriptor.m_Inputs[0]);
205 auto outputHandle = boost::polymorphic_downcast<IClTensorHandle*>(queueDescriptor.m_Outputs[0]);
206 BOOST_TEST(CompareIClTensorHandleShape(inputHandle, {2, 3, 8, 16}));
207 BOOST_TEST(CompareIClTensorHandleShape(outputHandle, {2, 2, 2, 10}));
208}
209
arovir019e53a352018-08-31 15:26:35 +0100210BOOST_AUTO_TEST_CASE(CreateConvolution2dFloatWorkload)
telsoa014fcda012018-03-09 14:13:49 +0000211{
arovir019e53a352018-08-31 15:26:35 +0100212 ClConvolution2dWorkloadTest<ClConvolution2dFloatWorkload, armnn::DataType::Float32>();
telsoa01c577f2c2018-08-31 09:22:23 +0100213}
214
215BOOST_AUTO_TEST_CASE(CreateConvolution2dFloat16Workload)
216{
arovir019e53a352018-08-31 15:26:35 +0100217 ClConvolution2dWorkloadTest<ClConvolution2dFloatWorkload, armnn::DataType::Float16>();
telsoa014fcda012018-03-09 14:13:49 +0000218}
219
220
telsoa01c577f2c2018-08-31 09:22:23 +0100221template <typename Convolution2dWorkloadType, typename armnn::DataType DataType>
222static void ClDirectConvolution2dWorkloadTest()
telsoa014fcda012018-03-09 14:13:49 +0000223{
telsoa01c577f2c2018-08-31 09:22:23 +0100224 Graph graph;
225 ClWorkloadFactory factory;
226 auto workload = CreateDirectConvolution2dWorkloadTest<Convolution2dWorkloadType, DataType>(
227 factory, graph);
telsoa014fcda012018-03-09 14:13:49 +0000228
telsoa01c577f2c2018-08-31 09:22:23 +0100229 // Checks that outputs and inputs are as we expect them (see definition of CreateDirectConvolution2dWorkloadTest).
telsoa014fcda012018-03-09 14:13:49 +0000230 Convolution2dQueueDescriptor queueDescriptor = workload->GetData();
231 auto inputHandle = boost::polymorphic_downcast<IClTensorHandle*>(queueDescriptor.m_Inputs[0]);
232 auto outputHandle = boost::polymorphic_downcast<IClTensorHandle*>(queueDescriptor.m_Outputs[0]);
233 BOOST_TEST(CompareIClTensorHandleShape(inputHandle, {2, 3, 6, 6}));
234 BOOST_TEST(CompareIClTensorHandleShape(outputHandle, {2, 2, 6, 6}));
235}
236
arovir019e53a352018-08-31 15:26:35 +0100237BOOST_AUTO_TEST_CASE(CreateDirectConvolution2dFloatWorkload)
telsoa014fcda012018-03-09 14:13:49 +0000238{
arovir019e53a352018-08-31 15:26:35 +0100239 ClDirectConvolution2dWorkloadTest<ClConvolution2dFloatWorkload, armnn::DataType::Float32>();
telsoa01c577f2c2018-08-31 09:22:23 +0100240}
241
242BOOST_AUTO_TEST_CASE(CreateDirectConvolution2dFloat16Workload)
243{
arovir019e53a352018-08-31 15:26:35 +0100244 ClDirectConvolution2dWorkloadTest<ClConvolution2dFloatWorkload, armnn::DataType::Float16>();
telsoa014fcda012018-03-09 14:13:49 +0000245}
246
247BOOST_AUTO_TEST_CASE(CreateDirectConvolution2dUint8Workload)
248{
telsoa01c577f2c2018-08-31 09:22:23 +0100249 ClDirectConvolution2dWorkloadTest<ClConvolution2dUint8Workload, armnn::DataType::QuantisedAsymm8>();
telsoa014fcda012018-03-09 14:13:49 +0000250}
251
telsoa01c577f2c2018-08-31 09:22:23 +0100252template <typename FullyConnectedWorkloadType, typename armnn::DataType DataType>
253static void ClCreateFullyConnectedWorkloadTest()
telsoa014fcda012018-03-09 14:13:49 +0000254{
telsoa01c577f2c2018-08-31 09:22:23 +0100255 Graph graph;
telsoa014fcda012018-03-09 14:13:49 +0000256 ClWorkloadFactory factory;
telsoa01c577f2c2018-08-31 09:22:23 +0100257 auto workload =
258 CreateFullyConnectedWorkloadTest<FullyConnectedWorkloadType, DataType>(factory, graph);
telsoa014fcda012018-03-09 14:13:49 +0000259
telsoa01c577f2c2018-08-31 09:22:23 +0100260 // Checks that outputs and inputs are as we expect them (see definition of CreateFullyConnectedWorkloadTest).
telsoa014fcda012018-03-09 14:13:49 +0000261 FullyConnectedQueueDescriptor queueDescriptor = workload->GetData();
262 auto inputHandle = boost::polymorphic_downcast<IClTensorHandle*>(queueDescriptor.m_Inputs[0]);
263 auto outputHandle = boost::polymorphic_downcast<IClTensorHandle*>(queueDescriptor.m_Outputs[0]);
264 BOOST_TEST(CompareIClTensorHandleShape(inputHandle, {3, 1, 4, 5}));
265 BOOST_TEST(CompareIClTensorHandleShape(outputHandle, {3, 7}));
266}
267
telsoa01c577f2c2018-08-31 09:22:23 +0100268
arovir019e53a352018-08-31 15:26:35 +0100269BOOST_AUTO_TEST_CASE(CreateFullyConnectedFloatWorkloadTest)
telsoa014fcda012018-03-09 14:13:49 +0000270{
Matthew Benthamab8cdc12018-09-17 11:17:41 +0100271 ClCreateFullyConnectedWorkloadTest<ClFullyConnectedWorkload, armnn::DataType::Float32>();
telsoa01c577f2c2018-08-31 09:22:23 +0100272}
273
274BOOST_AUTO_TEST_CASE(CreateFullyConnectedFloat16WorkloadTest)
275{
Matthew Benthamab8cdc12018-09-17 11:17:41 +0100276 ClCreateFullyConnectedWorkloadTest<ClFullyConnectedWorkload, armnn::DataType::Float16>();
telsoa01c577f2c2018-08-31 09:22:23 +0100277}
278
telsoa01c577f2c2018-08-31 09:22:23 +0100279template <typename NormalizationWorkloadType, typename armnn::DataType DataType>
280static void ClNormalizationWorkloadTest()
281{
282 Graph graph;
telsoa014fcda012018-03-09 14:13:49 +0000283 ClWorkloadFactory factory;
telsoa014fcda012018-03-09 14:13:49 +0000284
telsoa01c577f2c2018-08-31 09:22:23 +0100285 auto workload = CreateNormalizationWorkloadTest<NormalizationWorkloadType, DataType>
286 (factory, graph);
telsoa014fcda012018-03-09 14:13:49 +0000287
telsoa01c577f2c2018-08-31 09:22:23 +0100288 // Checks that inputs/outputs are as we expect them (see definition of CreateNormalizationWorkloadTest).
telsoa014fcda012018-03-09 14:13:49 +0000289 NormalizationQueueDescriptor queueDescriptor = workload->GetData();
290 auto inputHandle = boost::polymorphic_downcast<IClTensorHandle*>(queueDescriptor.m_Inputs[0]);
291 auto outputHandle = boost::polymorphic_downcast<IClTensorHandle*>(queueDescriptor.m_Outputs[0]);
292
293 BOOST_TEST(CompareIClTensorHandleShape(inputHandle, {3, 5, 5, 1}));
294 BOOST_TEST(CompareIClTensorHandleShape(outputHandle, {3, 5, 5, 1}));
295}
296
arovir019e53a352018-08-31 15:26:35 +0100297BOOST_AUTO_TEST_CASE(CreateNormalizationFloatWorkload)
telsoa014fcda012018-03-09 14:13:49 +0000298{
arovir019e53a352018-08-31 15:26:35 +0100299 ClNormalizationWorkloadTest<ClNormalizationFloatWorkload, armnn::DataType::Float32>();
telsoa01c577f2c2018-08-31 09:22:23 +0100300}
301
302BOOST_AUTO_TEST_CASE(CreateNormalizationFloat16Workload)
303{
arovir019e53a352018-08-31 15:26:35 +0100304 ClNormalizationWorkloadTest<ClNormalizationFloatWorkload, armnn::DataType::Float16>();
telsoa01c577f2c2018-08-31 09:22:23 +0100305}
306
307template <typename Pooling2dWorkloadType, typename armnn::DataType DataType>
308static void ClPooling2dWorkloadTest()
309{
310 Graph graph;
telsoa014fcda012018-03-09 14:13:49 +0000311 ClWorkloadFactory factory;
telsoa014fcda012018-03-09 14:13:49 +0000312
telsoa01c577f2c2018-08-31 09:22:23 +0100313 auto workload = CreatePooling2dWorkloadTest<Pooling2dWorkloadType, DataType>(factory, graph);
telsoa014fcda012018-03-09 14:13:49 +0000314
telsoa01c577f2c2018-08-31 09:22:23 +0100315 // Check that inputs/outputs are as we expect them (see definition of CreatePooling2dWorkloadTest).
telsoa014fcda012018-03-09 14:13:49 +0000316 Pooling2dQueueDescriptor queueDescriptor = workload->GetData();
317 auto inputHandle = boost::polymorphic_downcast<IClTensorHandle*>(queueDescriptor.m_Inputs[0]);
318 auto outputHandle = boost::polymorphic_downcast<IClTensorHandle*>(queueDescriptor.m_Outputs[0]);
319
320 BOOST_TEST(CompareIClTensorHandleShape(inputHandle, {3, 2, 5, 5}));
321 BOOST_TEST(CompareIClTensorHandleShape(outputHandle, {3, 2, 2, 4}));
322}
323
arovir019e53a352018-08-31 15:26:35 +0100324BOOST_AUTO_TEST_CASE(CreatePooling2dFloatWorkload)
telsoa01c577f2c2018-08-31 09:22:23 +0100325{
arovir019e53a352018-08-31 15:26:35 +0100326 ClPooling2dWorkloadTest<ClPooling2dFloatWorkload, armnn::DataType::Float32>();
telsoa01c577f2c2018-08-31 09:22:23 +0100327}
328
329BOOST_AUTO_TEST_CASE(CreatePooling2dFloat16Workload)
330{
arovir019e53a352018-08-31 15:26:35 +0100331 ClPooling2dWorkloadTest<ClPooling2dFloatWorkload, armnn::DataType::Float16>();
telsoa01c577f2c2018-08-31 09:22:23 +0100332}
333
334template <typename ReshapeWorkloadType, typename armnn::DataType DataType>
telsoa014fcda012018-03-09 14:13:49 +0000335static void ClCreateReshapeWorkloadTest()
336{
telsoa01c577f2c2018-08-31 09:22:23 +0100337 Graph graph;
telsoa014fcda012018-03-09 14:13:49 +0000338 ClWorkloadFactory factory;
telsoa014fcda012018-03-09 14:13:49 +0000339
telsoa01c577f2c2018-08-31 09:22:23 +0100340 auto workload = CreateReshapeWorkloadTest<ReshapeWorkloadType, DataType>(factory, graph);
telsoa014fcda012018-03-09 14:13:49 +0000341
telsoa01c577f2c2018-08-31 09:22:23 +0100342 // Checks that outputs and inputs are as we expect them (see definition of CreateReshapeWorkloadTest).
telsoa014fcda012018-03-09 14:13:49 +0000343 ReshapeQueueDescriptor queueDescriptor = workload->GetData();
telsoa01c577f2c2018-08-31 09:22:23 +0100344 auto inputHandle = boost::polymorphic_downcast<IClTensorHandle*>(queueDescriptor.m_Inputs[0]);
345 auto outputHandle = boost::polymorphic_downcast<IClTensorHandle*>(queueDescriptor.m_Outputs[0]);
telsoa014fcda012018-03-09 14:13:49 +0000346
347 BOOST_TEST(CompareIClTensorHandleShape(inputHandle, {4, 1}));
348 BOOST_TEST(CompareIClTensorHandleShape(outputHandle, {4})); // Leading size 1 dimensions are collapsed by ACL.
349}
350
arovir019e53a352018-08-31 15:26:35 +0100351BOOST_AUTO_TEST_CASE(CreateReshapeFloatWorkload)
telsoa014fcda012018-03-09 14:13:49 +0000352{
arovir019e53a352018-08-31 15:26:35 +0100353 ClCreateReshapeWorkloadTest<ClReshapeFloatWorkload, armnn::DataType::Float32>();
telsoa01c577f2c2018-08-31 09:22:23 +0100354}
355
356BOOST_AUTO_TEST_CASE(CreateReshapeFloat16Workload)
357{
arovir019e53a352018-08-31 15:26:35 +0100358 ClCreateReshapeWorkloadTest<ClReshapeFloatWorkload, armnn::DataType::Float16>();
telsoa014fcda012018-03-09 14:13:49 +0000359}
360
361BOOST_AUTO_TEST_CASE(CreateReshapeUint8Workload)
362{
telsoa01c577f2c2018-08-31 09:22:23 +0100363 ClCreateReshapeWorkloadTest<ClReshapeUint8Workload, armnn::DataType::QuantisedAsymm8>();
telsoa014fcda012018-03-09 14:13:49 +0000364}
365
telsoa01c577f2c2018-08-31 09:22:23 +0100366template <typename SoftmaxWorkloadType, typename armnn::DataType DataType>
367static void ClSoftmaxWorkloadTest()
telsoa014fcda012018-03-09 14:13:49 +0000368{
telsoa01c577f2c2018-08-31 09:22:23 +0100369 Graph graph;
telsoa014fcda012018-03-09 14:13:49 +0000370 ClWorkloadFactory factory;
telsoa014fcda012018-03-09 14:13:49 +0000371
telsoa01c577f2c2018-08-31 09:22:23 +0100372 auto workload = CreateSoftmaxWorkloadTest<SoftmaxWorkloadType, DataType>(factory, graph);
telsoa014fcda012018-03-09 14:13:49 +0000373
arovir019e53a352018-08-31 15:26:35 +0100374 // Checks that inputs/outputs are as we expect them (see definition of ClSoftmaxFloatWorkload).
telsoa014fcda012018-03-09 14:13:49 +0000375 SoftmaxQueueDescriptor queueDescriptor = workload->GetData();
telsoa01c577f2c2018-08-31 09:22:23 +0100376 auto inputHandle = boost::polymorphic_downcast<IClTensorHandle*>(queueDescriptor.m_Inputs[0]);
377 auto outputHandle = boost::polymorphic_downcast<IClTensorHandle*>(queueDescriptor.m_Outputs[0]);
telsoa014fcda012018-03-09 14:13:49 +0000378
379 BOOST_TEST(CompareIClTensorHandleShape(inputHandle, {4, 1}));
380 BOOST_TEST(CompareIClTensorHandleShape(outputHandle, {4, 1}));
381}
382
telsoa01c577f2c2018-08-31 09:22:23 +0100383
arovir019e53a352018-08-31 15:26:35 +0100384BOOST_AUTO_TEST_CASE(CreateSoftmaxFloatWorkloadTest)
telsoa01c577f2c2018-08-31 09:22:23 +0100385{
arovir019e53a352018-08-31 15:26:35 +0100386 ClSoftmaxWorkloadTest<ClSoftmaxFloatWorkload, armnn::DataType::Float32>();
telsoa01c577f2c2018-08-31 09:22:23 +0100387}
388
389BOOST_AUTO_TEST_CASE(CreateSoftmaxFloat16WorkloadTest)
390{
arovir019e53a352018-08-31 15:26:35 +0100391 ClSoftmaxWorkloadTest<ClSoftmaxFloatWorkload, armnn::DataType::Float16>();
telsoa01c577f2c2018-08-31 09:22:23 +0100392}
393
394template <typename SplitterWorkloadType, typename armnn::DataType DataType>
395static void ClSplitterWorkloadTest()
telsoa014fcda012018-03-09 14:13:49 +0000396{
397 Graph graph;
398 ClWorkloadFactory factory;
telsoa014fcda012018-03-09 14:13:49 +0000399
telsoa01c577f2c2018-08-31 09:22:23 +0100400 auto workload = CreateSplitterWorkloadTest<SplitterWorkloadType, DataType>(factory, graph);
telsoa014fcda012018-03-09 14:13:49 +0000401
telsoa01c577f2c2018-08-31 09:22:23 +0100402 // Checks that outputs are as we expect them (see definition of CreateSplitterWorkloadTest).
telsoa014fcda012018-03-09 14:13:49 +0000403 SplitterQueueDescriptor queueDescriptor = workload->GetData();
404 auto inputHandle = boost::polymorphic_downcast<IClTensorHandle*>(queueDescriptor.m_Inputs[0]);
surmeh013537c2c2018-05-18 16:31:43 +0100405 BOOST_TEST(CompareIClTensorHandleShape(inputHandle, {5, 7, 7}));
406
telsoa014fcda012018-03-09 14:13:49 +0000407 auto outputHandle1 = boost::polymorphic_downcast<IClTensorHandle*>(queueDescriptor.m_Outputs[1]);
surmeh013537c2c2018-05-18 16:31:43 +0100408 BOOST_TEST(CompareIClTensorHandleShape(outputHandle1, {2, 7, 7}));
409
telsoa014fcda012018-03-09 14:13:49 +0000410 auto outputHandle2 = boost::polymorphic_downcast<IClTensorHandle*>(queueDescriptor.m_Outputs[2]);
surmeh013537c2c2018-05-18 16:31:43 +0100411 BOOST_TEST(CompareIClTensorHandleShape(outputHandle2, {2, 7, 7}));
412
413 auto outputHandle0 = boost::polymorphic_downcast<IClTensorHandle*>(queueDescriptor.m_Outputs[0]);
414 // NOTE: At the moment the CL collapses the tensor to a 2 dim when dimension zero = 1
telsoa01c577f2c2018-08-31 09:22:23 +0100415 // 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 +0100416 BOOST_TEST(CompareIClTensorHandleShape(outputHandle0, {7, 7}));
telsoa014fcda012018-03-09 14:13:49 +0000417}
418
arovir019e53a352018-08-31 15:26:35 +0100419BOOST_AUTO_TEST_CASE(CreateSplitterFloatWorkload)
telsoa014fcda012018-03-09 14:13:49 +0000420{
arovir019e53a352018-08-31 15:26:35 +0100421 ClSplitterWorkloadTest<ClSplitterFloatWorkload, armnn::DataType::Float32>();
telsoa01c577f2c2018-08-31 09:22:23 +0100422}
423
424BOOST_AUTO_TEST_CASE(CreateSplitterFloat16Workload)
425{
arovir019e53a352018-08-31 15:26:35 +0100426 ClSplitterWorkloadTest<ClSplitterFloatWorkload, armnn::DataType::Float16>();
telsoa01c577f2c2018-08-31 09:22:23 +0100427}
428
429template <typename SplitterWorkloadType, typename MergerWorkloadType, typename armnn::DataType DataType>
430static void ClSplitterMergerTest()
431{
432 // Tests that it is possible to decide which output of the splitter layer
433 // should be lined to which input of the merger layer.
telsoa014fcda012018-03-09 14:13:49 +0000434 // We test that is is possible to specify 0th output
435 // of the splitter to be the 1st input to the merger and the 1st output of the splitter to be 0th input
436 // of the merger.
437
438 Graph graph;
439 ClWorkloadFactory factory;
telsoa014fcda012018-03-09 14:13:49 +0000440
441 auto workloads =
telsoa01c577f2c2018-08-31 09:22:23 +0100442 CreateSplitterMergerWorkloadTest<SplitterWorkloadType, MergerWorkloadType, DataType>
443 (factory, graph);
telsoa014fcda012018-03-09 14:13:49 +0000444
445 auto wlSplitter = std::move(workloads.first);
446 auto wlMerger = std::move(workloads.second);
447
telsoa01c577f2c2018-08-31 09:22:23 +0100448 //Checks that the index of inputs/outputs matches what we declared on InputDescriptor construction.
telsoa014fcda012018-03-09 14:13:49 +0000449 armnn::ClSubTensorHandle* sOut0 = dynamic_cast<armnn::ClSubTensorHandle*>(wlSplitter->GetData().m_Outputs[0]);
450 armnn::ClSubTensorHandle* sOut1 = dynamic_cast<armnn::ClSubTensorHandle*>(wlSplitter->GetData().m_Outputs[1]);
451 armnn::ClSubTensorHandle* mIn0 = dynamic_cast<armnn::ClSubTensorHandle*>(wlMerger->GetData().m_Inputs[0]);
452 armnn::ClSubTensorHandle* mIn1 = dynamic_cast<armnn::ClSubTensorHandle*>(wlMerger->GetData().m_Inputs[1]);
453
454 BOOST_TEST(sOut0);
455 BOOST_TEST(sOut1);
456 BOOST_TEST(mIn0);
457 BOOST_TEST(mIn1);
458
telsoa01c577f2c2018-08-31 09:22:23 +0100459 //Fliped order of inputs/outputs.
telsoa014fcda012018-03-09 14:13:49 +0000460 bool validDataPointers = (sOut0 == mIn1) && (sOut1 == mIn0);
461 BOOST_TEST(validDataPointers);
462
463
telsoa01c577f2c2018-08-31 09:22:23 +0100464 //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 +0000465 bool validSubTensorParents = (mIn0->GetTensor().parent() == mIn1->GetTensor().parent())
466 && (sOut0->GetTensor().parent() == sOut1->GetTensor().parent());
467
468 BOOST_TEST(validSubTensorParents);
469}
470
arovir019e53a352018-08-31 15:26:35 +0100471BOOST_AUTO_TEST_CASE(CreateSplitterMergerFloatWorkload)
telsoa01c577f2c2018-08-31 09:22:23 +0100472{
arovir019e53a352018-08-31 15:26:35 +0100473 ClSplitterMergerTest<ClSplitterFloatWorkload, ClMergerFloatWorkload, armnn::DataType::Float32>();
telsoa01c577f2c2018-08-31 09:22:23 +0100474}
475
476BOOST_AUTO_TEST_CASE(CreateSplitterMergerFloat16Workload)
477{
arovir019e53a352018-08-31 15:26:35 +0100478 ClSplitterMergerTest<ClSplitterFloatWorkload, ClMergerFloatWorkload, armnn::DataType::Float16>();
telsoa01c577f2c2018-08-31 09:22:23 +0100479}
480
481
telsoa014fcda012018-03-09 14:13:49 +0000482BOOST_AUTO_TEST_CASE(CreateSingleOutputMultipleInputs)
483{
484 // 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 +0100485 // 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 +0000486
487 Graph graph;
488 ClWorkloadFactory factory;
arovir019e53a352018-08-31 15:26:35 +0100489 std::unique_ptr<ClSplitterFloatWorkload> wlSplitter;
490 std::unique_ptr<ClActivationFloatWorkload> wlActiv0_0;
491 std::unique_ptr<ClActivationFloatWorkload> wlActiv0_1;
492 std::unique_ptr<ClActivationFloatWorkload> wlActiv1_0;
493 std::unique_ptr<ClActivationFloatWorkload> wlActiv1_1;
telsoa014fcda012018-03-09 14:13:49 +0000494
arovir019e53a352018-08-31 15:26:35 +0100495 CreateSplitterMultipleInputsOneOutputWorkloadTest<ClSplitterFloatWorkload,
496 ClActivationFloatWorkload, armnn::DataType::Float32>(factory, graph, wlSplitter, wlActiv0_0, wlActiv0_1,
telsoa01c577f2c2018-08-31 09:22:23 +0100497 wlActiv1_0, wlActiv1_1);
telsoa014fcda012018-03-09 14:13:49 +0000498
telsoa01c577f2c2018-08-31 09:22:23 +0100499 //Checks that the index of inputs/outputs matches what we declared on InputDescriptor construction.
telsoa014fcda012018-03-09 14:13:49 +0000500 armnn::ClSubTensorHandle* sOut0 = dynamic_cast<armnn::ClSubTensorHandle*>(wlSplitter->GetData().m_Outputs[0]);
501 armnn::ClSubTensorHandle* sOut1 = dynamic_cast<armnn::ClSubTensorHandle*>(wlSplitter->GetData().m_Outputs[1]);
502 armnn::ClSubTensorHandle* activ0_0Im = dynamic_cast<armnn::ClSubTensorHandle*>(wlActiv0_0->GetData().m_Inputs[0]);
503 armnn::ClSubTensorHandle* activ0_1Im = dynamic_cast<armnn::ClSubTensorHandle*>(wlActiv0_1->GetData().m_Inputs[0]);
504 armnn::ClSubTensorHandle* activ1_0Im = dynamic_cast<armnn::ClSubTensorHandle*>(wlActiv1_0->GetData().m_Inputs[0]);
505 armnn::ClSubTensorHandle* activ1_1Im = dynamic_cast<armnn::ClSubTensorHandle*>(wlActiv1_1->GetData().m_Inputs[0]);
506
507
508 BOOST_TEST(sOut0);
509 BOOST_TEST(sOut1);
510 BOOST_TEST(activ0_0Im);
511 BOOST_TEST(activ0_1Im);
512 BOOST_TEST(activ1_0Im);
513 BOOST_TEST(activ1_1Im);
514
515 bool validDataPointers = (sOut0 == activ0_0Im) && (sOut0 == activ0_1Im) &&
516 (sOut1 == activ1_0Im) && (sOut1 == activ1_1Im);
517
518 BOOST_TEST(validDataPointers);
519}
520
521BOOST_AUTO_TEST_CASE(CreateMemCopyWorkloadsCl)
522{
523 ClWorkloadFactory factory;
telsoa01c577f2c2018-08-31 09:22:23 +0100524 CreateMemCopyWorkloads<IClTensorHandle>(factory);
telsoa014fcda012018-03-09 14:13:49 +0000525}
526
Matteo Martincighbcd3c852018-09-28 14:14:12 +0100527template <typename L2NormalizationWorkloadType, typename armnn::DataType DataType>
528static void ClL2NormalizationWorkloadTest(DataLayout dataLayout)
telsoa014fcda012018-03-09 14:13:49 +0000529{
telsoa01c577f2c2018-08-31 09:22:23 +0100530 Graph graph;
telsoa014fcda012018-03-09 14:13:49 +0000531 ClWorkloadFactory factory;
telsoa014fcda012018-03-09 14:13:49 +0000532
Matteo Martincighbcd3c852018-09-28 14:14:12 +0100533 auto workload = CreateL2NormalizationWorkloadTest<L2NormalizationWorkloadType, DataType>
534 (factory, graph, dataLayout);
telsoa014fcda012018-03-09 14:13:49 +0000535
telsoa01c577f2c2018-08-31 09:22:23 +0100536 // Checks that inputs/outputs are as we expect them (see definition of CreateNormalizationWorkloadTest).
telsoa014fcda012018-03-09 14:13:49 +0000537 L2NormalizationQueueDescriptor queueDescriptor = workload->GetData();
538 auto inputHandle = boost::polymorphic_downcast<IClTensorHandle*>(queueDescriptor.m_Inputs[0]);
539 auto outputHandle = boost::polymorphic_downcast<IClTensorHandle*>(queueDescriptor.m_Outputs[0]);
540
541 BOOST_TEST(CompareIClTensorHandleShape(inputHandle, { 5, 20, 50, 67 }));
542 BOOST_TEST(CompareIClTensorHandleShape(outputHandle, { 5, 20, 50, 67 }));
543}
544
Matteo Martincighbcd3c852018-09-28 14:14:12 +0100545BOOST_AUTO_TEST_CASE(CreateL2NormalizationFloatNchwWorkload)
546{
547 ClL2NormalizationWorkloadTest<ClL2NormalizationFloatWorkload, armnn::DataType::Float32>(DataLayout::NCHW);
548}
549
550BOOST_AUTO_TEST_CASE(CreateL2NormalizationFloatNhwcWorkload)
551{
552 ClL2NormalizationWorkloadTest<ClL2NormalizationFloatWorkload, armnn::DataType::Float32>(DataLayout::NHWC);
553}
554
555BOOST_AUTO_TEST_CASE(CreateL2NormalizationFloat16NchwWorkload)
556{
557 ClL2NormalizationWorkloadTest<ClL2NormalizationFloatWorkload, armnn::DataType::Float16>(DataLayout::NCHW);
558}
559
560BOOST_AUTO_TEST_CASE(CreateL2NormalizationFloat16NhwcWorkload)
561{
562 ClL2NormalizationWorkloadTest<ClL2NormalizationFloatWorkload, armnn::DataType::Float16>(DataLayout::NHWC);
563}
564
telsoa01c577f2c2018-08-31 09:22:23 +0100565template <typename LstmWorkloadType>
566static void ClCreateLstmWorkloadTest()
567{
568 Graph graph;
569 ClWorkloadFactory factory;
570 auto workload = CreateLstmWorkloadTest<LstmWorkloadType>(factory, graph);
571
572 LstmQueueDescriptor queueDescriptor = workload->GetData();
573 auto inputHandle = boost::polymorphic_downcast<IClTensorHandle*>(queueDescriptor.m_Inputs[0]);
574 auto outputHandle = boost::polymorphic_downcast<IClTensorHandle*>(queueDescriptor.m_Outputs[1]);
575 BOOST_TEST(CompareIClTensorHandleShape(inputHandle, { 2, 2 }));
576 BOOST_TEST(CompareIClTensorHandleShape(outputHandle, { 2, 4 }));
577}
578
arovir019e53a352018-08-31 15:26:35 +0100579BOOST_AUTO_TEST_CASE(CreateLSTMWorkloadFloatWorkload)
telsoa01c577f2c2018-08-31 09:22:23 +0100580{
arovir019e53a352018-08-31 15:26:35 +0100581 ClCreateLstmWorkloadTest<ClLstmFloatWorkload>();
telsoa01c577f2c2018-08-31 09:22:23 +0100582}
583
584
telsoa014fcda012018-03-09 14:13:49 +0000585BOOST_AUTO_TEST_SUITE_END()