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