ArmNN
 20.05
ClCreateWorkloadTests.cpp
Go to the documentation of this file.
1 //
2 // Copyright © 2017 Arm Ltd. All rights reserved.
3 // SPDX-License-Identifier: MIT
4 //
5 
8 
11 
14 
15 #include <cl/ClTensorHandle.hpp>
16 #include <cl/ClWorkloadFactory.hpp>
19 
20 boost::test_tools::predicate_result CompareIClTensorHandleShape(IClTensorHandle* tensorHandle,
21  std::initializer_list<unsigned int> expectedDimensions)
22 {
23  return CompareTensorHandleShape<IClTensorHandle>(tensorHandle, expectedDimensions);
24 }
25 
26 BOOST_FIXTURE_TEST_SUITE(CreateWorkloadCl, ClContextControlFixture)
27 
28 template <armnn::DataType DataType>
29 static void ClCreateActivationWorkloadTest()
30 {
31  Graph graph;
32  ClWorkloadFactory factory =
33  ClWorkloadFactoryHelper::GetFactory(ClWorkloadFactoryHelper::GetMemoryManager());
34 
35  auto workload = CreateActivationWorkloadTest<ClActivationWorkload, DataType>(factory, graph);
36 
37  // Checks that inputs/outputs are as we expect them (see definition of CreateActivationWorkloadTest).
38  ActivationQueueDescriptor queueDescriptor = workload->GetData();
39  auto inputHandle = PolymorphicDowncast<IClTensorHandle*>(queueDescriptor.m_Inputs[0]);
40  auto outputHandle = PolymorphicDowncast<IClTensorHandle*>(queueDescriptor.m_Outputs[0]);
41 
42  BOOST_TEST(CompareIClTensorHandleShape(inputHandle, {1, 1}));
43  BOOST_TEST(CompareIClTensorHandleShape(outputHandle, {1, 1}));
44 }
45 
46 BOOST_AUTO_TEST_CASE(CreateActivationFloatWorkload)
47 {
48  ClCreateActivationWorkloadTest<armnn::DataType::Float32>();
49 }
50 
51 BOOST_AUTO_TEST_CASE(CreateActivationFloat16Workload)
52 {
53  ClCreateActivationWorkloadTest<armnn::DataType::Float16>();
54 }
55 
56 template <typename WorkloadType,
57  typename DescriptorType,
58  typename LayerType,
60 static void ClCreateElementwiseWorkloadTest()
61 {
62  Graph graph;
63  ClWorkloadFactory factory =
64  ClWorkloadFactoryHelper::GetFactory(ClWorkloadFactoryHelper::GetMemoryManager());
65 
66  auto workload = CreateElementwiseWorkloadTest<WorkloadType, DescriptorType, LayerType, DataType>(factory, graph);
67 
68  // Checks that inputs/outputs are as we expect them (see definition of CreateElementwiseWorkloadTest).
69  DescriptorType queueDescriptor = workload->GetData();
70  auto inputHandle1 = PolymorphicDowncast<IClTensorHandle*>(queueDescriptor.m_Inputs[0]);
71  auto inputHandle2 = PolymorphicDowncast<IClTensorHandle*>(queueDescriptor.m_Inputs[1]);
72  auto outputHandle = PolymorphicDowncast<IClTensorHandle*>(queueDescriptor.m_Outputs[0]);
73  BOOST_TEST(CompareIClTensorHandleShape(inputHandle1, {2, 3}));
74  BOOST_TEST(CompareIClTensorHandleShape(inputHandle2, {2, 3}));
75  BOOST_TEST(CompareIClTensorHandleShape(outputHandle, {2, 3}));
76 }
77 
78 BOOST_AUTO_TEST_CASE(CreateAdditionFloatWorkload)
79 {
80  ClCreateElementwiseWorkloadTest<ClAdditionWorkload,
84 }
85 
86 BOOST_AUTO_TEST_CASE(CreateAdditionFloat16Workload)
87 {
88  ClCreateElementwiseWorkloadTest<ClAdditionWorkload,
92 }
93 
94 BOOST_AUTO_TEST_CASE(CreateSubtractionFloatWorkload)
95 {
96  ClCreateElementwiseWorkloadTest<ClSubtractionWorkload,
100 }
101 
102 BOOST_AUTO_TEST_CASE(CreateSubtractionFloat16Workload)
103 {
104  ClCreateElementwiseWorkloadTest<ClSubtractionWorkload,
108 }
109 
110 BOOST_AUTO_TEST_CASE(CreateMultiplicationFloatWorkloadTest)
111 {
112  ClCreateElementwiseWorkloadTest<ClMultiplicationWorkload,
116 }
117 
118 BOOST_AUTO_TEST_CASE(CreateMultiplicationFloat16WorkloadTest)
119 {
120  ClCreateElementwiseWorkloadTest<ClMultiplicationWorkload,
124 }
125 
126 BOOST_AUTO_TEST_CASE(CreateMultiplicationUint8WorkloadTest)
127 {
128  ClCreateElementwiseWorkloadTest<ClMultiplicationWorkload,
132 }
133 
134 BOOST_AUTO_TEST_CASE(CreateDivisionFloatWorkloadTest)
135 {
136  ClCreateElementwiseWorkloadTest<ClDivisionFloatWorkload,
140 }
141 
142 BOOST_AUTO_TEST_CASE(CreateDivisionFloat16WorkloadTest)
143 {
144  ClCreateElementwiseWorkloadTest<ClDivisionFloatWorkload,
148 }
149 
150 template <typename WorkloadType,
151  typename DescriptorType,
153 static void ClCreateElementwiseUnaryWorkloadTest(armnn::UnaryOperation op)
154 {
155  Graph graph;
156  ClWorkloadFactory factory =
157  ClWorkloadFactoryHelper::GetFactory(ClWorkloadFactoryHelper::GetMemoryManager());
158 
159  auto workload = CreateElementwiseUnaryWorkloadTest<WorkloadType, DescriptorType, DataType>(factory, graph, op);
160 
161  DescriptorType queueDescriptor = workload->GetData();
162 
163  auto inputHandle = PolymorphicDowncast<IClTensorHandle*>(queueDescriptor.m_Inputs[0]);
164  auto outputHandle = PolymorphicDowncast<IClTensorHandle*>(queueDescriptor.m_Outputs[0]);
165 
166  BOOST_TEST(CompareIClTensorHandleShape(inputHandle, {2, 3}));
167  BOOST_TEST(CompareIClTensorHandleShape(outputHandle, {2, 3}));
168 }
169 
170 BOOST_AUTO_TEST_CASE(CreateRsqrtFloat32WorkloadTest)
171 {
172  ClCreateElementwiseUnaryWorkloadTest<ClRsqrtWorkload, RsqrtQueueDescriptor, armnn::DataType::Float32>(
173  UnaryOperation::Rsqrt);
174 }
175 
176 template <typename BatchNormalizationWorkloadType, armnn::DataType DataType>
177 static void ClCreateBatchNormalizationWorkloadTest(DataLayout dataLayout)
178 {
179  Graph graph;
180  ClWorkloadFactory factory =
181  ClWorkloadFactoryHelper::GetFactory(ClWorkloadFactoryHelper::GetMemoryManager());
182 
183  auto workload = CreateBatchNormalizationWorkloadTest<BatchNormalizationWorkloadType, DataType>
184  (factory, graph, dataLayout);
185 
186  // Checks that inputs/outputs are as we expect them (see definition of CreateBatchNormalizationWorkloadTest).
187  BatchNormalizationQueueDescriptor queueDescriptor = workload->GetData();
188  auto inputHandle = PolymorphicDowncast<IClTensorHandle*>(queueDescriptor.m_Inputs[0]);
189  auto outputHandle = PolymorphicDowncast<IClTensorHandle*>(queueDescriptor.m_Outputs[0]);
190 
191  switch (dataLayout)
192  {
193  case DataLayout::NHWC:
194  BOOST_TEST(CompareIClTensorHandleShape(inputHandle, { 2, 4, 4, 3 }));
195  BOOST_TEST(CompareIClTensorHandleShape(outputHandle, { 2, 4, 4, 3 }));
196  break;
197  default: // NCHW
198  BOOST_TEST(CompareIClTensorHandleShape(inputHandle, { 2, 3, 4, 4 }));
199  BOOST_TEST(CompareIClTensorHandleShape(outputHandle, { 2, 3, 4, 4 }));
200  }
201 }
202 
203 BOOST_AUTO_TEST_CASE(CreateBatchNormalizationFloatNchwWorkload)
204 {
205  ClCreateBatchNormalizationWorkloadTest<ClBatchNormalizationFloatWorkload,
206  armnn::DataType::Float32>(DataLayout::NCHW);
207 }
208 
209 BOOST_AUTO_TEST_CASE(CreateBatchNormalizationFloat16NchwWorkload)
210 {
211  ClCreateBatchNormalizationWorkloadTest<ClBatchNormalizationFloatWorkload,
212  armnn::DataType::Float16>(DataLayout::NCHW);
213 }
214 
215 BOOST_AUTO_TEST_CASE(CreateBatchNormalizationFloatNhwcWorkload)
216 {
217  ClCreateBatchNormalizationWorkloadTest<ClBatchNormalizationFloatWorkload,
218  armnn::DataType::Float32>(DataLayout::NHWC);
219 }
220 
221 BOOST_AUTO_TEST_CASE(CreateBatchNormalizationNhwcFloat16NhwcWorkload)
222 {
223  ClCreateBatchNormalizationWorkloadTest<ClBatchNormalizationFloatWorkload,
224  armnn::DataType::Float16>(DataLayout::NHWC);
225 }
226 
227 BOOST_AUTO_TEST_CASE(CreateConvertFp16ToFp32Workload)
228 {
229  Graph graph;
230  ClWorkloadFactory factory =
231  ClWorkloadFactoryHelper::GetFactory(ClWorkloadFactoryHelper::GetMemoryManager());
232 
233  auto workload = CreateConvertFp16ToFp32WorkloadTest<ClConvertFp16ToFp32Workload>(factory, graph);
234 
235  ConvertFp16ToFp32QueueDescriptor queueDescriptor = workload->GetData();
236  auto inputHandle = PolymorphicDowncast<IClTensorHandle*>(queueDescriptor.m_Inputs[0]);
237  auto outputHandle = PolymorphicDowncast<IClTensorHandle*>(queueDescriptor.m_Outputs[0]);
238 
239  BOOST_TEST(CompareIClTensorHandleShape(inputHandle, {1, 3, 2, 3}));
240  BOOST_TEST(CompareIClTensorHandleShape(outputHandle, {1, 3, 2, 3}));
241  BOOST_TEST((inputHandle->GetTensor().info()->data_type() == arm_compute::DataType::F16));
242  BOOST_TEST((outputHandle->GetTensor().info()->data_type() == arm_compute::DataType::F32));
243 }
244 
245 BOOST_AUTO_TEST_CASE(CreateConvertFp32ToFp16Workload)
246 {
247  Graph graph;
248  ClWorkloadFactory factory =
249  ClWorkloadFactoryHelper::GetFactory(ClWorkloadFactoryHelper::GetMemoryManager());
250 
251  auto workload = CreateConvertFp32ToFp16WorkloadTest<ClConvertFp32ToFp16Workload>(factory, graph);
252 
253  ConvertFp32ToFp16QueueDescriptor queueDescriptor = workload->GetData();
254  auto inputHandle = PolymorphicDowncast<IClTensorHandle*>(queueDescriptor.m_Inputs[0]);
255  auto outputHandle = PolymorphicDowncast<IClTensorHandle*>(queueDescriptor.m_Outputs[0]);
256 
257  BOOST_TEST(CompareIClTensorHandleShape(inputHandle, {1, 3, 2, 3}));
258  BOOST_TEST(CompareIClTensorHandleShape(outputHandle, {1, 3, 2, 3}));
259  BOOST_TEST((inputHandle->GetTensor().info()->data_type() == arm_compute::DataType::F32));
260  BOOST_TEST((outputHandle->GetTensor().info()->data_type() == arm_compute::DataType::F16));
261 }
262 
263 template <typename Convolution2dWorkloadType, typename armnn::DataType DataType>
264 static void ClConvolution2dWorkloadTest(DataLayout dataLayout)
265 {
266  Graph graph;
267  ClWorkloadFactory factory =
268  ClWorkloadFactoryHelper::GetFactory(ClWorkloadFactoryHelper::GetMemoryManager());
269 
270  auto workload = CreateConvolution2dWorkloadTest<ClConvolution2dWorkload, DataType>(factory,
271  graph,
272  dataLayout);
273 
274  TensorShape inputShape = (dataLayout == DataLayout::NCHW) ? std::initializer_list<unsigned int>({2, 3, 8, 16})
275  : std::initializer_list<unsigned int>({2, 8, 16, 3});
276  TensorShape outputShape = (dataLayout == DataLayout::NCHW) ? std::initializer_list<unsigned int>({2, 2, 2, 10})
277  : std::initializer_list<unsigned int>({2, 2, 10, 2});
278 
279  // Checks that outputs and inputs are as we expect them (see definition of CreateConvolution2dWorkloadTest).
280  Convolution2dQueueDescriptor queueDescriptor = workload->GetData();
281  auto inputHandle = PolymorphicDowncast<IClTensorHandle*>(queueDescriptor.m_Inputs[0]);
282  auto outputHandle = PolymorphicDowncast<IClTensorHandle*>(queueDescriptor.m_Outputs[0]);
283  BOOST_TEST((inputHandle->GetShape() == inputShape));
284  BOOST_TEST((outputHandle->GetShape() == outputShape));
285 }
286 
287 BOOST_AUTO_TEST_CASE(CreateConvolution2dFloatNchwWorkload)
288 {
289  ClConvolution2dWorkloadTest<ClConvolution2dWorkload, armnn::DataType::Float32>(DataLayout::NCHW);
290 }
291 
292 BOOST_AUTO_TEST_CASE(CreateConvolution2dFloatNhwcWorkload)
293 {
294  ClConvolution2dWorkloadTest<ClConvolution2dWorkload, armnn::DataType::Float32>(DataLayout::NHWC);
295 }
296 
297 BOOST_AUTO_TEST_CASE(CreateConvolution2dFloat16NchwWorkload)
298 {
299  ClConvolution2dWorkloadTest<ClConvolution2dWorkload, armnn::DataType::Float16>(DataLayout::NCHW);
300 }
301 
302 BOOST_AUTO_TEST_CASE(CreateConvolution2dFloat16NhwcWorkload)
303 {
304  ClConvolution2dWorkloadTest<ClConvolution2dWorkload, armnn::DataType::Float16>(DataLayout::NHWC);
305 }
306 
307 template <typename DepthwiseConvolutionWorkloadType, typename armnn::DataType DataType>
308 static void ClDepthwiseConvolutionWorkloadTest(DataLayout dataLayout)
309 {
310  Graph graph;
311  ClWorkloadFactory factory =
312  ClWorkloadFactoryHelper::GetFactory(ClWorkloadFactoryHelper::GetMemoryManager());
313 
314  auto workload = CreateDepthwiseConvolution2dWorkloadTest<DepthwiseConvolutionWorkloadType, DataType>
315  (factory, graph, dataLayout);
316 
317  // Checks that inputs/outputs are as we expect them (see definition of CreateDepthwiseConvolution2dWorkloadTest).
318  DepthwiseConvolution2dQueueDescriptor queueDescriptor = workload->GetData();
319  auto inputHandle = PolymorphicDowncast<IClTensorHandle*>(queueDescriptor.m_Inputs[0]);
320  auto outputHandle = PolymorphicDowncast<IClTensorHandle*>(queueDescriptor.m_Outputs[0]);
321 
322  TensorShape inputShape = (dataLayout == DataLayout::NCHW) ? std::initializer_list<unsigned int>({ 2, 2, 5, 5 })
323  : std::initializer_list<unsigned int>({ 2, 5, 5, 2 });
324  TensorShape outputShape = (dataLayout == DataLayout::NCHW) ? std::initializer_list<unsigned int>({ 2, 2, 5, 5 })
325  : std::initializer_list<unsigned int>({ 2, 5, 5, 2 });
326 
327  BOOST_TEST((inputHandle->GetShape() == inputShape));
328  BOOST_TEST((outputHandle->GetShape() == outputShape));
329 }
330 
331 BOOST_AUTO_TEST_CASE(CreateDepthwiseConvolutionFloat32NhwcWorkload)
332 {
333  ClDepthwiseConvolutionWorkloadTest<ClDepthwiseConvolutionWorkload, DataType::Float32>(DataLayout::NHWC);
334 }
335 
336 template <typename Convolution2dWorkloadType, typename armnn::DataType DataType>
337 static void ClDirectConvolution2dWorkloadTest()
338 {
339  Graph graph;
340  ClWorkloadFactory factory =
341  ClWorkloadFactoryHelper::GetFactory(ClWorkloadFactoryHelper::GetMemoryManager());
342 
343  auto workload = CreateDirectConvolution2dWorkloadTest<ClConvolution2dWorkload, DataType>(factory, graph);
344 
345  // Checks that outputs and inputs are as we expect them (see definition of CreateDirectConvolution2dWorkloadTest).
346  Convolution2dQueueDescriptor queueDescriptor = workload->GetData();
347  auto inputHandle = PolymorphicDowncast<IClTensorHandle*>(queueDescriptor.m_Inputs[0]);
348  auto outputHandle = PolymorphicDowncast<IClTensorHandle*>(queueDescriptor.m_Outputs[0]);
349  BOOST_TEST(CompareIClTensorHandleShape(inputHandle, {2, 3, 6, 6}));
350  BOOST_TEST(CompareIClTensorHandleShape(outputHandle, {2, 2, 6, 6}));
351 }
352 
353 BOOST_AUTO_TEST_CASE(CreateDirectConvolution2dFloatWorkload)
354 {
355  ClDirectConvolution2dWorkloadTest<ClConvolution2dWorkload, armnn::DataType::Float32>();
356 }
357 
358 BOOST_AUTO_TEST_CASE(CreateDirectConvolution2dFloat16Workload)
359 {
360  ClDirectConvolution2dWorkloadTest<ClConvolution2dWorkload, armnn::DataType::Float16>();
361 }
362 
363 BOOST_AUTO_TEST_CASE(CreateDirectConvolution2dUint8Workload)
364 {
365  ClDirectConvolution2dWorkloadTest<ClConvolution2dWorkload, armnn::DataType::QAsymmU8>();
366 }
367 
368 template <typename FullyConnectedWorkloadType, typename armnn::DataType DataType>
369 static void ClCreateFullyConnectedWorkloadTest()
370 {
371  Graph graph;
372  ClWorkloadFactory factory =
373  ClWorkloadFactoryHelper::GetFactory(ClWorkloadFactoryHelper::GetMemoryManager());
374 
375  auto workload =
376  CreateFullyConnectedWorkloadTest<FullyConnectedWorkloadType, DataType>(factory, graph);
377 
378  // Checks that outputs and inputs are as we expect them (see definition of CreateFullyConnectedWorkloadTest).
379  FullyConnectedQueueDescriptor queueDescriptor = workload->GetData();
380  auto inputHandle = PolymorphicDowncast<IClTensorHandle*>(queueDescriptor.m_Inputs[0]);
381  auto outputHandle = PolymorphicDowncast<IClTensorHandle*>(queueDescriptor.m_Outputs[0]);
382  BOOST_TEST(CompareIClTensorHandleShape(inputHandle, {3, 1, 4, 5}));
383  BOOST_TEST(CompareIClTensorHandleShape(outputHandle, {3, 7}));
384 }
385 
386 
387 BOOST_AUTO_TEST_CASE(CreateFullyConnectedFloatWorkloadTest)
388 {
389  ClCreateFullyConnectedWorkloadTest<ClFullyConnectedWorkload, armnn::DataType::Float32>();
390 }
391 
392 BOOST_AUTO_TEST_CASE(CreateFullyConnectedFloat16WorkloadTest)
393 {
394  ClCreateFullyConnectedWorkloadTest<ClFullyConnectedWorkload, armnn::DataType::Float16>();
395 }
396 
397 template <typename NormalizationWorkloadType, typename armnn::DataType DataType>
398 static void ClNormalizationWorkloadTest(DataLayout dataLayout)
399 {
400  Graph graph;
401  ClWorkloadFactory factory =
402  ClWorkloadFactoryHelper::GetFactory(ClWorkloadFactoryHelper::GetMemoryManager());
403 
404  auto workload = CreateNormalizationWorkloadTest<NormalizationWorkloadType, DataType>(factory, graph, dataLayout);
405 
406  // Checks that inputs/outputs are as we expect them (see definition of CreateNormalizationWorkloadTest).
407  NormalizationQueueDescriptor queueDescriptor = workload->GetData();
408  auto inputHandle = PolymorphicDowncast<IClTensorHandle*>(queueDescriptor.m_Inputs[0]);
409  auto outputHandle = PolymorphicDowncast<IClTensorHandle*>(queueDescriptor.m_Outputs[0]);
410 
411  TensorShape inputShape = (dataLayout == DataLayout::NCHW) ? std::initializer_list<unsigned int>({3, 5, 5, 1})
412  : std::initializer_list<unsigned int>({3, 1, 5, 5});
413  TensorShape outputShape = (dataLayout == DataLayout::NCHW) ? std::initializer_list<unsigned int>({3, 5, 5, 1})
414  : std::initializer_list<unsigned int>({3, 1, 5, 5});
415 
416  BOOST_TEST((inputHandle->GetShape() == inputShape));
417  BOOST_TEST((outputHandle->GetShape() == outputShape));
418 }
419 
420 BOOST_AUTO_TEST_CASE(CreateNormalizationFloat32NchwWorkload)
421 {
422  ClNormalizationWorkloadTest<ClNormalizationFloatWorkload, armnn::DataType::Float32>(DataLayout::NCHW);
423 }
424 
425 BOOST_AUTO_TEST_CASE(CreateNormalizationFloat16NchwWorkload)
426 {
427  ClNormalizationWorkloadTest<ClNormalizationFloatWorkload, armnn::DataType::Float16>(DataLayout::NCHW);
428 }
429 
430 BOOST_AUTO_TEST_CASE(CreateNormalizationFloat32NhwcWorkload)
431 {
432  ClNormalizationWorkloadTest<ClNormalizationFloatWorkload, armnn::DataType::Float32>(DataLayout::NHWC);
433 }
434 
435 BOOST_AUTO_TEST_CASE(CreateNormalizationFloat16NhwcWorkload)
436 {
437  ClNormalizationWorkloadTest<ClNormalizationFloatWorkload, armnn::DataType::Float16>(DataLayout::NHWC);
438 }
439 
440 template <typename armnn::DataType DataType>
441 static void ClPooling2dWorkloadTest(DataLayout dataLayout)
442 {
443  Graph graph;
444  ClWorkloadFactory factory =
445  ClWorkloadFactoryHelper::GetFactory(ClWorkloadFactoryHelper::GetMemoryManager());
446 
447  auto workload = CreatePooling2dWorkloadTest<ClPooling2dWorkload, DataType>(factory, graph, dataLayout);
448 
449  TensorShape inputShape = (dataLayout == DataLayout::NCHW) ? std::initializer_list<unsigned int>({3, 2, 5, 5})
450  : std::initializer_list<unsigned int>({3, 5, 5, 2});
451  TensorShape outputShape = (dataLayout == DataLayout::NCHW) ? std::initializer_list<unsigned int>({3, 2, 2, 4})
452  : std::initializer_list<unsigned int>({3, 2, 4, 2});
453 
454  // Check that inputs/outputs are as we expect them (see definition of CreatePooling2dWorkloadTest).
455  Pooling2dQueueDescriptor queueDescriptor = workload->GetData();
456  auto inputHandle = PolymorphicDowncast<IClTensorHandle*>(queueDescriptor.m_Inputs[0]);
457  auto outputHandle = PolymorphicDowncast<IClTensorHandle*>(queueDescriptor.m_Outputs[0]);
458 
459  BOOST_TEST((inputHandle->GetShape() == inputShape));
460  BOOST_TEST((outputHandle->GetShape() == outputShape));
461 }
462 
463 BOOST_AUTO_TEST_CASE(CreatePooling2dFloatNchwWorkload)
464 {
465  ClPooling2dWorkloadTest<armnn::DataType::Float32>(DataLayout::NCHW);
466 }
467 
468 BOOST_AUTO_TEST_CASE(CreatePooling2dFloatNhwcWorkload)
469 {
470  ClPooling2dWorkloadTest<armnn::DataType::Float32>(DataLayout::NHWC);
471 }
472 
473 BOOST_AUTO_TEST_CASE(CreatePooling2dFloat16NchwWorkload)
474 {
475  ClPooling2dWorkloadTest<armnn::DataType::Float16>(DataLayout::NCHW);
476 }
477 
478 BOOST_AUTO_TEST_CASE(CreatePooling2dFloat16NhwcWorkload)
479 {
480  ClPooling2dWorkloadTest<armnn::DataType::Float16>(DataLayout::NHWC);
481 }
482 
483 static void ClCreatePreluWorkloadTest(const armnn::TensorShape& inputShape,
484  const armnn::TensorShape& alphaShape,
485  const armnn::TensorShape& outputShape,
486  armnn::DataType dataType)
487 {
488  Graph graph;
489  ClWorkloadFactory factory =
490  ClWorkloadFactoryHelper::GetFactory(ClWorkloadFactoryHelper::GetMemoryManager());
491 
492  auto workload = CreatePreluWorkloadTest<ClPreluWorkload>(factory,
493  graph,
494  inputShape,
495  alphaShape,
496  outputShape,
497  dataType);
498 
499  // Checks that outputs and inputs are as we expect them (see definition of CreatePreluWorkloadTest).
500  PreluQueueDescriptor queueDescriptor = workload->GetData();
501  auto inputHandle = PolymorphicDowncast<IClTensorHandle*>(queueDescriptor.m_Inputs[0]);
502  auto alphaHandle = PolymorphicDowncast<IClTensorHandle*>(queueDescriptor.m_Inputs[1]);
503  auto outputHandle = PolymorphicDowncast<IClTensorHandle*>(queueDescriptor.m_Outputs[0]);
504 
505  BOOST_TEST((inputHandle->GetShape() == inputShape));
506  BOOST_TEST((alphaHandle->GetShape() == alphaShape));
507  BOOST_TEST((outputHandle->GetShape() == outputShape));
508 }
509 
510 BOOST_AUTO_TEST_CASE(CreatePreluFloat16Workload)
511 {
512  ClCreatePreluWorkloadTest({ 1, 4, 1, 2 }, { 5, 4, 3, 1 }, { 5, 4, 3, 2 }, DataType::Float16);
513 }
514 
515 BOOST_AUTO_TEST_CASE(CreatePreluFloatWorkload)
516 {
517  ClCreatePreluWorkloadTest({ 1, 4, 1, 2 }, { 5, 4, 3, 1 }, { 5, 4, 3, 2 }, DataType::Float32);
518 }
519 
520 BOOST_AUTO_TEST_CASE(CreatePreluUint8Workload)
521 {
522  ClCreatePreluWorkloadTest({ 1, 4, 1, 2 }, { 5, 4, 3, 1 }, { 5, 4, 3, 2 }, DataType::QAsymmU8);
523 }
524 
525 template <typename armnn::DataType DataType>
526 static void ClCreateReshapeWorkloadTest()
527 {
528  Graph graph;
529  ClWorkloadFactory factory =
530  ClWorkloadFactoryHelper::GetFactory(ClWorkloadFactoryHelper::GetMemoryManager());
531 
532  auto workload = CreateReshapeWorkloadTest<ClReshapeWorkload, DataType>(factory, graph);
533 
534  // Checks that outputs and inputs are as we expect them (see definition of CreateReshapeWorkloadTest).
535  ReshapeQueueDescriptor queueDescriptor = workload->GetData();
536  auto inputHandle = PolymorphicDowncast<IClTensorHandle*>(queueDescriptor.m_Inputs[0]);
537  auto outputHandle = PolymorphicDowncast<IClTensorHandle*>(queueDescriptor.m_Outputs[0]);
538 
539  BOOST_TEST(CompareIClTensorHandleShape(inputHandle, {4, 1}));
540  BOOST_TEST(CompareIClTensorHandleShape(outputHandle, {1, 4}));
541 }
542 
543 BOOST_AUTO_TEST_CASE(CreateReshapeFloatWorkload)
544 {
545  ClCreateReshapeWorkloadTest<armnn::DataType::Float32>();
546 }
547 
548 BOOST_AUTO_TEST_CASE(CreateReshapeFloat16Workload)
549 {
550  ClCreateReshapeWorkloadTest<armnn::DataType::Float16>();
551 }
552 
553 BOOST_AUTO_TEST_CASE(CreateReshapeUint8Workload)
554 {
555  ClCreateReshapeWorkloadTest<armnn::DataType::QAsymmU8>();
556 }
557 
558 template <typename SoftmaxWorkloadType, typename armnn::DataType DataType>
559 static void ClSoftmaxWorkloadTest()
560 {
561  Graph graph;
562  ClWorkloadFactory factory =
563  ClWorkloadFactoryHelper::GetFactory(ClWorkloadFactoryHelper::GetMemoryManager());
564 
565  auto workload = CreateSoftmaxWorkloadTest<SoftmaxWorkloadType, DataType>(factory, graph);
566 
567  // Checks that inputs/outputs are as we expect them (see definition of ClSoftmaxFloatWorkload).
568  SoftmaxQueueDescriptor queueDescriptor = workload->GetData();
569  auto inputHandle = PolymorphicDowncast<IClTensorHandle*>(queueDescriptor.m_Inputs[0]);
570  auto outputHandle = PolymorphicDowncast<IClTensorHandle*>(queueDescriptor.m_Outputs[0]);
571 
572  armnn::TensorInfo tensorInfo({4, 1}, DataType);
574  {
575  tensorInfo.SetQuantizationOffset(0);
576  tensorInfo.SetQuantizationScale(1.f / 256);
577  }
579  {
580  tensorInfo.SetQuantizationOffset(-128);
581  tensorInfo.SetQuantizationScale(1.f / 256);
582  }
583 
584  BOOST_TEST(CompareIClTensorHandleShape(inputHandle, {4, 1}));
585  BOOST_TEST(CompareIClTensorHandleShape(outputHandle, {4, 1}));
586 }
587 
588 
589 BOOST_AUTO_TEST_CASE(CreateSoftmaxFloat32WorkloadTest)
590 {
591  ClSoftmaxWorkloadTest<ClSoftmaxWorkload, armnn::DataType::Float32>();
592 }
593 
594 BOOST_AUTO_TEST_CASE(CreateSoftmaxFloat16WorkloadTest)
595 {
596  ClSoftmaxWorkloadTest<ClSoftmaxWorkload, armnn::DataType::Float16>();
597 }
598 
599 BOOST_AUTO_TEST_CASE(CreateSoftmaxQAsymmU8Workload)
600 {
601  ClSoftmaxWorkloadTest<ClSoftmaxWorkload, armnn::DataType::QAsymmU8>();
602 }
603 
604 BOOST_AUTO_TEST_CASE(CreateSoftmaxQAsymmS8Workload)
605 {
606  ClSoftmaxWorkloadTest<ClSoftmaxWorkload, armnn::DataType::QAsymmS8>();
607 }
608 
609 template <typename armnn::DataType DataType>
610 static void ClSplitterWorkloadTest()
611 {
612  Graph graph;
613  ClWorkloadFactory factory =
614  ClWorkloadFactoryHelper::GetFactory(ClWorkloadFactoryHelper::GetMemoryManager());
615 
616  auto workload = CreateSplitterWorkloadTest<ClSplitterWorkload, DataType>(factory, graph);
617 
618  // Checks that outputs are as we expect them (see definition of CreateSplitterWorkloadTest).
619  SplitterQueueDescriptor queueDescriptor = workload->GetData();
620  auto inputHandle = PolymorphicDowncast<IClTensorHandle*>(queueDescriptor.m_Inputs[0]);
621  BOOST_TEST(CompareIClTensorHandleShape(inputHandle, {5, 7, 7}));
622 
623  auto outputHandle1 = PolymorphicDowncast<IClTensorHandle*>(queueDescriptor.m_Outputs[1]);
624  BOOST_TEST(CompareIClTensorHandleShape(outputHandle1, {2, 7, 7}));
625 
626  auto outputHandle2 = PolymorphicDowncast<IClTensorHandle*>(queueDescriptor.m_Outputs[2]);
627  BOOST_TEST(CompareIClTensorHandleShape(outputHandle2, {2, 7, 7}));
628 
629  auto outputHandle0 = PolymorphicDowncast<IClTensorHandle*>(queueDescriptor.m_Outputs[0]);
630  BOOST_TEST(CompareIClTensorHandleShape(outputHandle0, {1, 7, 7}));
631 }
632 
633 BOOST_AUTO_TEST_CASE(CreateSplitterFloatWorkload)
634 {
635  ClSplitterWorkloadTest<armnn::DataType::Float32>();
636 }
637 
638 BOOST_AUTO_TEST_CASE(CreateSplitterFloat16Workload)
639 {
640  ClSplitterWorkloadTest<armnn::DataType::Float16>();
641 }
642 
643 template <typename armnn::DataType DataType>
644 static void ClSplitterConcatTest()
645 {
646  // Tests that it is possible to decide which output of the splitter layer
647  // should be lined to which input of the concat layer.
648  // We test that is is possible to specify 0th output
649  // of the splitter to be the 1st input to the concat and the 1st output of the splitter to be 0th input
650  // of the concat.
651 
652  Graph graph;
653  ClWorkloadFactory factory =
654  ClWorkloadFactoryHelper::GetFactory(ClWorkloadFactoryHelper::GetMemoryManager());
655 
656  auto workloads =
657  CreateSplitterConcatWorkloadTest<ClSplitterWorkload, ClConcatWorkload, DataType>
658  (factory, graph);
659 
660  auto wlSplitter = std::move(workloads.first);
661  auto wlConcat = std::move(workloads.second);
662 
663  //Checks that the index of inputs/outputs matches what we declared on InputDescriptor construction.
664  armnn::ClSubTensorHandle* sOut0 = dynamic_cast<armnn::ClSubTensorHandle*>(wlSplitter->GetData().m_Outputs[0]);
665  armnn::ClSubTensorHandle* sOut1 = dynamic_cast<armnn::ClSubTensorHandle*>(wlSplitter->GetData().m_Outputs[1]);
666  armnn::ClSubTensorHandle* mIn0 = dynamic_cast<armnn::ClSubTensorHandle*>(wlConcat->GetData().m_Inputs[0]);
667  armnn::ClSubTensorHandle* mIn1 = dynamic_cast<armnn::ClSubTensorHandle*>(wlConcat->GetData().m_Inputs[1]);
668 
669  BOOST_TEST(sOut0);
670  BOOST_TEST(sOut1);
671  BOOST_TEST(mIn0);
672  BOOST_TEST(mIn1);
673 
674  //Fliped order of inputs/outputs.
675  bool validDataPointers = (sOut0 == mIn1) && (sOut1 == mIn0);
676  BOOST_TEST(validDataPointers);
677 
678 
679  //Also make sure that the inputs are subtensors of one tensor and outputs are sub tensors of another tensor.
680  bool validSubTensorParents = (mIn0->GetTensor().parent() == mIn1->GetTensor().parent())
681  && (sOut0->GetTensor().parent() == sOut1->GetTensor().parent());
682 
683  BOOST_TEST(validSubTensorParents);
684 }
685 
686 BOOST_AUTO_TEST_CASE(CreateSplitterConcatFloatWorkload)
687 {
688  ClSplitterConcatTest<armnn::DataType::Float32>();
689 }
690 
691 BOOST_AUTO_TEST_CASE(CreateSplitterConcatFloat16Workload)
692 {
693  ClSplitterConcatTest<armnn::DataType::Float16>();
694 }
695 
696 
697 BOOST_AUTO_TEST_CASE(CreateSingleOutputMultipleInputs)
698 {
699  // Test that it is possible to assign multiple (two) different layers to each of the outputs of a splitter layer.
700  // We create a splitter with two outputs. That each of those outputs is used by two different activation layers.
701 
702  Graph graph;
703  ClWorkloadFactory factory =
704  ClWorkloadFactoryHelper::GetFactory(ClWorkloadFactoryHelper::GetMemoryManager());
705 
706  std::unique_ptr<ClSplitterWorkload> wlSplitter;
707  std::unique_ptr<ClActivationWorkload> wlActiv0_0;
708  std::unique_ptr<ClActivationWorkload> wlActiv0_1;
709  std::unique_ptr<ClActivationWorkload> wlActiv1_0;
710  std::unique_ptr<ClActivationWorkload> wlActiv1_1;
711 
712  CreateSplitterMultipleInputsOneOutputWorkloadTest<ClSplitterWorkload,
713  ClActivationWorkload, armnn::DataType::Float32>(factory, graph, wlSplitter, wlActiv0_0, wlActiv0_1,
714  wlActiv1_0, wlActiv1_1);
715 
716  //Checks that the index of inputs/outputs matches what we declared on InputDescriptor construction.
717  armnn::ClSubTensorHandle* sOut0 = dynamic_cast<armnn::ClSubTensorHandle*>(wlSplitter->GetData().m_Outputs[0]);
718  armnn::ClSubTensorHandle* sOut1 = dynamic_cast<armnn::ClSubTensorHandle*>(wlSplitter->GetData().m_Outputs[1]);
719  armnn::ClSubTensorHandle* activ0_0Im = dynamic_cast<armnn::ClSubTensorHandle*>(wlActiv0_0->GetData().m_Inputs[0]);
720  armnn::ClSubTensorHandle* activ0_1Im = dynamic_cast<armnn::ClSubTensorHandle*>(wlActiv0_1->GetData().m_Inputs[0]);
721  armnn::ClSubTensorHandle* activ1_0Im = dynamic_cast<armnn::ClSubTensorHandle*>(wlActiv1_0->GetData().m_Inputs[0]);
722  armnn::ClSubTensorHandle* activ1_1Im = dynamic_cast<armnn::ClSubTensorHandle*>(wlActiv1_1->GetData().m_Inputs[0]);
723 
724 
725  BOOST_TEST(sOut0);
726  BOOST_TEST(sOut1);
727  BOOST_TEST(activ0_0Im);
728  BOOST_TEST(activ0_1Im);
729  BOOST_TEST(activ1_0Im);
730  BOOST_TEST(activ1_1Im);
731 
732  bool validDataPointers = (sOut0 == activ0_0Im) && (sOut0 == activ0_1Im) &&
733  (sOut1 == activ1_0Im) && (sOut1 == activ1_1Im);
734 
735  BOOST_TEST(validDataPointers);
736 }
737 
738 #if defined(ARMNNREF_ENABLED)
739 
740 // This test unit needs the reference backend, it's not available if the reference backend is not built
741 
742 BOOST_AUTO_TEST_CASE(CreateMemCopyWorkloadsCl)
743 {
744  ClWorkloadFactory factory =
745  ClWorkloadFactoryHelper::GetFactory(ClWorkloadFactoryHelper::GetMemoryManager());
746 
747  CreateMemCopyWorkloads<IClTensorHandle>(factory);
748 }
749 
750 #endif
751 
752 template <typename L2NormalizationWorkloadType, typename armnn::DataType DataType>
753 static void ClL2NormalizationWorkloadTest(DataLayout dataLayout)
754 {
755  Graph graph;
756  ClWorkloadFactory factory =
757  ClWorkloadFactoryHelper::GetFactory(ClWorkloadFactoryHelper::GetMemoryManager());
758 
759  auto workload =
760  CreateL2NormalizationWorkloadTest<L2NormalizationWorkloadType, DataType>(factory, graph, dataLayout);
761 
762  // Checks that inputs/outputs are as we expect them (see definition of CreateNormalizationWorkloadTest).
763  L2NormalizationQueueDescriptor queueDescriptor = workload->GetData();
764  auto inputHandle = PolymorphicDowncast<IClTensorHandle*>(queueDescriptor.m_Inputs[0]);
765  auto outputHandle = PolymorphicDowncast<IClTensorHandle*>(queueDescriptor.m_Outputs[0]);
766 
767  TensorShape inputShape = (dataLayout == DataLayout::NCHW) ? std::initializer_list<unsigned int>({ 5, 20, 50, 67 })
768  : std::initializer_list<unsigned int>({ 5, 50, 67, 20 });
769  TensorShape outputShape = (dataLayout == DataLayout::NCHW) ? std::initializer_list<unsigned int>({ 5, 20, 50, 67 })
770  : std::initializer_list<unsigned int>({ 5, 50, 67, 20 });
771 
772  BOOST_TEST((inputHandle->GetShape() == inputShape));
773  BOOST_TEST((outputHandle->GetShape() == outputShape));
774 }
775 
776 BOOST_AUTO_TEST_CASE(CreateL2NormalizationFloatNchwWorkload)
777 {
778  ClL2NormalizationWorkloadTest<ClL2NormalizationFloatWorkload, armnn::DataType::Float32>(DataLayout::NCHW);
779 }
780 
781 BOOST_AUTO_TEST_CASE(CreateL2NormalizationFloatNhwcWorkload)
782 {
783  ClL2NormalizationWorkloadTest<ClL2NormalizationFloatWorkload, armnn::DataType::Float32>(DataLayout::NHWC);
784 }
785 
786 BOOST_AUTO_TEST_CASE(CreateL2NormalizationFloat16NchwWorkload)
787 {
788  ClL2NormalizationWorkloadTest<ClL2NormalizationFloatWorkload, armnn::DataType::Float16>(DataLayout::NCHW);
789 }
790 
791 BOOST_AUTO_TEST_CASE(CreateL2NormalizationFloat16NhwcWorkload)
792 {
793  ClL2NormalizationWorkloadTest<ClL2NormalizationFloatWorkload, armnn::DataType::Float16>(DataLayout::NHWC);
794 }
795 
796 template <typename LstmWorkloadType>
797 static void ClCreateLstmWorkloadTest()
798 {
799  Graph graph;
800  ClWorkloadFactory factory =
801  ClWorkloadFactoryHelper::GetFactory(ClWorkloadFactoryHelper::GetMemoryManager());
802 
803  auto workload = CreateLstmWorkloadTest<LstmWorkloadType>(factory, graph);
804 
805  LstmQueueDescriptor queueDescriptor = workload->GetData();
806  auto inputHandle = PolymorphicDowncast<IClTensorHandle*>(queueDescriptor.m_Inputs[0]);
807  auto outputHandle = PolymorphicDowncast<IClTensorHandle*>(queueDescriptor.m_Outputs[1]);
808  BOOST_TEST(CompareIClTensorHandleShape(inputHandle, { 2, 2 }));
809  BOOST_TEST(CompareIClTensorHandleShape(outputHandle, { 2, 4 }));
810 }
811 
812 BOOST_AUTO_TEST_CASE(CreateLSTMWorkloadFloatWorkload)
813 {
814  ClCreateLstmWorkloadTest<ClLstmFloatWorkload>();
815 }
816 
817 template <typename ResizeWorkloadType, typename armnn::DataType DataType>
818 static void ClResizeWorkloadTest(DataLayout dataLayout)
819 {
820  Graph graph;
821  ClWorkloadFactory factory =
822  ClWorkloadFactoryHelper::GetFactory(ClWorkloadFactoryHelper::GetMemoryManager());
823 
824  auto workload = CreateResizeBilinearWorkloadTest<ResizeWorkloadType, DataType>(factory, graph, dataLayout);
825 
826  auto queueDescriptor = workload->GetData();
827 
828  auto inputHandle = PolymorphicDowncast<IClTensorHandle*>(queueDescriptor.m_Inputs[0]);
829  auto outputHandle = PolymorphicDowncast<IClTensorHandle*>(queueDescriptor.m_Outputs[0]);
830 
831  switch (dataLayout)
832  {
833  case DataLayout::NHWC:
834  BOOST_TEST(CompareIClTensorHandleShape(inputHandle, { 2, 4, 4, 3 }));
835  BOOST_TEST(CompareIClTensorHandleShape(outputHandle, { 2, 2, 2, 3 }));
836  break;
837  case DataLayout::NCHW:
838  default:
839  BOOST_TEST(CompareIClTensorHandleShape(inputHandle, { 2, 3, 4, 4 }));
840  BOOST_TEST(CompareIClTensorHandleShape(outputHandle, { 2, 3, 2, 2 }));
841  }
842 }
843 
844 BOOST_AUTO_TEST_CASE(CreateResizeFloat32NchwWorkload)
845 {
846  ClResizeWorkloadTest<ClResizeWorkload, armnn::DataType::Float32>(DataLayout::NCHW);
847 }
848 
849 BOOST_AUTO_TEST_CASE(CreateResizeFloat16NchwWorkload)
850 {
851  ClResizeWorkloadTest<ClResizeWorkload, armnn::DataType::Float16>(DataLayout::NCHW);
852 }
853 
854 BOOST_AUTO_TEST_CASE(CreateResizeUint8NchwWorkload)
855 {
856  ClResizeWorkloadTest<ClResizeWorkload, armnn::DataType::QAsymmU8>(DataLayout::NCHW);
857 }
858 
859 BOOST_AUTO_TEST_CASE(CreateResizeFloat32NhwcWorkload)
860 {
861  ClResizeWorkloadTest<ClResizeWorkload, armnn::DataType::Float32>(DataLayout::NHWC);
862 }
863 
864 BOOST_AUTO_TEST_CASE(CreateResizeFloat16NhwcWorkload)
865 {
866  ClResizeWorkloadTest<ClResizeWorkload, armnn::DataType::Float16>(DataLayout::NHWC);
867 }
868 
869 BOOST_AUTO_TEST_CASE(CreateResizeUint8NhwcWorkload)
870 {
871  ClResizeWorkloadTest<ClResizeWorkload, armnn::DataType::QAsymmU8>(DataLayout::NHWC);
872 }
873 
874 template <typename MeanWorkloadType, typename armnn::DataType DataType>
875 static void ClMeanWorkloadTest()
876 {
877  Graph graph;
878  ClWorkloadFactory factory =
879  ClWorkloadFactoryHelper::GetFactory(ClWorkloadFactoryHelper::GetMemoryManager());
880 
881  auto workload = CreateMeanWorkloadTest<MeanWorkloadType, DataType>(factory, graph);
882 
883  // Checks that inputs/outputs are as we expect them (see definition of CreateMeanWorkloadTest).
884  MeanQueueDescriptor queueDescriptor = workload->GetData();
885  auto inputHandle = PolymorphicDowncast<IClTensorHandle*>(queueDescriptor.m_Inputs[0]);
886  auto outputHandle = PolymorphicDowncast<IClTensorHandle*>(queueDescriptor.m_Outputs[0]);
887 
888  // The first dimension (batch size) in both input and output is singular thus it has been reduced by ACL.
889  BOOST_TEST(CompareIClTensorHandleShape(inputHandle, { 1, 3, 7, 4 }));
890  BOOST_TEST(CompareIClTensorHandleShape(outputHandle, { 1, 4 }));
891 }
892 
893 BOOST_AUTO_TEST_CASE(CreateMeanFloat32Workload)
894 {
895  ClMeanWorkloadTest<ClMeanWorkload, armnn::DataType::Float32>();
896 }
897 
898 BOOST_AUTO_TEST_CASE(CreateMeanFloat16Workload)
899 {
900  ClMeanWorkloadTest<ClMeanWorkload, armnn::DataType::Float16>();
901 }
902 
903 BOOST_AUTO_TEST_CASE(CreateMeanUint8Workload)
904 {
905  ClMeanWorkloadTest<ClMeanWorkload, armnn::DataType::QAsymmU8>();
906 }
907 
908 template <typename ConcatWorkloadType, armnn::DataType DataType>
909 static void ClCreateConcatWorkloadTest(std::initializer_list<unsigned int> outputShape,
910  unsigned int concatAxis)
911 {
912  Graph graph;
913  ClWorkloadFactory factory =
914  ClWorkloadFactoryHelper::GetFactory(ClWorkloadFactoryHelper::GetMemoryManager());
915 
916  auto workload = CreateConcatWorkloadTest<ConcatWorkloadType, DataType>(factory, graph, outputShape, concatAxis);
917 
918  ConcatQueueDescriptor queueDescriptor = workload->GetData();
919  auto inputHandle0 = PolymorphicDowncast<IClTensorHandle*>(queueDescriptor.m_Inputs[0]);
920  auto inputHandle1 = PolymorphicDowncast<IClTensorHandle*>(queueDescriptor.m_Inputs[1]);
921  auto outputHandle = PolymorphicDowncast<IClTensorHandle*>(queueDescriptor.m_Outputs[0]);
922 
923  BOOST_TEST(CompareIClTensorHandleShape(inputHandle0, { 2, 3, 2, 5 }));
924  BOOST_TEST(CompareIClTensorHandleShape(inputHandle1, { 2, 3, 2, 5 }));
925  BOOST_TEST(CompareIClTensorHandleShape(outputHandle, outputShape));
926 }
927 
928 BOOST_AUTO_TEST_CASE(CreateConcatDim0Float32Workload)
929 {
930  ClCreateConcatWorkloadTest<ClConcatWorkload, armnn::DataType::Float32>({ 4, 3, 2, 5 }, 0);
931 }
932 
933 BOOST_AUTO_TEST_CASE(CreateConcatDim1Float32Workload)
934 {
935  ClCreateConcatWorkloadTest<ClConcatWorkload, armnn::DataType::Float32>({ 2, 6, 2, 5 }, 1);
936 }
937 
938 BOOST_AUTO_TEST_CASE(CreateConcatDim3Float32Workload)
939 {
940  ClCreateConcatWorkloadTest<ClConcatWorkload, armnn::DataType::Float32>({ 2, 3, 2, 10 }, 3);
941 }
942 
943 BOOST_AUTO_TEST_CASE(CreateConcatDim0Uint8Workload)
944 {
945  ClCreateConcatWorkloadTest<ClConcatWorkload, armnn::DataType::QAsymmU8>({ 4, 3, 2, 5 }, 0);
946 }
947 
948 BOOST_AUTO_TEST_CASE(CreateConcatDim1Uint8Workload)
949 {
950  ClCreateConcatWorkloadTest<ClConcatWorkload, armnn::DataType::QAsymmU8>({ 2, 6, 2, 5 }, 1);
951 }
952 
953 BOOST_AUTO_TEST_CASE(CreateConcatDim3Uint8Workload)
954 {
955  ClCreateConcatWorkloadTest<ClConcatWorkload, armnn::DataType::QAsymmU8>({ 2, 3, 2, 10 }, 3);
956 }
957 
958 template <typename SpaceToDepthWorkloadType, typename armnn::DataType DataType>
959 static void ClSpaceToDepthWorkloadTest()
960 {
961  Graph graph;
962  ClWorkloadFactory factory =
963  ClWorkloadFactoryHelper::GetFactory(ClWorkloadFactoryHelper::GetMemoryManager());
964 
965  auto workload = CreateSpaceToDepthWorkloadTest<SpaceToDepthWorkloadType, DataType>(factory, graph);
966 
967  SpaceToDepthQueueDescriptor queueDescriptor = workload->GetData();
968  auto inputHandle = PolymorphicDowncast<IClTensorHandle*>(queueDescriptor.m_Inputs[0]);
969  auto outputHandle = PolymorphicDowncast<IClTensorHandle*>(queueDescriptor.m_Outputs[0]);
970 
971  BOOST_TEST(CompareIClTensorHandleShape(inputHandle, { 1, 2, 2, 1 }));
972  BOOST_TEST(CompareIClTensorHandleShape(outputHandle, { 1, 1, 1, 4 }));
973 }
974 
975 BOOST_AUTO_TEST_CASE(CreateSpaceToDepthFloat32Workload)
976 {
977  ClSpaceToDepthWorkloadTest<ClSpaceToDepthWorkload, armnn::DataType::Float32>();
978 }
979 
980 BOOST_AUTO_TEST_CASE(CreateSpaceToDepthFloat16Workload)
981 {
982  ClSpaceToDepthWorkloadTest<ClSpaceToDepthWorkload, armnn::DataType::Float16>();
983 }
984 
985 BOOST_AUTO_TEST_CASE(CreateSpaceToDepthQAsymm8Workload)
986 {
987  ClSpaceToDepthWorkloadTest<ClSpaceToDepthWorkload, armnn::DataType::QAsymmU8>();
988 }
989 
990 BOOST_AUTO_TEST_CASE(CreateSpaceToDepthQSymm16Workload)
991 {
992  ClSpaceToDepthWorkloadTest<ClSpaceToDepthWorkload, armnn::DataType::QSymmS16>();
993 }
994 
995 template <armnn::DataType DataType>
996 static void ClCreateStackWorkloadTest(const std::initializer_list<unsigned int>& inputShape,
997  const std::initializer_list<unsigned int>& outputShape,
998  unsigned int axis,
999  unsigned int numInputs)
1000 {
1001  armnn::Graph graph;
1002  ClWorkloadFactory factory =
1003  ClWorkloadFactoryHelper::GetFactory(ClWorkloadFactoryHelper::GetMemoryManager());
1004 
1005  auto workload = CreateStackWorkloadTest<ClStackWorkload, DataType>(factory,
1006  graph,
1007  TensorShape(inputShape),
1008  TensorShape(outputShape),
1009  axis,
1010  numInputs);
1011 
1012  // Check inputs and output are as expected
1013  StackQueueDescriptor queueDescriptor = workload->GetData();
1014  for (unsigned int i = 0; i < numInputs; ++i)
1015  {
1016  auto inputHandle = PolymorphicDowncast<IClTensorHandle*>(queueDescriptor.m_Inputs[i]);
1017  BOOST_TEST(CompareIClTensorHandleShape(inputHandle, inputShape));
1018  }
1019  auto outputHandle = PolymorphicDowncast<IClTensorHandle*>(queueDescriptor.m_Outputs[0]);
1020  BOOST_TEST(CompareIClTensorHandleShape(outputHandle, outputShape));
1021 }
1022 
1023 BOOST_AUTO_TEST_CASE(CreateStackFloat32Workload)
1024 {
1025  ClCreateStackWorkloadTest<armnn::DataType::Float32>({ 3, 4, 5 }, { 3, 4, 2, 5 }, 2, 2);
1026 }
1027 
1028 BOOST_AUTO_TEST_CASE(CreateStackFloat16Workload)
1029 {
1030  ClCreateStackWorkloadTest<armnn::DataType::Float16>({ 3, 4, 5 }, { 3, 4, 2, 5 }, 2, 2);
1031 }
1032 
1033 BOOST_AUTO_TEST_CASE(CreateStackUint8Workload)
1034 {
1035  ClCreateStackWorkloadTest<armnn::DataType::QAsymmU8>({ 3, 4, 5 }, { 3, 4, 2, 5 }, 2, 2);
1036 }
1037 
1038 
1039 template <typename QLstmWorkloadType>
1040 static void ClCreateQLstmWorkloadTest()
1041 {
1042  Graph graph;
1043  ClWorkloadFactory factory = ClWorkloadFactoryHelper::GetFactory(ClWorkloadFactoryHelper::GetMemoryManager());
1044 
1045  auto workload = CreateQLstmWorkloadTest<QLstmWorkloadType>(factory, graph);
1046  QLstmQueueDescriptor queueDescriptor = workload->GetData();
1047 
1048  IAclTensorHandle* inputHandle = PolymorphicDowncast<IAclTensorHandle*>(queueDescriptor.m_Inputs[0]);
1049  BOOST_TEST((inputHandle->GetShape() == TensorShape({2, 4})));
1050  BOOST_TEST((inputHandle->GetDataType() == arm_compute::DataType::QASYMM8_SIGNED));
1051 
1052  IAclTensorHandle* cellStateOutHandle = PolymorphicDowncast<IAclTensorHandle*>(queueDescriptor.m_Outputs[1]);
1053  BOOST_TEST((cellStateOutHandle->GetShape() == TensorShape({2, 4})));
1054  BOOST_TEST((cellStateOutHandle->GetDataType() == arm_compute::DataType::QSYMM16));
1055 
1056  IAclTensorHandle* outputHandle = PolymorphicDowncast<IAclTensorHandle*>(queueDescriptor.m_Outputs[2]);
1057  BOOST_TEST((outputHandle->GetShape() == TensorShape({2, 4})));
1058  BOOST_TEST((outputHandle->GetDataType() == arm_compute::DataType::QASYMM8_SIGNED));
1059 }
1060 
1061 BOOST_AUTO_TEST_CASE(CreateQLstmWorkloadTest)
1062 {
1063  ClCreateQLstmWorkloadTest<ClQLstmWorkload>();
1064 }
1065 
1066 template <typename QuantizedLstmWorkloadType>
1067 static void ClCreateQuantizedLstmWorkloadTest()
1068 {
1069  using namespace armnn::armcomputetensorutils;
1070 
1071  Graph graph;
1072  ClWorkloadFactory factory =
1073  ClWorkloadFactoryHelper::GetFactory(ClWorkloadFactoryHelper::GetMemoryManager());
1074 
1075  auto workload = CreateQuantizedLstmWorkloadTest<QuantizedLstmWorkloadType>(factory, graph);
1076 
1077  QuantizedLstmQueueDescriptor queueDescriptor = workload->GetData();
1078 
1079  IAclTensorHandle* inputHandle = PolymorphicDowncast<IAclTensorHandle*>(queueDescriptor.m_Inputs[0]);
1080  BOOST_TEST((inputHandle->GetShape() == TensorShape({2, 2})));
1081  BOOST_TEST((inputHandle->GetDataType() == arm_compute::DataType::QASYMM8));
1082 
1083  IAclTensorHandle* cellStateInHandle = PolymorphicDowncast<IAclTensorHandle*>(queueDescriptor.m_Inputs[1]);
1084  BOOST_TEST((cellStateInHandle->GetShape() == TensorShape({2, 4})));
1085  BOOST_TEST((cellStateInHandle->GetDataType() == arm_compute::DataType::QSYMM16));
1086 
1087  IAclTensorHandle* outputStateInHandle = PolymorphicDowncast<IAclTensorHandle*>(queueDescriptor.m_Inputs[2]);
1088  BOOST_TEST((outputStateInHandle->GetShape() == TensorShape({2, 4})));
1089  BOOST_TEST((outputStateInHandle->GetDataType() == arm_compute::DataType::QASYMM8));
1090 
1091  IAclTensorHandle* cellStateOutHandle = PolymorphicDowncast<IAclTensorHandle*>(queueDescriptor.m_Outputs[0]);
1092  BOOST_TEST((cellStateOutHandle->GetShape() == TensorShape({2, 4})));
1093  BOOST_TEST((cellStateOutHandle->GetDataType() == arm_compute::DataType::QSYMM16));
1094 
1095  IAclTensorHandle* outputStateOutHandle = PolymorphicDowncast<IAclTensorHandle*>(queueDescriptor.m_Outputs[1]);
1096  BOOST_TEST((outputStateOutHandle->GetShape() == TensorShape({2, 4})));
1097  BOOST_TEST((outputStateOutHandle->GetDataType() == arm_compute::DataType::QASYMM8));
1098 }
1099 
1100 BOOST_AUTO_TEST_CASE(CreateQuantizedLstmWorkload)
1101 {
1102  ClCreateQuantizedLstmWorkloadTest<ClQuantizedLstmWorkload>();
1103 }
1104 
DataLayout
Definition: Types.hpp:49
BOOST_AUTO_TEST_CASE(CreateActivationFloatWorkload)
virtual arm_compute::DataType GetDataType() const =0
DataType
Definition: Types.hpp:32
BOOST_AUTO_TEST_CASE(CheckConvolution2dLayer)
virtual TensorShape GetShape() const =0
Get the number of elements for each dimension ordered from slowest iterating dimension to fastest ite...
This layer represents an addition operation.
BOOST_AUTO_TEST_SUITE_END()
This layer represents a subtraction operation.
std::vector< ITensorHandle * > m_Outputs
boost::test_tools::predicate_result CompareIClTensorHandleShape(IClTensorHandle *tensorHandle, std::initializer_list< unsigned int > expectedDimensions)
This layer represents a division operation.
UnaryOperation
Definition: Types.hpp:87
void SetQuantizationOffset(int32_t offset)
Definition: Tensor.cpp:276
std::vector< ITensorHandle * > m_Inputs
This layer represents a multiplication operation.
arm_compute::CLSubTensor & GetTensor() override