1 //
2 // Copyright © 2020, 2023 Arm Ltd and Contributors. All rights reserved.
3 // SPDX-License-Identifier: MIT
4 //
5
6 #include "ActivationTestHelper.hpp"
7
8 #include <armnn_delegate.hpp>
9
10 #include <flatbuffers/flatbuffers.h>
11 #include <tensorflow/lite/interpreter.h>
12 #include <schema_generated.h>
13
14 #include <doctest/doctest.h>
15
16 namespace armnnDelegate
17 {
18
19
ActivationReLuTest(std::vector<armnn::BackendId> & backends)20 void ActivationReLuTest(std::vector<armnn::BackendId>& backends)
21 {
22 std::vector<float> inputData = {
23 -0.1f, -0.2f, -0.3f, -0.4f,
24 0.1f, 0.2f, 0.3f, 0.4f,
25 -1.0f, -2.0f, -3.0f, -4.0f,
26 1.0f, 2.0f, 3.0f, 4.0f
27 };
28
29 // Calculate output values for input.
30 auto f = [](float value)
31 {
32 return std::fmax(0.0f, value);
33 };
34 std::vector<float> outputExpectedData(inputData.size());
35 std::transform(inputData.begin(), inputData.end(), outputExpectedData.begin(), f);
36
37 ActivationTest(tflite::BuiltinOperator_RELU,
38 backends,
39 inputData,
40 outputExpectedData);
41 }
42
ActivationBoundedReluTest(std::vector<armnn::BackendId> & backends)43 void ActivationBoundedReluTest(std::vector<armnn::BackendId>& backends)
44 {
45 std::vector<float> inputData = {
46 -0.1f, -0.2f, -0.3f, -0.4f,
47 0.1f, 0.2f, 0.3f, 0.4f,
48 -1.0f, -2.0f, -3.0f, -4.0f,
49 1.0f, 2.0f, 3.0f, 4.0f
50 };
51
52 const float a = 6.0f;
53 const float b = 0.0f;
54 // Calculate output values for input.
55 auto f = [a, b](float value)
56 {
57 return std::min(a, std::max(b, value));
58 };
59 std::vector<float> outputExpectedData(inputData.size());
60 std::transform(inputData.begin(), inputData.end(), outputExpectedData.begin(), f);
61
62 ActivationTest(tflite::BuiltinOperator_RELU6,
63 backends,
64 inputData,
65 outputExpectedData);
66 }
67
ActivationSigmoidTest(std::vector<armnn::BackendId> & backends)68 void ActivationSigmoidTest(std::vector<armnn::BackendId>& backends)
69 {
70 std::vector<float> inputData = {
71 -0.1f, -0.2f, -0.3f, -0.4f,
72 0.1f, 0.2f, 0.3f, 0.4f,
73 -1.0f, -2.0f, -3.0f, -4.0f,
74 1.0f, 2.0f, 3.0f, 4.0f
75 };
76
77 // Calculate output values for input.
78 auto f = [](float value)
79 {
80 return 1.0f / (1.0f + std::exp(-value));
81 };
82 std::vector<float> outputExpectedData(inputData.size());
83 std::transform(inputData.begin(), inputData.end(), outputExpectedData.begin(), f);
84
85 ActivationTest(tflite::BuiltinOperator_LOGISTIC,
86 backends,
87 inputData,
88 outputExpectedData);
89 }
90
91
ActivationTanHTest(std::vector<armnn::BackendId> & backends)92 void ActivationTanHTest(std::vector<armnn::BackendId>& backends)
93 {
94 std::vector<float> inputData = {
95 -0.1f, -0.2f, -0.3f, -0.4f,
96 0.1f, 0.2f, 0.3f, 0.4f,
97 -1.0f, -2.0f, -3.0f, -4.0f,
98 1.0f, 2.0f, 3.0f, 4.0f
99 };
100
101 // Calculate output values for input.
102 auto f = [](float value)
103 {
104 return tanhf(value);
105 };
106 std::vector<float> outputExpectedData(inputData.size());
107 std::transform(inputData.begin(), inputData.end(), outputExpectedData.begin(), f);
108
109 ActivationTest(tflite::BuiltinOperator_TANH,
110 backends,
111 inputData,
112 outputExpectedData);
113 }
114
ActivationEluTest(std::vector<armnn::BackendId> & backends)115 void ActivationEluTest(std::vector<armnn::BackendId>& backends)
116 {
117 std::vector<float> inputData = {
118 -0.1f, -0.2f, -0.3f, -0.4f,
119 0.1f, 0.2f, 0.3f, 0.4f,
120 -1.0f, -2.0f, -3.0f, -4.0f,
121 1.0f, 2.0f, 3.0f, 4.0f
122 };
123
124 // Calculate output values for input.
125 auto f = [](float value)
126 {
127 if (value < 0)
128 {
129 // alpha * (exp(x) - 1)
130 return 1 * (std::exp(value) - 1);
131 }
132 return value;
133 };
134 std::vector<float> outputExpectedData(inputData.size());
135 std::transform(inputData.begin(), inputData.end(), outputExpectedData.begin(), f);
136
137 ActivationTest(tflite::BuiltinOperator_ELU,
138 backends,
139 inputData,
140 outputExpectedData);
141 }
142
ActivationHardSwishTest(std::vector<armnn::BackendId> & backends)143 void ActivationHardSwishTest(std::vector<armnn::BackendId>& backends)
144 {
145 std::vector<float> inputData = {
146 -0.1f, -0.2f, -0.3f, -0.4f,
147 0.1f, 0.2f, 0.3f, 0.4f,
148 -1.0f, -2.0f, -3.0f, -4.0f,
149 1.0f, 2.0f, 3.0f, 4.0f
150 };
151
152 // Calculate output values for input.
153 auto f = [](float x)
154 {
155 // Break down the calculation to help with verification.
156 // hard_swish(x) = x * relu6(x+3) / 6
157 // relu6(x) = min(max(x,0),6)
158 float reLu6_step1 = std::max((x + 3),0.0f);
159 float reLu6Complete = std::min(reLu6_step1, 6.0f);
160 float hardSwish_step1 = x * reLu6Complete;
161 float result = hardSwish_step1 / 6;
162 return result;
163 };
164 std::vector<float> outputExpectedData(inputData.size());
165 std::transform(inputData.begin(), inputData.end(), outputExpectedData.begin(), f);
166
167 ActivationTest(tflite::BuiltinOperator_HARD_SWISH,
168 backends,
169 inputData,
170 outputExpectedData);
171 }
172
173 TEST_SUITE("Activation_CpuRefTests")
174 {
175
176 TEST_CASE ("Activation_ReLu_CpuRef_Test")
177 {
178 std::vector<armnn::BackendId> backends = { armnn::Compute::CpuRef };
179 ActivationReLuTest(backends);
180 }
181
182 TEST_CASE ("Activation_Bounded_Relu6_CpuRef_Test")
183 {
184 std::vector<armnn::BackendId> backends = { armnn::Compute::CpuRef };
185 ActivationBoundedReluTest(backends);
186 }
187
188 TEST_CASE ("Activation_Sigmoid_CpuRef_Test")
189 {
190 std::vector<armnn::BackendId> backends = { armnn::Compute::CpuRef };
191 ActivationSigmoidTest(backends);
192 }
193
194 TEST_CASE ("Activation_TanH_CpuRef_Test")
195 {
196 std::vector<armnn::BackendId> backends = { armnn::Compute::CpuRef };
197 ActivationTanHTest(backends);
198 }
199
200 TEST_CASE ("Activation_Elu_CpuRef_Test")
201 {
202 std::vector<armnn::BackendId> backends = { armnn::Compute::CpuRef };
203 ActivationEluTest(backends);
204 }
205
206 TEST_CASE ("Activation_HardSwish_CpuRef_Test")
207 {
208 std::vector<armnn::BackendId> backends = { armnn::Compute::CpuRef };
209 ActivationHardSwishTest(backends);
210 }
211
212 }
213
214 TEST_SUITE("Activation_CpuAccTests")
215 {
216
217 TEST_CASE ("Activation_ReLu_CpuAcc_Test")
218 {
219 std::vector<armnn::BackendId> backends = { armnn::Compute::CpuAcc };
220 ActivationReLuTest(backends);
221 }
222
223 TEST_CASE ("Activation_Bounded_Relu6_CpuAcc_Test")
224 {
225 std::vector<armnn::BackendId> backends = { armnn::Compute::CpuAcc };
226 ActivationBoundedReluTest(backends);
227 }
228
229 TEST_CASE ("Activation_Sigmoid_CpuAcc_Test")
230 {
231 std::vector<armnn::BackendId> backends = { armnn::Compute::CpuAcc };
232 ActivationSigmoidTest(backends);
233 }
234
235 TEST_CASE ("Activation_TanH_CpuAcc_Test")
236 {
237 std::vector<armnn::BackendId> backends = { armnn::Compute::CpuAcc };
238 ActivationTanHTest(backends);
239 }
240
241 TEST_CASE ("Activation_Elu_CpuAcc_Test")
242 {
243 std::vector<armnn::BackendId> backends = { armnn::Compute::CpuAcc };
244 ActivationEluTest(backends);
245 }
246
247 TEST_CASE ("Activation_HardSwish_CpuAcc_Test")
248 {
249 std::vector<armnn::BackendId> backends = { armnn::Compute::CpuAcc };
250 ActivationHardSwishTest(backends);
251 }
252
253 }
254
255 TEST_SUITE("Activation_GpuAccTests")
256 {
257
258 TEST_CASE ("Activation_ReLu_GpuAcc_Test")
259 {
260 std::vector<armnn::BackendId> backends = { armnn::Compute::GpuAcc };
261 ActivationReLuTest(backends);
262 }
263
264 TEST_CASE ("Activation_Bounded_Relu6_GpuAcc_Test")
265 {
266 std::vector<armnn::BackendId> backends = { armnn::Compute::GpuAcc };
267 ActivationBoundedReluTest(backends);
268 }
269
270 TEST_CASE ("Activation_Sigmoid_GpuAcc_Test")
271 {
272 std::vector<armnn::BackendId> backends = { armnn::Compute::GpuAcc };
273 ActivationSigmoidTest(backends);
274 }
275
276 TEST_CASE ("Activation_TanH_GpuAcc_Test")
277 {
278 std::vector<armnn::BackendId> backends = { armnn::Compute::GpuAcc };
279 ActivationTanHTest(backends);
280 }
281
282 TEST_CASE ("Activation_Elu_GpuAcc_Test")
283 {
284 std::vector<armnn::BackendId> backends = { armnn::Compute::GpuAcc };
285 ActivationEluTest(backends);
286 }
287
288 TEST_CASE ("Activation_HardSwish_GpuAcc_Test")
289 {
290 std::vector<armnn::BackendId> backends = { armnn::Compute::GpuAcc };
291 ActivationHardSwishTest(backends);
292 }
293
294 }
295
296 } // namespace armnnDelegate