IVGCVSW-3296 Add CL backend support for ResizeNearestNeighbour
[platform/upstream/armnn.git] / src / backends / cl / test / ClCreateWorkloadTests.cpp
1 //
2 // Copyright © 2017 Arm Ltd. All rights reserved.
3 // SPDX-License-Identifier: MIT
4 //
5
6 #include "ClContextControlFixture.hpp"
7 #include "ClWorkloadFactoryHelper.hpp"
8
9 #include <backendsCommon/MemCopyWorkload.hpp>
10
11 #include <aclCommon/test/CreateWorkloadClNeon.hpp>
12
13 #include <cl/ClTensorHandle.hpp>
14 #include <cl/ClWorkloadFactory.hpp>
15 #include <cl/workloads/ClWorkloads.hpp>
16 #include <cl/workloads/ClWorkloadUtils.hpp>
17
18 boost::test_tools::predicate_result CompareIClTensorHandleShape(IClTensorHandle*                    tensorHandle,
19                                                                 std::initializer_list<unsigned int> expectedDimensions)
20 {
21     return CompareTensorHandleShape<IClTensorHandle>(tensorHandle, expectedDimensions);
22 }
23
24 BOOST_FIXTURE_TEST_SUITE(CreateWorkloadCl, ClContextControlFixture)
25
26 template <armnn::DataType DataType>
27 static void ClCreateActivationWorkloadTest()
28 {
29     Graph graph;
30     ClWorkloadFactory factory =
31         ClWorkloadFactoryHelper::GetFactory(ClWorkloadFactoryHelper::GetMemoryManager());
32
33     auto workload = CreateActivationWorkloadTest<ClActivationWorkload, DataType>(factory, graph);
34
35     // Checks that inputs/outputs are as we expect them (see definition of CreateActivationWorkloadTest).
36     ActivationQueueDescriptor queueDescriptor = workload->GetData();
37     auto inputHandle = boost::polymorphic_downcast<IClTensorHandle*>(queueDescriptor.m_Inputs[0]);
38     auto outputHandle = boost::polymorphic_downcast<IClTensorHandle*>(queueDescriptor.m_Outputs[0]);
39
40     BOOST_TEST(CompareIClTensorHandleShape(inputHandle, {1, 1}));
41     BOOST_TEST(CompareIClTensorHandleShape(outputHandle, {1, 1}));
42 }
43
44 BOOST_AUTO_TEST_CASE(CreateActivationFloatWorkload)
45 {
46     ClCreateActivationWorkloadTest<armnn::DataType::Float32>();
47 }
48
49 BOOST_AUTO_TEST_CASE(CreateActivationFloat16Workload)
50 {
51     ClCreateActivationWorkloadTest<armnn::DataType::Float16>();
52 }
53
54 template <typename WorkloadType,
55           typename DescriptorType,
56           typename LayerType,
57           armnn::DataType DataType>
58 static void ClCreateElementwiseWorkloadTest()
59 {
60     Graph graph;
61     ClWorkloadFactory factory =
62         ClWorkloadFactoryHelper::GetFactory(ClWorkloadFactoryHelper::GetMemoryManager());
63
64     auto workload = CreateElementwiseWorkloadTest<WorkloadType, DescriptorType, LayerType, DataType>(factory, graph);
65
66     // Checks that inputs/outputs are as we expect them (see definition of CreateElementwiseWorkloadTest).
67     DescriptorType queueDescriptor = workload->GetData();
68     auto inputHandle1 = boost::polymorphic_downcast<IClTensorHandle*>(queueDescriptor.m_Inputs[0]);
69     auto inputHandle2 = boost::polymorphic_downcast<IClTensorHandle*>(queueDescriptor.m_Inputs[1]);
70     auto outputHandle = boost::polymorphic_downcast<IClTensorHandle*>(queueDescriptor.m_Outputs[0]);
71     BOOST_TEST(CompareIClTensorHandleShape(inputHandle1, {2, 3}));
72     BOOST_TEST(CompareIClTensorHandleShape(inputHandle2, {2, 3}));
73     BOOST_TEST(CompareIClTensorHandleShape(outputHandle, {2, 3}));
74 }
75
76 BOOST_AUTO_TEST_CASE(CreateAdditionFloatWorkload)
77 {
78     ClCreateElementwiseWorkloadTest<ClAdditionWorkload,
79                                     AdditionQueueDescriptor,
80                                     AdditionLayer,
81                                     armnn::DataType::Float32>();
82 }
83
84 BOOST_AUTO_TEST_CASE(CreateAdditionFloat16Workload)
85 {
86     ClCreateElementwiseWorkloadTest<ClAdditionWorkload,
87                                     AdditionQueueDescriptor,
88                                     AdditionLayer,
89                                     armnn::DataType::Float16>();
90 }
91
92 BOOST_AUTO_TEST_CASE(CreateSubtractionFloatWorkload)
93 {
94     ClCreateElementwiseWorkloadTest<ClSubtractionWorkload,
95                                     SubtractionQueueDescriptor,
96                                     SubtractionLayer,
97                                     armnn::DataType::Float32>();
98 }
99
100 BOOST_AUTO_TEST_CASE(CreateSubtractionFloat16Workload)
101 {
102     ClCreateElementwiseWorkloadTest<ClSubtractionWorkload,
103                                     SubtractionQueueDescriptor,
104                                     SubtractionLayer,
105                                     armnn::DataType::Float16>();
106 }
107
108 BOOST_AUTO_TEST_CASE(CreateMultiplicationFloatWorkloadTest)
109 {
110     ClCreateElementwiseWorkloadTest<ClMultiplicationWorkload,
111                                     MultiplicationQueueDescriptor,
112                                     MultiplicationLayer,
113                                     armnn::DataType::Float32>();
114 }
115
116 BOOST_AUTO_TEST_CASE(CreateMultiplicationFloat16WorkloadTest)
117 {
118     ClCreateElementwiseWorkloadTest<ClMultiplicationWorkload,
119                                     MultiplicationQueueDescriptor,
120                                     MultiplicationLayer,
121                                     armnn::DataType::Float16>();
122 }
123
124 BOOST_AUTO_TEST_CASE(CreateMultiplicationUint8WorkloadTest)
125 {
126     ClCreateElementwiseWorkloadTest<ClMultiplicationWorkload,
127                                     MultiplicationQueueDescriptor,
128                                     MultiplicationLayer,
129                                     armnn::DataType::QuantisedAsymm8>();
130 }
131
132 BOOST_AUTO_TEST_CASE(CreateDivisionFloatWorkloadTest)
133 {
134     ClCreateElementwiseWorkloadTest<ClDivisionFloatWorkload,
135                                     DivisionQueueDescriptor,
136                                     DivisionLayer,
137                                     armnn::DataType::Float32>();
138 }
139
140 BOOST_AUTO_TEST_CASE(CreateDivisionFloat16WorkloadTest)
141 {
142     ClCreateElementwiseWorkloadTest<ClDivisionFloatWorkload,
143                                     DivisionQueueDescriptor,
144                                     DivisionLayer,
145                                     armnn::DataType::Float16>();
146 }
147
148 template <typename BatchNormalizationWorkloadType, armnn::DataType DataType>
149 static void ClCreateBatchNormalizationWorkloadTest(DataLayout dataLayout)
150 {
151     Graph graph;
152     ClWorkloadFactory factory =
153         ClWorkloadFactoryHelper::GetFactory(ClWorkloadFactoryHelper::GetMemoryManager());
154
155     auto workload = CreateBatchNormalizationWorkloadTest<BatchNormalizationWorkloadType, DataType>
156                     (factory, graph, dataLayout);
157
158     // Checks that inputs/outputs are as we expect them (see definition of CreateBatchNormalizationWorkloadTest).
159     BatchNormalizationQueueDescriptor queueDescriptor = workload->GetData();
160     auto inputHandle = boost::polymorphic_downcast<IClTensorHandle*>(queueDescriptor.m_Inputs[0]);
161     auto outputHandle = boost::polymorphic_downcast<IClTensorHandle*>(queueDescriptor.m_Outputs[0]);
162
163      switch (dataLayout)
164     {
165         case DataLayout::NHWC:
166             BOOST_TEST(CompareIClTensorHandleShape(inputHandle, { 2, 4, 4, 3 }));
167             BOOST_TEST(CompareIClTensorHandleShape(outputHandle, { 2, 4, 4, 3 }));
168             break;
169         default: // NCHW
170             BOOST_TEST(CompareIClTensorHandleShape(inputHandle, { 2, 3, 4, 4 }));
171             BOOST_TEST(CompareIClTensorHandleShape(outputHandle, { 2, 3, 4, 4 }));
172     }
173 }
174
175 BOOST_AUTO_TEST_CASE(CreateBatchNormalizationFloatNchwWorkload)
176 {
177     ClCreateBatchNormalizationWorkloadTest<ClBatchNormalizationFloatWorkload,
178                                            armnn::DataType::Float32>(DataLayout::NCHW);
179 }
180
181 BOOST_AUTO_TEST_CASE(CreateBatchNormalizationFloat16NchwWorkload)
182 {
183     ClCreateBatchNormalizationWorkloadTest<ClBatchNormalizationFloatWorkload,
184                                            armnn::DataType::Float16>(DataLayout::NCHW);
185 }
186
187 BOOST_AUTO_TEST_CASE(CreateBatchNormalizationFloatNhwcWorkload)
188 {
189     ClCreateBatchNormalizationWorkloadTest<ClBatchNormalizationFloatWorkload,
190                                            armnn::DataType::Float32>(DataLayout::NHWC);
191 }
192
193 BOOST_AUTO_TEST_CASE(CreateBatchNormalizationNhwcFloat16NhwcWorkload)
194 {
195     ClCreateBatchNormalizationWorkloadTest<ClBatchNormalizationFloatWorkload,
196                                            armnn::DataType::Float16>(DataLayout::NHWC);
197 }
198
199 BOOST_AUTO_TEST_CASE(CreateConvertFp16ToFp32Workload)
200 {
201     Graph graph;
202     ClWorkloadFactory factory =
203         ClWorkloadFactoryHelper::GetFactory(ClWorkloadFactoryHelper::GetMemoryManager());
204
205     auto workload = CreateConvertFp16ToFp32WorkloadTest<ClConvertFp16ToFp32Workload>(factory, graph);
206
207     ConvertFp16ToFp32QueueDescriptor queueDescriptor = workload->GetData();
208     auto inputHandle  = boost::polymorphic_downcast<IClTensorHandle*>(queueDescriptor.m_Inputs[0]);
209     auto outputHandle = boost::polymorphic_downcast<IClTensorHandle*>(queueDescriptor.m_Outputs[0]);
210
211     BOOST_TEST(CompareIClTensorHandleShape(inputHandle, {1, 3, 2, 3}));
212     BOOST_TEST(CompareIClTensorHandleShape(outputHandle, {1, 3, 2, 3}));
213     BOOST_TEST((inputHandle->GetTensor().info()->data_type() == arm_compute::DataType::F16));
214     BOOST_TEST((outputHandle->GetTensor().info()->data_type() == arm_compute::DataType::F32));
215 }
216
217 BOOST_AUTO_TEST_CASE(CreateConvertFp32ToFp16Workload)
218 {
219     Graph graph;
220     ClWorkloadFactory factory =
221         ClWorkloadFactoryHelper::GetFactory(ClWorkloadFactoryHelper::GetMemoryManager());
222
223     auto workload = CreateConvertFp32ToFp16WorkloadTest<ClConvertFp32ToFp16Workload>(factory, graph);
224
225     ConvertFp32ToFp16QueueDescriptor queueDescriptor = workload->GetData();
226     auto inputHandle  = boost::polymorphic_downcast<IClTensorHandle*>(queueDescriptor.m_Inputs[0]);
227     auto outputHandle = boost::polymorphic_downcast<IClTensorHandle*>(queueDescriptor.m_Outputs[0]);
228
229     BOOST_TEST(CompareIClTensorHandleShape(inputHandle, {1, 3, 2, 3}));
230     BOOST_TEST(CompareIClTensorHandleShape(outputHandle, {1, 3, 2, 3}));
231     BOOST_TEST((inputHandle->GetTensor().info()->data_type() == arm_compute::DataType::F32));
232     BOOST_TEST((outputHandle->GetTensor().info()->data_type() == arm_compute::DataType::F16));
233 }
234
235 template <typename Convolution2dWorkloadType, typename armnn::DataType DataType>
236 static void ClConvolution2dWorkloadTest(DataLayout dataLayout)
237 {
238     Graph graph;
239     ClWorkloadFactory factory =
240         ClWorkloadFactoryHelper::GetFactory(ClWorkloadFactoryHelper::GetMemoryManager());
241
242     auto workload = CreateConvolution2dWorkloadTest<ClConvolution2dWorkload, DataType>(factory,
243                                                                                        graph,
244                                                                                        dataLayout);
245
246     TensorShape inputShape  = (dataLayout == DataLayout::NCHW) ? std::initializer_list<unsigned int>({2, 3, 8, 16})
247                                                                : std::initializer_list<unsigned int>({2, 8, 16, 3});
248     TensorShape outputShape = (dataLayout == DataLayout::NCHW) ? std::initializer_list<unsigned int>({2, 2, 2, 10})
249                                                                : std::initializer_list<unsigned int>({2, 2, 10, 2});
250
251     // Checks that outputs and inputs are as we expect them (see definition of CreateConvolution2dWorkloadTest).
252     Convolution2dQueueDescriptor queueDescriptor = workload->GetData();
253     auto inputHandle  = boost::polymorphic_downcast<IClTensorHandle*>(queueDescriptor.m_Inputs[0]);
254     auto outputHandle = boost::polymorphic_downcast<IClTensorHandle*>(queueDescriptor.m_Outputs[0]);
255     BOOST_TEST((inputHandle->GetShape() == inputShape));
256     BOOST_TEST((outputHandle->GetShape() == outputShape));
257 }
258
259 BOOST_AUTO_TEST_CASE(CreateConvolution2dFloatNchwWorkload)
260 {
261     ClConvolution2dWorkloadTest<ClConvolution2dWorkload, armnn::DataType::Float32>(DataLayout::NCHW);
262 }
263
264 BOOST_AUTO_TEST_CASE(CreateConvolution2dFloatNhwcWorkload)
265 {
266     ClConvolution2dWorkloadTest<ClConvolution2dWorkload, armnn::DataType::Float32>(DataLayout::NHWC);
267 }
268
269 BOOST_AUTO_TEST_CASE(CreateConvolution2dFloat16NchwWorkload)
270 {
271     ClConvolution2dWorkloadTest<ClConvolution2dWorkload, armnn::DataType::Float16>(DataLayout::NCHW);
272 }
273
274 BOOST_AUTO_TEST_CASE(CreateConvolution2dFloat16NhwcWorkload)
275 {
276     ClConvolution2dWorkloadTest<ClConvolution2dWorkload, armnn::DataType::Float16>(DataLayout::NHWC);
277 }
278
279 template <typename DepthwiseConvolutionWorkloadType, typename armnn::DataType DataType>
280 static void ClDepthwiseConvolutionWorkloadTest(DataLayout dataLayout)
281 {
282     Graph graph;
283     ClWorkloadFactory factory =
284         ClWorkloadFactoryHelper::GetFactory(ClWorkloadFactoryHelper::GetMemoryManager());
285
286     auto workload = CreateDepthwiseConvolution2dWorkloadTest<DepthwiseConvolutionWorkloadType, DataType>
287                     (factory, graph, dataLayout);
288
289     // Checks that inputs/outputs are as we expect them (see definition of CreateDepthwiseConvolution2dWorkloadTest).
290     DepthwiseConvolution2dQueueDescriptor queueDescriptor = workload->GetData();
291     auto inputHandle  = boost::polymorphic_downcast<IClTensorHandle*>(queueDescriptor.m_Inputs[0]);
292     auto outputHandle = boost::polymorphic_downcast<IClTensorHandle*>(queueDescriptor.m_Outputs[0]);
293
294     TensorShape inputShape  = (dataLayout == DataLayout::NCHW) ? std::initializer_list<unsigned int>({ 2, 2, 5, 5 })
295                                                                : std::initializer_list<unsigned int>({ 2, 5, 5, 2 });
296     TensorShape outputShape = (dataLayout == DataLayout::NCHW) ? std::initializer_list<unsigned int>({ 2, 2, 5, 5 })
297                                                                : std::initializer_list<unsigned int>({ 2, 5, 5, 2 });
298
299     BOOST_TEST((inputHandle->GetShape() == inputShape));
300     BOOST_TEST((outputHandle->GetShape() == outputShape));
301 }
302
303 BOOST_AUTO_TEST_CASE(CreateDepthwiseConvolutionFloat32NhwcWorkload)
304 {
305     ClDepthwiseConvolutionWorkloadTest<ClDepthwiseConvolutionWorkload, DataType::Float32>(DataLayout::NHWC);
306 }
307
308 template <typename Convolution2dWorkloadType, typename armnn::DataType DataType>
309 static void ClDirectConvolution2dWorkloadTest()
310 {
311     Graph graph;
312     ClWorkloadFactory factory =
313         ClWorkloadFactoryHelper::GetFactory(ClWorkloadFactoryHelper::GetMemoryManager());
314
315     auto workload = CreateDirectConvolution2dWorkloadTest<ClConvolution2dWorkload, DataType>(factory, graph);
316
317     // Checks that outputs and inputs are as we expect them (see definition of CreateDirectConvolution2dWorkloadTest).
318     Convolution2dQueueDescriptor queueDescriptor = workload->GetData();
319     auto inputHandle  = boost::polymorphic_downcast<IClTensorHandle*>(queueDescriptor.m_Inputs[0]);
320     auto outputHandle = boost::polymorphic_downcast<IClTensorHandle*>(queueDescriptor.m_Outputs[0]);
321     BOOST_TEST(CompareIClTensorHandleShape(inputHandle, {2, 3, 6, 6}));
322     BOOST_TEST(CompareIClTensorHandleShape(outputHandle, {2, 2, 6, 6}));
323 }
324
325 BOOST_AUTO_TEST_CASE(CreateDirectConvolution2dFloatWorkload)
326 {
327     ClDirectConvolution2dWorkloadTest<ClConvolution2dWorkload, armnn::DataType::Float32>();
328 }
329
330 BOOST_AUTO_TEST_CASE(CreateDirectConvolution2dFloat16Workload)
331 {
332     ClDirectConvolution2dWorkloadTest<ClConvolution2dWorkload, armnn::DataType::Float16>();
333 }
334
335 BOOST_AUTO_TEST_CASE(CreateDirectConvolution2dUint8Workload)
336 {
337     ClDirectConvolution2dWorkloadTest<ClConvolution2dWorkload, armnn::DataType::QuantisedAsymm8>();
338 }
339
340 template <typename FullyConnectedWorkloadType, typename armnn::DataType DataType>
341 static void ClCreateFullyConnectedWorkloadTest()
342 {
343     Graph graph;
344     ClWorkloadFactory factory =
345         ClWorkloadFactoryHelper::GetFactory(ClWorkloadFactoryHelper::GetMemoryManager());
346
347     auto workload =
348         CreateFullyConnectedWorkloadTest<FullyConnectedWorkloadType, DataType>(factory, graph);
349
350     // Checks that outputs and inputs are as we expect them (see definition of CreateFullyConnectedWorkloadTest).
351     FullyConnectedQueueDescriptor queueDescriptor = workload->GetData();
352     auto inputHandle = boost::polymorphic_downcast<IClTensorHandle*>(queueDescriptor.m_Inputs[0]);
353     auto outputHandle = boost::polymorphic_downcast<IClTensorHandle*>(queueDescriptor.m_Outputs[0]);
354     BOOST_TEST(CompareIClTensorHandleShape(inputHandle, {3, 1, 4, 5}));
355     BOOST_TEST(CompareIClTensorHandleShape(outputHandle, {3, 7}));
356 }
357
358
359 BOOST_AUTO_TEST_CASE(CreateFullyConnectedFloatWorkloadTest)
360 {
361     ClCreateFullyConnectedWorkloadTest<ClFullyConnectedWorkload, armnn::DataType::Float32>();
362 }
363
364 BOOST_AUTO_TEST_CASE(CreateFullyConnectedFloat16WorkloadTest)
365 {
366     ClCreateFullyConnectedWorkloadTest<ClFullyConnectedWorkload, armnn::DataType::Float16>();
367 }
368
369 template <typename NormalizationWorkloadType, typename armnn::DataType DataType>
370 static void ClNormalizationWorkloadTest(DataLayout dataLayout)
371 {
372     Graph graph;
373     ClWorkloadFactory factory =
374         ClWorkloadFactoryHelper::GetFactory(ClWorkloadFactoryHelper::GetMemoryManager());
375
376     auto workload = CreateNormalizationWorkloadTest<NormalizationWorkloadType, DataType>(factory, graph, dataLayout);
377
378     // Checks that inputs/outputs are as we expect them (see definition of CreateNormalizationWorkloadTest).
379     NormalizationQueueDescriptor queueDescriptor = workload->GetData();
380     auto inputHandle  = boost::polymorphic_downcast<IClTensorHandle*>(queueDescriptor.m_Inputs[0]);
381     auto outputHandle = boost::polymorphic_downcast<IClTensorHandle*>(queueDescriptor.m_Outputs[0]);
382
383     TensorShape inputShape  = (dataLayout == DataLayout::NCHW) ? std::initializer_list<unsigned int>({3, 5, 5, 1})
384                                                                : std::initializer_list<unsigned int>({3, 1, 5, 5});
385     TensorShape outputShape = (dataLayout == DataLayout::NCHW) ? std::initializer_list<unsigned int>({3, 5, 5, 1})
386                                                                : std::initializer_list<unsigned int>({3, 1, 5, 5});
387
388     BOOST_TEST((inputHandle->GetShape() == inputShape));
389     BOOST_TEST((outputHandle->GetShape() == outputShape));
390 }
391
392 BOOST_AUTO_TEST_CASE(CreateNormalizationFloat32NchwWorkload)
393 {
394     ClNormalizationWorkloadTest<ClNormalizationFloatWorkload, armnn::DataType::Float32>(DataLayout::NCHW);
395 }
396
397 BOOST_AUTO_TEST_CASE(CreateNormalizationFloat16NchwWorkload)
398 {
399     ClNormalizationWorkloadTest<ClNormalizationFloatWorkload, armnn::DataType::Float16>(DataLayout::NCHW);
400 }
401
402 BOOST_AUTO_TEST_CASE(CreateNormalizationFloat32NhwcWorkload)
403 {
404     ClNormalizationWorkloadTest<ClNormalizationFloatWorkload, armnn::DataType::Float32>(DataLayout::NHWC);
405 }
406
407 BOOST_AUTO_TEST_CASE(CreateNormalizationFloat16NhwcWorkload)
408 {
409     ClNormalizationWorkloadTest<ClNormalizationFloatWorkload, armnn::DataType::Float16>(DataLayout::NHWC);
410 }
411
412 template <typename armnn::DataType DataType>
413 static void ClPooling2dWorkloadTest(DataLayout dataLayout)
414 {
415     Graph graph;
416     ClWorkloadFactory factory =
417         ClWorkloadFactoryHelper::GetFactory(ClWorkloadFactoryHelper::GetMemoryManager());
418
419     auto workload = CreatePooling2dWorkloadTest<ClPooling2dWorkload, DataType>(factory, graph, dataLayout);
420
421     TensorShape inputShape  = (dataLayout == DataLayout::NCHW) ? std::initializer_list<unsigned int>({3, 2, 5, 5})
422                                                                : std::initializer_list<unsigned int>({3, 5, 5, 2});
423     TensorShape outputShape = (dataLayout == DataLayout::NCHW) ? std::initializer_list<unsigned int>({3, 2, 2, 4})
424                                                                : std::initializer_list<unsigned int>({3, 2, 4, 2});
425
426     // Check that inputs/outputs are as we expect them (see definition of CreatePooling2dWorkloadTest).
427     Pooling2dQueueDescriptor queueDescriptor = workload->GetData();
428     auto inputHandle  = boost::polymorphic_downcast<IClTensorHandle*>(queueDescriptor.m_Inputs[0]);
429     auto outputHandle = boost::polymorphic_downcast<IClTensorHandle*>(queueDescriptor.m_Outputs[0]);
430
431     BOOST_TEST((inputHandle->GetShape() == inputShape));
432     BOOST_TEST((outputHandle->GetShape() == outputShape));
433 }
434
435 BOOST_AUTO_TEST_CASE(CreatePooling2dFloatNchwWorkload)
436 {
437     ClPooling2dWorkloadTest<armnn::DataType::Float32>(DataLayout::NCHW);
438 }
439
440 BOOST_AUTO_TEST_CASE(CreatePooling2dFloatNhwcWorkload)
441 {
442     ClPooling2dWorkloadTest<armnn::DataType::Float32>(DataLayout::NHWC);
443 }
444
445 BOOST_AUTO_TEST_CASE(CreatePooling2dFloat16NchwWorkload)
446 {
447     ClPooling2dWorkloadTest<armnn::DataType::Float16>(DataLayout::NCHW);
448 }
449
450 BOOST_AUTO_TEST_CASE(CreatePooling2dFloat16NhwcWorkload)
451 {
452     ClPooling2dWorkloadTest<armnn::DataType::Float16>(DataLayout::NHWC);
453 }
454
455 static void ClCreatePreluWorkloadTest(const armnn::TensorShape& inputShape,
456                                       const armnn::TensorShape& alphaShape,
457                                       const armnn::TensorShape& outputShape,
458                                       armnn::DataType dataType)
459 {
460     Graph graph;
461     ClWorkloadFactory factory =
462             ClWorkloadFactoryHelper::GetFactory(ClWorkloadFactoryHelper::GetMemoryManager());
463
464     auto workload = CreatePreluWorkloadTest<ClPreluWorkload>(factory,
465                                                              graph,
466                                                              inputShape,
467                                                              alphaShape,
468                                                              outputShape,
469                                                              dataType);
470
471     // Checks that outputs and inputs are as we expect them (see definition of CreatePreluWorkloadTest).
472     PreluQueueDescriptor queueDescriptor = workload->GetData();
473     auto inputHandle = boost::polymorphic_downcast<IClTensorHandle*>(queueDescriptor.m_Inputs[0]);
474     auto alphaHandle = boost::polymorphic_downcast<IClTensorHandle*>(queueDescriptor.m_Inputs[1]);
475     auto outputHandle = boost::polymorphic_downcast<IClTensorHandle*>(queueDescriptor.m_Outputs[0]);
476
477     BOOST_TEST((inputHandle->GetShape() == inputShape));
478     BOOST_TEST((alphaHandle->GetShape() == alphaShape));
479     BOOST_TEST((outputHandle->GetShape() == outputShape));
480 }
481
482 BOOST_AUTO_TEST_CASE(CreatePreluFloat16Workload)
483 {
484     ClCreatePreluWorkloadTest({ 1, 4, 1, 2 }, { 5, 4, 3, 1 }, { 5, 4, 3, 2 }, DataType::Float16);
485 }
486
487 BOOST_AUTO_TEST_CASE(CreatePreluFloatWorkload)
488 {
489     ClCreatePreluWorkloadTest({ 1, 4, 1, 2 }, { 5, 4, 3, 1 }, { 5, 4, 3, 2 }, DataType::Float32);
490 }
491
492 BOOST_AUTO_TEST_CASE(CreatePreluUint8Workload)
493 {
494     ClCreatePreluWorkloadTest({ 1, 4, 1, 2 }, { 5, 4, 3, 1 }, { 5, 4, 3, 2 }, DataType::QuantisedAsymm8);
495 }
496
497 template <typename armnn::DataType DataType>
498 static void ClCreateReshapeWorkloadTest()
499 {
500     Graph graph;
501     ClWorkloadFactory factory =
502         ClWorkloadFactoryHelper::GetFactory(ClWorkloadFactoryHelper::GetMemoryManager());
503
504     auto workload = CreateReshapeWorkloadTest<ClReshapeWorkload, DataType>(factory, graph);
505
506     // Checks that outputs and inputs are as we expect them (see definition of CreateReshapeWorkloadTest).
507     ReshapeQueueDescriptor queueDescriptor = workload->GetData();
508     auto inputHandle = boost::polymorphic_downcast<IClTensorHandle*>(queueDescriptor.m_Inputs[0]);
509     auto outputHandle = boost::polymorphic_downcast<IClTensorHandle*>(queueDescriptor.m_Outputs[0]);
510
511     BOOST_TEST(CompareIClTensorHandleShape(inputHandle, {4, 1}));
512     BOOST_TEST(CompareIClTensorHandleShape(outputHandle, {1, 4}));
513 }
514
515 BOOST_AUTO_TEST_CASE(CreateReshapeFloatWorkload)
516 {
517     ClCreateReshapeWorkloadTest<armnn::DataType::Float32>();
518 }
519
520 BOOST_AUTO_TEST_CASE(CreateReshapeFloat16Workload)
521 {
522     ClCreateReshapeWorkloadTest<armnn::DataType::Float16>();
523 }
524
525 BOOST_AUTO_TEST_CASE(CreateReshapeUint8Workload)
526 {
527     ClCreateReshapeWorkloadTest<armnn::DataType::QuantisedAsymm8>();
528 }
529
530 template <typename SoftmaxWorkloadType, typename armnn::DataType DataType>
531 static void ClSoftmaxWorkloadTest()
532 {
533     Graph graph;
534     ClWorkloadFactory factory =
535         ClWorkloadFactoryHelper::GetFactory(ClWorkloadFactoryHelper::GetMemoryManager());
536
537     auto workload = CreateSoftmaxWorkloadTest<SoftmaxWorkloadType, DataType>(factory, graph);
538
539     // Checks that inputs/outputs are as we expect them (see definition of ClSoftmaxFloatWorkload).
540     SoftmaxQueueDescriptor queueDescriptor = workload->GetData();
541     auto inputHandle = boost::polymorphic_downcast<IClTensorHandle*>(queueDescriptor.m_Inputs[0]);
542     auto outputHandle = boost::polymorphic_downcast<IClTensorHandle*>(queueDescriptor.m_Outputs[0]);
543
544     BOOST_TEST(CompareIClTensorHandleShape(inputHandle, {4, 1}));
545     BOOST_TEST(CompareIClTensorHandleShape(outputHandle, {4, 1}));
546 }
547
548
549 BOOST_AUTO_TEST_CASE(CreateSoftmaxFloatWorkloadTest)
550 {
551     ClSoftmaxWorkloadTest<ClSoftmaxFloatWorkload, armnn::DataType::Float32>();
552 }
553
554 BOOST_AUTO_TEST_CASE(CreateSoftmaxFloat16WorkloadTest)
555 {
556     ClSoftmaxWorkloadTest<ClSoftmaxFloatWorkload, armnn::DataType::Float16>();
557 }
558
559 template <typename armnn::DataType DataType>
560 static void ClSplitterWorkloadTest()
561 {
562     Graph graph;
563     ClWorkloadFactory factory =
564         ClWorkloadFactoryHelper::GetFactory(ClWorkloadFactoryHelper::GetMemoryManager());
565
566     auto workload = CreateSplitterWorkloadTest<ClSplitterWorkload, DataType>(factory, graph);
567
568     // Checks that outputs are as we expect them (see definition of CreateSplitterWorkloadTest).
569     SplitterQueueDescriptor queueDescriptor = workload->GetData();
570     auto inputHandle = boost::polymorphic_downcast<IClTensorHandle*>(queueDescriptor.m_Inputs[0]);
571     BOOST_TEST(CompareIClTensorHandleShape(inputHandle, {5, 7, 7}));
572
573     auto outputHandle1 = boost::polymorphic_downcast<IClTensorHandle*>(queueDescriptor.m_Outputs[1]);
574     BOOST_TEST(CompareIClTensorHandleShape(outputHandle1, {2, 7, 7}));
575
576     auto outputHandle2 = boost::polymorphic_downcast<IClTensorHandle*>(queueDescriptor.m_Outputs[2]);
577     BOOST_TEST(CompareIClTensorHandleShape(outputHandle2, {2, 7, 7}));
578
579     auto outputHandle0 = boost::polymorphic_downcast<IClTensorHandle*>(queueDescriptor.m_Outputs[0]);
580     BOOST_TEST(CompareIClTensorHandleShape(outputHandle0, {1, 7, 7}));
581 }
582
583 BOOST_AUTO_TEST_CASE(CreateSplitterFloatWorkload)
584 {
585     ClSplitterWorkloadTest<armnn::DataType::Float32>();
586 }
587
588 BOOST_AUTO_TEST_CASE(CreateSplitterFloat16Workload)
589 {
590     ClSplitterWorkloadTest<armnn::DataType::Float16>();
591 }
592
593 template <typename armnn::DataType DataType>
594 static void ClSplitterConcatTest()
595 {
596     // Tests that it is possible to decide which output of the splitter layer
597     // should be lined to which input of the concat layer.
598     // We test that is is possible to specify 0th output
599     // of the splitter to be the 1st input to the concat and the 1st output of the splitter  to be 0th input
600     // of the concat.
601
602     Graph graph;
603     ClWorkloadFactory factory =
604         ClWorkloadFactoryHelper::GetFactory(ClWorkloadFactoryHelper::GetMemoryManager());
605
606     auto workloads =
607         CreateSplitterConcatWorkloadTest<ClSplitterWorkload, ClConcatWorkload, DataType>
608             (factory, graph);
609
610     auto wlSplitter = std::move(workloads.first);
611     auto wlConcat = std::move(workloads.second);
612
613     //Checks that the index of inputs/outputs matches what we declared on InputDescriptor construction.
614     armnn::ClSubTensorHandle* sOut0 = dynamic_cast<armnn::ClSubTensorHandle*>(wlSplitter->GetData().m_Outputs[0]);
615     armnn::ClSubTensorHandle* sOut1 = dynamic_cast<armnn::ClSubTensorHandle*>(wlSplitter->GetData().m_Outputs[1]);
616     armnn::ClSubTensorHandle* mIn0 = dynamic_cast<armnn::ClSubTensorHandle*>(wlConcat->GetData().m_Inputs[0]);
617     armnn::ClSubTensorHandle* mIn1 = dynamic_cast<armnn::ClSubTensorHandle*>(wlConcat->GetData().m_Inputs[1]);
618
619     BOOST_TEST(sOut0);
620     BOOST_TEST(sOut1);
621     BOOST_TEST(mIn0);
622     BOOST_TEST(mIn1);
623
624     //Fliped order of inputs/outputs.
625     bool validDataPointers = (sOut0 == mIn1) && (sOut1 == mIn0);
626     BOOST_TEST(validDataPointers);
627
628
629     //Also make sure that the inputs are subtensors of one tensor and outputs are sub tensors of another tensor.
630     bool validSubTensorParents = (mIn0->GetTensor().parent() == mIn1->GetTensor().parent())
631                                     && (sOut0->GetTensor().parent() == sOut1->GetTensor().parent());
632
633     BOOST_TEST(validSubTensorParents);
634 }
635
636 BOOST_AUTO_TEST_CASE(CreateSplitterConcatFloatWorkload)
637 {
638     ClSplitterConcatTest<armnn::DataType::Float32>();
639 }
640
641 BOOST_AUTO_TEST_CASE(CreateSplitterConcatFloat16Workload)
642 {
643     ClSplitterConcatTest<armnn::DataType::Float16>();
644 }
645
646
647 BOOST_AUTO_TEST_CASE(CreateSingleOutputMultipleInputs)
648 {
649     // Test that it is possible to assign multiple (two) different layers to each of the outputs of a splitter layer.
650     // We create a splitter with two outputs. That each of those outputs is used by two different activation layers.
651
652     Graph graph;
653     ClWorkloadFactory factory =
654         ClWorkloadFactoryHelper::GetFactory(ClWorkloadFactoryHelper::GetMemoryManager());
655
656     std::unique_ptr<ClSplitterWorkload> wlSplitter;
657     std::unique_ptr<ClActivationWorkload> wlActiv0_0;
658     std::unique_ptr<ClActivationWorkload> wlActiv0_1;
659     std::unique_ptr<ClActivationWorkload> wlActiv1_0;
660     std::unique_ptr<ClActivationWorkload> wlActiv1_1;
661
662     CreateSplitterMultipleInputsOneOutputWorkloadTest<ClSplitterWorkload,
663         ClActivationWorkload, armnn::DataType::Float32>(factory, graph, wlSplitter, wlActiv0_0, wlActiv0_1,
664                                                                wlActiv1_0, wlActiv1_1);
665
666     //Checks that the index of inputs/outputs matches what we declared on InputDescriptor construction.
667     armnn::ClSubTensorHandle* sOut0 = dynamic_cast<armnn::ClSubTensorHandle*>(wlSplitter->GetData().m_Outputs[0]);
668     armnn::ClSubTensorHandle* sOut1 = dynamic_cast<armnn::ClSubTensorHandle*>(wlSplitter->GetData().m_Outputs[1]);
669     armnn::ClSubTensorHandle* activ0_0Im = dynamic_cast<armnn::ClSubTensorHandle*>(wlActiv0_0->GetData().m_Inputs[0]);
670     armnn::ClSubTensorHandle* activ0_1Im = dynamic_cast<armnn::ClSubTensorHandle*>(wlActiv0_1->GetData().m_Inputs[0]);
671     armnn::ClSubTensorHandle* activ1_0Im = dynamic_cast<armnn::ClSubTensorHandle*>(wlActiv1_0->GetData().m_Inputs[0]);
672     armnn::ClSubTensorHandle* activ1_1Im = dynamic_cast<armnn::ClSubTensorHandle*>(wlActiv1_1->GetData().m_Inputs[0]);
673
674
675     BOOST_TEST(sOut0);
676     BOOST_TEST(sOut1);
677     BOOST_TEST(activ0_0Im);
678     BOOST_TEST(activ0_1Im);
679     BOOST_TEST(activ1_0Im);
680     BOOST_TEST(activ1_1Im);
681
682     bool validDataPointers = (sOut0 == activ0_0Im) && (sOut0 == activ0_1Im) &&
683                              (sOut1 == activ1_0Im) && (sOut1 == activ1_1Im);
684
685     BOOST_TEST(validDataPointers);
686 }
687
688 BOOST_AUTO_TEST_CASE(CreateMemCopyWorkloadsCl)
689 {
690     ClWorkloadFactory factory =
691         ClWorkloadFactoryHelper::GetFactory(ClWorkloadFactoryHelper::GetMemoryManager());
692
693     CreateMemCopyWorkloads<IClTensorHandle>(factory);
694 }
695
696 template <typename L2NormalizationWorkloadType, typename armnn::DataType DataType>
697 static void ClL2NormalizationWorkloadTest(DataLayout dataLayout)
698 {
699     Graph graph;
700     ClWorkloadFactory factory =
701         ClWorkloadFactoryHelper::GetFactory(ClWorkloadFactoryHelper::GetMemoryManager());
702
703     auto workload =
704             CreateL2NormalizationWorkloadTest<L2NormalizationWorkloadType, DataType>(factory, graph, dataLayout);
705
706     // Checks that inputs/outputs are as we expect them (see definition of CreateNormalizationWorkloadTest).
707     L2NormalizationQueueDescriptor queueDescriptor = workload->GetData();
708     auto inputHandle = boost::polymorphic_downcast<IClTensorHandle*>(queueDescriptor.m_Inputs[0]);
709     auto outputHandle = boost::polymorphic_downcast<IClTensorHandle*>(queueDescriptor.m_Outputs[0]);
710
711     TensorShape inputShape  = (dataLayout == DataLayout::NCHW) ? std::initializer_list<unsigned int>({ 5, 20, 50, 67 })
712                                                                : std::initializer_list<unsigned int>({ 5, 50, 67, 20 });
713     TensorShape outputShape = (dataLayout == DataLayout::NCHW) ? std::initializer_list<unsigned int>({ 5, 20, 50, 67 })
714                                                                : std::initializer_list<unsigned int>({ 5, 50, 67, 20 });
715
716     BOOST_TEST((inputHandle->GetShape() == inputShape));
717     BOOST_TEST((outputHandle->GetShape() == outputShape));
718 }
719
720 BOOST_AUTO_TEST_CASE(CreateL2NormalizationFloatNchwWorkload)
721 {
722     ClL2NormalizationWorkloadTest<ClL2NormalizationFloatWorkload, armnn::DataType::Float32>(DataLayout::NCHW);
723 }
724
725 BOOST_AUTO_TEST_CASE(CreateL2NormalizationFloatNhwcWorkload)
726 {
727     ClL2NormalizationWorkloadTest<ClL2NormalizationFloatWorkload, armnn::DataType::Float32>(DataLayout::NHWC);
728 }
729
730 BOOST_AUTO_TEST_CASE(CreateL2NormalizationFloat16NchwWorkload)
731 {
732     ClL2NormalizationWorkloadTest<ClL2NormalizationFloatWorkload, armnn::DataType::Float16>(DataLayout::NCHW);
733 }
734
735 BOOST_AUTO_TEST_CASE(CreateL2NormalizationFloat16NhwcWorkload)
736 {
737     ClL2NormalizationWorkloadTest<ClL2NormalizationFloatWorkload, armnn::DataType::Float16>(DataLayout::NHWC);
738 }
739
740 template <typename LstmWorkloadType>
741 static void ClCreateLstmWorkloadTest()
742 {
743     Graph graph;
744     ClWorkloadFactory factory =
745         ClWorkloadFactoryHelper::GetFactory(ClWorkloadFactoryHelper::GetMemoryManager());
746
747     auto workload = CreateLstmWorkloadTest<LstmWorkloadType>(factory, graph);
748
749     LstmQueueDescriptor queueDescriptor = workload->GetData();
750     auto inputHandle  = boost::polymorphic_downcast<IClTensorHandle*>(queueDescriptor.m_Inputs[0]);
751     auto outputHandle = boost::polymorphic_downcast<IClTensorHandle*>(queueDescriptor.m_Outputs[1]);
752     BOOST_TEST(CompareIClTensorHandleShape(inputHandle, { 2, 2 }));
753     BOOST_TEST(CompareIClTensorHandleShape(outputHandle, { 2, 4 }));
754 }
755
756 BOOST_AUTO_TEST_CASE(CreateLSTMWorkloadFloatWorkload)
757 {
758     ClCreateLstmWorkloadTest<ClLstmFloatWorkload>();
759 }
760
761 template <typename ResizeWorkloadType, typename armnn::DataType DataType>
762 static void ClResizeWorkloadTest(DataLayout dataLayout)
763 {
764     Graph graph;
765     ClWorkloadFactory factory =
766         ClWorkloadFactoryHelper::GetFactory(ClWorkloadFactoryHelper::GetMemoryManager());
767
768     auto workload = CreateResizeBilinearWorkloadTest<ResizeWorkloadType, DataType>(factory, graph, dataLayout);
769
770     auto queueDescriptor = workload->GetData();
771
772     auto inputHandle  = boost::polymorphic_downcast<IClTensorHandle*>(queueDescriptor.m_Inputs[0]);
773     auto outputHandle = boost::polymorphic_downcast<IClTensorHandle*>(queueDescriptor.m_Outputs[0]);
774
775     switch (dataLayout)
776     {
777         case DataLayout::NHWC:
778             BOOST_TEST(CompareIClTensorHandleShape(inputHandle, { 2, 4, 4, 3 }));
779             BOOST_TEST(CompareIClTensorHandleShape(outputHandle, { 2, 2, 2, 3 }));
780             break;
781         case DataLayout::NCHW:
782         default:
783             BOOST_TEST(CompareIClTensorHandleShape(inputHandle, { 2, 3, 4, 4 }));
784             BOOST_TEST(CompareIClTensorHandleShape(outputHandle, { 2, 3, 2, 2 }));
785     }
786 }
787
788 BOOST_AUTO_TEST_CASE(CreateResizeFloat32NchwWorkload)
789 {
790     ClResizeWorkloadTest<ClResizeWorkload, armnn::DataType::Float32>(DataLayout::NCHW);
791 }
792
793 BOOST_AUTO_TEST_CASE(CreateResizeFloat16NchwWorkload)
794 {
795     ClResizeWorkloadTest<ClResizeWorkload, armnn::DataType::Float16>(DataLayout::NCHW);
796 }
797
798 BOOST_AUTO_TEST_CASE(CreateResizeUint8NchwWorkload)
799 {
800     ClResizeWorkloadTest<ClResizeWorkload, armnn::DataType::QuantisedAsymm8>(DataLayout::NCHW);
801 }
802
803 BOOST_AUTO_TEST_CASE(CreateResizeFloat32NhwcWorkload)
804 {
805     ClResizeWorkloadTest<ClResizeWorkload, armnn::DataType::Float32>(DataLayout::NHWC);
806 }
807
808 BOOST_AUTO_TEST_CASE(CreateResizeFloat16NhwcWorkload)
809 {
810     ClResizeWorkloadTest<ClResizeWorkload, armnn::DataType::Float16>(DataLayout::NHWC);
811 }
812
813 BOOST_AUTO_TEST_CASE(CreateResizeUint8NhwcWorkload)
814 {
815     ClResizeWorkloadTest<ClResizeWorkload, armnn::DataType::QuantisedAsymm8>(DataLayout::NHWC);
816 }
817
818 template <typename MeanWorkloadType, typename armnn::DataType DataType>
819 static void ClMeanWorkloadTest()
820 {
821     Graph graph;
822     ClWorkloadFactory factory =
823         ClWorkloadFactoryHelper::GetFactory(ClWorkloadFactoryHelper::GetMemoryManager());
824
825     auto workload = CreateMeanWorkloadTest<MeanWorkloadType, DataType>(factory, graph);
826
827     // Checks that inputs/outputs are as we expect them (see definition of CreateMeanWorkloadTest).
828     MeanQueueDescriptor queueDescriptor = workload->GetData();
829     auto inputHandle  = boost::polymorphic_downcast<IClTensorHandle*>(queueDescriptor.m_Inputs[0]);
830     auto outputHandle = boost::polymorphic_downcast<IClTensorHandle*>(queueDescriptor.m_Outputs[0]);
831
832     // The first dimension (batch size) in both input and output is singular thus it has been reduced by ACL.
833     BOOST_TEST(CompareIClTensorHandleShape(inputHandle, {  1, 3, 7, 4 }));
834     BOOST_TEST(CompareIClTensorHandleShape(outputHandle, { 1, 4 }));
835 }
836
837 BOOST_AUTO_TEST_CASE(CreateMeanFloat32Workload)
838 {
839     ClMeanWorkloadTest<ClMeanWorkload, armnn::DataType::Float32>();
840 }
841
842 BOOST_AUTO_TEST_CASE(CreateMeanFloat16Workload)
843 {
844     ClMeanWorkloadTest<ClMeanWorkload, armnn::DataType::Float16>();
845 }
846
847 BOOST_AUTO_TEST_CASE(CreateMeanUint8Workload)
848 {
849     ClMeanWorkloadTest<ClMeanWorkload, armnn::DataType::QuantisedAsymm8>();
850 }
851
852 template <typename ConcatWorkloadType, armnn::DataType DataType>
853 static void ClCreateConcatWorkloadTest(std::initializer_list<unsigned int> outputShape,
854                                        unsigned int concatAxis)
855 {
856     Graph graph;
857     ClWorkloadFactory factory =
858         ClWorkloadFactoryHelper::GetFactory(ClWorkloadFactoryHelper::GetMemoryManager());
859
860     auto workload = CreateConcatWorkloadTest<ConcatWorkloadType, DataType>(factory, graph, outputShape, concatAxis);
861
862     ConcatQueueDescriptor queueDescriptor = workload->GetData();
863     auto inputHandle0  = boost::polymorphic_downcast<IClTensorHandle*>(queueDescriptor.m_Inputs[0]);
864     auto inputHandle1  = boost::polymorphic_downcast<IClTensorHandle*>(queueDescriptor.m_Inputs[1]);
865     auto outputHandle = boost::polymorphic_downcast<IClTensorHandle*>(queueDescriptor.m_Outputs[0]);
866
867     BOOST_TEST(CompareIClTensorHandleShape(inputHandle0, { 2, 3, 2, 5 }));
868     BOOST_TEST(CompareIClTensorHandleShape(inputHandle1, { 2, 3, 2, 5 }));
869     BOOST_TEST(CompareIClTensorHandleShape(outputHandle, outputShape));
870 }
871
872 BOOST_AUTO_TEST_CASE(CreateConcatDim0Float32Workload)
873 {
874     ClCreateConcatWorkloadTest<ClConcatWorkload, armnn::DataType::Float32>({ 4, 3, 2, 5 }, 0);
875 }
876
877 BOOST_AUTO_TEST_CASE(CreateConcatDim1Float32Workload)
878 {
879     ClCreateConcatWorkloadTest<ClConcatWorkload, armnn::DataType::Float32>({ 2, 6, 2, 5 }, 1);
880 }
881
882 BOOST_AUTO_TEST_CASE(CreateConcatDim3Float32Workload)
883 {
884     ClCreateConcatWorkloadTest<ClConcatWorkload, armnn::DataType::Float32>({ 2, 3, 2, 10 }, 3);
885 }
886
887 BOOST_AUTO_TEST_CASE(CreateConcatDim0Uint8Workload)
888 {
889     ClCreateConcatWorkloadTest<ClConcatWorkload, armnn::DataType::QuantisedAsymm8>({ 4, 3, 2, 5 }, 0);
890 }
891
892 BOOST_AUTO_TEST_CASE(CreateConcatDim1Uint8Workload)
893 {
894     ClCreateConcatWorkloadTest<ClConcatWorkload, armnn::DataType::QuantisedAsymm8>({ 2, 6, 2, 5 }, 1);
895 }
896
897 BOOST_AUTO_TEST_CASE(CreateConcatDim3Uint8Workload)
898 {
899     ClCreateConcatWorkloadTest<ClConcatWorkload, armnn::DataType::QuantisedAsymm8>({ 2, 3, 2, 10 }, 3);
900 }
901
902 template <typename SpaceToDepthWorkloadType, typename armnn::DataType DataType>
903 static void ClSpaceToDepthWorkloadTest()
904 {
905     Graph graph;
906     ClWorkloadFactory factory =
907             ClWorkloadFactoryHelper::GetFactory(ClWorkloadFactoryHelper::GetMemoryManager());
908
909     auto workload = CreateSpaceToDepthWorkloadTest<SpaceToDepthWorkloadType, DataType>(factory, graph);
910
911     SpaceToDepthQueueDescriptor queueDescriptor = workload->GetData();
912     auto inputHandle  = boost::polymorphic_downcast<IClTensorHandle*>(queueDescriptor.m_Inputs[0]);
913     auto outputHandle = boost::polymorphic_downcast<IClTensorHandle*>(queueDescriptor.m_Outputs[0]);
914
915     BOOST_TEST(CompareIClTensorHandleShape(inputHandle, { 1, 2, 2, 1 }));
916     BOOST_TEST(CompareIClTensorHandleShape(outputHandle, { 1, 1, 1, 4 }));
917 }
918
919 BOOST_AUTO_TEST_CASE(CreateSpaceToDepthFloat32Workload)
920 {
921     ClSpaceToDepthWorkloadTest<ClSpaceToDepthWorkload, armnn::DataType::Float32>();
922 }
923
924 BOOST_AUTO_TEST_CASE(CreateSpaceToDepthFloat16Workload)
925 {
926     ClSpaceToDepthWorkloadTest<ClSpaceToDepthWorkload, armnn::DataType::Float16>();
927 }
928
929 BOOST_AUTO_TEST_CASE(CreateSpaceToDepthQAsymm8Workload)
930 {
931     ClSpaceToDepthWorkloadTest<ClSpaceToDepthWorkload, armnn::DataType::QuantisedAsymm8>();
932 }
933
934 BOOST_AUTO_TEST_CASE(CreateSpaceToDepthQSymm16Workload)
935 {
936     ClSpaceToDepthWorkloadTest<ClSpaceToDepthWorkload, armnn::DataType::QuantisedSymm16>();
937 }
938
939 BOOST_AUTO_TEST_SUITE_END()