blob: 63716453cd98a144629ec5809c513b255b8f9f85 [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//
5#pragma once
6
7#include <armnn/ArmNN.hpp>
8#include <armnn/Tensor.hpp>
9#include <armnn/TypesUtils.hpp>
telsoa014fcda012018-03-09 14:13:49 +000010
David Beckac42efd2018-09-26 17:41:13 +010011#include <test/TensorHelpers.hpp>
telsoa014fcda012018-03-09 14:13:49 +000012#include "QuantizeHelper.hpp"
13
David Beckac42efd2018-09-26 17:41:13 +010014#include <backends/CpuTensorHandle.hpp>
15#include <backends/WorkloadFactory.hpp>
telsoa014fcda012018-03-09 14:13:49 +000016#include "ActivationFixture.hpp"
17
18#include <algorithm>
19
20template<typename T>
21LayerTestResult<T, 4> BoundedReLuTestCommon(armnn::IWorkloadFactory& workloadFactory,
22 float upperBound, float lowerBound,
23 float inputScale, int32_t inputOffset, float outputScale, int32_t outputOffset,
24 const std::vector<T>& inputData, const std::vector<T>& outputExpectedData,
25 unsigned int inputWidth, unsigned int inputHeight,
26 unsigned int inputChannels, unsigned int inputBatchSize)
27{
28 unsigned int outputWidth = inputWidth;
29 unsigned int outputHeight = inputHeight;
30 unsigned int outputChannels = inputChannels;
31 unsigned int outputBatchSize = inputBatchSize;
32
33 armnn::TensorInfo inputTensorInfo({ inputBatchSize, inputChannels, inputHeight, inputWidth },
34 armnn::GetDataType<T>());
35
36 armnn::TensorInfo outputTensorInfo({ outputBatchSize, outputChannels, outputHeight, outputWidth },
37 armnn::GetDataType<T>());
38
39 if(armnn::IsQuantizedType<T>())
40 {
41 inputTensorInfo.SetQuantizationScale(inputScale);
42 inputTensorInfo.SetQuantizationOffset(inputOffset);
43
44 outputTensorInfo.SetQuantizationScale(outputScale);
45 outputTensorInfo.SetQuantizationOffset(outputOffset);
46 }
47
48 LayerTestResult<T, 4> result(inputTensorInfo);
49
50 auto input = MakeTensor<T, 4>(inputTensorInfo, inputData);
51
52 std::unique_ptr<armnn::ITensorHandle> inputHandle = workloadFactory.CreateTensorHandle(inputTensorInfo);
53 std::unique_ptr<armnn::ITensorHandle> outputHandle = workloadFactory.CreateTensorHandle(outputTensorInfo);
54
telsoa01c577f2c2018-08-31 09:22:23 +010055 // Setup bounded ReLu.
telsoa014fcda012018-03-09 14:13:49 +000056 armnn::ActivationQueueDescriptor descriptor;
57 armnn::WorkloadInfo workloadInfo;
58 AddInputToWorkload(descriptor, workloadInfo, inputTensorInfo, inputHandle.get());
59 AddOutputToWorkload(descriptor, workloadInfo, outputTensorInfo, outputHandle.get());
60
61 descriptor.m_Parameters.m_Function = armnn::ActivationFunction::BoundedReLu;
62 descriptor.m_Parameters.m_A = upperBound;
63 descriptor.m_Parameters.m_B = lowerBound;
64
65 std::unique_ptr<armnn::IWorkload> workload = workloadFactory.CreateActivation(descriptor, workloadInfo);
66
67 inputHandle->Allocate();
68 outputHandle->Allocate();
69
70 CopyDataToITensorHandle(inputHandle.get(), &input[0][0][0][0]);
71
72 workload->Execute();
73
74 CopyDataFromITensorHandle(&result.output[0][0][0][0], outputHandle.get());
75
76 result.outputExpected = MakeTensor<T, 4>(outputTensorInfo, outputExpectedData);
77
78 return result;
79}
80
81LayerTestResult<float, 4> BoundedReLuUpperAndLowerBoundTest(armnn::IWorkloadFactory& workloadFactory)
82{
83 unsigned int inputWidth = 4u;
84 unsigned int inputHeight = 5u;
85 unsigned int inputChannels = 1u;
86 unsigned int inputBatchSize = 1;
87
88 std::vector<float> input = std::vector<float>{
89 -2.0f, 0.1f, 0.5f, 1.25f,
90 0.786f, 0.9875f, -1.5f, 0.384f,
91 1.0001f, 3.5f, 7.5f, 0.896f,
92 2.126f, 2.0f, 0.3f, 0.15f,
93 0.999f, 1.2f, 0.89f, 6.1f,
94 };
95
telsoa01c577f2c2018-08-31 09:22:23 +010096 // Calculated manually.
telsoa014fcda012018-03-09 14:13:49 +000097 std::vector<float> output = std::vector<float>{
98 -1.0f, 0.1f, 0.5f, 1.0f,
99 0.786f, 0.9875f, -1.0f, 0.384f,
100 1.0f, 1.0f, 1.0f, 0.896f,
101 1.0f, 1.0f, 0.3f, 0.15f,
102 0.999f, 1.0f, 0.89f, 1.0f,
103 };
104
105 return BoundedReLuTestCommon(workloadFactory, 1.0f, -1.0f, 1.0f, 0, 1.0f, 0, input, output,
106 inputWidth, inputHeight, inputChannels, inputBatchSize);
107}
108
109LayerTestResult<float, 4> BoundedReLuUpperBoundOnlyTest(armnn::IWorkloadFactory& workloadFactory)
110{
111 unsigned int inputWidth = 4u;
112 unsigned int inputHeight = 5u;
113 unsigned int inputChannels = 1u;
114 unsigned int inputBatchSize = 1;
115
116 std::vector<float> input = std::vector<float>{
117 -1.0f, 0.1f, 0.5f, 6.25f,
118 0.786f, 5.9875f, -0.5f, 0.384f,
119 6.0001f, 3.5f, 7.5f, 0.896f,
120 2.126f, 12.0f, 0.3f, 0.15f,
121 0.999f, 1.2f, 0.89f, 6.1f,
122 };
123
David Beckac42efd2018-09-26 17:41:13 +0100124 // Calculated manually.
telsoa014fcda012018-03-09 14:13:49 +0000125 std::vector<float> output = std::vector<float>{
126 0.0f, 0.1f, 0.5f, 6.0f,
127 0.786f, 5.9875f, 0.0f, 0.384f,
128 6.0f, 3.5f, 6.0f, 0.896f,
129 2.126f, 6.0f, 0.3f, 0.15f,
130 0.999f, 1.2f, 0.89f, 6.0f,
131 };
132
133 return BoundedReLuTestCommon(workloadFactory, 6.0f, 0.0f, 1.0f, 0, 1.0f, 0, input, output,
134 inputWidth, inputHeight, inputChannels, inputBatchSize);
135}
136
137LayerTestResult<uint8_t, 4> BoundedReLuUint8UpperBoundOnlyTest(armnn::IWorkloadFactory& workloadFactory)
138{
139 unsigned int inputWidth = 3u;
140 unsigned int inputHeight = 2u;
141 unsigned int inputChannels = 1u;
142 unsigned int inputBatchSize = 1;
143
144 std::vector<uint8_t> input = std::vector<uint8_t>{
145 51, 124, 28,
146 251, 8, 92
147 };
148
David Beckac42efd2018-09-26 17:41:13 +0100149 // Calculated manually.
telsoa014fcda012018-03-09 14:13:49 +0000150 std::vector<uint8_t> output = std::vector<uint8_t>{
151 0, 122, 0,
152 255, 0, 58
153 };
154
155 float inputScale = 12.0f / 255.0f;
156 int32_t inputOffset = 63;
157 float outputScale = 6.0f / 255.0f;
158 int32_t outputOffset = 0;
159
160 return BoundedReLuTestCommon(workloadFactory, 6.0f, 0.0f,
161 inputScale, inputOffset, outputScale, outputOffset,
162 input, output,
163 inputWidth, inputHeight, inputChannels, inputBatchSize);
164}
165
166LayerTestResult<uint8_t, 4> BoundedReLuUint8UpperAndLowerBoundTest(armnn::IWorkloadFactory& workloadFactory)
167{
168 unsigned int inputWidth = 3u;
169 unsigned int inputHeight = 2u;
170 unsigned int inputChannels = 1u;
171 unsigned int inputBatchSize = 1;
172
173 std::vector<uint8_t> input = std::vector<uint8_t>{
174 51, 230, 28,
175 251, 8, 92
176 };
177
telsoa01c577f2c2018-08-31 09:22:23 +0100178 // Calculated manually.
telsoa014fcda012018-03-09 14:13:49 +0000179 std::vector<uint8_t> output = std::vector<uint8_t>{
180 51, 192, 32,
181 192, 32, 92
182 };
183
184 int32_t inputOffset = 112;
185 float inputScale = 0.0125f;
186
187 return BoundedReLuTestCommon(workloadFactory, 1.0f, -1.0f,
telsoa01c577f2c2018-08-31 09:22:23 +0100188 inputScale, inputOffset, inputScale, inputOffset, // Input/output scale & offset same.
telsoa014fcda012018-03-09 14:13:49 +0000189 input, output,
190 inputWidth, inputHeight, inputChannels, inputBatchSize);
191}
192
193namespace
194{
195
196struct BoundedReLuRandomInputTestTraits
197{
198 constexpr static unsigned int inputHeight = 31u;
199 constexpr static unsigned int inputWidth = 19u;
200 constexpr static unsigned int inputChannels = 4u;
201 constexpr static unsigned int inputBatchSize = 2;
202
203 constexpr static unsigned int outputHeight = inputHeight;
204 constexpr static unsigned int outputWidth = inputWidth;
205 constexpr static unsigned int outputChannels = inputChannels;
206 constexpr static unsigned int outputBatchSize = inputBatchSize;
207
208 static armnn::TensorInfo GetInputTensorInfo()
209 {
210 return armnn::TensorInfo({ inputBatchSize, inputChannels, inputHeight, inputWidth },
211 armnn::DataType::Float32);
212 }
213
214 static armnn::TensorInfo GetOutputTensorInfo()
215 {
216 return armnn::TensorInfo({ outputBatchSize, outputChannels, outputHeight, outputWidth },
217 armnn::DataType::Float32);
218 }
219};
220
221boost::multi_array<float, 4> BoundedReLuRandomInputTest(armnn::IWorkloadFactory& workloadFactory,
222 float lowerBound,
223 float upperBound,
224 const armnn::ActivationDescriptor& activationDescriptor)
225{
226 const armnn::TensorInfo inputTensorInfo = BoundedReLuRandomInputTestTraits::GetInputTensorInfo();
227 const armnn::TensorInfo outputTensorInfo = BoundedReLuRandomInputTestTraits::GetOutputTensorInfo();
228
229 boost::multi_array<float, 4> output(GetTensorShapeAsArray<4>(outputTensorInfo));
230
telsoa01c577f2c2018-08-31 09:22:23 +0100231 // Min/max random values passed to MakeRandomTensor are purposely outside of the ReLu
232 // range [lowerBound, upperBound].
telsoa014fcda012018-03-09 14:13:49 +0000233 auto input = MakeRandomTensor<float, 4>(inputTensorInfo, 4605828, lowerBound - 5.0f, upperBound * 2.0f);
234
235 std::unique_ptr<armnn::ITensorHandle> inputHandle = workloadFactory.CreateTensorHandle(inputTensorInfo);
236 std::unique_ptr<armnn::ITensorHandle> outputHandle = workloadFactory.CreateTensorHandle(outputTensorInfo);
237
telsoa01c577f2c2018-08-31 09:22:23 +0100238 // Set up bounded ReLu.
telsoa014fcda012018-03-09 14:13:49 +0000239 armnn::ActivationQueueDescriptor descriptor;
240 armnn::WorkloadInfo workloadInfo;
241 AddInputToWorkload(descriptor, workloadInfo, inputTensorInfo, inputHandle.get());
242 AddOutputToWorkload(descriptor, workloadInfo, outputTensorInfo, outputHandle.get());
243 descriptor.m_Parameters = activationDescriptor;
244
245 std::unique_ptr<armnn::IWorkload> workload = workloadFactory.CreateActivation(descriptor, workloadInfo);
246
247 inputHandle->Allocate();
248 outputHandle->Allocate();
249
250 CopyDataToITensorHandle(inputHandle.get(), &input[0][0][0][0]);
251
252 workload->Execute();
253
254 CopyDataFromITensorHandle(&output[0][0][0][0], outputHandle.get());
255
256 return output;
257}
258
259} // namespace
260
261LayerTestResult<float, 4> CompareBoundedReLuTest(armnn::IWorkloadFactory& workloadFactory,
262 armnn::IWorkloadFactory& otherWorkloadFactory,
263 float upperBound,
264 float lowerBound)
265{
266 LayerTestResult<float, 4> result(BoundedReLuRandomInputTestTraits::GetOutputTensorInfo());
267
268 armnn::ActivationDescriptor activationDescriptor;
269 activationDescriptor.m_Function = armnn::ActivationFunction::BoundedReLu;
270 activationDescriptor.m_A = upperBound;
271 activationDescriptor.m_B = lowerBound;
272
273 result.output = BoundedReLuRandomInputTest(workloadFactory, 0.0f, upperBound, activationDescriptor);
274 result.outputExpected = BoundedReLuRandomInputTest(otherWorkloadFactory, 0.0f, upperBound, activationDescriptor);
275
276 return result;
277}
278
279template<typename T>
280LayerTestResult<T,4> ConstantLinearActivationTestCommon(armnn::IWorkloadFactory& workloadFactory,
281 float qScale = 0.0f,
282 int32_t qOffset = 0)
283{
284 unsigned int inputHeight = 20;
285 unsigned int inputWidth = 17;
286 unsigned int inputChannels = 3;
287 unsigned int batchSize = 5;
288
289 armnn::TensorInfo inputTensorInfo;
290 armnn::TensorInfo outputTensorInfo;
291
292 unsigned int shape[] = {batchSize, inputChannels, inputHeight, inputWidth};
293
294 inputTensorInfo = armnn::TensorInfo(4, shape, armnn::GetDataType<T>());
295 outputTensorInfo = armnn::TensorInfo(4, shape, armnn::GetDataType<T>());
296
297 // Set quantization parameters if the requested type is a quantized type.
298 if(armnn::IsQuantizedType<T>())
299 {
300 inputTensorInfo.SetQuantizationScale(qScale);
301 inputTensorInfo.SetQuantizationOffset(qOffset);
302 outputTensorInfo.SetQuantizationScale(qScale);
303 outputTensorInfo.SetQuantizationOffset(qOffset);
304 }
305
306 LayerTestResult<T, 4> ret(outputTensorInfo);
307
308 std::unique_ptr<armnn::ITensorHandle> inputHandle = workloadFactory.CreateTensorHandle(inputTensorInfo);
309 std::unique_ptr<armnn::ITensorHandle> outputHandle = workloadFactory.CreateTensorHandle(outputTensorInfo);
310
telsoa01c577f2c2018-08-31 09:22:23 +0100311 // Do linear activation that should leave the tensor unchanged.
telsoa014fcda012018-03-09 14:13:49 +0000312 armnn::ActivationQueueDescriptor data;
313 armnn::WorkloadInfo info;
314 AddInputToWorkload(data, info, inputTensorInfo, inputHandle.get());
315 AddOutputToWorkload(data, info, outputTensorInfo, outputHandle.get());
316 data.m_Parameters.m_A = 1.0f;
317 data.m_Parameters.m_B = 0.0f;
318 data.m_Parameters.m_Function = armnn::ActivationFunction::Linear;
319
320 std::unique_ptr<armnn::IWorkload> workload = workloadFactory.CreateActivation(data, info);
321
322 inputHandle->Allocate();
323 outputHandle->Allocate();
324
325 boost::multi_array<T, 4> input = MakeRandomTensor<T, 4>(inputTensorInfo, 7123561);
326 CopyDataToITensorHandle(inputHandle.get(), &input[0][0][0][0]);
327
328 workload->Execute();
329
330 CopyDataFromITensorHandle(&ret.output[0][0][0][0], outputHandle.get());
331
telsoa01c577f2c2018-08-31 09:22:23 +0100332 // Ensure output equals input.
telsoa014fcda012018-03-09 14:13:49 +0000333 ret.outputExpected = input;
334
335 return ret;
336}
337
338LayerTestResult<float, 4> ConstantLinearActivationTest(armnn::IWorkloadFactory& workloadFactory)
339{
340 return ConstantLinearActivationTestCommon<float>(workloadFactory);
341}
342
343LayerTestResult<uint8_t, 4> ConstantLinearActivationUint8Test(armnn::IWorkloadFactory& workloadFactory)
344{
345 return ConstantLinearActivationTestCommon<uint8_t>(workloadFactory, 4.0f, 3);
346}
347
348template<typename T>
349LayerTestResult<T, 4> SimpleActivationTest(armnn::IWorkloadFactory& workloadFactory,
350 armnn::ActivationFunction activationFunction,
351 float activationParameterA,
352 float activationParameterB,
353 float qScale,
354 int32_t qOffset,
355 const std::vector<float>& inputData,
356 const std::vector<float>& outputExpectedData)
357{
358 constexpr static unsigned int inputWidth = 16u;
359 constexpr static unsigned int inputHeight = 1u;
360 constexpr static unsigned int inputChannels = 1u;
361 constexpr static unsigned int inputBatchSize = 1u;
362
363 constexpr static unsigned int outputWidth = inputWidth;
364 constexpr static unsigned int outputHeight = inputHeight;
365 constexpr static unsigned int outputChannels = inputChannels;
366 constexpr static unsigned int outputBatchSize = inputBatchSize;
367
368 armnn::TensorInfo inputTensorInfo({ inputBatchSize, inputChannels, inputHeight, inputWidth },
369 armnn::GetDataType<T>());
370 armnn::TensorInfo outputTensorInfo({ outputBatchSize, outputChannels, outputHeight, outputWidth },
371 armnn::GetDataType<T>());
372
373 // Set quantization parameters if the requested type is a quantized type.
374 if(armnn::IsQuantizedType<T>())
375 {
376 inputTensorInfo.SetQuantizationScale(qScale);
377 inputTensorInfo.SetQuantizationOffset(qOffset);
378 outputTensorInfo.SetQuantizationScale(qScale);
379 outputTensorInfo.SetQuantizationOffset(qOffset);
380 }
381
382 LayerTestResult<T, 4> result(inputTensorInfo);
383
384 auto input = MakeTensor<T, 4>(inputTensorInfo, QuantizedVector<T>(qScale, qOffset, inputData));
385
386 std::unique_ptr<armnn::ITensorHandle> inputHandle = workloadFactory.CreateTensorHandle(inputTensorInfo);
387 std::unique_ptr<armnn::ITensorHandle> outputHandle = workloadFactory.CreateTensorHandle(outputTensorInfo);
388
telsoa01c577f2c2018-08-31 09:22:23 +0100389 // Setup bounded ReLu.
telsoa014fcda012018-03-09 14:13:49 +0000390 armnn::ActivationQueueDescriptor descriptor;
391 armnn::WorkloadInfo workloadInfo;
392 AddInputToWorkload(descriptor, workloadInfo, inputTensorInfo, inputHandle.get());
393 AddOutputToWorkload(descriptor, workloadInfo, outputTensorInfo, outputHandle.get());
394
395 descriptor.m_Parameters.m_Function = activationFunction;
396 descriptor.m_Parameters.m_A = activationParameterA;
397 descriptor.m_Parameters.m_B = activationParameterB;
398
399 std::unique_ptr<armnn::IWorkload> workload = workloadFactory.CreateActivation(descriptor, workloadInfo);
400
401 inputHandle->Allocate();
402 outputHandle->Allocate();
403
404 CopyDataToITensorHandle(inputHandle.get(), &input[0][0][0][0]);
405
406 workload->Execute();
407
408 CopyDataFromITensorHandle(&result.output[0][0][0][0], outputHandle.get());
409
telsoa01c577f2c2018-08-31 09:22:23 +0100410 // Calculated manually.
telsoa014fcda012018-03-09 14:13:49 +0000411 result.outputExpected = MakeTensor<T, 4>(outputTensorInfo, QuantizedVector<T>(qScale, qOffset, outputExpectedData));
412
413 return result;
414}
415
416template<typename T>
417LayerTestResult<T, 4> SimpleSigmoidTestCommon(armnn::IWorkloadFactory& workloadFactory, float qScale, int32_t qOffset)
418{
419 std::vector<float> inputData = {
420 -0.1f, -0.2f, -0.3f, -0.4f,
421 0.1f, 0.2f, 0.3f, 0.4f,
422 -1.0f, -2.0f, -3.0f, -4.0f,
423 1.0f, 2.0f, 3.0f, 4.0f
424 };
425
telsoa01c577f2c2018-08-31 09:22:23 +0100426 // Calculate output values for input.
telsoa014fcda012018-03-09 14:13:49 +0000427 auto f = [](float value)
428 {
429 return 1.0f / (1.0f + std::exp(-value));
430 };
431 std::vector<float> outputExpectedData(inputData.size());
432 std::transform(inputData.begin(), inputData.end(), outputExpectedData.begin(), f);
433
434 return SimpleActivationTest<T>(workloadFactory,
435 armnn::ActivationFunction::Sigmoid,
436 0.f,
437 0.f,
438 qScale,
439 qOffset,
440 inputData,
441 outputExpectedData);
442}
443
444LayerTestResult<float, 4> SimpleSigmoidTest(armnn::IWorkloadFactory& workloadFactory)
445{
446 return SimpleSigmoidTestCommon<float>(workloadFactory, 0.0f, 0);
447}
448
449LayerTestResult<uint8_t, 4> SimpleSigmoidUint8Test(armnn::IWorkloadFactory& workloadFactory)
450{
451 return SimpleSigmoidTestCommon<uint8_t>(workloadFactory, 0.1f, 50);
452}
453
454template<typename T>
455LayerTestResult<T,4> CompareActivationTestImpl(armnn::IWorkloadFactory& workloadFactory,
456 armnn::IWorkloadFactory& refWorkloadFactory,
457 armnn::ActivationFunction f,
458 unsigned int batchSize = 5,
459 float qScale = 0.0f,
460 int32_t qOffset = 0)
461{
462 unsigned int width = 17;
463 unsigned int height = 29;
464 unsigned int channels = 2;
465
466 float a = 0.234f;
467 float b = -12.345f;
468
469 armnn::TensorInfo inputTensorInfo;
470 armnn::TensorInfo outputTensorInfo;
471
472 unsigned int shape[] = {batchSize, channels, height, width};
473
474 inputTensorInfo = armnn::TensorInfo(4, shape, armnn::GetDataType<T>());
475 outputTensorInfo = armnn::TensorInfo(4, shape, armnn::GetDataType<T>());
476
477 // Set quantization parameters if the requested type is a quantized type.
478 if(armnn::IsQuantizedType<T>())
479 {
480 inputTensorInfo.SetQuantizationScale(qScale);
481 inputTensorInfo.SetQuantizationOffset(qOffset);
482 outputTensorInfo.SetQuantizationScale(qScale);
483 outputTensorInfo.SetQuantizationOffset(qOffset);
484 }
485
486 float minVal = -10.f;
487 if (f == armnn::ActivationFunction::Sqrt)
488 {
489 minVal = 0.f;
490 }
491
492 boost::multi_array<T, 4> input = MakeRandomTensor<T, 4>(inputTensorInfo, 21453, minVal, 10.f);
493
494
495 LayerTestResult<T,4> ret(outputTensorInfo);
496 auto boostArrayExtents = boost::extents
497 [boost::numeric_cast<boost::multi_array_types::extent_gen::index>(batchSize)]
498 [boost::numeric_cast<boost::multi_array_types::extent_gen::index>(channels)]
499 [boost::numeric_cast<boost::multi_array_types::extent_gen::index>(height)]
500 [boost::numeric_cast<boost::multi_array_types::extent_gen::index>(width)];
501 ret.output.resize(boostArrayExtents);
502 ret.outputExpected.resize(boostArrayExtents);
503
504
505 std::unique_ptr<armnn::ITensorHandle> inputHandle = workloadFactory.CreateTensorHandle(inputTensorInfo);
506 std::unique_ptr<armnn::ITensorHandle> outputHandle = workloadFactory.CreateTensorHandle(outputTensorInfo);
507
508 std::unique_ptr<armnn::ITensorHandle> inputHandleRef = refWorkloadFactory.CreateTensorHandle(inputTensorInfo);
509 std::unique_ptr<armnn::ITensorHandle> outputHandleRef = refWorkloadFactory.CreateTensorHandle(outputTensorInfo);
510
511 armnn::ActivationQueueDescriptor data;
512 armnn::WorkloadInfo info;
513 AddInputToWorkload(data, info, inputTensorInfo, inputHandle.get());
514 AddOutputToWorkload(data, info, outputTensorInfo, outputHandle.get());
515 data.m_Parameters.m_A = a;
516 data.m_Parameters.m_B = b;
517 data.m_Parameters.m_Function = f;
518
519 armnn::ActivationQueueDescriptor refData = data;
520 armnn::WorkloadInfo refInfo = info;
521 SetWorkloadInput(refData, refInfo, 0, inputTensorInfo, inputHandleRef.get());
522 SetWorkloadOutput(refData, refInfo, 0, outputTensorInfo, outputHandleRef.get());
523
524 std::unique_ptr<armnn::IWorkload> workload = workloadFactory.CreateActivation(data, info);
525 BOOST_ASSERT(workload != nullptr);
526 std::unique_ptr<armnn::IWorkload> workloadRef = refWorkloadFactory.CreateActivation(refData, refInfo);
527 BOOST_ASSERT(workloadRef != nullptr);
528
529 inputHandle->Allocate();
530 outputHandle->Allocate();
531 inputHandleRef->Allocate();
532 outputHandleRef->Allocate();
533
534 CopyDataToITensorHandle(inputHandle.get(), &input[0][0][0][0]);
535 CopyDataToITensorHandle(inputHandleRef.get(), &input[0][0][0][0]);
536
537 workload->Execute();
538 workloadRef->Execute();
539
540 CopyDataFromITensorHandle(&ret.output[0][0][0][0], outputHandle.get());
541 CopyDataFromITensorHandle(&ret.outputExpected[0][0][0][0], outputHandleRef.get());
542
543 return ret;
544}
545
546LayerTestResult<float,4> CompareActivationTest(armnn::IWorkloadFactory& workloadFactory,
547 armnn::IWorkloadFactory& refWorkloadFactory,
548 armnn::ActivationFunction f,
549 unsigned int batchSize)
550{
551 return CompareActivationTestImpl<float>(workloadFactory, refWorkloadFactory, f, batchSize);
552}
553
554LayerTestResult<uint8_t,4> CompareActivationUint8Test(armnn::IWorkloadFactory& workloadFactory,
555 armnn::IWorkloadFactory& refWorkloadFactory,
556 armnn::ActivationFunction f)
557{
558 return CompareActivationTestImpl<uint8_t>(workloadFactory, refWorkloadFactory, f, 5, 0.1f, 50);
559}