blob: e7e39b0f7087437a1358ec6cacf60cd72b909a51 [file] [log] [blame]
telsoa014fcda012018-03-09 14:13:49 +00001//
2// Copyright © 2017 Arm Ltd. All rights reserved.
David Beckecb56cd2018-09-05 12:52:57 +01003// SPDX-License-Identifier: MIT
telsoa014fcda012018-03-09 14:13:49 +00004//
David Beckac42efd2018-09-26 17:41:13 +01005#include <backends/cl/ClWorkloadFactory.hpp>
David Beckb4540be2018-09-24 13:18:27 +01006#include <backends/reference/RefWorkloadFactory.hpp>
7#include <backends/MemCopyWorkload.hpp>
David Beckac42efd2018-09-26 17:41:13 +01008#include <backends/cl/workloads/ClWorkloadUtils.hpp>
9#include <backends/cl/workloads/ClWorkloads.hpp>
10#include <backends/cl/ClTensorHandle.hpp>
telsoa01c577f2c2018-08-31 09:22:23 +010011#include "ClContextControlFixture.hpp"
telsoa014fcda012018-03-09 14:13:49 +000012
David Beckac42efd2018-09-26 17:41:13 +010013#include <test/CreateWorkloadClNeon.hpp>
telsoa014fcda012018-03-09 14:13:49 +000014
15boost::test_tools::predicate_result CompareIClTensorHandleShape(IClTensorHandle* tensorHandle,
16 std::initializer_list<unsigned int> expectedDimensions)
17{
18 return CompareTensorHandleShape<IClTensorHandle>(tensorHandle, expectedDimensions);
19}
20
telsoa01c577f2c2018-08-31 09:22:23 +010021BOOST_FIXTURE_TEST_SUITE(CreateWorkloadCl, ClContextControlFixture)
telsoa014fcda012018-03-09 14:13:49 +000022
telsoa01c577f2c2018-08-31 09:22:23 +010023template <typename ActivationWorkloadType, armnn::DataType DataType>
24static void ClCreateActivationWorkloadTest()
telsoa014fcda012018-03-09 14:13:49 +000025{
26 Graph graph;
27 ClWorkloadFactory factory;
telsoa014fcda012018-03-09 14:13:49 +000028
telsoa01c577f2c2018-08-31 09:22:23 +010029 auto workload = CreateActivationWorkloadTest<ActivationWorkloadType, DataType>(factory, graph);
telsoa014fcda012018-03-09 14:13:49 +000030
telsoa01c577f2c2018-08-31 09:22:23 +010031 // Checks that inputs/outputs are as we expect them (see definition of CreateActivationWorkloadTest).
telsoa014fcda012018-03-09 14:13:49 +000032 ActivationQueueDescriptor queueDescriptor = workload->GetData();
33 auto inputHandle = boost::polymorphic_downcast<IClTensorHandle*>(queueDescriptor.m_Inputs[0]);
34 auto outputHandle = boost::polymorphic_downcast<IClTensorHandle*>(queueDescriptor.m_Outputs[0]);
35
36 BOOST_TEST(CompareIClTensorHandleShape(inputHandle, {1}));
37 BOOST_TEST(CompareIClTensorHandleShape(outputHandle, {1}));
38}
39
arovir019e53a352018-08-31 15:26:35 +010040BOOST_AUTO_TEST_CASE(CreateActivationFloatWorkload)
telsoa01c577f2c2018-08-31 09:22:23 +010041{
arovir019e53a352018-08-31 15:26:35 +010042 ClCreateActivationWorkloadTest<ClActivationFloatWorkload, armnn::DataType::Float32>();
telsoa01c577f2c2018-08-31 09:22:23 +010043}
44
45BOOST_AUTO_TEST_CASE(CreateActivationFloat16Workload)
46{
arovir019e53a352018-08-31 15:26:35 +010047 ClCreateActivationWorkloadTest<ClActivationFloatWorkload, armnn::DataType::Float16>();
telsoa01c577f2c2018-08-31 09:22:23 +010048}
49
David Beck4a8692c2018-09-07 16:19:24 +010050template <typename WorkloadType,
51 typename DescriptorType,
52 typename LayerType,
53 armnn::DataType DataType>
54static void ClCreateArithmethicWorkloadTest()
telsoa014fcda012018-03-09 14:13:49 +000055{
56 Graph graph;
57 ClWorkloadFactory factory;
David Beck4a8692c2018-09-07 16:19:24 +010058 auto workload = CreateArithmeticWorkloadTest<WorkloadType, DescriptorType, LayerType, DataType>(factory, graph);
telsoa014fcda012018-03-09 14:13:49 +000059
James Conroyb9bf9462018-09-19 11:58:44 +010060 // Checks that inputs/outputs are as we expect them (see definition of CreateArithmeticWorkloadTest).
David Beck4a8692c2018-09-07 16:19:24 +010061 DescriptorType queueDescriptor = workload->GetData();
telsoa014fcda012018-03-09 14:13:49 +000062 auto inputHandle1 = boost::polymorphic_downcast<IClTensorHandle*>(queueDescriptor.m_Inputs[0]);
63 auto inputHandle2 = boost::polymorphic_downcast<IClTensorHandle*>(queueDescriptor.m_Inputs[1]);
64 auto outputHandle = boost::polymorphic_downcast<IClTensorHandle*>(queueDescriptor.m_Outputs[0]);
65 BOOST_TEST(CompareIClTensorHandleShape(inputHandle1, {2, 3}));
66 BOOST_TEST(CompareIClTensorHandleShape(inputHandle2, {2, 3}));
67 BOOST_TEST(CompareIClTensorHandleShape(outputHandle, {2, 3}));
68}
69
arovir019e53a352018-08-31 15:26:35 +010070BOOST_AUTO_TEST_CASE(CreateAdditionFloatWorkload)
telsoa014fcda012018-03-09 14:13:49 +000071{
David Beck0a710c42018-09-11 15:21:14 +010072 ClCreateArithmethicWorkloadTest<ClAdditionWorkload<armnn::DataType::Float16, armnn::DataType::Float32>,
David Beck4a8692c2018-09-07 16:19:24 +010073 AdditionQueueDescriptor,
74 AdditionLayer,
75 armnn::DataType::Float32>();
telsoa01c577f2c2018-08-31 09:22:23 +010076}
77
78BOOST_AUTO_TEST_CASE(CreateAdditionFloat16Workload)
79{
David Beck0a710c42018-09-11 15:21:14 +010080 ClCreateArithmethicWorkloadTest<ClAdditionWorkload<armnn::DataType::Float16, armnn::DataType::Float32>,
David Beck4a8692c2018-09-07 16:19:24 +010081 AdditionQueueDescriptor,
82 AdditionLayer,
83 armnn::DataType::Float16>();
84}
85
86BOOST_AUTO_TEST_CASE(CreateSubtractionFloatWorkload)
87{
Matthew Bentham092b3042018-10-01 16:39:28 +010088 ClCreateArithmethicWorkloadTest<ClSubtractionWorkload,
David Beck4a8692c2018-09-07 16:19:24 +010089 SubtractionQueueDescriptor,
90 SubtractionLayer,
91 armnn::DataType::Float32>();
92}
93
94BOOST_AUTO_TEST_CASE(CreateSubtractionFloat16Workload)
95{
Matthew Bentham092b3042018-10-01 16:39:28 +010096 ClCreateArithmethicWorkloadTest<ClSubtractionWorkload,
David Beck4a8692c2018-09-07 16:19:24 +010097 SubtractionQueueDescriptor,
98 SubtractionLayer,
99 armnn::DataType::Float16>();
100}
101
102BOOST_AUTO_TEST_CASE(CreateMultiplicationFloatWorkloadTest)
103{
Matthew Benthame2ec3302018-10-01 11:32:48 +0100104 ClCreateArithmethicWorkloadTest<ClMultiplicationWorkload,
David Beck4a8692c2018-09-07 16:19:24 +0100105 MultiplicationQueueDescriptor,
106 MultiplicationLayer,
107 armnn::DataType::Float32>();
108}
109
110BOOST_AUTO_TEST_CASE(CreateMultiplicationFloat16WorkloadTest)
111{
Matthew Benthame2ec3302018-10-01 11:32:48 +0100112 ClCreateArithmethicWorkloadTest<ClMultiplicationWorkload,
David Beck4a8692c2018-09-07 16:19:24 +0100113 MultiplicationQueueDescriptor,
114 MultiplicationLayer,
115 armnn::DataType::Float16>();
116}
117
Matthew Benthame2ec3302018-10-01 11:32:48 +0100118BOOST_AUTO_TEST_CASE(CreateMultiplicationUint8WorkloadTest)
119{
120 ClCreateArithmethicWorkloadTest<ClMultiplicationWorkload,
121 MultiplicationQueueDescriptor,
122 MultiplicationLayer,
123 armnn::DataType::QuantisedAsymm8>();
124}
125
David Beck4a8692c2018-09-07 16:19:24 +0100126BOOST_AUTO_TEST_CASE(CreateDivisionFloatWorkloadTest)
127{
128 ClCreateArithmethicWorkloadTest<ClDivisionFloatWorkload,
129 DivisionQueueDescriptor,
130 DivisionLayer,
131 armnn::DataType::Float32>();
132}
133
134BOOST_AUTO_TEST_CASE(CreateDivisionFloat16WorkloadTest)
135{
136 ClCreateArithmethicWorkloadTest<ClDivisionFloatWorkload,
137 DivisionQueueDescriptor,
138 DivisionLayer,
139 armnn::DataType::Float16>();
telsoa01c577f2c2018-08-31 09:22:23 +0100140}
141
142template <typename BatchNormalizationWorkloadType, armnn::DataType DataType>
143static void ClCreateBatchNormalizationWorkloadTest()
144{
145 Graph graph;
telsoa014fcda012018-03-09 14:13:49 +0000146 ClWorkloadFactory factory;
telsoa014fcda012018-03-09 14:13:49 +0000147
telsoa01c577f2c2018-08-31 09:22:23 +0100148 auto workload = CreateBatchNormalizationWorkloadTest<BatchNormalizationWorkloadType, DataType>
149 (factory, graph);
telsoa014fcda012018-03-09 14:13:49 +0000150
telsoa01c577f2c2018-08-31 09:22:23 +0100151 // Checks that inputs/outputs are as we expect them (see definition of CreateBatchNormalizationWorkloadTest).
telsoa014fcda012018-03-09 14:13:49 +0000152 BatchNormalizationQueueDescriptor queueDescriptor = workload->GetData();
153 auto inputHandle = boost::polymorphic_downcast<IClTensorHandle*>(queueDescriptor.m_Inputs[0]);
154 auto outputHandle = boost::polymorphic_downcast<IClTensorHandle*>(queueDescriptor.m_Outputs[0]);
155
156 BOOST_TEST(CompareIClTensorHandleShape(inputHandle, {2, 3, 1, 1}));
157 BOOST_TEST(CompareIClTensorHandleShape(outputHandle, {2, 3, 1, 1}));
158}
159
arovir019e53a352018-08-31 15:26:35 +0100160BOOST_AUTO_TEST_CASE(CreateBatchNormalizationFloatWorkload)
telsoa014fcda012018-03-09 14:13:49 +0000161{
arovir019e53a352018-08-31 15:26:35 +0100162 ClCreateBatchNormalizationWorkloadTest<ClBatchNormalizationFloatWorkload, armnn::DataType::Float32>();
telsoa01c577f2c2018-08-31 09:22:23 +0100163}
telsoa014fcda012018-03-09 14:13:49 +0000164
telsoa01c577f2c2018-08-31 09:22:23 +0100165BOOST_AUTO_TEST_CASE(CreateBatchNormalizationFloat16Workload)
166{
arovir019e53a352018-08-31 15:26:35 +0100167 ClCreateBatchNormalizationWorkloadTest<ClBatchNormalizationFloatWorkload, armnn::DataType::Float16>();
telsoa01c577f2c2018-08-31 09:22:23 +0100168}
169
170BOOST_AUTO_TEST_CASE(CreateConvertFp16ToFp32Workload)
171{
172 Graph graph;
173 ClWorkloadFactory factory;
174 auto workload = CreateConvertFp16ToFp32WorkloadTest<ClConvertFp16ToFp32Workload>(factory, graph);
175
176 ConvertFp16ToFp32QueueDescriptor queueDescriptor = workload->GetData();
177 auto inputHandle = boost::polymorphic_downcast<IClTensorHandle*>(queueDescriptor.m_Inputs[0]);
178 auto outputHandle = boost::polymorphic_downcast<IClTensorHandle*>(queueDescriptor.m_Outputs[0]);
179
180 BOOST_TEST(CompareIClTensorHandleShape(inputHandle, {3, 2, 3}));
181 BOOST_TEST(CompareIClTensorHandleShape(outputHandle, {3, 2, 3}));
182 BOOST_TEST((inputHandle->GetTensor().info()->data_type() == arm_compute::DataType::F16));
183 BOOST_TEST((outputHandle->GetTensor().info()->data_type() == arm_compute::DataType::F32));
184}
185
186BOOST_AUTO_TEST_CASE(CreateConvertFp32ToFp16Workload)
187{
188 Graph graph;
189 ClWorkloadFactory factory;
190 auto workload = CreateConvertFp32ToFp16WorkloadTest<ClConvertFp32ToFp16Workload>(factory, graph);
191
192 ConvertFp32ToFp16QueueDescriptor queueDescriptor = workload->GetData();
193 auto inputHandle = boost::polymorphic_downcast<IClTensorHandle*>(queueDescriptor.m_Inputs[0]);
194 auto outputHandle = boost::polymorphic_downcast<IClTensorHandle*>(queueDescriptor.m_Outputs[0]);
195
196 BOOST_TEST(CompareIClTensorHandleShape(inputHandle, {3, 2, 3}));
197 BOOST_TEST(CompareIClTensorHandleShape(outputHandle, {3, 2, 3}));
198 BOOST_TEST((inputHandle->GetTensor().info()->data_type() == arm_compute::DataType::F32));
199 BOOST_TEST((outputHandle->GetTensor().info()->data_type() == arm_compute::DataType::F16));
200}
201
Matthew Benthamd8067922018-10-03 17:18:04 +0100202template <typename armnn::DataType DataType>
telsoa01c577f2c2018-08-31 09:22:23 +0100203static void ClConvolution2dWorkloadTest()
204{
205 Graph graph;
206 ClWorkloadFactory factory;
Matthew Benthamd8067922018-10-03 17:18:04 +0100207 auto workload = CreateConvolution2dWorkloadTest<ClConvolution2dWorkload, DataType>(factory, graph);
telsoa01c577f2c2018-08-31 09:22:23 +0100208
209 // Checks that outputs and inputs are as we expect them (see definition of CreateConvolution2dWorkloadTest).
telsoa014fcda012018-03-09 14:13:49 +0000210 Convolution2dQueueDescriptor queueDescriptor = workload->GetData();
211 auto inputHandle = boost::polymorphic_downcast<IClTensorHandle*>(queueDescriptor.m_Inputs[0]);
212 auto outputHandle = boost::polymorphic_downcast<IClTensorHandle*>(queueDescriptor.m_Outputs[0]);
213 BOOST_TEST(CompareIClTensorHandleShape(inputHandle, {2, 3, 8, 16}));
214 BOOST_TEST(CompareIClTensorHandleShape(outputHandle, {2, 2, 2, 10}));
215}
216
arovir019e53a352018-08-31 15:26:35 +0100217BOOST_AUTO_TEST_CASE(CreateConvolution2dFloatWorkload)
telsoa014fcda012018-03-09 14:13:49 +0000218{
Matthew Benthamd8067922018-10-03 17:18:04 +0100219 ClConvolution2dWorkloadTest<armnn::DataType::Float32>();
telsoa01c577f2c2018-08-31 09:22:23 +0100220}
221
222BOOST_AUTO_TEST_CASE(CreateConvolution2dFloat16Workload)
223{
Matthew Benthamd8067922018-10-03 17:18:04 +0100224 ClConvolution2dWorkloadTest<armnn::DataType::Float16>();
telsoa014fcda012018-03-09 14:13:49 +0000225}
226
Matthew Benthamd8067922018-10-03 17:18:04 +0100227template <typename armnn::DataType DataType>
telsoa01c577f2c2018-08-31 09:22:23 +0100228static void ClDirectConvolution2dWorkloadTest()
telsoa014fcda012018-03-09 14:13:49 +0000229{
telsoa01c577f2c2018-08-31 09:22:23 +0100230 Graph graph;
231 ClWorkloadFactory factory;
Matthew Benthamd8067922018-10-03 17:18:04 +0100232 auto workload = CreateDirectConvolution2dWorkloadTest<ClConvolution2dWorkload, DataType>(factory, graph);
telsoa014fcda012018-03-09 14:13:49 +0000233
telsoa01c577f2c2018-08-31 09:22:23 +0100234 // Checks that outputs and inputs are as we expect them (see definition of CreateDirectConvolution2dWorkloadTest).
telsoa014fcda012018-03-09 14:13:49 +0000235 Convolution2dQueueDescriptor queueDescriptor = workload->GetData();
236 auto inputHandle = boost::polymorphic_downcast<IClTensorHandle*>(queueDescriptor.m_Inputs[0]);
237 auto outputHandle = boost::polymorphic_downcast<IClTensorHandle*>(queueDescriptor.m_Outputs[0]);
238 BOOST_TEST(CompareIClTensorHandleShape(inputHandle, {2, 3, 6, 6}));
239 BOOST_TEST(CompareIClTensorHandleShape(outputHandle, {2, 2, 6, 6}));
240}
241
arovir019e53a352018-08-31 15:26:35 +0100242BOOST_AUTO_TEST_CASE(CreateDirectConvolution2dFloatWorkload)
telsoa014fcda012018-03-09 14:13:49 +0000243{
Matthew Benthamd8067922018-10-03 17:18:04 +0100244 ClDirectConvolution2dWorkloadTest<armnn::DataType::Float32>();
telsoa01c577f2c2018-08-31 09:22:23 +0100245}
246
247BOOST_AUTO_TEST_CASE(CreateDirectConvolution2dFloat16Workload)
248{
Matthew Benthamd8067922018-10-03 17:18:04 +0100249 ClDirectConvolution2dWorkloadTest<armnn::DataType::Float16>();
telsoa014fcda012018-03-09 14:13:49 +0000250}
251
252BOOST_AUTO_TEST_CASE(CreateDirectConvolution2dUint8Workload)
253{
Matthew Benthamd8067922018-10-03 17:18:04 +0100254 ClDirectConvolution2dWorkloadTest<armnn::DataType::QuantisedAsymm8>();
telsoa014fcda012018-03-09 14:13:49 +0000255}
256
telsoa01c577f2c2018-08-31 09:22:23 +0100257template <typename FullyConnectedWorkloadType, typename armnn::DataType DataType>
258static void ClCreateFullyConnectedWorkloadTest()
telsoa014fcda012018-03-09 14:13:49 +0000259{
telsoa01c577f2c2018-08-31 09:22:23 +0100260 Graph graph;
telsoa014fcda012018-03-09 14:13:49 +0000261 ClWorkloadFactory factory;
telsoa01c577f2c2018-08-31 09:22:23 +0100262 auto workload =
263 CreateFullyConnectedWorkloadTest<FullyConnectedWorkloadType, DataType>(factory, graph);
telsoa014fcda012018-03-09 14:13:49 +0000264
telsoa01c577f2c2018-08-31 09:22:23 +0100265 // Checks that outputs and inputs are as we expect them (see definition of CreateFullyConnectedWorkloadTest).
telsoa014fcda012018-03-09 14:13:49 +0000266 FullyConnectedQueueDescriptor queueDescriptor = workload->GetData();
267 auto inputHandle = boost::polymorphic_downcast<IClTensorHandle*>(queueDescriptor.m_Inputs[0]);
268 auto outputHandle = boost::polymorphic_downcast<IClTensorHandle*>(queueDescriptor.m_Outputs[0]);
269 BOOST_TEST(CompareIClTensorHandleShape(inputHandle, {3, 1, 4, 5}));
270 BOOST_TEST(CompareIClTensorHandleShape(outputHandle, {3, 7}));
271}
272
telsoa01c577f2c2018-08-31 09:22:23 +0100273
arovir019e53a352018-08-31 15:26:35 +0100274BOOST_AUTO_TEST_CASE(CreateFullyConnectedFloatWorkloadTest)
telsoa014fcda012018-03-09 14:13:49 +0000275{
Matthew Benthamab8cdc12018-09-17 11:17:41 +0100276 ClCreateFullyConnectedWorkloadTest<ClFullyConnectedWorkload, armnn::DataType::Float32>();
telsoa01c577f2c2018-08-31 09:22:23 +0100277}
278
279BOOST_AUTO_TEST_CASE(CreateFullyConnectedFloat16WorkloadTest)
280{
Matthew Benthamab8cdc12018-09-17 11:17:41 +0100281 ClCreateFullyConnectedWorkloadTest<ClFullyConnectedWorkload, armnn::DataType::Float16>();
telsoa01c577f2c2018-08-31 09:22:23 +0100282}
283
telsoa01c577f2c2018-08-31 09:22:23 +0100284template <typename NormalizationWorkloadType, typename armnn::DataType DataType>
narpra0155a97bc2018-10-02 14:35:53 +0100285static void ClNormalizationWorkloadTest(DataLayout dataLayout)
telsoa01c577f2c2018-08-31 09:22:23 +0100286{
287 Graph graph;
telsoa014fcda012018-03-09 14:13:49 +0000288 ClWorkloadFactory factory;
telsoa014fcda012018-03-09 14:13:49 +0000289
telsoa01c577f2c2018-08-31 09:22:23 +0100290 auto workload = CreateNormalizationWorkloadTest<NormalizationWorkloadType, DataType>
narpra0155a97bc2018-10-02 14:35:53 +0100291 (factory, graph, dataLayout);
telsoa014fcda012018-03-09 14:13:49 +0000292
telsoa01c577f2c2018-08-31 09:22:23 +0100293 // Checks that inputs/outputs are as we expect them (see definition of CreateNormalizationWorkloadTest).
telsoa014fcda012018-03-09 14:13:49 +0000294 NormalizationQueueDescriptor queueDescriptor = workload->GetData();
295 auto inputHandle = boost::polymorphic_downcast<IClTensorHandle*>(queueDescriptor.m_Inputs[0]);
296 auto outputHandle = boost::polymorphic_downcast<IClTensorHandle*>(queueDescriptor.m_Outputs[0]);
297
298 BOOST_TEST(CompareIClTensorHandleShape(inputHandle, {3, 5, 5, 1}));
299 BOOST_TEST(CompareIClTensorHandleShape(outputHandle, {3, 5, 5, 1}));
300}
301
narpra0155a97bc2018-10-02 14:35:53 +0100302BOOST_AUTO_TEST_CASE(CreateNormalizationFloat32NchwWorkload)
telsoa014fcda012018-03-09 14:13:49 +0000303{
narpra0155a97bc2018-10-02 14:35:53 +0100304 ClNormalizationWorkloadTest<ClNormalizationFloatWorkload, armnn::DataType::Float32>(DataLayout::NCHW);
telsoa01c577f2c2018-08-31 09:22:23 +0100305}
306
narpra0155a97bc2018-10-02 14:35:53 +0100307BOOST_AUTO_TEST_CASE(CreateNormalizationFloat16NchwWorkload)
telsoa01c577f2c2018-08-31 09:22:23 +0100308{
narpra0155a97bc2018-10-02 14:35:53 +0100309 ClNormalizationWorkloadTest<ClNormalizationFloatWorkload, armnn::DataType::Float16>(DataLayout::NCHW);
310}
311
312BOOST_AUTO_TEST_CASE(CreateNormalizationFloat32NhwcWorkload)
313{
314 ClNormalizationWorkloadTest<ClNormalizationFloatWorkload, armnn::DataType::Float32>(DataLayout::NHWC);
315}
316
317BOOST_AUTO_TEST_CASE(CreateNormalizationFloat16NhwcWorkload)
318{
319 ClNormalizationWorkloadTest<ClNormalizationFloatWorkload, armnn::DataType::Float16>(DataLayout::NHWC);
telsoa01c577f2c2018-08-31 09:22:23 +0100320}
321
322template <typename Pooling2dWorkloadType, typename armnn::DataType DataType>
323static void ClPooling2dWorkloadTest()
324{
325 Graph graph;
telsoa014fcda012018-03-09 14:13:49 +0000326 ClWorkloadFactory factory;
telsoa014fcda012018-03-09 14:13:49 +0000327
telsoa01c577f2c2018-08-31 09:22:23 +0100328 auto workload = CreatePooling2dWorkloadTest<Pooling2dWorkloadType, DataType>(factory, graph);
telsoa014fcda012018-03-09 14:13:49 +0000329
telsoa01c577f2c2018-08-31 09:22:23 +0100330 // Check that inputs/outputs are as we expect them (see definition of CreatePooling2dWorkloadTest).
telsoa014fcda012018-03-09 14:13:49 +0000331 Pooling2dQueueDescriptor queueDescriptor = workload->GetData();
332 auto inputHandle = boost::polymorphic_downcast<IClTensorHandle*>(queueDescriptor.m_Inputs[0]);
333 auto outputHandle = boost::polymorphic_downcast<IClTensorHandle*>(queueDescriptor.m_Outputs[0]);
334
335 BOOST_TEST(CompareIClTensorHandleShape(inputHandle, {3, 2, 5, 5}));
336 BOOST_TEST(CompareIClTensorHandleShape(outputHandle, {3, 2, 2, 4}));
337}
338
arovir019e53a352018-08-31 15:26:35 +0100339BOOST_AUTO_TEST_CASE(CreatePooling2dFloatWorkload)
telsoa01c577f2c2018-08-31 09:22:23 +0100340{
arovir019e53a352018-08-31 15:26:35 +0100341 ClPooling2dWorkloadTest<ClPooling2dFloatWorkload, armnn::DataType::Float32>();
telsoa01c577f2c2018-08-31 09:22:23 +0100342}
343
344BOOST_AUTO_TEST_CASE(CreatePooling2dFloat16Workload)
345{
arovir019e53a352018-08-31 15:26:35 +0100346 ClPooling2dWorkloadTest<ClPooling2dFloatWorkload, armnn::DataType::Float16>();
telsoa01c577f2c2018-08-31 09:22:23 +0100347}
348
349template <typename ReshapeWorkloadType, typename armnn::DataType DataType>
telsoa014fcda012018-03-09 14:13:49 +0000350static void ClCreateReshapeWorkloadTest()
351{
telsoa01c577f2c2018-08-31 09:22:23 +0100352 Graph graph;
telsoa014fcda012018-03-09 14:13:49 +0000353 ClWorkloadFactory factory;
telsoa014fcda012018-03-09 14:13:49 +0000354
telsoa01c577f2c2018-08-31 09:22:23 +0100355 auto workload = CreateReshapeWorkloadTest<ReshapeWorkloadType, DataType>(factory, graph);
telsoa014fcda012018-03-09 14:13:49 +0000356
telsoa01c577f2c2018-08-31 09:22:23 +0100357 // Checks that outputs and inputs are as we expect them (see definition of CreateReshapeWorkloadTest).
telsoa014fcda012018-03-09 14:13:49 +0000358 ReshapeQueueDescriptor queueDescriptor = workload->GetData();
telsoa01c577f2c2018-08-31 09:22:23 +0100359 auto inputHandle = boost::polymorphic_downcast<IClTensorHandle*>(queueDescriptor.m_Inputs[0]);
360 auto outputHandle = boost::polymorphic_downcast<IClTensorHandle*>(queueDescriptor.m_Outputs[0]);
telsoa014fcda012018-03-09 14:13:49 +0000361
362 BOOST_TEST(CompareIClTensorHandleShape(inputHandle, {4, 1}));
363 BOOST_TEST(CompareIClTensorHandleShape(outputHandle, {4})); // Leading size 1 dimensions are collapsed by ACL.
364}
365
arovir019e53a352018-08-31 15:26:35 +0100366BOOST_AUTO_TEST_CASE(CreateReshapeFloatWorkload)
telsoa014fcda012018-03-09 14:13:49 +0000367{
arovir019e53a352018-08-31 15:26:35 +0100368 ClCreateReshapeWorkloadTest<ClReshapeFloatWorkload, armnn::DataType::Float32>();
telsoa01c577f2c2018-08-31 09:22:23 +0100369}
370
371BOOST_AUTO_TEST_CASE(CreateReshapeFloat16Workload)
372{
arovir019e53a352018-08-31 15:26:35 +0100373 ClCreateReshapeWorkloadTest<ClReshapeFloatWorkload, armnn::DataType::Float16>();
telsoa014fcda012018-03-09 14:13:49 +0000374}
375
376BOOST_AUTO_TEST_CASE(CreateReshapeUint8Workload)
377{
telsoa01c577f2c2018-08-31 09:22:23 +0100378 ClCreateReshapeWorkloadTest<ClReshapeUint8Workload, armnn::DataType::QuantisedAsymm8>();
telsoa014fcda012018-03-09 14:13:49 +0000379}
380
telsoa01c577f2c2018-08-31 09:22:23 +0100381template <typename SoftmaxWorkloadType, typename armnn::DataType DataType>
382static void ClSoftmaxWorkloadTest()
telsoa014fcda012018-03-09 14:13:49 +0000383{
telsoa01c577f2c2018-08-31 09:22:23 +0100384 Graph graph;
telsoa014fcda012018-03-09 14:13:49 +0000385 ClWorkloadFactory factory;
telsoa014fcda012018-03-09 14:13:49 +0000386
telsoa01c577f2c2018-08-31 09:22:23 +0100387 auto workload = CreateSoftmaxWorkloadTest<SoftmaxWorkloadType, DataType>(factory, graph);
telsoa014fcda012018-03-09 14:13:49 +0000388
arovir019e53a352018-08-31 15:26:35 +0100389 // Checks that inputs/outputs are as we expect them (see definition of ClSoftmaxFloatWorkload).
telsoa014fcda012018-03-09 14:13:49 +0000390 SoftmaxQueueDescriptor queueDescriptor = workload->GetData();
telsoa01c577f2c2018-08-31 09:22:23 +0100391 auto inputHandle = boost::polymorphic_downcast<IClTensorHandle*>(queueDescriptor.m_Inputs[0]);
392 auto outputHandle = boost::polymorphic_downcast<IClTensorHandle*>(queueDescriptor.m_Outputs[0]);
telsoa014fcda012018-03-09 14:13:49 +0000393
394 BOOST_TEST(CompareIClTensorHandleShape(inputHandle, {4, 1}));
395 BOOST_TEST(CompareIClTensorHandleShape(outputHandle, {4, 1}));
396}
397
telsoa01c577f2c2018-08-31 09:22:23 +0100398
arovir019e53a352018-08-31 15:26:35 +0100399BOOST_AUTO_TEST_CASE(CreateSoftmaxFloatWorkloadTest)
telsoa01c577f2c2018-08-31 09:22:23 +0100400{
arovir019e53a352018-08-31 15:26:35 +0100401 ClSoftmaxWorkloadTest<ClSoftmaxFloatWorkload, armnn::DataType::Float32>();
telsoa01c577f2c2018-08-31 09:22:23 +0100402}
403
404BOOST_AUTO_TEST_CASE(CreateSoftmaxFloat16WorkloadTest)
405{
arovir019e53a352018-08-31 15:26:35 +0100406 ClSoftmaxWorkloadTest<ClSoftmaxFloatWorkload, armnn::DataType::Float16>();
telsoa01c577f2c2018-08-31 09:22:23 +0100407}
408
Matthew Bentham29cadb32018-10-01 17:22:32 +0100409template <typename armnn::DataType DataType>
telsoa01c577f2c2018-08-31 09:22:23 +0100410static void ClSplitterWorkloadTest()
telsoa014fcda012018-03-09 14:13:49 +0000411{
412 Graph graph;
413 ClWorkloadFactory factory;
telsoa014fcda012018-03-09 14:13:49 +0000414
Matthew Bentham29cadb32018-10-01 17:22:32 +0100415 auto workload = CreateSplitterWorkloadTest<ClSplitterWorkload, DataType>(factory, graph);
telsoa014fcda012018-03-09 14:13:49 +0000416
telsoa01c577f2c2018-08-31 09:22:23 +0100417 // Checks that outputs are as we expect them (see definition of CreateSplitterWorkloadTest).
telsoa014fcda012018-03-09 14:13:49 +0000418 SplitterQueueDescriptor queueDescriptor = workload->GetData();
419 auto inputHandle = boost::polymorphic_downcast<IClTensorHandle*>(queueDescriptor.m_Inputs[0]);
surmeh013537c2c2018-05-18 16:31:43 +0100420 BOOST_TEST(CompareIClTensorHandleShape(inputHandle, {5, 7, 7}));
421
telsoa014fcda012018-03-09 14:13:49 +0000422 auto outputHandle1 = boost::polymorphic_downcast<IClTensorHandle*>(queueDescriptor.m_Outputs[1]);
surmeh013537c2c2018-05-18 16:31:43 +0100423 BOOST_TEST(CompareIClTensorHandleShape(outputHandle1, {2, 7, 7}));
424
telsoa014fcda012018-03-09 14:13:49 +0000425 auto outputHandle2 = boost::polymorphic_downcast<IClTensorHandle*>(queueDescriptor.m_Outputs[2]);
surmeh013537c2c2018-05-18 16:31:43 +0100426 BOOST_TEST(CompareIClTensorHandleShape(outputHandle2, {2, 7, 7}));
427
428 auto outputHandle0 = boost::polymorphic_downcast<IClTensorHandle*>(queueDescriptor.m_Outputs[0]);
429 // NOTE: At the moment the CL collapses the tensor to a 2 dim when dimension zero = 1
telsoa01c577f2c2018-08-31 09:22:23 +0100430 // 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 +0100431 BOOST_TEST(CompareIClTensorHandleShape(outputHandle0, {7, 7}));
telsoa014fcda012018-03-09 14:13:49 +0000432}
433
arovir019e53a352018-08-31 15:26:35 +0100434BOOST_AUTO_TEST_CASE(CreateSplitterFloatWorkload)
telsoa014fcda012018-03-09 14:13:49 +0000435{
Matthew Bentham29cadb32018-10-01 17:22:32 +0100436 ClSplitterWorkloadTest<armnn::DataType::Float32>();
telsoa01c577f2c2018-08-31 09:22:23 +0100437}
438
439BOOST_AUTO_TEST_CASE(CreateSplitterFloat16Workload)
440{
Matthew Bentham29cadb32018-10-01 17:22:32 +0100441 ClSplitterWorkloadTest<armnn::DataType::Float16>();
telsoa01c577f2c2018-08-31 09:22:23 +0100442}
443
Matthew Bentham29cadb32018-10-01 17:22:32 +0100444template <typename MergerWorkloadType, typename armnn::DataType DataType>
telsoa01c577f2c2018-08-31 09:22:23 +0100445static void ClSplitterMergerTest()
446{
447 // Tests that it is possible to decide which output of the splitter layer
448 // should be lined to which input of the merger layer.
telsoa014fcda012018-03-09 14:13:49 +0000449 // We test that is is possible to specify 0th output
450 // of the splitter to be the 1st input to the merger and the 1st output of the splitter to be 0th input
451 // of the merger.
452
453 Graph graph;
454 ClWorkloadFactory factory;
telsoa014fcda012018-03-09 14:13:49 +0000455
456 auto workloads =
Matthew Bentham29cadb32018-10-01 17:22:32 +0100457 CreateSplitterMergerWorkloadTest<ClSplitterWorkload, MergerWorkloadType, DataType>
telsoa01c577f2c2018-08-31 09:22:23 +0100458 (factory, graph);
telsoa014fcda012018-03-09 14:13:49 +0000459
460 auto wlSplitter = std::move(workloads.first);
461 auto wlMerger = std::move(workloads.second);
462
telsoa01c577f2c2018-08-31 09:22:23 +0100463 //Checks that the index of inputs/outputs matches what we declared on InputDescriptor construction.
telsoa014fcda012018-03-09 14:13:49 +0000464 armnn::ClSubTensorHandle* sOut0 = dynamic_cast<armnn::ClSubTensorHandle*>(wlSplitter->GetData().m_Outputs[0]);
465 armnn::ClSubTensorHandle* sOut1 = dynamic_cast<armnn::ClSubTensorHandle*>(wlSplitter->GetData().m_Outputs[1]);
466 armnn::ClSubTensorHandle* mIn0 = dynamic_cast<armnn::ClSubTensorHandle*>(wlMerger->GetData().m_Inputs[0]);
467 armnn::ClSubTensorHandle* mIn1 = dynamic_cast<armnn::ClSubTensorHandle*>(wlMerger->GetData().m_Inputs[1]);
468
469 BOOST_TEST(sOut0);
470 BOOST_TEST(sOut1);
471 BOOST_TEST(mIn0);
472 BOOST_TEST(mIn1);
473
telsoa01c577f2c2018-08-31 09:22:23 +0100474 //Fliped order of inputs/outputs.
telsoa014fcda012018-03-09 14:13:49 +0000475 bool validDataPointers = (sOut0 == mIn1) && (sOut1 == mIn0);
476 BOOST_TEST(validDataPointers);
477
478
telsoa01c577f2c2018-08-31 09:22:23 +0100479 //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 +0000480 bool validSubTensorParents = (mIn0->GetTensor().parent() == mIn1->GetTensor().parent())
481 && (sOut0->GetTensor().parent() == sOut1->GetTensor().parent());
482
483 BOOST_TEST(validSubTensorParents);
484}
485
arovir019e53a352018-08-31 15:26:35 +0100486BOOST_AUTO_TEST_CASE(CreateSplitterMergerFloatWorkload)
telsoa01c577f2c2018-08-31 09:22:23 +0100487{
Matthew Bentham29cadb32018-10-01 17:22:32 +0100488 ClSplitterMergerTest<ClMergerFloatWorkload, armnn::DataType::Float32>();
telsoa01c577f2c2018-08-31 09:22:23 +0100489}
490
491BOOST_AUTO_TEST_CASE(CreateSplitterMergerFloat16Workload)
492{
Matthew Bentham29cadb32018-10-01 17:22:32 +0100493 ClSplitterMergerTest<ClMergerFloatWorkload, armnn::DataType::Float16>();
telsoa01c577f2c2018-08-31 09:22:23 +0100494}
495
496
telsoa014fcda012018-03-09 14:13:49 +0000497BOOST_AUTO_TEST_CASE(CreateSingleOutputMultipleInputs)
498{
499 // 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 +0100500 // 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 +0000501
502 Graph graph;
503 ClWorkloadFactory factory;
Matthew Bentham29cadb32018-10-01 17:22:32 +0100504 std::unique_ptr<ClSplitterWorkload> wlSplitter;
arovir019e53a352018-08-31 15:26:35 +0100505 std::unique_ptr<ClActivationFloatWorkload> wlActiv0_0;
506 std::unique_ptr<ClActivationFloatWorkload> wlActiv0_1;
507 std::unique_ptr<ClActivationFloatWorkload> wlActiv1_0;
508 std::unique_ptr<ClActivationFloatWorkload> wlActiv1_1;
telsoa014fcda012018-03-09 14:13:49 +0000509
Matthew Bentham29cadb32018-10-01 17:22:32 +0100510 CreateSplitterMultipleInputsOneOutputWorkloadTest<ClSplitterWorkload,
arovir019e53a352018-08-31 15:26:35 +0100511 ClActivationFloatWorkload, armnn::DataType::Float32>(factory, graph, wlSplitter, wlActiv0_0, wlActiv0_1,
telsoa01c577f2c2018-08-31 09:22:23 +0100512 wlActiv1_0, wlActiv1_1);
telsoa014fcda012018-03-09 14:13:49 +0000513
telsoa01c577f2c2018-08-31 09:22:23 +0100514 //Checks that the index of inputs/outputs matches what we declared on InputDescriptor construction.
telsoa014fcda012018-03-09 14:13:49 +0000515 armnn::ClSubTensorHandle* sOut0 = dynamic_cast<armnn::ClSubTensorHandle*>(wlSplitter->GetData().m_Outputs[0]);
516 armnn::ClSubTensorHandle* sOut1 = dynamic_cast<armnn::ClSubTensorHandle*>(wlSplitter->GetData().m_Outputs[1]);
517 armnn::ClSubTensorHandle* activ0_0Im = dynamic_cast<armnn::ClSubTensorHandle*>(wlActiv0_0->GetData().m_Inputs[0]);
518 armnn::ClSubTensorHandle* activ0_1Im = dynamic_cast<armnn::ClSubTensorHandle*>(wlActiv0_1->GetData().m_Inputs[0]);
519 armnn::ClSubTensorHandle* activ1_0Im = dynamic_cast<armnn::ClSubTensorHandle*>(wlActiv1_0->GetData().m_Inputs[0]);
520 armnn::ClSubTensorHandle* activ1_1Im = dynamic_cast<armnn::ClSubTensorHandle*>(wlActiv1_1->GetData().m_Inputs[0]);
521
522
523 BOOST_TEST(sOut0);
524 BOOST_TEST(sOut1);
525 BOOST_TEST(activ0_0Im);
526 BOOST_TEST(activ0_1Im);
527 BOOST_TEST(activ1_0Im);
528 BOOST_TEST(activ1_1Im);
529
530 bool validDataPointers = (sOut0 == activ0_0Im) && (sOut0 == activ0_1Im) &&
531 (sOut1 == activ1_0Im) && (sOut1 == activ1_1Im);
532
533 BOOST_TEST(validDataPointers);
534}
535
536BOOST_AUTO_TEST_CASE(CreateMemCopyWorkloadsCl)
537{
538 ClWorkloadFactory factory;
telsoa01c577f2c2018-08-31 09:22:23 +0100539 CreateMemCopyWorkloads<IClTensorHandle>(factory);
telsoa014fcda012018-03-09 14:13:49 +0000540}
541
Matteo Martincighbcd3c852018-09-28 14:14:12 +0100542template <typename L2NormalizationWorkloadType, typename armnn::DataType DataType>
543static void ClL2NormalizationWorkloadTest(DataLayout dataLayout)
telsoa014fcda012018-03-09 14:13:49 +0000544{
telsoa01c577f2c2018-08-31 09:22:23 +0100545 Graph graph;
telsoa014fcda012018-03-09 14:13:49 +0000546 ClWorkloadFactory factory;
telsoa014fcda012018-03-09 14:13:49 +0000547
Matteo Martincighbcd3c852018-09-28 14:14:12 +0100548 auto workload = CreateL2NormalizationWorkloadTest<L2NormalizationWorkloadType, DataType>
549 (factory, graph, dataLayout);
telsoa014fcda012018-03-09 14:13:49 +0000550
telsoa01c577f2c2018-08-31 09:22:23 +0100551 // Checks that inputs/outputs are as we expect them (see definition of CreateNormalizationWorkloadTest).
telsoa014fcda012018-03-09 14:13:49 +0000552 L2NormalizationQueueDescriptor queueDescriptor = workload->GetData();
553 auto inputHandle = boost::polymorphic_downcast<IClTensorHandle*>(queueDescriptor.m_Inputs[0]);
554 auto outputHandle = boost::polymorphic_downcast<IClTensorHandle*>(queueDescriptor.m_Outputs[0]);
555
556 BOOST_TEST(CompareIClTensorHandleShape(inputHandle, { 5, 20, 50, 67 }));
557 BOOST_TEST(CompareIClTensorHandleShape(outputHandle, { 5, 20, 50, 67 }));
558}
559
Matteo Martincighbcd3c852018-09-28 14:14:12 +0100560BOOST_AUTO_TEST_CASE(CreateL2NormalizationFloatNchwWorkload)
561{
562 ClL2NormalizationWorkloadTest<ClL2NormalizationFloatWorkload, armnn::DataType::Float32>(DataLayout::NCHW);
563}
564
565BOOST_AUTO_TEST_CASE(CreateL2NormalizationFloatNhwcWorkload)
566{
567 ClL2NormalizationWorkloadTest<ClL2NormalizationFloatWorkload, armnn::DataType::Float32>(DataLayout::NHWC);
568}
569
570BOOST_AUTO_TEST_CASE(CreateL2NormalizationFloat16NchwWorkload)
571{
572 ClL2NormalizationWorkloadTest<ClL2NormalizationFloatWorkload, armnn::DataType::Float16>(DataLayout::NCHW);
573}
574
575BOOST_AUTO_TEST_CASE(CreateL2NormalizationFloat16NhwcWorkload)
576{
577 ClL2NormalizationWorkloadTest<ClL2NormalizationFloatWorkload, armnn::DataType::Float16>(DataLayout::NHWC);
578}
579
telsoa01c577f2c2018-08-31 09:22:23 +0100580template <typename LstmWorkloadType>
581static void ClCreateLstmWorkloadTest()
582{
583 Graph graph;
584 ClWorkloadFactory factory;
585 auto workload = CreateLstmWorkloadTest<LstmWorkloadType>(factory, graph);
586
587 LstmQueueDescriptor queueDescriptor = workload->GetData();
588 auto inputHandle = boost::polymorphic_downcast<IClTensorHandle*>(queueDescriptor.m_Inputs[0]);
589 auto outputHandle = boost::polymorphic_downcast<IClTensorHandle*>(queueDescriptor.m_Outputs[1]);
590 BOOST_TEST(CompareIClTensorHandleShape(inputHandle, { 2, 2 }));
591 BOOST_TEST(CompareIClTensorHandleShape(outputHandle, { 2, 4 }));
592}
593
arovir019e53a352018-08-31 15:26:35 +0100594BOOST_AUTO_TEST_CASE(CreateLSTMWorkloadFloatWorkload)
telsoa01c577f2c2018-08-31 09:22:23 +0100595{
arovir019e53a352018-08-31 15:26:35 +0100596 ClCreateLstmWorkloadTest<ClLstmFloatWorkload>();
telsoa01c577f2c2018-08-31 09:22:23 +0100597}
598
James Conroy074f3712018-10-03 09:32:03 +0100599template <typename ResizeBilinearWorkloadType, typename armnn::DataType DataType>
600static void ClResizeBilinearWorkloadTest(DataLayout dataLayout)
601{
602 Graph graph;
603 ClWorkloadFactory factory;
604
605 auto workload = CreateResizeBilinearWorkloadTest<ResizeBilinearWorkloadType, DataType>(factory, graph, dataLayout);
606
607 // Checks that inputs/outputs are as we expect them (see definition of CreateResizeBilinearWorkloadTest).
608 ResizeBilinearQueueDescriptor queueDescriptor = workload->GetData();
609 auto inputHandle = boost::polymorphic_downcast<IClTensorHandle*>(queueDescriptor.m_Inputs[0]);
610 auto outputHandle = boost::polymorphic_downcast<IClTensorHandle*>(queueDescriptor.m_Outputs[0]);
611
612 switch (dataLayout)
613 {
614 case DataLayout::NHWC:
615 BOOST_TEST(CompareIClTensorHandleShape(inputHandle, { 2, 4, 4, 3 }));
616 BOOST_TEST(CompareIClTensorHandleShape(outputHandle, { 2, 2, 2, 3 }));
617 break;
618 default: // NCHW
619 BOOST_TEST(CompareIClTensorHandleShape(inputHandle, { 2, 3, 4, 4 }));
620 BOOST_TEST(CompareIClTensorHandleShape(outputHandle, { 2, 3, 2, 2 }));
621 }
622}
623
624BOOST_AUTO_TEST_CASE(CreateResizeBilinearFloat32NchwWorkload)
625{
626 ClResizeBilinearWorkloadTest<ClResizeBilinearFloatWorkload, armnn::DataType::Float32>(DataLayout::NCHW);
627}
628
629BOOST_AUTO_TEST_CASE(CreateResizeBilinearFloat16NchwWorkload)
630{
631 ClResizeBilinearWorkloadTest<ClResizeBilinearFloatWorkload, armnn::DataType::Float16>(DataLayout::NCHW);
632}
633
634BOOST_AUTO_TEST_CASE(CreateResizeBilinearFloat32NhwcWorkload)
635{
636 ClResizeBilinearWorkloadTest<ClResizeBilinearFloatWorkload, armnn::DataType::Float32>(DataLayout::NHWC);
637}
638
639BOOST_AUTO_TEST_CASE(CreateResizeBilinearFloat16NhwcWorkload)
640{
641 ClResizeBilinearWorkloadTest<ClResizeBilinearFloatWorkload, armnn::DataType::Float16>(DataLayout::NHWC);
642}
telsoa01c577f2c2018-08-31 09:22:23 +0100643
telsoa014fcda012018-03-09 14:13:49 +0000644BOOST_AUTO_TEST_SUITE_END()