blob: 5be8c22648df6b3d377307f1ab848b1174bd4c47 [file] [log] [blame]
telsoa014fcda012018-03-09 14:13:49 +00001//
Teresa Charlinfbf0e5b2020-08-17 01:01:06 +01002// Copyright © 2017 Arm Ltd and Contributors. All rights reserved.
David Beckecb56cd2018-09-05 12:52:57 +01003// SPDX-License-Identifier: MIT
telsoa014fcda012018-03-09 14:13:49 +00004//
telsoa014fcda012018-03-09 14:13:49 +00005
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01006#include "ActivationTestImpl.hpp"
7
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01008#include <QuantizeHelper.hpp>
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01009#include <ResolveType.hpp>
Aron Virginas-Tarc9cc8042018-11-01 16:15:57 +000010
telsoa014fcda012018-03-09 14:13:49 +000011
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +010012#include <backendsCommon/test/ActivationFixture.hpp>
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +010013#include <backendsCommon/test/TensorCopyUtils.hpp>
14#include <backendsCommon/test/WorkloadTestUtils.hpp>
telsoa014fcda012018-03-09 14:13:49 +000015
Aron Virginas-Tarc9cc8042018-11-01 16:15:57 +000016#include <test/TensorHelpers.hpp>
telsoa014fcda012018-03-09 14:13:49 +000017
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +010018#include <boost/multi_array.hpp>
19
telsoa014fcda012018-03-09 14:13:49 +000020#include <algorithm>
21
Nattapat Chaimanowong649dd952019-01-22 16:10:44 +000022template<armnn::DataType ArmnnType, typename T = armnn::ResolveType<ArmnnType>>
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{
Jan Eilers8eb25602020-03-09 12:13:48 +000039 IgnoreUnused(memoryManager);
telsoa014fcda012018-03-09 14:13:49 +000040 unsigned int outputWidth = inputWidth;
41 unsigned int outputHeight = inputHeight;
42 unsigned int outputChannels = inputChannels;
43 unsigned int outputBatchSize = inputBatchSize;
44
Nattapat Chaimanowong649dd952019-01-22 16:10:44 +000045 armnn::TensorInfo inputTensorInfo({ inputBatchSize, inputChannels, inputHeight, inputWidth }, ArmnnType);
telsoa014fcda012018-03-09 14:13:49 +000046
Nattapat Chaimanowong649dd952019-01-22 16:10:44 +000047 armnn::TensorInfo outputTensorInfo({ outputBatchSize, outputChannels, outputHeight, outputWidth }, ArmnnType);
telsoa014fcda012018-03-09 14:13:49 +000048
49 if(armnn::IsQuantizedType<T>())
50 {
51 inputTensorInfo.SetQuantizationScale(inputScale);
52 inputTensorInfo.SetQuantizationOffset(inputOffset);
53
54 outputTensorInfo.SetQuantizationScale(outputScale);
55 outputTensorInfo.SetQuantizationOffset(outputOffset);
56 }
57
58 LayerTestResult<T, 4> result(inputTensorInfo);
59
60 auto input = MakeTensor<T, 4>(inputTensorInfo, inputData);
61
Teresa Charlinfbf0e5b2020-08-17 01:01:06 +010062 ARMNN_NO_DEPRECATE_WARN_BEGIN
telsoa014fcda012018-03-09 14:13:49 +000063 std::unique_ptr<armnn::ITensorHandle> inputHandle = workloadFactory.CreateTensorHandle(inputTensorInfo);
64 std::unique_ptr<armnn::ITensorHandle> outputHandle = workloadFactory.CreateTensorHandle(outputTensorInfo);
Teresa Charlinfbf0e5b2020-08-17 01:01:06 +010065 ARMNN_NO_DEPRECATE_WARN_END
telsoa014fcda012018-03-09 14:13:49 +000066
telsoa01c577f2c2018-08-31 09:22:23 +010067 // Setup bounded ReLu.
telsoa014fcda012018-03-09 14:13:49 +000068 armnn::ActivationQueueDescriptor descriptor;
69 armnn::WorkloadInfo workloadInfo;
70 AddInputToWorkload(descriptor, workloadInfo, inputTensorInfo, inputHandle.get());
71 AddOutputToWorkload(descriptor, workloadInfo, outputTensorInfo, outputHandle.get());
72
73 descriptor.m_Parameters.m_Function = armnn::ActivationFunction::BoundedReLu;
74 descriptor.m_Parameters.m_A = upperBound;
75 descriptor.m_Parameters.m_B = lowerBound;
76
77 std::unique_ptr<armnn::IWorkload> workload = workloadFactory.CreateActivation(descriptor, workloadInfo);
78
79 inputHandle->Allocate();
80 outputHandle->Allocate();
81
82 CopyDataToITensorHandle(inputHandle.get(), &input[0][0][0][0]);
83
84 workload->Execute();
85
86 CopyDataFromITensorHandle(&result.output[0][0][0][0], outputHandle.get());
87
88 result.outputExpected = MakeTensor<T, 4>(outputTensorInfo, outputExpectedData);
89
90 return result;
91}
92
Aron Virginas-Tar5caf9072018-11-14 18:35:18 +000093LayerTestResult<float, 4> BoundedReLuUpperAndLowerBoundTest(
94 armnn::IWorkloadFactory& workloadFactory,
95 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager)
telsoa014fcda012018-03-09 14:13:49 +000096{
97 unsigned int inputWidth = 4u;
98 unsigned int inputHeight = 5u;
99 unsigned int inputChannels = 1u;
100 unsigned int inputBatchSize = 1;
101
102 std::vector<float> input = std::vector<float>{
103 -2.0f, 0.1f, 0.5f, 1.25f,
104 0.786f, 0.9875f, -1.5f, 0.384f,
105 1.0001f, 3.5f, 7.5f, 0.896f,
106 2.126f, 2.0f, 0.3f, 0.15f,
107 0.999f, 1.2f, 0.89f, 6.1f,
108 };
109
telsoa01c577f2c2018-08-31 09:22:23 +0100110 // Calculated manually.
telsoa014fcda012018-03-09 14:13:49 +0000111 std::vector<float> output = std::vector<float>{
112 -1.0f, 0.1f, 0.5f, 1.0f,
113 0.786f, 0.9875f, -1.0f, 0.384f,
114 1.0f, 1.0f, 1.0f, 0.896f,
115 1.0f, 1.0f, 0.3f, 0.15f,
116 0.999f, 1.0f, 0.89f, 1.0f,
117 };
118
Nattapat Chaimanowong649dd952019-01-22 16:10:44 +0000119 return BoundedReLuTestCommon<armnn::DataType::Float32>(
Aron Virginas-Tar5caf9072018-11-14 18:35:18 +0000120 workloadFactory, memoryManager, 1.0f, -1.0f, 1.0f, 0, 1.0f, 0, input, output,
121 inputWidth, inputHeight, inputChannels, inputBatchSize);
telsoa014fcda012018-03-09 14:13:49 +0000122}
123
Aron Virginas-Tar5caf9072018-11-14 18:35:18 +0000124LayerTestResult<float, 4> BoundedReLuUpperBoundOnlyTest(
125 armnn::IWorkloadFactory& workloadFactory,
126 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager)
telsoa014fcda012018-03-09 14:13:49 +0000127{
128 unsigned int inputWidth = 4u;
129 unsigned int inputHeight = 5u;
130 unsigned int inputChannels = 1u;
131 unsigned int inputBatchSize = 1;
132
133 std::vector<float> input = std::vector<float>{
134 -1.0f, 0.1f, 0.5f, 6.25f,
135 0.786f, 5.9875f, -0.5f, 0.384f,
136 6.0001f, 3.5f, 7.5f, 0.896f,
137 2.126f, 12.0f, 0.3f, 0.15f,
138 0.999f, 1.2f, 0.89f, 6.1f,
139 };
140
David Beckac42efd2018-09-26 17:41:13 +0100141 // Calculated manually.
telsoa014fcda012018-03-09 14:13:49 +0000142 std::vector<float> output = std::vector<float>{
143 0.0f, 0.1f, 0.5f, 6.0f,
144 0.786f, 5.9875f, 0.0f, 0.384f,
145 6.0f, 3.5f, 6.0f, 0.896f,
146 2.126f, 6.0f, 0.3f, 0.15f,
147 0.999f, 1.2f, 0.89f, 6.0f,
148 };
149
Nattapat Chaimanowong649dd952019-01-22 16:10:44 +0000150 return BoundedReLuTestCommon<armnn::DataType::Float32>(
Aron Virginas-Tar5caf9072018-11-14 18:35:18 +0000151 workloadFactory, memoryManager, 6.0f, 0.0f, 1.0f, 0, 1.0f, 0, input, output,
152 inputWidth, inputHeight, inputChannels, inputBatchSize);
telsoa014fcda012018-03-09 14:13:49 +0000153}
154
Aron Virginas-Tar5caf9072018-11-14 18:35:18 +0000155LayerTestResult<uint8_t, 4> BoundedReLuUint8UpperBoundOnlyTest(
156 armnn::IWorkloadFactory& workloadFactory,
157 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager)
telsoa014fcda012018-03-09 14:13:49 +0000158{
159 unsigned int inputWidth = 3u;
160 unsigned int inputHeight = 2u;
161 unsigned int inputChannels = 1u;
162 unsigned int inputBatchSize = 1;
163
164 std::vector<uint8_t> input = std::vector<uint8_t>{
165 51, 124, 28,
166 251, 8, 92
167 };
168
David Beckac42efd2018-09-26 17:41:13 +0100169 // Calculated manually.
telsoa014fcda012018-03-09 14:13:49 +0000170 std::vector<uint8_t> output = std::vector<uint8_t>{
171 0, 122, 0,
172 255, 0, 58
173 };
174
175 float inputScale = 12.0f / 255.0f;
176 int32_t inputOffset = 63;
177 float outputScale = 6.0f / 255.0f;
178 int32_t outputOffset = 0;
179
Derek Lambertif90c56d2020-01-10 17:14:08 +0000180 return BoundedReLuTestCommon<armnn::DataType::QAsymmU8>(
Nattapat Chaimanowong649dd952019-01-22 16:10:44 +0000181 workloadFactory, memoryManager, 6.0f, 0.0f,
182 inputScale, inputOffset, outputScale, outputOffset,
183 input, output, inputWidth, inputHeight, inputChannels, inputBatchSize);
telsoa014fcda012018-03-09 14:13:49 +0000184}
185
Aron Virginas-Tar5caf9072018-11-14 18:35:18 +0000186LayerTestResult<uint8_t, 4> BoundedReLuUint8UpperAndLowerBoundTest(
187 armnn::IWorkloadFactory& workloadFactory,
188 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager)
telsoa014fcda012018-03-09 14:13:49 +0000189{
190 unsigned int inputWidth = 3u;
191 unsigned int inputHeight = 2u;
192 unsigned int inputChannels = 1u;
193 unsigned int inputBatchSize = 1;
194
195 std::vector<uint8_t> input = std::vector<uint8_t>{
196 51, 230, 28,
197 251, 8, 92
198 };
199
telsoa01c577f2c2018-08-31 09:22:23 +0100200 // Calculated manually.
telsoa014fcda012018-03-09 14:13:49 +0000201 std::vector<uint8_t> output = std::vector<uint8_t>{
202 51, 192, 32,
203 192, 32, 92
204 };
205
206 int32_t inputOffset = 112;
207 float inputScale = 0.0125f;
208
Derek Lambertif90c56d2020-01-10 17:14:08 +0000209 return BoundedReLuTestCommon<armnn::DataType::QAsymmU8>(
Nattapat Chaimanowong649dd952019-01-22 16:10:44 +0000210 workloadFactory, memoryManager, 1.0f, -1.0f,
211 inputScale, inputOffset, inputScale, inputOffset, // Input/output scale & offset same.
212 input, output, inputWidth, inputHeight, inputChannels, inputBatchSize);
telsoa014fcda012018-03-09 14:13:49 +0000213}
214
215namespace
216{
217
218struct BoundedReLuRandomInputTestTraits
219{
220 constexpr static unsigned int inputHeight = 31u;
221 constexpr static unsigned int inputWidth = 19u;
222 constexpr static unsigned int inputChannels = 4u;
223 constexpr static unsigned int inputBatchSize = 2;
224
225 constexpr static unsigned int outputHeight = inputHeight;
226 constexpr static unsigned int outputWidth = inputWidth;
227 constexpr static unsigned int outputChannels = inputChannels;
228 constexpr static unsigned int outputBatchSize = inputBatchSize;
229
230 static armnn::TensorInfo GetInputTensorInfo()
231 {
232 return armnn::TensorInfo({ inputBatchSize, inputChannels, inputHeight, inputWidth },
233 armnn::DataType::Float32);
234 }
235
236 static armnn::TensorInfo GetOutputTensorInfo()
237 {
238 return armnn::TensorInfo({ outputBatchSize, outputChannels, outputHeight, outputWidth },
239 armnn::DataType::Float32);
240 }
241};
242
Aron Virginas-Tar5caf9072018-11-14 18:35:18 +0000243boost::multi_array<float, 4> BoundedReLuRandomInputTest(
244 armnn::IWorkloadFactory& workloadFactory,
245 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
246 float lowerBound,
247 float upperBound,
248 const armnn::ActivationDescriptor& activationDescriptor)
telsoa014fcda012018-03-09 14:13:49 +0000249{
Jan Eilers8eb25602020-03-09 12:13:48 +0000250 IgnoreUnused(memoryManager);
telsoa014fcda012018-03-09 14:13:49 +0000251 const armnn::TensorInfo inputTensorInfo = BoundedReLuRandomInputTestTraits::GetInputTensorInfo();
252 const armnn::TensorInfo outputTensorInfo = BoundedReLuRandomInputTestTraits::GetOutputTensorInfo();
253
254 boost::multi_array<float, 4> output(GetTensorShapeAsArray<4>(outputTensorInfo));
255
telsoa01c577f2c2018-08-31 09:22:23 +0100256 // Min/max random values passed to MakeRandomTensor are purposely outside of the ReLu
257 // range [lowerBound, upperBound].
telsoa014fcda012018-03-09 14:13:49 +0000258 auto input = MakeRandomTensor<float, 4>(inputTensorInfo, 4605828, lowerBound - 5.0f, upperBound * 2.0f);
259
Teresa Charlinfbf0e5b2020-08-17 01:01:06 +0100260 ARMNN_NO_DEPRECATE_WARN_BEGIN
telsoa014fcda012018-03-09 14:13:49 +0000261 std::unique_ptr<armnn::ITensorHandle> inputHandle = workloadFactory.CreateTensorHandle(inputTensorInfo);
262 std::unique_ptr<armnn::ITensorHandle> outputHandle = workloadFactory.CreateTensorHandle(outputTensorInfo);
Teresa Charlinfbf0e5b2020-08-17 01:01:06 +0100263 ARMNN_NO_DEPRECATE_WARN_END
telsoa014fcda012018-03-09 14:13:49 +0000264
telsoa01c577f2c2018-08-31 09:22:23 +0100265 // Set up bounded ReLu.
telsoa014fcda012018-03-09 14:13:49 +0000266 armnn::ActivationQueueDescriptor descriptor;
267 armnn::WorkloadInfo workloadInfo;
268 AddInputToWorkload(descriptor, workloadInfo, inputTensorInfo, inputHandle.get());
269 AddOutputToWorkload(descriptor, workloadInfo, outputTensorInfo, outputHandle.get());
270 descriptor.m_Parameters = activationDescriptor;
271
272 std::unique_ptr<armnn::IWorkload> workload = workloadFactory.CreateActivation(descriptor, workloadInfo);
273
274 inputHandle->Allocate();
275 outputHandle->Allocate();
276
277 CopyDataToITensorHandle(inputHandle.get(), &input[0][0][0][0]);
278
279 workload->Execute();
280
281 CopyDataFromITensorHandle(&output[0][0][0][0], outputHandle.get());
282
283 return output;
284}
285
286} // namespace
287
Aron Virginas-Tar5caf9072018-11-14 18:35:18 +0000288LayerTestResult<float, 4> CompareBoundedReLuTest(
289 armnn::IWorkloadFactory& workloadFactory,
290 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
291 armnn::IWorkloadFactory& refWorkloadFactory,
292 float upperBound,
293 float lowerBound)
telsoa014fcda012018-03-09 14:13:49 +0000294{
295 LayerTestResult<float, 4> result(BoundedReLuRandomInputTestTraits::GetOutputTensorInfo());
296
297 armnn::ActivationDescriptor activationDescriptor;
298 activationDescriptor.m_Function = armnn::ActivationFunction::BoundedReLu;
299 activationDescriptor.m_A = upperBound;
300 activationDescriptor.m_B = lowerBound;
301
Aron Virginas-Tar5caf9072018-11-14 18:35:18 +0000302 result.output = BoundedReLuRandomInputTest(
303 workloadFactory, memoryManager, 0.0f, upperBound, activationDescriptor);
304 result.outputExpected = BoundedReLuRandomInputTest(
305 refWorkloadFactory, nullptr, 0.0f, upperBound, activationDescriptor);
telsoa014fcda012018-03-09 14:13:49 +0000306
307 return result;
308}
309
Nattapat Chaimanowong649dd952019-01-22 16:10:44 +0000310template<armnn::DataType ArmnnType, typename T = armnn::ResolveType<ArmnnType>>
Aron Virginas-Tar5caf9072018-11-14 18:35:18 +0000311LayerTestResult<T,4> ConstantLinearActivationTestCommon(
312 armnn::IWorkloadFactory& workloadFactory,
313 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
314 float qScale = 0.0f,
315 int32_t qOffset = 0)
telsoa014fcda012018-03-09 14:13:49 +0000316{
Jan Eilers8eb25602020-03-09 12:13:48 +0000317 IgnoreUnused(memoryManager);
telsoa014fcda012018-03-09 14:13:49 +0000318 unsigned int inputHeight = 20;
319 unsigned int inputWidth = 17;
320 unsigned int inputChannels = 3;
321 unsigned int batchSize = 5;
322
323 armnn::TensorInfo inputTensorInfo;
324 armnn::TensorInfo outputTensorInfo;
325
326 unsigned int shape[] = {batchSize, inputChannels, inputHeight, inputWidth};
327
Nattapat Chaimanowong649dd952019-01-22 16:10:44 +0000328 inputTensorInfo = armnn::TensorInfo(4, shape, ArmnnType);
329 outputTensorInfo = armnn::TensorInfo(4, shape, ArmnnType);
telsoa014fcda012018-03-09 14:13:49 +0000330
331 // Set quantization parameters if the requested type is a quantized type.
332 if(armnn::IsQuantizedType<T>())
333 {
334 inputTensorInfo.SetQuantizationScale(qScale);
335 inputTensorInfo.SetQuantizationOffset(qOffset);
336 outputTensorInfo.SetQuantizationScale(qScale);
337 outputTensorInfo.SetQuantizationOffset(qOffset);
338 }
339
340 LayerTestResult<T, 4> ret(outputTensorInfo);
Teresa Charlinfbf0e5b2020-08-17 01:01:06 +0100341 ARMNN_NO_DEPRECATE_WARN_BEGIN
telsoa014fcda012018-03-09 14:13:49 +0000342 std::unique_ptr<armnn::ITensorHandle> inputHandle = workloadFactory.CreateTensorHandle(inputTensorInfo);
343 std::unique_ptr<armnn::ITensorHandle> outputHandle = workloadFactory.CreateTensorHandle(outputTensorInfo);
Teresa Charlinfbf0e5b2020-08-17 01:01:06 +0100344 ARMNN_NO_DEPRECATE_WARN_END
telsoa014fcda012018-03-09 14:13:49 +0000345
telsoa01c577f2c2018-08-31 09:22:23 +0100346 // Do linear activation that should leave the tensor unchanged.
telsoa014fcda012018-03-09 14:13:49 +0000347 armnn::ActivationQueueDescriptor data;
348 armnn::WorkloadInfo info;
349 AddInputToWorkload(data, info, inputTensorInfo, inputHandle.get());
350 AddOutputToWorkload(data, info, outputTensorInfo, outputHandle.get());
351 data.m_Parameters.m_A = 1.0f;
352 data.m_Parameters.m_B = 0.0f;
353 data.m_Parameters.m_Function = armnn::ActivationFunction::Linear;
354
355 std::unique_ptr<armnn::IWorkload> workload = workloadFactory.CreateActivation(data, info);
356
357 inputHandle->Allocate();
358 outputHandle->Allocate();
359
360 boost::multi_array<T, 4> input = MakeRandomTensor<T, 4>(inputTensorInfo, 7123561);
361 CopyDataToITensorHandle(inputHandle.get(), &input[0][0][0][0]);
362
363 workload->Execute();
364
365 CopyDataFromITensorHandle(&ret.output[0][0][0][0], outputHandle.get());
366
telsoa01c577f2c2018-08-31 09:22:23 +0100367 // Ensure output equals input.
telsoa014fcda012018-03-09 14:13:49 +0000368 ret.outputExpected = input;
369
370 return ret;
371}
372
Aron Virginas-Tar5caf9072018-11-14 18:35:18 +0000373LayerTestResult<float, 4> ConstantLinearActivationTest(
374 armnn::IWorkloadFactory& workloadFactory,
375 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager)
telsoa014fcda012018-03-09 14:13:49 +0000376{
Nattapat Chaimanowong649dd952019-01-22 16:10:44 +0000377 return ConstantLinearActivationTestCommon<armnn::DataType::Float32>(workloadFactory, memoryManager);
telsoa014fcda012018-03-09 14:13:49 +0000378}
379
Aron Virginas-Tar5caf9072018-11-14 18:35:18 +0000380LayerTestResult<uint8_t, 4> ConstantLinearActivationUint8Test(
381 armnn::IWorkloadFactory& workloadFactory,
382 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager)
telsoa014fcda012018-03-09 14:13:49 +0000383{
Derek Lambertif90c56d2020-01-10 17:14:08 +0000384 return ConstantLinearActivationTestCommon<armnn::DataType::QAsymmU8>(
Nattapat Chaimanowong649dd952019-01-22 16:10:44 +0000385 workloadFactory, memoryManager, 4.0f, 3);
telsoa014fcda012018-03-09 14:13:49 +0000386}
387
Teresa Charlin18515e22019-04-24 10:17:46 +0100388LayerTestResult<int16_t, 4> ConstantLinearActivationInt16Test(
389 armnn::IWorkloadFactory& workloadFactory,
390 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager)
391{
Derek Lambertif90c56d2020-01-10 17:14:08 +0000392 return ConstantLinearActivationTestCommon<armnn::DataType::QSymmS16>(
Teresa Charlin18515e22019-04-24 10:17:46 +0100393 workloadFactory, memoryManager, 0.1f, 0);
394}
395
Nattapat Chaimanowong649dd952019-01-22 16:10:44 +0000396template<armnn::DataType ArmnnType, typename T = armnn::ResolveType<ArmnnType>>
Aron Virginas-Tar5caf9072018-11-14 18:35:18 +0000397LayerTestResult<T, 4> SimpleActivationTest(
398 armnn::IWorkloadFactory& workloadFactory,
399 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
400 armnn::ActivationFunction activationFunction,
401 float activationParameterA,
402 float activationParameterB,
Ferran Balaguerb2b5a262019-06-24 12:43:38 +0100403 float scale,
404 int32_t offset,
Aron Virginas-Tar5caf9072018-11-14 18:35:18 +0000405 const std::vector<float>& inputData,
Ferran Balaguerb2b5a262019-06-24 12:43:38 +0100406 float outScale,
407 int32_t outOffset,
Aron Virginas-Tar5caf9072018-11-14 18:35:18 +0000408 const std::vector<float>& outputExpectedData)
telsoa014fcda012018-03-09 14:13:49 +0000409{
Jan Eilers8eb25602020-03-09 12:13:48 +0000410 IgnoreUnused(memoryManager);
telsoa014fcda012018-03-09 14:13:49 +0000411 constexpr static unsigned int inputWidth = 16u;
412 constexpr static unsigned int inputHeight = 1u;
413 constexpr static unsigned int inputChannels = 1u;
414 constexpr static unsigned int inputBatchSize = 1u;
415
416 constexpr static unsigned int outputWidth = inputWidth;
417 constexpr static unsigned int outputHeight = inputHeight;
418 constexpr static unsigned int outputChannels = inputChannels;
419 constexpr static unsigned int outputBatchSize = inputBatchSize;
420
Nattapat Chaimanowong649dd952019-01-22 16:10:44 +0000421 armnn::TensorInfo inputTensorInfo({ inputBatchSize, inputChannels, inputHeight, inputWidth }, ArmnnType);
422 armnn::TensorInfo outputTensorInfo({ outputBatchSize, outputChannels, outputHeight, outputWidth }, ArmnnType);
telsoa014fcda012018-03-09 14:13:49 +0000423
424 // Set quantization parameters if the requested type is a quantized type.
425 if(armnn::IsQuantizedType<T>())
426 {
Ferran Balaguerb2b5a262019-06-24 12:43:38 +0100427 inputTensorInfo.SetQuantizationScale(scale);
428 inputTensorInfo.SetQuantizationOffset(offset);
429 outputTensorInfo.SetQuantizationScale(outScale);
430 outputTensorInfo.SetQuantizationOffset(outOffset);
telsoa014fcda012018-03-09 14:13:49 +0000431 }
432
433 LayerTestResult<T, 4> result(inputTensorInfo);
434
Aron Virginas-Tar48623a02019-10-22 10:00:28 +0100435 auto input = MakeTensor<T, 4>(inputTensorInfo, armnnUtils::QuantizedVector<T>(inputData, scale, offset));
telsoa014fcda012018-03-09 14:13:49 +0000436
Teresa Charlinfbf0e5b2020-08-17 01:01:06 +0100437 ARMNN_NO_DEPRECATE_WARN_BEGIN
telsoa014fcda012018-03-09 14:13:49 +0000438 std::unique_ptr<armnn::ITensorHandle> inputHandle = workloadFactory.CreateTensorHandle(inputTensorInfo);
439 std::unique_ptr<armnn::ITensorHandle> outputHandle = workloadFactory.CreateTensorHandle(outputTensorInfo);
Teresa Charlinfbf0e5b2020-08-17 01:01:06 +0100440 ARMNN_NO_DEPRECATE_WARN_END
telsoa014fcda012018-03-09 14:13:49 +0000441
telsoa01c577f2c2018-08-31 09:22:23 +0100442 // Setup bounded ReLu.
telsoa014fcda012018-03-09 14:13:49 +0000443 armnn::ActivationQueueDescriptor descriptor;
444 armnn::WorkloadInfo workloadInfo;
445 AddInputToWorkload(descriptor, workloadInfo, inputTensorInfo, inputHandle.get());
446 AddOutputToWorkload(descriptor, workloadInfo, outputTensorInfo, outputHandle.get());
447
448 descriptor.m_Parameters.m_Function = activationFunction;
449 descriptor.m_Parameters.m_A = activationParameterA;
450 descriptor.m_Parameters.m_B = activationParameterB;
451
452 std::unique_ptr<armnn::IWorkload> workload = workloadFactory.CreateActivation(descriptor, workloadInfo);
453
454 inputHandle->Allocate();
455 outputHandle->Allocate();
456
457 CopyDataToITensorHandle(inputHandle.get(), &input[0][0][0][0]);
458
459 workload->Execute();
460
461 CopyDataFromITensorHandle(&result.output[0][0][0][0], outputHandle.get());
462
telsoa01c577f2c2018-08-31 09:22:23 +0100463 // Calculated manually.
Aron Virginas-Tar48623a02019-10-22 10:00:28 +0100464 result.outputExpected =
465 MakeTensor<T, 4>(outputTensorInfo, armnnUtils::QuantizedVector<T>(outputExpectedData, outScale, outOffset));
telsoa014fcda012018-03-09 14:13:49 +0000466
467 return result;
468}
469
Nattapat Chaimanowong649dd952019-01-22 16:10:44 +0000470template<armnn::DataType ArmnnType, typename T = armnn::ResolveType<ArmnnType>>
Aron Virginas-Tar5caf9072018-11-14 18:35:18 +0000471LayerTestResult<T, 4> SimpleSigmoidTestCommon(
472 armnn::IWorkloadFactory& workloadFactory,
473 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
474 float qScale,
475 int32_t qOffset)
telsoa014fcda012018-03-09 14:13:49 +0000476{
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100477 std::vector<float> inputData =
478 {
telsoa014fcda012018-03-09 14:13:49 +0000479 -0.1f, -0.2f, -0.3f, -0.4f,
480 0.1f, 0.2f, 0.3f, 0.4f,
481 -1.0f, -2.0f, -3.0f, -4.0f,
482 1.0f, 2.0f, 3.0f, 4.0f
483 };
484
telsoa01c577f2c2018-08-31 09:22:23 +0100485 // Calculate output values for input.
telsoa014fcda012018-03-09 14:13:49 +0000486 auto f = [](float value)
487 {
488 return 1.0f / (1.0f + std::exp(-value));
489 };
490 std::vector<float> outputExpectedData(inputData.size());
491 std::transform(inputData.begin(), inputData.end(), outputExpectedData.begin(), f);
492
Nattapat Chaimanowong649dd952019-01-22 16:10:44 +0000493 return SimpleActivationTest<ArmnnType>(workloadFactory,
494 memoryManager,
495 armnn::ActivationFunction::Sigmoid,
496 0.f,
497 0.f,
498 qScale,
499 qOffset,
500 inputData,
Ferran Balaguerb2b5a262019-06-24 12:43:38 +0100501 1.f / 256.f,
502 0,
Nattapat Chaimanowong649dd952019-01-22 16:10:44 +0000503 outputExpectedData);
telsoa014fcda012018-03-09 14:13:49 +0000504}
505
Aron Virginas-Tar5caf9072018-11-14 18:35:18 +0000506LayerTestResult<float, 4> SimpleSigmoidTest(
507 armnn::IWorkloadFactory& workloadFactory,
508 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager)
telsoa014fcda012018-03-09 14:13:49 +0000509{
Nattapat Chaimanowong649dd952019-01-22 16:10:44 +0000510 return SimpleSigmoidTestCommon<armnn::DataType::Float32>(workloadFactory, memoryManager, 0.0f, 0);
telsoa014fcda012018-03-09 14:13:49 +0000511}
512
Aron Virginas-Tar5caf9072018-11-14 18:35:18 +0000513LayerTestResult<uint8_t, 4> SimpleSigmoidUint8Test(
514 armnn::IWorkloadFactory& workloadFactory,
515 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager)
telsoa014fcda012018-03-09 14:13:49 +0000516{
Derek Lambertif90c56d2020-01-10 17:14:08 +0000517 return SimpleSigmoidTestCommon<armnn::DataType::QAsymmU8>(workloadFactory, memoryManager, 0.1f, 50);
telsoa014fcda012018-03-09 14:13:49 +0000518}
519
Teresa Charlin18515e22019-04-24 10:17:46 +0100520LayerTestResult<int16_t, 4> SimpleSigmoidInt16Test(
521 armnn::IWorkloadFactory& workloadFactory,
522 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager)
523{
Derek Lambertif90c56d2020-01-10 17:14:08 +0000524 return SimpleSigmoidTestCommon<armnn::DataType::QSymmS16>(workloadFactory, memoryManager, 0.1f, 0);
Teresa Charlin18515e22019-04-24 10:17:46 +0100525}
526
527template<armnn::DataType ArmnnType, typename T = armnn::ResolveType<ArmnnType>>
528LayerTestResult<T, 4> ReLuTestCommon(
529 armnn::IWorkloadFactory& workloadFactory,
530 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
531 float qScale,
532 int32_t qOffset)
533{
534 std::vector<float> inputData = {
535 -0.1f, -0.2f, -0.3f, -0.4f,
536 0.1f, 0.2f, 0.3f, 0.4f,
537 -1.0f, -2.0f, -3.0f, -4.0f,
538 1.0f, 2.0f, 3.0f, 4.0f
539 };
540
541 // Calculate output values for input.
542 auto f = [](float value)
543 {
544 return std::fmax(0.0f, value);
545 };
546 std::vector<float> outputExpectedData(inputData.size());
547 std::transform(inputData.begin(), inputData.end(), outputExpectedData.begin(), f);
548
549 return SimpleActivationTest<ArmnnType>(workloadFactory,
550 memoryManager,
551 armnn::ActivationFunction::ReLu,
552 0.f,
553 0.f,
554 qScale,
555 qOffset,
556 inputData,
Ferran Balaguerb2b5a262019-06-24 12:43:38 +0100557 qScale,
558 qOffset,
Teresa Charlin18515e22019-04-24 10:17:46 +0100559 outputExpectedData);
560}
561
562LayerTestResult<int16_t, 4> ReLuInt16Test(
563 armnn::IWorkloadFactory& workloadFactory,
564 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager)
565{
Derek Lambertif90c56d2020-01-10 17:14:08 +0000566 return ReLuTestCommon<armnn::DataType::QSymmS16>(workloadFactory, memoryManager, 0.1f, 0);
Teresa Charlin18515e22019-04-24 10:17:46 +0100567}
568
569
konsof017f6db402019-06-07 15:15:58 +0100570LayerTestResult<uint8_t, 4> ReLuUint8Test(
571 armnn::IWorkloadFactory& workloadFactory,
572 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager)
573{
Derek Lambertif90c56d2020-01-10 17:14:08 +0000574 return ReLuTestCommon<armnn::DataType::QAsymmU8>(workloadFactory, memoryManager, 0.1f, 0);
konsof017f6db402019-06-07 15:15:58 +0100575}
576
577LayerTestResult<float, 4> ReLuTest(
578 armnn::IWorkloadFactory& workloadFactory,
579 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager)
580{
581 return ReLuTestCommon<armnn::DataType::Float32>(workloadFactory, memoryManager, 0.1f, 0);
582}
583
584
Teresa Charlin18515e22019-04-24 10:17:46 +0100585template<armnn::DataType ArmnnType, typename T = armnn::ResolveType<ArmnnType>>
586LayerTestResult<T, 4> BoundedReLuTestCommon(
587 armnn::IWorkloadFactory& workloadFactory,
588 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
589 float qScale,
590 int32_t qOffset)
591{
592 std::vector<float> inputData = {
593 -0.1f, -0.2f, -0.3f, -0.4f,
594 0.1f, 0.2f, 0.3f, 0.4f,
595 -1.0f, -2.0f, -3.0f, -4.0f,
596 1.0f, 2.0f, 3.0f, 4.0f
597 };
598 const float a = 1.0f;
599 const float b = -1.0f;
600 // Calculate output values for input.
601 auto f = [a, b](float value)
602 {
603 return std::min(a, std::max(b, value));
604 };
605 std::vector<float> outputExpectedData(inputData.size());
606 std::transform(inputData.begin(), inputData.end(), outputExpectedData.begin(), f);
607
608 return SimpleActivationTest<ArmnnType>(workloadFactory,
609 memoryManager,
610 armnn::ActivationFunction::BoundedReLu,
611 a,
612 b,
613 qScale,
614 qOffset,
615 inputData,
Ferran Balaguerb2b5a262019-06-24 12:43:38 +0100616 qScale,
617 qOffset,
Teresa Charlin18515e22019-04-24 10:17:46 +0100618 outputExpectedData);
619}
620
621LayerTestResult<int16_t, 4> BoundedReLuInt16Test(
622 armnn::IWorkloadFactory& workloadFactory,
623 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager)
624{
Derek Lambertif90c56d2020-01-10 17:14:08 +0000625 return ReLuTestCommon<armnn::DataType::QSymmS16>(workloadFactory, memoryManager, 0.1f, 0);
Teresa Charlin18515e22019-04-24 10:17:46 +0100626}
627
628
629
630template<armnn::DataType ArmnnType, typename T = armnn::ResolveType<ArmnnType>>
631LayerTestResult<T, 4> SoftReLuTestCommon(
632 armnn::IWorkloadFactory& workloadFactory,
633 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
634 float qScale,
635 int32_t qOffset)
636{
637 std::vector<float> inputData = {
638 -0.1f, -0.2f, -0.3f, -0.4f,
639 0.1f, 0.2f, 0.3f, 0.4f,
640 -1.0f, -2.0f, -3.0f, -4.0f,
641 1.0f, 2.0f, 3.0f, 4.0f
642 };
643
644 // Calculate output values for input.
645 auto f = [](float value)
646 {
647 return std::log(1.0f + std::exp(value));
648 };
649 std::vector<float> outputExpectedData(inputData.size());
650 std::transform(inputData.begin(), inputData.end(), outputExpectedData.begin(), f);
651
652 return SimpleActivationTest<ArmnnType>(workloadFactory,
653 memoryManager,
654 armnn::ActivationFunction::SoftReLu,
655 0.f,
656 0.f,
657 qScale,
658 qOffset,
659 inputData,
Ferran Balaguerb2b5a262019-06-24 12:43:38 +0100660 qScale,
661 qOffset,
Teresa Charlin18515e22019-04-24 10:17:46 +0100662 outputExpectedData);
663}
664
konsof017f6db402019-06-07 15:15:58 +0100665LayerTestResult<float, 4> SoftReLuTest(
666 armnn::IWorkloadFactory& workloadFactory,
667 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager)
668{
669 return SoftReLuTestCommon<armnn::DataType::Float32>(workloadFactory, memoryManager, 0.1f, 0);
670}
671
672LayerTestResult<uint8_t, 4> SoftReLuUint8Test(
673 armnn::IWorkloadFactory& workloadFactory,
674 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager)
675{
Derek Lambertif90c56d2020-01-10 17:14:08 +0000676 return SoftReLuTestCommon<armnn::DataType::QAsymmU8>(workloadFactory, memoryManager, 0.0625f, 64);
konsof017f6db402019-06-07 15:15:58 +0100677}
678
Teresa Charlin18515e22019-04-24 10:17:46 +0100679LayerTestResult<int16_t, 4> SoftReLuInt16Test(
680 armnn::IWorkloadFactory& workloadFactory,
681 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager)
682{
Derek Lambertif90c56d2020-01-10 17:14:08 +0000683 return SoftReLuTestCommon<armnn::DataType::QSymmS16>(workloadFactory, memoryManager, 0.1f, 0);
Teresa Charlin18515e22019-04-24 10:17:46 +0100684}
685
686template<armnn::DataType ArmnnType, typename T = armnn::ResolveType<ArmnnType>>
687LayerTestResult<T, 4> LeakyReLuTestCommon(
688 armnn::IWorkloadFactory& workloadFactory,
689 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
690 float qScale,
691 int32_t qOffset)
692{
693 std::vector<float> inputData = {
694 -0.1f, -0.2f, -0.3f, -0.4f,
695 0.1f, 0.2f, 0.3f, 0.4f,
696 -1.0f, -2.0f, -3.0f, -4.0f,
697 1.0f, 2.0f, 3.0f, 4.0f
698 };
699
700 const float a = 0.01f;
701 // Calculate output values for input.
702 auto f = [a](float value)
703 {
704 return value > 0.0f ? value : (value * a);
705 };
706 std::vector<float> outputExpectedData(inputData.size());
707 std::transform(inputData.begin(), inputData.end(), outputExpectedData.begin(), f);
708
709 return SimpleActivationTest<ArmnnType>(workloadFactory,
710 memoryManager,
711 armnn::ActivationFunction::LeakyReLu,
712 a,
713 0.f,
714 qScale,
715 qOffset,
716 inputData,
Ferran Balaguerb2b5a262019-06-24 12:43:38 +0100717 qScale,
718 qOffset,
Teresa Charlin18515e22019-04-24 10:17:46 +0100719 outputExpectedData);
720}
721
konsof017f6db402019-06-07 15:15:58 +0100722LayerTestResult<float, 4> LeakyReLuTest(
723 armnn::IWorkloadFactory& workloadFactory,
724 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager)
725{
726 return LeakyReLuTestCommon<armnn::DataType::Float32>(workloadFactory, memoryManager, 0.1f, 0);
727}
728
729LayerTestResult<uint8_t, 4> LeakyReLuUint8Test(
730 armnn::IWorkloadFactory& workloadFactory,
731 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager)
732{
Derek Lambertif90c56d2020-01-10 17:14:08 +0000733 return LeakyReLuTestCommon<armnn::DataType::QAsymmU8>(workloadFactory, memoryManager, 0.0625f, 64);
konsof017f6db402019-06-07 15:15:58 +0100734}
735
Teresa Charlin18515e22019-04-24 10:17:46 +0100736LayerTestResult<int16_t, 4> LeakyReLuInt16Test(
737 armnn::IWorkloadFactory& workloadFactory,
738 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager)
739{
Derek Lambertif90c56d2020-01-10 17:14:08 +0000740 return LeakyReLuTestCommon<armnn::DataType::QSymmS16>(workloadFactory, memoryManager, 0.1f, 0);
Teresa Charlin18515e22019-04-24 10:17:46 +0100741}
742
743template<armnn::DataType ArmnnType, typename T = armnn::ResolveType<ArmnnType>>
744LayerTestResult<T, 4> AbsTestCommon(
745 armnn::IWorkloadFactory& workloadFactory,
746 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
747 float qScale,
748 int32_t qOffset)
749{
750 std::vector<float> inputData = {
751 -0.1f, -0.2f, -0.3f, -0.4f,
752 0.1f, 0.2f, 0.3f, 0.4f,
753 -1.0f, -2.0f, -3.0f, -4.0f,
754 1.0f, 2.0f, 3.0f, 4.0f
755 };
756
757 // Calculate output values for input.
758 auto f = [](float value)
759 {
760 return std::abs(value);
761 };
762 std::vector<float> outputExpectedData(inputData.size());
763 std::transform(inputData.begin(), inputData.end(), outputExpectedData.begin(), f);
764
765 return SimpleActivationTest<ArmnnType>(workloadFactory,
766 memoryManager,
767 armnn::ActivationFunction::Abs,
768 0.f,
769 0.f,
770 qScale,
771 qOffset,
772 inputData,
Ferran Balaguerb2b5a262019-06-24 12:43:38 +0100773 qScale,
774 qOffset,
Teresa Charlin18515e22019-04-24 10:17:46 +0100775 outputExpectedData);
776}
777
konsof017f6db402019-06-07 15:15:58 +0100778LayerTestResult<float, 4> AbsTest(
779 armnn::IWorkloadFactory& workloadFactory,
780 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager)
781{
782 return AbsTestCommon<armnn::DataType::Float32>(workloadFactory, memoryManager, 0.1f, 0);
783}
784
785LayerTestResult<uint8_t, 4> AbsUint8Test(
786 armnn::IWorkloadFactory& workloadFactory,
787 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager)
788{
Derek Lambertif90c56d2020-01-10 17:14:08 +0000789 return AbsTestCommon<armnn::DataType::QAsymmU8>(workloadFactory, memoryManager, 0.0625f, 64);
konsof017f6db402019-06-07 15:15:58 +0100790}
791
Teresa Charlin18515e22019-04-24 10:17:46 +0100792LayerTestResult<int16_t, 4> AbsInt16Test(
793 armnn::IWorkloadFactory& workloadFactory,
794 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager)
795{
Derek Lambertif90c56d2020-01-10 17:14:08 +0000796 return AbsTestCommon<armnn::DataType::QSymmS16>(workloadFactory, memoryManager, 0.1f, 0);
Teresa Charlin18515e22019-04-24 10:17:46 +0100797}
798
Sadik Armagan6095ba52019-09-13 17:07:19 +0100799LayerTestResult<float, 5> SqrtNNTest(
800 armnn::IWorkloadFactory& workloadFactory,
801 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager)
802{
Jan Eilers8eb25602020-03-09 12:13:48 +0000803 IgnoreUnused(memoryManager);
Sadik Armagan6095ba52019-09-13 17:07:19 +0100804 const int inputDataSize = 120;
805 std::vector<float> inputData(inputDataSize);
806
807 for (unsigned int i = 0u; i < inputDataSize; ++i)
808 {
809 inputData[i] = static_cast<float>(i) / 10;
810 }
811
812 auto f = [](float value)
813 {
814 return std::sqrt(value);
815 };
816 std::vector<float> outputExpectedData(inputDataSize);
817 std::transform(inputData.begin(), inputData.end(), outputExpectedData.begin(), f);
818
819 armnn::TensorInfo inputTensorInfo(
820 { 1u, 2u, 3u, 4u, 5u }, armnn::DataType::Float32);
821 armnn::TensorInfo outputTensorInfo(
822 { 1u, 2u, 3u, 4u, 5u }, armnn::DataType::Float32);
823
824 LayerTestResult<float, 5> result(inputTensorInfo);
825
Aron Virginas-Tar48623a02019-10-22 10:00:28 +0100826 auto input = MakeTensor<float, 5>(inputTensorInfo, inputData);
Sadik Armagan6095ba52019-09-13 17:07:19 +0100827
Teresa Charlinfbf0e5b2020-08-17 01:01:06 +0100828 ARMNN_NO_DEPRECATE_WARN_BEGIN
Sadik Armagan6095ba52019-09-13 17:07:19 +0100829 std::unique_ptr<armnn::ITensorHandle> inputHandle = workloadFactory.CreateTensorHandle(inputTensorInfo);
830 std::unique_ptr<armnn::ITensorHandle> outputHandle = workloadFactory.CreateTensorHandle(outputTensorInfo);
Teresa Charlinfbf0e5b2020-08-17 01:01:06 +0100831 ARMNN_NO_DEPRECATE_WARN_END
Sadik Armagan6095ba52019-09-13 17:07:19 +0100832
833 armnn::ActivationQueueDescriptor descriptor;
834 armnn::WorkloadInfo workloadInfo;
835 AddInputToWorkload(descriptor, workloadInfo, inputTensorInfo, inputHandle.get());
836 AddOutputToWorkload(descriptor, workloadInfo, outputTensorInfo, outputHandle.get());
837
838 descriptor.m_Parameters.m_Function = armnn::ActivationFunction::Sqrt;
839
840 std::unique_ptr<armnn::IWorkload> workload = workloadFactory.CreateActivation(descriptor, workloadInfo);
841
842 inputHandle->Allocate();
843 outputHandle->Allocate();
844
845 CopyDataToITensorHandle(inputHandle.get(), &input[0][0][0][0][0]);
846
847 workload->Execute();
848
849 CopyDataFromITensorHandle(&result.output[0][0][0][0][0], outputHandle.get());
850
851 // Calculated manually.
Aron Virginas-Tar48623a02019-10-22 10:00:28 +0100852 result.outputExpected = MakeTensor<float, 5>(outputTensorInfo, outputExpectedData);
Sadik Armagan6095ba52019-09-13 17:07:19 +0100853
854 return result;
855};
856
Teresa Charlin18515e22019-04-24 10:17:46 +0100857template<armnn::DataType ArmnnType, typename T = armnn::ResolveType<ArmnnType>>
858LayerTestResult<T, 4> SqrtTestCommon(
859 armnn::IWorkloadFactory& workloadFactory,
860 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
861 float qScale,
862 int32_t qOffset)
863{
864 std::vector<float> inputData = {
865 0.1f, 0.2f, 0.3f, 0.4f,
866 0.1f, 0.2f, 0.3f, 0.4f,
867 1.0f, 2.0f, 3.0f, 4.0f,
868 1.0f, 2.0f, 3.0f, 4.0f
869 };
870
871 // Calculate output values for input.
872 auto f = [](float value)
873 {
874 return std::sqrt(value);
875 };
876 std::vector<float> outputExpectedData(inputData.size());
877 std::transform(inputData.begin(), inputData.end(), outputExpectedData.begin(), f);
878
879 return SimpleActivationTest<ArmnnType>(workloadFactory,
880 memoryManager,
881 armnn::ActivationFunction::Sqrt,
882 0.f,
883 0.f,
884 qScale,
885 qOffset,
886 inputData,
Ferran Balaguerb2b5a262019-06-24 12:43:38 +0100887 qScale,
888 qOffset,
Teresa Charlin18515e22019-04-24 10:17:46 +0100889 outputExpectedData);
890}
891
konsof017f6db402019-06-07 15:15:58 +0100892LayerTestResult<float, 4> SqrtTest(
893 armnn::IWorkloadFactory& workloadFactory,
894 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager)
895{
896 return SqrtTestCommon<armnn::DataType::Float32>(workloadFactory, memoryManager, 0.1f, 0);
897}
898
899LayerTestResult<uint8_t, 4> SqrtUint8Test(
900 armnn::IWorkloadFactory& workloadFactory,
901 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager)
902{
Derek Lambertif90c56d2020-01-10 17:14:08 +0000903 return SqrtTestCommon<armnn::DataType::QAsymmU8>(workloadFactory, memoryManager, 0.0625f, 64);
konsof017f6db402019-06-07 15:15:58 +0100904}
905
Teresa Charlin18515e22019-04-24 10:17:46 +0100906LayerTestResult<int16_t, 4> SqrtInt16Test(
907 armnn::IWorkloadFactory& workloadFactory,
908 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager)
909{
Derek Lambertif90c56d2020-01-10 17:14:08 +0000910 return SqrtTestCommon<armnn::DataType::QSymmS16>(workloadFactory, memoryManager, 0.1f, 0);
Teresa Charlin18515e22019-04-24 10:17:46 +0100911}
912
913template<armnn::DataType ArmnnType, typename T = armnn::ResolveType<ArmnnType>>
914LayerTestResult<T, 4> SquareTestCommon(
915 armnn::IWorkloadFactory& workloadFactory,
916 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
917 float qScale,
918 int32_t qOffset)
919{
920 std::vector<float> inputData = {
921 -0.1f, -0.2f, -0.3f, -0.4f,
922 0.1f, 0.2f, 0.3f, 0.4f,
923 -1.0f, -2.0f, -3.0f, -4.0f,
924 1.0f, 2.0f, 3.0f, 4.0f
925 };
926
927 // Calculate output values for input.
928 auto f = [](float value)
929 {
930 return std::pow(value,2);
931 };
932 std::vector<float> outputExpectedData(inputData.size());
933 std::transform(inputData.begin(), inputData.end(), outputExpectedData.begin(), f);
934
935 return SimpleActivationTest<ArmnnType>(workloadFactory,
936 memoryManager,
937 armnn::ActivationFunction::Square,
938 0.f,
939 0.f,
940 qScale,
941 qOffset,
942 inputData,
Ferran Balaguerb2b5a262019-06-24 12:43:38 +0100943 qScale,
944 qOffset,
Teresa Charlin18515e22019-04-24 10:17:46 +0100945 outputExpectedData);
946}
947
konsof017f6db402019-06-07 15:15:58 +0100948LayerTestResult<float, 4> SquareTest(
949 armnn::IWorkloadFactory& workloadFactory,
950 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager)
951{
952 return SquareTestCommon<armnn::DataType::Float32>(workloadFactory, memoryManager, 0.1f, 0);
953}
954
955LayerTestResult<uint8_t, 4> SquareUint8Test(
956 armnn::IWorkloadFactory& workloadFactory,
957 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager)
958{
Derek Lambertif90c56d2020-01-10 17:14:08 +0000959 return SquareTestCommon<armnn::DataType::QAsymmU8>(workloadFactory, memoryManager, 0.0625f, 64);
konsof017f6db402019-06-07 15:15:58 +0100960}
961
Teresa Charlin18515e22019-04-24 10:17:46 +0100962LayerTestResult<int16_t, 4> SquareInt16Test(
963 armnn::IWorkloadFactory& workloadFactory,
964 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager)
965{
Derek Lambertif90c56d2020-01-10 17:14:08 +0000966 return SquareTestCommon<armnn::DataType::QSymmS16>(workloadFactory, memoryManager, 0.1f, 0);
Teresa Charlin18515e22019-04-24 10:17:46 +0100967}
968
969template<armnn::DataType ArmnnType, typename T = armnn::ResolveType<ArmnnType>>
970LayerTestResult<T, 4> TanhTestCommon(
971 armnn::IWorkloadFactory& workloadFactory,
972 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
973 float qScale,
974 int32_t qOffset)
975{
976 std::vector<float> inputData = {
977 -0.1f, -0.2f, -0.3f, -0.4f,
978 0.1f, 0.2f, 0.3f, 0.4f,
979 -1.0f, -2.0f, -3.0f, -4.0f,
980 1.0f, 2.0f, 3.0f, 4.0f
981 };
982
983 const float a = 2.0f;
984 const float b = 3.0f;
985 // Calculate output values for input.
986 auto f = [a, b](float value)
987 {
988 return a * tanhf(b * value);
989 };
990 std::vector<float> outputExpectedData(inputData.size());
991 std::transform(inputData.begin(), inputData.end(), outputExpectedData.begin(), f);
992
993 return SimpleActivationTest<ArmnnType>(workloadFactory,
994 memoryManager,
995 armnn::ActivationFunction::TanH,
996 a,
997 b,
998 qScale,
999 qOffset,
1000 inputData,
Ferran Balaguerb2b5a262019-06-24 12:43:38 +01001001 qScale,
1002 qOffset,
Teresa Charlin18515e22019-04-24 10:17:46 +01001003 outputExpectedData);
1004}
1005
konsof017f6db402019-06-07 15:15:58 +01001006LayerTestResult<float, 4> TanhTest(
1007 armnn::IWorkloadFactory& workloadFactory,
1008 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager)
1009{
1010 return TanhTestCommon<armnn::DataType::Float32>(workloadFactory, memoryManager, 0.1f, 0);
1011}
1012
1013LayerTestResult<uint8_t, 4> TanhUint8Test(
1014 armnn::IWorkloadFactory& workloadFactory,
1015 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager)
1016{
Derek Lambertif90c56d2020-01-10 17:14:08 +00001017 return TanhTestCommon<armnn::DataType::QAsymmU8>(workloadFactory, memoryManager, 0.1f, 64);
konsof017f6db402019-06-07 15:15:58 +01001018}
1019
Teresa Charlin18515e22019-04-24 10:17:46 +01001020LayerTestResult<int16_t, 4> TanhInt16Test(
1021 armnn::IWorkloadFactory& workloadFactory,
1022 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager)
1023{
Derek Lambertif90c56d2020-01-10 17:14:08 +00001024 return TanhTestCommon<armnn::DataType::QSymmS16>(workloadFactory, memoryManager, 0.1f, 0);
Teresa Charlin18515e22019-04-24 10:17:46 +01001025}
1026
1027
David Monahan3b3c3812020-02-25 09:03:29 +00001028template<armnn::DataType ArmnnType, typename T = armnn::ResolveType<ArmnnType>>
1029LayerTestResult<T, 4> EluTestCommon(
1030 armnn::IWorkloadFactory& workloadFactory,
1031 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
1032 float qScale,
1033 int32_t qOffset)
1034{
1035 std::vector<float> inputData = {
1036 -0.1f, -0.2f, -0.3f, -0.4f,
1037 0.1f, 0.2f, 0.3f, 0.4f,
1038 -1.0f, -2.0f, -3.0f, -4.0f,
1039 1.0f, 2.0f, 3.0f, 4.0f
1040 };
1041
1042
1043 const float a = 0.01f;
1044 // Calculate output values for input.
1045 auto f = [a](float value)
1046 {
1047 return (value >= 0) ? value : a * (expf(value) - 1);
1048 };
1049 std::vector<float> outputExpectedData(inputData.size());
1050 std::transform(inputData.begin(), inputData.end(), outputExpectedData.begin(), f);
1051
1052 return SimpleActivationTest<ArmnnType>(workloadFactory,
1053 memoryManager,
1054 armnn::ActivationFunction::Elu,
1055 a,
1056 0.0f,
1057 qScale,
1058 qOffset,
1059 inputData,
1060 qScale,
1061 qOffset,
1062 outputExpectedData);
1063}
1064
1065LayerTestResult<float, 4> EluTest(
1066 armnn::IWorkloadFactory& workloadFactory,
1067 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager)
1068{
1069 return EluTestCommon<armnn::DataType::Float32>(workloadFactory, memoryManager, 0.1f, 0);
1070}
1071
1072LayerTestResult<uint8_t, 4> EluUint8Test(
1073 armnn::IWorkloadFactory& workloadFactory,
1074 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager)
1075{
1076 return EluTestCommon<armnn::DataType::QAsymmU8>(workloadFactory, memoryManager, 0.1f, 64);
1077}
1078
1079LayerTestResult<int16_t, 4> EluInt16Test(
1080 armnn::IWorkloadFactory& workloadFactory,
1081 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager)
1082{
1083 return EluTestCommon<armnn::DataType::QSymmS16>(workloadFactory, memoryManager, 0.1f, 0);
1084}
1085
Teresa Charlin18515e22019-04-24 10:17:46 +01001086
Nattapat Chaimanowong649dd952019-01-22 16:10:44 +00001087template<armnn::DataType ArmnnType, typename T = armnn::ResolveType<ArmnnType>>
Colm Donelan03fbeaf2020-02-26 15:39:23 +00001088LayerTestResult<T, 4> HardSwishTestCommon(
1089 armnn::IWorkloadFactory& workloadFactory,
1090 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
1091 float qScale,
1092 int32_t qOffset)
1093{
1094 std::vector<float> inputData = {
1095 -0.1f, -0.2f, -0.3f, -0.4f,
1096 0.1f, 0.2f, 0.3f, 0.4f,
1097 -1.0f, -2.0f, -3.0f, -4.0f,
1098 1.0f, 2.0f, 3.0f, 4.0f
1099 };
1100 // Calculate output values for input.
1101 auto f = [](float x)
1102 {
1103 // Break down the calculation to help with verification.
1104 // hard_swish(x) = x * relu6(x+3) / 6
1105 // relu6(x) = min(max(x,0),6)
1106 float reLu6_step1 = std::max((x + 3),0.0f);
1107 float reLu6Complete = std::min(reLu6_step1, 6.0f);
1108 float hardSwish_step1 = x * reLu6Complete;
1109 float result = hardSwish_step1 / 6;
1110 return result;
1111 };
1112 std::vector<float> outputExpectedData(inputData.size());
1113 std::transform(inputData.begin(), inputData.end(), outputExpectedData.begin(), f);
1114
1115 return SimpleActivationTest<ArmnnType>(workloadFactory,
1116 memoryManager,
1117 armnn::ActivationFunction::HardSwish,
1118 0.f,
1119 0.f,
1120 qScale,
1121 qOffset,
1122 inputData,
1123 qScale,
1124 qOffset,
1125 outputExpectedData);
1126}
1127
1128LayerTestResult<float, 4> HardSwishTest(
1129 armnn::IWorkloadFactory& workloadFactory,
1130 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager)
1131{
1132 return HardSwishTestCommon<armnn::DataType::Float32>(workloadFactory, memoryManager, 0.1f, 0);
1133}
1134
1135LayerTestResult<uint8_t, 4> HardSwishUint8Test(
1136 armnn::IWorkloadFactory& workloadFactory,
1137 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager)
1138{
1139 return HardSwishTestCommon<armnn::DataType::QAsymmU8>(workloadFactory, memoryManager, 0.1f, 64);
1140}
1141
1142LayerTestResult<int16_t, 4> HardSwishInt16Test(
1143 armnn::IWorkloadFactory& workloadFactory,
1144 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager)
1145{
1146 return HardSwishTestCommon<armnn::DataType::QSymmS16>(workloadFactory, memoryManager, 0.1f, 0);
1147}
1148
1149
1150template<armnn::DataType ArmnnType, typename T = armnn::ResolveType<ArmnnType>>
Aron Virginas-Tar5caf9072018-11-14 18:35:18 +00001151LayerTestResult<T,4> CompareActivationTestImpl(
1152 armnn::IWorkloadFactory& workloadFactory,
1153 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
1154 armnn::IWorkloadFactory& refWorkloadFactory,
1155 armnn::ActivationFunction f,
1156 unsigned int batchSize = 5,
1157 float qScale = 0.0f,
1158 int32_t qOffset = 0)
telsoa014fcda012018-03-09 14:13:49 +00001159{
Jan Eilers8eb25602020-03-09 12:13:48 +00001160 IgnoreUnused(memoryManager);
telsoa014fcda012018-03-09 14:13:49 +00001161 unsigned int width = 17;
1162 unsigned int height = 29;
1163 unsigned int channels = 2;
1164
1165 float a = 0.234f;
1166 float b = -12.345f;
1167
1168 armnn::TensorInfo inputTensorInfo;
1169 armnn::TensorInfo outputTensorInfo;
1170
1171 unsigned int shape[] = {batchSize, channels, height, width};
1172
Nattapat Chaimanowong649dd952019-01-22 16:10:44 +00001173 inputTensorInfo = armnn::TensorInfo(4, shape, ArmnnType);
1174 outputTensorInfo = armnn::TensorInfo(4, shape, ArmnnType);
telsoa014fcda012018-03-09 14:13:49 +00001175
1176 // Set quantization parameters if the requested type is a quantized type.
1177 if(armnn::IsQuantizedType<T>())
1178 {
1179 inputTensorInfo.SetQuantizationScale(qScale);
1180 inputTensorInfo.SetQuantizationOffset(qOffset);
1181 outputTensorInfo.SetQuantizationScale(qScale);
1182 outputTensorInfo.SetQuantizationOffset(qOffset);
1183 }
1184
1185 float minVal = -10.f;
1186 if (f == armnn::ActivationFunction::Sqrt)
1187 {
1188 minVal = 0.f;
1189 }
1190
1191 boost::multi_array<T, 4> input = MakeRandomTensor<T, 4>(inputTensorInfo, 21453, minVal, 10.f);
1192
1193
1194 LayerTestResult<T,4> ret(outputTensorInfo);
1195 auto boostArrayExtents = boost::extents
1196 [boost::numeric_cast<boost::multi_array_types::extent_gen::index>(batchSize)]
1197 [boost::numeric_cast<boost::multi_array_types::extent_gen::index>(channels)]
1198 [boost::numeric_cast<boost::multi_array_types::extent_gen::index>(height)]
1199 [boost::numeric_cast<boost::multi_array_types::extent_gen::index>(width)];
1200 ret.output.resize(boostArrayExtents);
1201 ret.outputExpected.resize(boostArrayExtents);
1202
Teresa Charlinfbf0e5b2020-08-17 01:01:06 +01001203 ARMNN_NO_DEPRECATE_WARN_BEGIN
telsoa014fcda012018-03-09 14:13:49 +00001204 std::unique_ptr<armnn::ITensorHandle> inputHandle = workloadFactory.CreateTensorHandle(inputTensorInfo);
1205 std::unique_ptr<armnn::ITensorHandle> outputHandle = workloadFactory.CreateTensorHandle(outputTensorInfo);
1206
1207 std::unique_ptr<armnn::ITensorHandle> inputHandleRef = refWorkloadFactory.CreateTensorHandle(inputTensorInfo);
1208 std::unique_ptr<armnn::ITensorHandle> outputHandleRef = refWorkloadFactory.CreateTensorHandle(outputTensorInfo);
Teresa Charlinfbf0e5b2020-08-17 01:01:06 +01001209 ARMNN_NO_DEPRECATE_WARN_END
telsoa014fcda012018-03-09 14:13:49 +00001210
1211 armnn::ActivationQueueDescriptor data;
1212 armnn::WorkloadInfo info;
1213 AddInputToWorkload(data, info, inputTensorInfo, inputHandle.get());
1214 AddOutputToWorkload(data, info, outputTensorInfo, outputHandle.get());
1215 data.m_Parameters.m_A = a;
1216 data.m_Parameters.m_B = b;
1217 data.m_Parameters.m_Function = f;
1218
1219 armnn::ActivationQueueDescriptor refData = data;
1220 armnn::WorkloadInfo refInfo = info;
1221 SetWorkloadInput(refData, refInfo, 0, inputTensorInfo, inputHandleRef.get());
1222 SetWorkloadOutput(refData, refInfo, 0, outputTensorInfo, outputHandleRef.get());
1223
1224 std::unique_ptr<armnn::IWorkload> workload = workloadFactory.CreateActivation(data, info);
Narumol Prangnawaratac2770a2020-04-01 16:51:23 +01001225 ARMNN_ASSERT(workload != nullptr);
telsoa014fcda012018-03-09 14:13:49 +00001226 std::unique_ptr<armnn::IWorkload> workloadRef = refWorkloadFactory.CreateActivation(refData, refInfo);
Narumol Prangnawaratac2770a2020-04-01 16:51:23 +01001227 ARMNN_ASSERT(workloadRef != nullptr);
telsoa014fcda012018-03-09 14:13:49 +00001228
1229 inputHandle->Allocate();
1230 outputHandle->Allocate();
1231 inputHandleRef->Allocate();
1232 outputHandleRef->Allocate();
1233
1234 CopyDataToITensorHandle(inputHandle.get(), &input[0][0][0][0]);
1235 CopyDataToITensorHandle(inputHandleRef.get(), &input[0][0][0][0]);
1236
1237 workload->Execute();
1238 workloadRef->Execute();
1239
1240 CopyDataFromITensorHandle(&ret.output[0][0][0][0], outputHandle.get());
1241 CopyDataFromITensorHandle(&ret.outputExpected[0][0][0][0], outputHandleRef.get());
1242
1243 return ret;
1244}
1245
Aron Virginas-Tar5caf9072018-11-14 18:35:18 +00001246LayerTestResult<float,4> CompareActivationTest(
1247 armnn::IWorkloadFactory& workloadFactory,
1248 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
1249 armnn::IWorkloadFactory& refWorkloadFactory,
1250 armnn::ActivationFunction f,
1251 unsigned int batchSize)
telsoa014fcda012018-03-09 14:13:49 +00001252{
Nattapat Chaimanowong649dd952019-01-22 16:10:44 +00001253 return CompareActivationTestImpl<armnn::DataType::Float32>(
Aron Virginas-Tar5caf9072018-11-14 18:35:18 +00001254 workloadFactory, memoryManager, refWorkloadFactory, f, batchSize);
telsoa014fcda012018-03-09 14:13:49 +00001255}
1256
Aron Virginas-Tar5caf9072018-11-14 18:35:18 +00001257LayerTestResult<uint8_t,4> CompareActivationUint8Test(
1258 armnn::IWorkloadFactory& workloadFactory,
1259 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
1260 armnn::IWorkloadFactory& refWorkloadFactory,
1261 armnn::ActivationFunction f)
telsoa014fcda012018-03-09 14:13:49 +00001262{
Derek Lambertif90c56d2020-01-10 17:14:08 +00001263 return CompareActivationTestImpl<armnn::DataType::QAsymmU8>(
Aron Virginas-Tar5caf9072018-11-14 18:35:18 +00001264 workloadFactory, memoryManager, refWorkloadFactory, f, 5, 0.1f, 50);
telsoa014fcda012018-03-09 14:13:49 +00001265}
Teresa Charlin18515e22019-04-24 10:17:46 +01001266
1267LayerTestResult<int16_t,4> CompareActivationInt16Test(
1268 armnn::IWorkloadFactory& workloadFactory,
1269 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
1270 armnn::IWorkloadFactory& refWorkloadFactory,
1271 armnn::ActivationFunction f)
1272{
Derek Lambertif90c56d2020-01-10 17:14:08 +00001273 return CompareActivationTestImpl<armnn::DataType::QSymmS16>(
Teresa Charlin18515e22019-04-24 10:17:46 +01001274 workloadFactory, memoryManager, refWorkloadFactory, f, 5, 0.1f, 0);
1275}