blob: 46c700ce026cbc0e849da283c9ed30a98b63772b [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>
Aron Virginas-Tar5caf9072018-11-14 18:35:18 +000015#include <backendsCommon/IBackendInternal.hpp>
Aron Virginas-Tarc9cc8042018-11-01 16:15:57 +000016#include <backendsCommon/WorkloadFactory.hpp>
telsoa014fcda012018-03-09 14:13:49 +000017
Aron Virginas-Tarc9cc8042018-11-01 16:15:57 +000018#include <test/TensorHelpers.hpp>
telsoa014fcda012018-03-09 14:13:49 +000019
20#include <algorithm>
21
22template<typename T>
Aron Virginas-Tar5caf9072018-11-14 18:35:18 +000023LayerTestResult<T, 4> BoundedReLuTestCommon(
24 armnn::IWorkloadFactory& workloadFactory,
25 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
26 float upperBound,
27 float lowerBound,
28 float inputScale,
29 int32_t inputOffset,
30 float outputScale,
31 int32_t outputOffset,
32 const std::vector<T>& inputData,
33 const std::vector<T>& outputExpectedData,
34 unsigned int inputWidth,
35 unsigned int inputHeight,
36 unsigned int inputChannels,
37 unsigned int inputBatchSize)
telsoa014fcda012018-03-09 14:13:49 +000038{
39 unsigned int outputWidth = inputWidth;
40 unsigned int outputHeight = inputHeight;
41 unsigned int outputChannels = inputChannels;
42 unsigned int outputBatchSize = inputBatchSize;
43
44 armnn::TensorInfo inputTensorInfo({ inputBatchSize, inputChannels, inputHeight, inputWidth },
45 armnn::GetDataType<T>());
46
47 armnn::TensorInfo outputTensorInfo({ outputBatchSize, outputChannels, outputHeight, outputWidth },
48 armnn::GetDataType<T>());
49
50 if(armnn::IsQuantizedType<T>())
51 {
52 inputTensorInfo.SetQuantizationScale(inputScale);
53 inputTensorInfo.SetQuantizationOffset(inputOffset);
54
55 outputTensorInfo.SetQuantizationScale(outputScale);
56 outputTensorInfo.SetQuantizationOffset(outputOffset);
57 }
58
59 LayerTestResult<T, 4> result(inputTensorInfo);
60
61 auto input = MakeTensor<T, 4>(inputTensorInfo, inputData);
62
63 std::unique_ptr<armnn::ITensorHandle> inputHandle = workloadFactory.CreateTensorHandle(inputTensorInfo);
64 std::unique_ptr<armnn::ITensorHandle> outputHandle = workloadFactory.CreateTensorHandle(outputTensorInfo);
65
telsoa01c577f2c2018-08-31 09:22:23 +010066 // Setup bounded ReLu.
telsoa014fcda012018-03-09 14:13:49 +000067 armnn::ActivationQueueDescriptor descriptor;
68 armnn::WorkloadInfo workloadInfo;
69 AddInputToWorkload(descriptor, workloadInfo, inputTensorInfo, inputHandle.get());
70 AddOutputToWorkload(descriptor, workloadInfo, outputTensorInfo, outputHandle.get());
71
72 descriptor.m_Parameters.m_Function = armnn::ActivationFunction::BoundedReLu;
73 descriptor.m_Parameters.m_A = upperBound;
74 descriptor.m_Parameters.m_B = lowerBound;
75
76 std::unique_ptr<armnn::IWorkload> workload = workloadFactory.CreateActivation(descriptor, workloadInfo);
77
78 inputHandle->Allocate();
79 outputHandle->Allocate();
80
81 CopyDataToITensorHandle(inputHandle.get(), &input[0][0][0][0]);
82
83 workload->Execute();
84
85 CopyDataFromITensorHandle(&result.output[0][0][0][0], outputHandle.get());
86
87 result.outputExpected = MakeTensor<T, 4>(outputTensorInfo, outputExpectedData);
88
89 return result;
90}
91
Aron Virginas-Tar5caf9072018-11-14 18:35:18 +000092LayerTestResult<float, 4> BoundedReLuUpperAndLowerBoundTest(
93 armnn::IWorkloadFactory& workloadFactory,
94 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager)
telsoa014fcda012018-03-09 14:13:49 +000095{
96 unsigned int inputWidth = 4u;
97 unsigned int inputHeight = 5u;
98 unsigned int inputChannels = 1u;
99 unsigned int inputBatchSize = 1;
100
101 std::vector<float> input = std::vector<float>{
102 -2.0f, 0.1f, 0.5f, 1.25f,
103 0.786f, 0.9875f, -1.5f, 0.384f,
104 1.0001f, 3.5f, 7.5f, 0.896f,
105 2.126f, 2.0f, 0.3f, 0.15f,
106 0.999f, 1.2f, 0.89f, 6.1f,
107 };
108
telsoa01c577f2c2018-08-31 09:22:23 +0100109 // Calculated manually.
telsoa014fcda012018-03-09 14:13:49 +0000110 std::vector<float> output = std::vector<float>{
111 -1.0f, 0.1f, 0.5f, 1.0f,
112 0.786f, 0.9875f, -1.0f, 0.384f,
113 1.0f, 1.0f, 1.0f, 0.896f,
114 1.0f, 1.0f, 0.3f, 0.15f,
115 0.999f, 1.0f, 0.89f, 1.0f,
116 };
117
Aron Virginas-Tar5caf9072018-11-14 18:35:18 +0000118 return BoundedReLuTestCommon(
119 workloadFactory, memoryManager, 1.0f, -1.0f, 1.0f, 0, 1.0f, 0, input, output,
120 inputWidth, inputHeight, inputChannels, inputBatchSize);
telsoa014fcda012018-03-09 14:13:49 +0000121}
122
Aron Virginas-Tar5caf9072018-11-14 18:35:18 +0000123LayerTestResult<float, 4> BoundedReLuUpperBoundOnlyTest(
124 armnn::IWorkloadFactory& workloadFactory,
125 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager)
telsoa014fcda012018-03-09 14:13:49 +0000126{
127 unsigned int inputWidth = 4u;
128 unsigned int inputHeight = 5u;
129 unsigned int inputChannels = 1u;
130 unsigned int inputBatchSize = 1;
131
132 std::vector<float> input = std::vector<float>{
133 -1.0f, 0.1f, 0.5f, 6.25f,
134 0.786f, 5.9875f, -0.5f, 0.384f,
135 6.0001f, 3.5f, 7.5f, 0.896f,
136 2.126f, 12.0f, 0.3f, 0.15f,
137 0.999f, 1.2f, 0.89f, 6.1f,
138 };
139
David Beckac42efd2018-09-26 17:41:13 +0100140 // Calculated manually.
telsoa014fcda012018-03-09 14:13:49 +0000141 std::vector<float> output = std::vector<float>{
142 0.0f, 0.1f, 0.5f, 6.0f,
143 0.786f, 5.9875f, 0.0f, 0.384f,
144 6.0f, 3.5f, 6.0f, 0.896f,
145 2.126f, 6.0f, 0.3f, 0.15f,
146 0.999f, 1.2f, 0.89f, 6.0f,
147 };
148
Aron Virginas-Tar5caf9072018-11-14 18:35:18 +0000149 return BoundedReLuTestCommon(
150 workloadFactory, memoryManager, 6.0f, 0.0f, 1.0f, 0, 1.0f, 0, input, output,
151 inputWidth, inputHeight, inputChannels, inputBatchSize);
telsoa014fcda012018-03-09 14:13:49 +0000152}
153
Aron Virginas-Tar5caf9072018-11-14 18:35:18 +0000154LayerTestResult<uint8_t, 4> BoundedReLuUint8UpperBoundOnlyTest(
155 armnn::IWorkloadFactory& workloadFactory,
156 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager)
telsoa014fcda012018-03-09 14:13:49 +0000157{
158 unsigned int inputWidth = 3u;
159 unsigned int inputHeight = 2u;
160 unsigned int inputChannels = 1u;
161 unsigned int inputBatchSize = 1;
162
163 std::vector<uint8_t> input = std::vector<uint8_t>{
164 51, 124, 28,
165 251, 8, 92
166 };
167
David Beckac42efd2018-09-26 17:41:13 +0100168 // Calculated manually.
telsoa014fcda012018-03-09 14:13:49 +0000169 std::vector<uint8_t> output = std::vector<uint8_t>{
170 0, 122, 0,
171 255, 0, 58
172 };
173
174 float inputScale = 12.0f / 255.0f;
175 int32_t inputOffset = 63;
176 float outputScale = 6.0f / 255.0f;
177 int32_t outputOffset = 0;
178
Aron Virginas-Tar5caf9072018-11-14 18:35:18 +0000179 return BoundedReLuTestCommon(workloadFactory, memoryManager, 6.0f, 0.0f,
telsoa014fcda012018-03-09 14:13:49 +0000180 inputScale, inputOffset, outputScale, outputOffset,
181 input, output,
182 inputWidth, inputHeight, inputChannels, inputBatchSize);
183}
184
Aron Virginas-Tar5caf9072018-11-14 18:35:18 +0000185LayerTestResult<uint8_t, 4> BoundedReLuUint8UpperAndLowerBoundTest(
186 armnn::IWorkloadFactory& workloadFactory,
187 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager)
telsoa014fcda012018-03-09 14:13:49 +0000188{
189 unsigned int inputWidth = 3u;
190 unsigned int inputHeight = 2u;
191 unsigned int inputChannels = 1u;
192 unsigned int inputBatchSize = 1;
193
194 std::vector<uint8_t> input = std::vector<uint8_t>{
195 51, 230, 28,
196 251, 8, 92
197 };
198
telsoa01c577f2c2018-08-31 09:22:23 +0100199 // Calculated manually.
telsoa014fcda012018-03-09 14:13:49 +0000200 std::vector<uint8_t> output = std::vector<uint8_t>{
201 51, 192, 32,
202 192, 32, 92
203 };
204
205 int32_t inputOffset = 112;
206 float inputScale = 0.0125f;
207
Aron Virginas-Tar5caf9072018-11-14 18:35:18 +0000208 return BoundedReLuTestCommon(workloadFactory, memoryManager, 1.0f, -1.0f,
telsoa01c577f2c2018-08-31 09:22:23 +0100209 inputScale, inputOffset, inputScale, inputOffset, // Input/output scale & offset same.
telsoa014fcda012018-03-09 14:13:49 +0000210 input, output,
211 inputWidth, inputHeight, inputChannels, inputBatchSize);
212}
213
214namespace
215{
216
217struct BoundedReLuRandomInputTestTraits
218{
219 constexpr static unsigned int inputHeight = 31u;
220 constexpr static unsigned int inputWidth = 19u;
221 constexpr static unsigned int inputChannels = 4u;
222 constexpr static unsigned int inputBatchSize = 2;
223
224 constexpr static unsigned int outputHeight = inputHeight;
225 constexpr static unsigned int outputWidth = inputWidth;
226 constexpr static unsigned int outputChannels = inputChannels;
227 constexpr static unsigned int outputBatchSize = inputBatchSize;
228
229 static armnn::TensorInfo GetInputTensorInfo()
230 {
231 return armnn::TensorInfo({ inputBatchSize, inputChannels, inputHeight, inputWidth },
232 armnn::DataType::Float32);
233 }
234
235 static armnn::TensorInfo GetOutputTensorInfo()
236 {
237 return armnn::TensorInfo({ outputBatchSize, outputChannels, outputHeight, outputWidth },
238 armnn::DataType::Float32);
239 }
240};
241
Aron Virginas-Tar5caf9072018-11-14 18:35:18 +0000242boost::multi_array<float, 4> BoundedReLuRandomInputTest(
243 armnn::IWorkloadFactory& workloadFactory,
244 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
245 float lowerBound,
246 float upperBound,
247 const armnn::ActivationDescriptor& activationDescriptor)
telsoa014fcda012018-03-09 14:13:49 +0000248{
249 const armnn::TensorInfo inputTensorInfo = BoundedReLuRandomInputTestTraits::GetInputTensorInfo();
250 const armnn::TensorInfo outputTensorInfo = BoundedReLuRandomInputTestTraits::GetOutputTensorInfo();
251
252 boost::multi_array<float, 4> output(GetTensorShapeAsArray<4>(outputTensorInfo));
253
telsoa01c577f2c2018-08-31 09:22:23 +0100254 // Min/max random values passed to MakeRandomTensor are purposely outside of the ReLu
255 // range [lowerBound, upperBound].
telsoa014fcda012018-03-09 14:13:49 +0000256 auto input = MakeRandomTensor<float, 4>(inputTensorInfo, 4605828, lowerBound - 5.0f, upperBound * 2.0f);
257
258 std::unique_ptr<armnn::ITensorHandle> inputHandle = workloadFactory.CreateTensorHandle(inputTensorInfo);
259 std::unique_ptr<armnn::ITensorHandle> outputHandle = workloadFactory.CreateTensorHandle(outputTensorInfo);
260
telsoa01c577f2c2018-08-31 09:22:23 +0100261 // Set up bounded ReLu.
telsoa014fcda012018-03-09 14:13:49 +0000262 armnn::ActivationQueueDescriptor descriptor;
263 armnn::WorkloadInfo workloadInfo;
264 AddInputToWorkload(descriptor, workloadInfo, inputTensorInfo, inputHandle.get());
265 AddOutputToWorkload(descriptor, workloadInfo, outputTensorInfo, outputHandle.get());
266 descriptor.m_Parameters = activationDescriptor;
267
268 std::unique_ptr<armnn::IWorkload> workload = workloadFactory.CreateActivation(descriptor, workloadInfo);
269
270 inputHandle->Allocate();
271 outputHandle->Allocate();
272
273 CopyDataToITensorHandle(inputHandle.get(), &input[0][0][0][0]);
274
275 workload->Execute();
276
277 CopyDataFromITensorHandle(&output[0][0][0][0], outputHandle.get());
278
279 return output;
280}
281
282} // namespace
283
Aron Virginas-Tar5caf9072018-11-14 18:35:18 +0000284LayerTestResult<float, 4> CompareBoundedReLuTest(
285 armnn::IWorkloadFactory& workloadFactory,
286 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
287 armnn::IWorkloadFactory& refWorkloadFactory,
288 float upperBound,
289 float lowerBound)
telsoa014fcda012018-03-09 14:13:49 +0000290{
291 LayerTestResult<float, 4> result(BoundedReLuRandomInputTestTraits::GetOutputTensorInfo());
292
293 armnn::ActivationDescriptor activationDescriptor;
294 activationDescriptor.m_Function = armnn::ActivationFunction::BoundedReLu;
295 activationDescriptor.m_A = upperBound;
296 activationDescriptor.m_B = lowerBound;
297
Aron Virginas-Tar5caf9072018-11-14 18:35:18 +0000298 result.output = BoundedReLuRandomInputTest(
299 workloadFactory, memoryManager, 0.0f, upperBound, activationDescriptor);
300 result.outputExpected = BoundedReLuRandomInputTest(
301 refWorkloadFactory, nullptr, 0.0f, upperBound, activationDescriptor);
telsoa014fcda012018-03-09 14:13:49 +0000302
303 return result;
304}
305
306template<typename T>
Aron Virginas-Tar5caf9072018-11-14 18:35:18 +0000307LayerTestResult<T,4> ConstantLinearActivationTestCommon(
308 armnn::IWorkloadFactory& workloadFactory,
309 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
310 float qScale = 0.0f,
311 int32_t qOffset = 0)
telsoa014fcda012018-03-09 14:13:49 +0000312{
313 unsigned int inputHeight = 20;
314 unsigned int inputWidth = 17;
315 unsigned int inputChannels = 3;
316 unsigned int batchSize = 5;
317
318 armnn::TensorInfo inputTensorInfo;
319 armnn::TensorInfo outputTensorInfo;
320
321 unsigned int shape[] = {batchSize, inputChannels, inputHeight, inputWidth};
322
323 inputTensorInfo = armnn::TensorInfo(4, shape, armnn::GetDataType<T>());
324 outputTensorInfo = armnn::TensorInfo(4, shape, armnn::GetDataType<T>());
325
326 // Set quantization parameters if the requested type is a quantized type.
327 if(armnn::IsQuantizedType<T>())
328 {
329 inputTensorInfo.SetQuantizationScale(qScale);
330 inputTensorInfo.SetQuantizationOffset(qOffset);
331 outputTensorInfo.SetQuantizationScale(qScale);
332 outputTensorInfo.SetQuantizationOffset(qOffset);
333 }
334
335 LayerTestResult<T, 4> ret(outputTensorInfo);
336
337 std::unique_ptr<armnn::ITensorHandle> inputHandle = workloadFactory.CreateTensorHandle(inputTensorInfo);
338 std::unique_ptr<armnn::ITensorHandle> outputHandle = workloadFactory.CreateTensorHandle(outputTensorInfo);
339
telsoa01c577f2c2018-08-31 09:22:23 +0100340 // Do linear activation that should leave the tensor unchanged.
telsoa014fcda012018-03-09 14:13:49 +0000341 armnn::ActivationQueueDescriptor data;
342 armnn::WorkloadInfo info;
343 AddInputToWorkload(data, info, inputTensorInfo, inputHandle.get());
344 AddOutputToWorkload(data, info, outputTensorInfo, outputHandle.get());
345 data.m_Parameters.m_A = 1.0f;
346 data.m_Parameters.m_B = 0.0f;
347 data.m_Parameters.m_Function = armnn::ActivationFunction::Linear;
348
349 std::unique_ptr<armnn::IWorkload> workload = workloadFactory.CreateActivation(data, info);
350
351 inputHandle->Allocate();
352 outputHandle->Allocate();
353
354 boost::multi_array<T, 4> input = MakeRandomTensor<T, 4>(inputTensorInfo, 7123561);
355 CopyDataToITensorHandle(inputHandle.get(), &input[0][0][0][0]);
356
357 workload->Execute();
358
359 CopyDataFromITensorHandle(&ret.output[0][0][0][0], outputHandle.get());
360
telsoa01c577f2c2018-08-31 09:22:23 +0100361 // Ensure output equals input.
telsoa014fcda012018-03-09 14:13:49 +0000362 ret.outputExpected = input;
363
364 return ret;
365}
366
Aron Virginas-Tar5caf9072018-11-14 18:35:18 +0000367LayerTestResult<float, 4> ConstantLinearActivationTest(
368 armnn::IWorkloadFactory& workloadFactory,
369 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager)
telsoa014fcda012018-03-09 14:13:49 +0000370{
Aron Virginas-Tar5caf9072018-11-14 18:35:18 +0000371 return ConstantLinearActivationTestCommon<float>(workloadFactory, memoryManager);
telsoa014fcda012018-03-09 14:13:49 +0000372}
373
Aron Virginas-Tar5caf9072018-11-14 18:35:18 +0000374LayerTestResult<uint8_t, 4> ConstantLinearActivationUint8Test(
375 armnn::IWorkloadFactory& workloadFactory,
376 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager)
telsoa014fcda012018-03-09 14:13:49 +0000377{
Aron Virginas-Tar5caf9072018-11-14 18:35:18 +0000378 return ConstantLinearActivationTestCommon<uint8_t>(workloadFactory, memoryManager, 4.0f, 3);
telsoa014fcda012018-03-09 14:13:49 +0000379}
380
381template<typename T>
Aron Virginas-Tar5caf9072018-11-14 18:35:18 +0000382LayerTestResult<T, 4> SimpleActivationTest(
383 armnn::IWorkloadFactory& workloadFactory,
384 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
385 armnn::ActivationFunction activationFunction,
386 float activationParameterA,
387 float activationParameterB,
388 float qScale,
389 int32_t qOffset,
390 const std::vector<float>& inputData,
391 const std::vector<float>& outputExpectedData)
telsoa014fcda012018-03-09 14:13:49 +0000392{
393 constexpr static unsigned int inputWidth = 16u;
394 constexpr static unsigned int inputHeight = 1u;
395 constexpr static unsigned int inputChannels = 1u;
396 constexpr static unsigned int inputBatchSize = 1u;
397
398 constexpr static unsigned int outputWidth = inputWidth;
399 constexpr static unsigned int outputHeight = inputHeight;
400 constexpr static unsigned int outputChannels = inputChannels;
401 constexpr static unsigned int outputBatchSize = inputBatchSize;
402
403 armnn::TensorInfo inputTensorInfo({ inputBatchSize, inputChannels, inputHeight, inputWidth },
404 armnn::GetDataType<T>());
405 armnn::TensorInfo outputTensorInfo({ outputBatchSize, outputChannels, outputHeight, outputWidth },
406 armnn::GetDataType<T>());
407
408 // Set quantization parameters if the requested type is a quantized type.
409 if(armnn::IsQuantizedType<T>())
410 {
411 inputTensorInfo.SetQuantizationScale(qScale);
412 inputTensorInfo.SetQuantizationOffset(qOffset);
413 outputTensorInfo.SetQuantizationScale(qScale);
414 outputTensorInfo.SetQuantizationOffset(qOffset);
415 }
416
417 LayerTestResult<T, 4> result(inputTensorInfo);
418
419 auto input = MakeTensor<T, 4>(inputTensorInfo, QuantizedVector<T>(qScale, qOffset, inputData));
420
421 std::unique_ptr<armnn::ITensorHandle> inputHandle = workloadFactory.CreateTensorHandle(inputTensorInfo);
422 std::unique_ptr<armnn::ITensorHandle> outputHandle = workloadFactory.CreateTensorHandle(outputTensorInfo);
423
telsoa01c577f2c2018-08-31 09:22:23 +0100424 // Setup bounded ReLu.
telsoa014fcda012018-03-09 14:13:49 +0000425 armnn::ActivationQueueDescriptor descriptor;
426 armnn::WorkloadInfo workloadInfo;
427 AddInputToWorkload(descriptor, workloadInfo, inputTensorInfo, inputHandle.get());
428 AddOutputToWorkload(descriptor, workloadInfo, outputTensorInfo, outputHandle.get());
429
430 descriptor.m_Parameters.m_Function = activationFunction;
431 descriptor.m_Parameters.m_A = activationParameterA;
432 descriptor.m_Parameters.m_B = activationParameterB;
433
434 std::unique_ptr<armnn::IWorkload> workload = workloadFactory.CreateActivation(descriptor, workloadInfo);
435
436 inputHandle->Allocate();
437 outputHandle->Allocate();
438
439 CopyDataToITensorHandle(inputHandle.get(), &input[0][0][0][0]);
440
441 workload->Execute();
442
443 CopyDataFromITensorHandle(&result.output[0][0][0][0], outputHandle.get());
444
telsoa01c577f2c2018-08-31 09:22:23 +0100445 // Calculated manually.
telsoa014fcda012018-03-09 14:13:49 +0000446 result.outputExpected = MakeTensor<T, 4>(outputTensorInfo, QuantizedVector<T>(qScale, qOffset, outputExpectedData));
447
448 return result;
449}
450
451template<typename T>
Aron Virginas-Tar5caf9072018-11-14 18:35:18 +0000452LayerTestResult<T, 4> SimpleSigmoidTestCommon(
453 armnn::IWorkloadFactory& workloadFactory,
454 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
455 float qScale,
456 int32_t qOffset)
telsoa014fcda012018-03-09 14:13:49 +0000457{
458 std::vector<float> inputData = {
459 -0.1f, -0.2f, -0.3f, -0.4f,
460 0.1f, 0.2f, 0.3f, 0.4f,
461 -1.0f, -2.0f, -3.0f, -4.0f,
462 1.0f, 2.0f, 3.0f, 4.0f
463 };
464
telsoa01c577f2c2018-08-31 09:22:23 +0100465 // Calculate output values for input.
telsoa014fcda012018-03-09 14:13:49 +0000466 auto f = [](float value)
467 {
468 return 1.0f / (1.0f + std::exp(-value));
469 };
470 std::vector<float> outputExpectedData(inputData.size());
471 std::transform(inputData.begin(), inputData.end(), outputExpectedData.begin(), f);
472
473 return SimpleActivationTest<T>(workloadFactory,
Aron Virginas-Tar5caf9072018-11-14 18:35:18 +0000474 memoryManager,
telsoa014fcda012018-03-09 14:13:49 +0000475 armnn::ActivationFunction::Sigmoid,
476 0.f,
477 0.f,
478 qScale,
479 qOffset,
480 inputData,
481 outputExpectedData);
482}
483
Aron Virginas-Tar5caf9072018-11-14 18:35:18 +0000484LayerTestResult<float, 4> SimpleSigmoidTest(
485 armnn::IWorkloadFactory& workloadFactory,
486 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager)
telsoa014fcda012018-03-09 14:13:49 +0000487{
Aron Virginas-Tar5caf9072018-11-14 18:35:18 +0000488 return SimpleSigmoidTestCommon<float>(workloadFactory, memoryManager, 0.0f, 0);
telsoa014fcda012018-03-09 14:13:49 +0000489}
490
Aron Virginas-Tar5caf9072018-11-14 18:35:18 +0000491LayerTestResult<uint8_t, 4> SimpleSigmoidUint8Test(
492 armnn::IWorkloadFactory& workloadFactory,
493 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager)
telsoa014fcda012018-03-09 14:13:49 +0000494{
Aron Virginas-Tar5caf9072018-11-14 18:35:18 +0000495 return SimpleSigmoidTestCommon<uint8_t>(workloadFactory, memoryManager, 0.1f, 50);
telsoa014fcda012018-03-09 14:13:49 +0000496}
497
498template<typename T>
Aron Virginas-Tar5caf9072018-11-14 18:35:18 +0000499LayerTestResult<T,4> CompareActivationTestImpl(
500 armnn::IWorkloadFactory& workloadFactory,
501 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
502 armnn::IWorkloadFactory& refWorkloadFactory,
503 armnn::ActivationFunction f,
504 unsigned int batchSize = 5,
505 float qScale = 0.0f,
506 int32_t qOffset = 0)
telsoa014fcda012018-03-09 14:13:49 +0000507{
508 unsigned int width = 17;
509 unsigned int height = 29;
510 unsigned int channels = 2;
511
512 float a = 0.234f;
513 float b = -12.345f;
514
515 armnn::TensorInfo inputTensorInfo;
516 armnn::TensorInfo outputTensorInfo;
517
518 unsigned int shape[] = {batchSize, channels, height, width};
519
520 inputTensorInfo = armnn::TensorInfo(4, shape, armnn::GetDataType<T>());
521 outputTensorInfo = armnn::TensorInfo(4, shape, armnn::GetDataType<T>());
522
523 // Set quantization parameters if the requested type is a quantized type.
524 if(armnn::IsQuantizedType<T>())
525 {
526 inputTensorInfo.SetQuantizationScale(qScale);
527 inputTensorInfo.SetQuantizationOffset(qOffset);
528 outputTensorInfo.SetQuantizationScale(qScale);
529 outputTensorInfo.SetQuantizationOffset(qOffset);
530 }
531
532 float minVal = -10.f;
533 if (f == armnn::ActivationFunction::Sqrt)
534 {
535 minVal = 0.f;
536 }
537
538 boost::multi_array<T, 4> input = MakeRandomTensor<T, 4>(inputTensorInfo, 21453, minVal, 10.f);
539
540
541 LayerTestResult<T,4> ret(outputTensorInfo);
542 auto boostArrayExtents = boost::extents
543 [boost::numeric_cast<boost::multi_array_types::extent_gen::index>(batchSize)]
544 [boost::numeric_cast<boost::multi_array_types::extent_gen::index>(channels)]
545 [boost::numeric_cast<boost::multi_array_types::extent_gen::index>(height)]
546 [boost::numeric_cast<boost::multi_array_types::extent_gen::index>(width)];
547 ret.output.resize(boostArrayExtents);
548 ret.outputExpected.resize(boostArrayExtents);
549
550
551 std::unique_ptr<armnn::ITensorHandle> inputHandle = workloadFactory.CreateTensorHandle(inputTensorInfo);
552 std::unique_ptr<armnn::ITensorHandle> outputHandle = workloadFactory.CreateTensorHandle(outputTensorInfo);
553
554 std::unique_ptr<armnn::ITensorHandle> inputHandleRef = refWorkloadFactory.CreateTensorHandle(inputTensorInfo);
555 std::unique_ptr<armnn::ITensorHandle> outputHandleRef = refWorkloadFactory.CreateTensorHandle(outputTensorInfo);
556
557 armnn::ActivationQueueDescriptor data;
558 armnn::WorkloadInfo info;
559 AddInputToWorkload(data, info, inputTensorInfo, inputHandle.get());
560 AddOutputToWorkload(data, info, outputTensorInfo, outputHandle.get());
561 data.m_Parameters.m_A = a;
562 data.m_Parameters.m_B = b;
563 data.m_Parameters.m_Function = f;
564
565 armnn::ActivationQueueDescriptor refData = data;
566 armnn::WorkloadInfo refInfo = info;
567 SetWorkloadInput(refData, refInfo, 0, inputTensorInfo, inputHandleRef.get());
568 SetWorkloadOutput(refData, refInfo, 0, outputTensorInfo, outputHandleRef.get());
569
570 std::unique_ptr<armnn::IWorkload> workload = workloadFactory.CreateActivation(data, info);
571 BOOST_ASSERT(workload != nullptr);
572 std::unique_ptr<armnn::IWorkload> workloadRef = refWorkloadFactory.CreateActivation(refData, refInfo);
573 BOOST_ASSERT(workloadRef != nullptr);
574
575 inputHandle->Allocate();
576 outputHandle->Allocate();
577 inputHandleRef->Allocate();
578 outputHandleRef->Allocate();
579
580 CopyDataToITensorHandle(inputHandle.get(), &input[0][0][0][0]);
581 CopyDataToITensorHandle(inputHandleRef.get(), &input[0][0][0][0]);
582
583 workload->Execute();
584 workloadRef->Execute();
585
586 CopyDataFromITensorHandle(&ret.output[0][0][0][0], outputHandle.get());
587 CopyDataFromITensorHandle(&ret.outputExpected[0][0][0][0], outputHandleRef.get());
588
589 return ret;
590}
591
Aron Virginas-Tar5caf9072018-11-14 18:35:18 +0000592LayerTestResult<float,4> CompareActivationTest(
593 armnn::IWorkloadFactory& workloadFactory,
594 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
595 armnn::IWorkloadFactory& refWorkloadFactory,
596 armnn::ActivationFunction f,
597 unsigned int batchSize)
telsoa014fcda012018-03-09 14:13:49 +0000598{
Aron Virginas-Tar5caf9072018-11-14 18:35:18 +0000599 return CompareActivationTestImpl<float>(
600 workloadFactory, memoryManager, refWorkloadFactory, f, batchSize);
telsoa014fcda012018-03-09 14:13:49 +0000601}
602
Aron Virginas-Tar5caf9072018-11-14 18:35:18 +0000603LayerTestResult<uint8_t,4> CompareActivationUint8Test(
604 armnn::IWorkloadFactory& workloadFactory,
605 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
606 armnn::IWorkloadFactory& refWorkloadFactory,
607 armnn::ActivationFunction f)
telsoa014fcda012018-03-09 14:13:49 +0000608{
Aron Virginas-Tar5caf9072018-11-14 18:35:18 +0000609 return CompareActivationTestImpl<uint8_t>(
610 workloadFactory, memoryManager, refWorkloadFactory, f, 5, 0.1f, 50);
telsoa014fcda012018-03-09 14:13:49 +0000611}