blob: 0a60658b47404ccd85a038b9dff8d6f964fc4475 [file] [log] [blame]
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001//
Teresa Charlinfbf0e5b2020-08-17 01:01:06 +01002// Copyright © 2017 Arm Ltd and Contributors. All rights reserved.
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01003// SPDX-License-Identifier: MIT
4//
5
6#include "L2NormalizationTestImpl.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>
Matteo Martincighe011d202019-11-28 11:35:47 +000010
11#include <armnnUtils/TensorUtils.hpp>
12#include <armnnUtils/Permute.hpp>
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +010013
Sadik Armagana097d2a2021-11-24 15:47:28 +000014#include <armnnTestUtils/TensorCopyUtils.hpp>
Colm Donelan0c479742021-12-10 12:43:54 +000015#include <armnnTestUtils/WorkloadTestUtils.hpp>
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +010016
Sadik Armagana097d2a2021-11-24 15:47:28 +000017#include <TensorHelpers.hpp>
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +010018
Rob Hughesc013bc82021-07-14 09:31:31 +010019#include <numeric>
20
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +010021namespace
22{
23
24template<armnn::DataType ArmnnType, typename T = armnn::ResolveType<ArmnnType>>
25LayerTestResult<T, 4> L2NormalizationTestImpl(
26 armnn::IWorkloadFactory& workloadFactory,
27 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
Finn Williamsc43de6a2020-08-27 11:13:25 +010028 const armnn::ITensorHandleFactory& tensorHandleFactory,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +010029 const armnn::TensorShape& inputOutputTensorShape,
30 float scale,
31 int32_t offset,
32 const std::vector<float>& inputValues,
33 float outScale,
34 int32_t outOffset,
Sadik Armagan483c8112021-06-01 09:24:52 +010035 std::vector<float>& expectedOutputValues,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +010036 const armnn::DataLayout layout,
37 float epsilon = 1e-12f)
38{
Jan Eilers8eb25602020-03-09 12:13:48 +000039 IgnoreUnused(memoryManager);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +010040 const armnn::TensorInfo inputTensorInfo(inputOutputTensorShape, ArmnnType, scale, offset);
41 const armnn::TensorInfo outputTensorInfo(inputOutputTensorShape, ArmnnType, outScale, outOffset);
42
43 // at this point if we require it permute the input data
44 const armnn::PermutationVector NCHWToNHWC = { 0, 3, 1, 2 };
45 std::vector<float> inputData = inputValues;
46 if (layout == armnn::DataLayout::NHWC)
47 {
48 std::vector<float> tmp(inputData.size());
49 armnnUtils::Permute(inputTensorInfo.GetShape(), NCHWToNHWC, inputData.data(), tmp.data(), sizeof(float));
50 inputData = tmp;
51 }
52
Sadik Armagan483c8112021-06-01 09:24:52 +010053 auto inputTensor = armnnUtils::QuantizedVector<T>(inputData,
54 inputTensorInfo.GetQuantizationScale(),
55 inputTensorInfo.GetQuantizationOffset());
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +010056
Sadik Armagan483c8112021-06-01 09:24:52 +010057 std::vector<T> actualOutput(outputTensorInfo.GetNumElements());
58
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +010059 if (layout == armnn::DataLayout::NHWC)
60 {
Sadik Armagan483c8112021-06-01 09:24:52 +010061 std::vector<float> tmp(expectedOutputValues.size());
62 armnnUtils::Permute(inputTensorInfo.GetShape(), NCHWToNHWC, expectedOutputValues.data(), tmp.data(),
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +010063 sizeof(float));
Sadik Armagan483c8112021-06-01 09:24:52 +010064 expectedOutputValues = tmp;
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +010065 }
66
Sadik Armagan483c8112021-06-01 09:24:52 +010067 std::vector<T> expectedOutputData = armnnUtils::QuantizedVector<T>(expectedOutputValues,
68 outputTensorInfo.GetQuantizationScale(),
69 outputTensorInfo.GetQuantizationOffset());
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +010070
Finn Williamsc43de6a2020-08-27 11:13:25 +010071 std::unique_ptr<armnn::ITensorHandle> inputHandle = tensorHandleFactory.CreateTensorHandle(inputTensorInfo);
72 std::unique_ptr<armnn::ITensorHandle> outputHandle = tensorHandleFactory.CreateTensorHandle(outputTensorInfo);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +010073
74 armnn::L2NormalizationQueueDescriptor descriptor;
75 descriptor.m_Parameters.m_Eps = epsilon;
76 descriptor.m_Parameters.m_DataLayout = layout;
77 armnn::WorkloadInfo info;
78
79 AddInputToWorkload(descriptor, info, inputTensorInfo, inputHandle.get());
80 AddOutputToWorkload(descriptor, info, outputTensorInfo, outputHandle.get());
81
Teresa Charlin611c7fb2022-01-07 09:47:29 +000082 std::unique_ptr<armnn::IWorkload> workload = workloadFactory.CreateWorkload(armnn::LayerType::L2Normalization,
83 descriptor,
84 info);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +010085
86 inputHandle->Allocate();
87 outputHandle->Allocate();
88
Sadik Armagan483c8112021-06-01 09:24:52 +010089 CopyDataToITensorHandle(inputHandle.get(), inputTensor.data());
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +010090
91 workload->PostAllocationConfigure();
92 ExecuteWorkload(*workload, memoryManager);
93
Sadik Armagan483c8112021-06-01 09:24:52 +010094 CopyDataFromITensorHandle(actualOutput.data(), outputHandle.get());
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +010095
Sadik Armagan483c8112021-06-01 09:24:52 +010096 return LayerTestResult<T, 4>(actualOutput,
97 expectedOutputData,
98 outputHandle->GetShape(),
99 outputTensorInfo.GetShape());
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100100}
101
102float CalcInvL2Norm(std::initializer_list<float> elements)
103{
104 const float reduction = std::accumulate(elements.begin(), elements.end(), 0.0f,
105 [](float acc, float element) { return acc + element * element; });
106 return 1.0f / sqrtf(reduction);
107}
108
109template<armnn::DataType ArmnnType, typename T = armnn::ResolveType<ArmnnType>>
110LayerTestResult<T, 4> L2NormalizationEpsilonTestCommon(
111 armnn::IWorkloadFactory& workloadFactory,
112 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
Finn Williamsc43de6a2020-08-27 11:13:25 +0100113 const armnn::ITensorHandleFactory& tensorHandleFactory,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100114 float scale,
115 int32_t offset,
116 float outScale,
117 int32_t outOffset,
118 const armnn::DataLayout layout,
119 float epsilon)
120{
121 // Width: 1
122 // Height: 1
123 // Channels: 3
124 // BatchSize: 1
125 unsigned int numberOfBatches = 1;
126 unsigned int numberOfChannels = 3;
127 unsigned int height = 1;
128 unsigned int width = 1;
129
130 const armnn::TensorShape inputOutputShape = armnnUtils::GetTensorShape(
131 numberOfBatches, numberOfChannels, height, width, layout);
132
133 // 0.0000001^2 + 0.00000002^2 + 0.00000003^2 < 1e-12
134 std::vector<float> inputValues
135 {
136 // Batch 0, Channel 0, Height (1) x Width (1)
137 0.00000001f,
138
139 // Batch 0, Channel 1, Height (1) x Width (1)
140 0.00000002f,
141
142 // Batch 0, Channel 2, Height (1) x Width (1)
143 0.00000003f,
144 };
145
146 const float approxInvL2Norm = 1.f / sqrtf(epsilon);
147 std::vector<float> expectedOutputValues
148 {
149 // Batch 0, Channel 0, Height (1) x Width (1)
150 0.00000001f * approxInvL2Norm,
151 0.00000002f * approxInvL2Norm,
152 0.00000003f * approxInvL2Norm,
153 };
154
155 return L2NormalizationTestImpl<ArmnnType>(
156 workloadFactory,
157 memoryManager,
Finn Williamsc43de6a2020-08-27 11:13:25 +0100158 tensorHandleFactory,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100159 inputOutputShape,
160 scale,
161 offset,
162 inputValues,
163 outScale,
164 outOffset,
165 expectedOutputValues,
166 layout,
167 epsilon);
168}
169
170
171template<armnn::DataType ArmnnType, typename T = armnn::ResolveType<ArmnnType>>
172LayerTestResult<T, 4> L2Normalization1dTestCommon(
173 armnn::IWorkloadFactory& workloadFactory,
174 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
Finn Williamsc43de6a2020-08-27 11:13:25 +0100175 const armnn::ITensorHandleFactory& tensorHandleFactory,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100176 float scale,
177 int32_t offset,
178 float outScale,
179 int32_t outOffset,
180 const armnn::DataLayout layout)
181{
182 // Width: 1
183 // Height: 1
184 // Channels: 10
185 // BatchSize: 1
186 unsigned int numberOfBatches = 1;
187 unsigned int numberOfChannels = 10;
188 unsigned int height = 1;
189 unsigned int width = 1;
190
191
192 const armnn::TensorShape inputOutputShape = armnnUtils::GetTensorShape(
193 numberOfBatches, numberOfChannels, height, width, layout);
194 std::vector<float> inputValues
195 {
196 // Batch 0, Channel 0, Height (1) x Width (1)
197 1.0f,
198
199 // Batch 0, Channel 1, Height (1) x Width (1)
200 2.0f,
201
202 // Batch 0, Channel 2, Height (1) x Width (1)
203 3.0f,
204
205 // Batch 0, Channel 3, Height (1) x Width (1)
206 4.0f,
207
208 // Batch 0, Channel 4, Height (1) x Width (1)
209 5.0f,
210
211 // Batch 0, Channel 5, Height (1) x Width (1)
212 6.0f,
213
214 // Batch 0, Channel 6, Height (1) x Width (1)
215 7.0f,
216
217 // Batch 0, Channel 7, Height (1) x Width (1)
218 8.0f,
219
220 // Batch 0, Channel 8, Height (1) x Width (1)
221 9.0f,
222
223 // Batch 0, Channel 9, Height (1) x Width (1)
224 10.0f
225 };
226 const float approxInvL2Norm = 0.050964719f;
227 std::vector<float> expectedOutputValues
228 {
229 // Batch 0, Channel 0, Height (1) x Width (1)
230 1.0f * approxInvL2Norm,
231 2.0f * approxInvL2Norm,
232 3.0f * approxInvL2Norm,
233 4.0f * approxInvL2Norm,
234 5.0f * approxInvL2Norm,
235 6.0f * approxInvL2Norm,
236 7.0f * approxInvL2Norm,
237 8.0f * approxInvL2Norm,
238 9.0f * approxInvL2Norm,
239 10.0f * approxInvL2Norm
240 };
241
242
243 return L2NormalizationTestImpl<ArmnnType>(
244 workloadFactory,
245 memoryManager,
Finn Williamsc43de6a2020-08-27 11:13:25 +0100246 tensorHandleFactory,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100247 inputOutputShape,
248 scale,
249 offset,
250 inputValues,
251 outScale,
252 outOffset,
253 expectedOutputValues,
254 layout);
255}
256
257template<armnn::DataType ArmnnType, typename T = armnn::ResolveType<ArmnnType>>
258LayerTestResult<T, 4> L2Normalization2dTestCommon(
259 armnn::IWorkloadFactory& workloadFactory,
260 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
Finn Williamsc43de6a2020-08-27 11:13:25 +0100261 const armnn::ITensorHandleFactory& tensorHandleFactory,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100262 float scale,
263 int32_t offset,
264 float outScale,
265 int32_t outOffset,
266 const armnn::DataLayout layout)
267{
268 // Width: 5
269 // Height: 1
270 // Channels: 2
271 // BatchSize: 1
272 unsigned int numberOfBatches = 1;
273 unsigned int numberOfChannels = 2;
274 unsigned int height = 1;
275 unsigned int width = 5;
276
277 const armnn::TensorShape inputOutputShape = armnnUtils::GetTensorShape(
278 numberOfBatches, numberOfChannels, height, width, layout);
279 std::vector<float> inputValues
280 {
281 // Batch 0, Channel 0, Height (1) x Width (5)
282 1.0f, 3.0f, 5.0f, 7.0f, 9.0f,
283
284 // Batch 0, Channel 1, Height (1) x Width (5)
285 2.0f, 4.0f, 6.0f, 8.0f, 10.0f
286 };
287 std::vector<float> expectedOutputValues
288 {
289 // Batch 0, Channel 0, Height (1) x Width (5)
290 1.0f * CalcInvL2Norm({ 1.0f, 2.0f }),
291 3.0f * CalcInvL2Norm({ 3.0f, 4.0f }),
292 5.0f * CalcInvL2Norm({ 5.0f, 6.0f }),
293 7.0f * CalcInvL2Norm({ 7.0f, 8.0f }),
294 9.0f * CalcInvL2Norm({ 9.0f, 10.0f }),
295
296 // Batch 0, Channel 1, Height (1) x Width (5)
297 2.0f * CalcInvL2Norm({ 1.0f, 2.0f }),
298 4.0f * CalcInvL2Norm({ 3.0f, 4.0f }),
299 6.0f * CalcInvL2Norm({ 5.0f, 6.0f }),
300 8.0f * CalcInvL2Norm({ 7.0f, 8.0f }),
301 10.0f * CalcInvL2Norm({ 9.0f, 10.0f })
302 };
303
304 return L2NormalizationTestImpl<ArmnnType>(
305 workloadFactory,
306 memoryManager,
Finn Williamsc43de6a2020-08-27 11:13:25 +0100307 tensorHandleFactory,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100308 inputOutputShape,
309 scale,
310 offset,
311 inputValues,
312 outScale,
313 outOffset,
314 expectedOutputValues,
315 layout);
316}
317
318template<armnn::DataType ArmnnType, typename T = armnn::ResolveType<ArmnnType>>
319LayerTestResult<T, 4> L2Normalization3dTestCommon(
320 armnn::IWorkloadFactory& workloadFactory,
321 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
Finn Williamsc43de6a2020-08-27 11:13:25 +0100322 const armnn::ITensorHandleFactory& tensorHandleFactory,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100323 float scale,
324 int32_t offset,
325 float outScale,
326 int32_t outOffset,
327 const armnn::DataLayout layout)
328{
329 // Width: 3
330 // Height: 4
331 // Channels: 2
332 // BatchSize: 1
333 unsigned int numberOfBatches = 1;
334 unsigned int numberOfChannels = 2;
335 unsigned int height = 4;
336 unsigned int width = 3;
337
338 const armnn::TensorShape inputOutputShape = armnnUtils::GetTensorShape(
339 numberOfBatches, numberOfChannels, height, width, layout);
340 std::vector<float> inputValues
341 {
342 // Batch 0, Channel 0, Height (4) x Width (3)
343 119.0f, 21.0f, 150.0f,
344 149.0f, 32.0f, 179.0f,
345 15.0f, 227.0f, 141.0f,
346 147.0f, 199.0f, 220.0f,
347
348 // Batch 0, Channel 1, Height (4) x Width (3)
349 110.0f, 140.0f, 73.0f,
350 211.0f, 212.0f, 89.0f,
351 24.0f, 138.0f, 188.0f,
352 162.0f, 12.0f, 161.0f
353 };
354 std::vector<float> expectedOutputValues
355 {
356 // Batch 0, Channel 0, Height (4) x Width (3)
357 119.0f * CalcInvL2Norm({ 119.0f, 110.0f }),
358 21.0f * CalcInvL2Norm({ 21.0f, 140.0f }),
359 150.0f * CalcInvL2Norm({ 150.0f, 73.0f }),
360 149.0f * CalcInvL2Norm({ 149.0f, 211.0f }),
361 32.0f * CalcInvL2Norm({ 32.0f, 212.0f }),
362 179.0f * CalcInvL2Norm({ 179.0f, 89.0f }),
363 15.0f * CalcInvL2Norm({ 15.0f, 24.0f }),
364 227.0f * CalcInvL2Norm({ 227.0f, 138.0f }),
365 141.0f * CalcInvL2Norm({ 141.0f, 188.0f }),
366 147.0f * CalcInvL2Norm({ 147.0f, 162.0f }),
367 199.0f * CalcInvL2Norm({ 199.0f, 12.0f }),
368 220.0f * CalcInvL2Norm({ 220.0f, 161.0f }),
369
370 // Batch 0, Channel 1, Height (4) x Width (3)
371 110.0f * CalcInvL2Norm({ 119.0f, 110.0f }),
372 140.0f * CalcInvL2Norm({ 21.0f, 140.0f }),
373 73.0f * CalcInvL2Norm({ 150.0f, 73.0f }),
374 211.0f * CalcInvL2Norm({ 149.0f, 211.0f }),
375 212.0f * CalcInvL2Norm({ 32.0f, 212.0f }),
376 89.0f * CalcInvL2Norm({ 179.0f, 89.0f }),
377 24.0f * CalcInvL2Norm({ 15.0f, 24.0f }),
378 138.0f * CalcInvL2Norm({ 227.0f, 138.0f }),
379 188.0f * CalcInvL2Norm({ 141.0f, 188.0f }),
380 162.0f * CalcInvL2Norm({ 147.0f, 162.0f }),
381 12.0f * CalcInvL2Norm({ 199.0f, 12.0f }),
382 161.0f * CalcInvL2Norm({ 220.0f, 161.0f })
383 };
384
385 return L2NormalizationTestImpl<ArmnnType>(
386 workloadFactory,
387 memoryManager,
Finn Williamsc43de6a2020-08-27 11:13:25 +0100388 tensorHandleFactory,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100389 inputOutputShape,
390 scale,
391 offset,
392 inputValues,
393 outScale,
394 outOffset,
395 expectedOutputValues,
396 layout);
397}
398
399template<armnn::DataType ArmnnType, typename T = armnn::ResolveType<ArmnnType>>
400LayerTestResult<T, 4> L2Normalization4dTestCommon(
401 armnn::IWorkloadFactory& workloadFactory,
402 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
Finn Williamsc43de6a2020-08-27 11:13:25 +0100403 const armnn::ITensorHandleFactory& tensorHandleFactory,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100404 float scale,
405 int32_t offset,
406 float outScale,
407 int32_t outOffset,
408 const armnn::DataLayout layout)
409{
410 // Width: 3
411 // Height: 4
412 // Channels: 3
413 // BatchSize: 2
414 unsigned int numberOfBatches = 2;
415 unsigned int numberOfChannels = 3;
416 unsigned int height = 4;
417 unsigned int width = 3;
418
419 const armnn::TensorShape inputOutputShape = armnnUtils::GetTensorShape(
420 numberOfBatches, numberOfChannels, height, width, layout);
421 std::vector<float> inputValues
422 {
423 // Batch 0, Channel 0, Height (4) x Width (3)
424 235.0f, 46.0f, 178.0f,
425 100.0f, 123.0f, 19.0f,
426 172.0f, 74.0f, 250.0f,
427 6.0f, 195.0f, 80.0f,
428
429 // Batch 0, Channel 1, Height (4) x Width (3)
430 113.0f, 95.0f, 202.0f,
431 77.0f, 114.0f, 71.0f,
432 122.0f, 246.0f, 166.0f,
433 82.0f, 28.0f, 37.0f,
434
435 // Batch 0, Channel 2, Height (4) x Width (3)
436 56.0f, 170.0f, 162.0f,
437 194.0f, 89.0f, 254.0f,
438 12.0f, 209.0f, 200.0f,
439 1.0f, 64.0f, 54.0f,
440
441 // Batch 1, Channel 0, Height (4) x Width (3)
442 67.0f, 90.0f, 49.0f,
443 7.0f, 163.0f, 18.0f,
444 25.0f, 117.0f, 103.0f,
445 247.0f, 59.0f, 189.0f,
446
447 // Batch 1, Channel 1, Height (4) x Width (3)
448 239.0f, 104.0f, 199.0f,
449 17.0f, 124.0f, 153.0f,
450 222.0f, 217.0f, 75.0f,
451 32.0f, 126.0f, 21.0f,
452
453 // Batch 1, Channel 2, Height (4) x Width (3)
454 97.0f, 145.0f, 215.0f,
455 115.0f, 116.0f, 238.0f,
456 226.0f, 16.0f, 132.0f,
457 92.0f, 125.0f, 88.0f
458 };
459 std::vector<float> expectedOutputValues
460 {
461 // Batch 0, Channel 0, Height (4) x Width (3)
462 235.0f * CalcInvL2Norm({ 235.0f, 113.0f, 56.0f }),
463 46.0f * CalcInvL2Norm({ 46.0f, 95.0f, 170.0f }),
464 178.0f * CalcInvL2Norm({ 178.0f, 202.0F, 162.0f }),
465 100.0f * CalcInvL2Norm({ 100.0f, 77.0f, 194.0f }),
466 123.0f * CalcInvL2Norm({ 123.0f, 114.0f, 89.0f }),
467 19.0f * CalcInvL2Norm({ 19.0f, 71.0f, 254.0f }),
468 172.0f * CalcInvL2Norm({ 172.0f, 122.0f, 12.0f }),
469 74.0f * CalcInvL2Norm({ 74.0f, 246.0f, 209.0f }),
470 250.0f * CalcInvL2Norm({ 250.0f, 166.0f, 200.0f }),
471 6.0f * CalcInvL2Norm({ 6.0f, 82.0f, 1.0f }),
472 195.0f * CalcInvL2Norm({ 195.0f, 28.0f, 64.0f }),
473 80.0f * CalcInvL2Norm({ 80.0f, 37.0f, 54.0f }),
474
475 // Batch 0, Channel 1, Height (4) x Width (3)
476 113.0f * CalcInvL2Norm({ 235.0f, 113.0f, 56.0f }),
477 95.0f * CalcInvL2Norm({ 46.0f, 95.0f, 170.0f }),
478 202.0f * CalcInvL2Norm({ 178.0f, 202.0F, 162.0f }),
479 77.0f * CalcInvL2Norm({ 100.0f, 77.0f, 194.0f }),
480 114.0f * CalcInvL2Norm({ 123.0f, 114.0f, 89.0f }),
481 71.0f * CalcInvL2Norm({ 19.0f, 71.0f, 254.0f }),
482 122.0f * CalcInvL2Norm({ 172.0f, 122.0f, 12.0f }),
483 246.0f * CalcInvL2Norm({ 74.0f, 246.0f, 209.0f }),
484 166.0f * CalcInvL2Norm({ 250.0f, 166.0f, 200.0f }),
485 82.0f * CalcInvL2Norm({ 6.0f, 82.0f, 1.0f }),
486 28.0f * CalcInvL2Norm({ 195.0f, 28.0f, 64.0f }),
487 37.0f * CalcInvL2Norm({ 80.0f, 37.0f, 54.0f }),
488
489 // Batch 0, Channel 2, Height (4) x Width (3)
490 56.0f * CalcInvL2Norm({ 235.0f, 113.0f, 56.0f }),
491 170.0f * CalcInvL2Norm({ 46.0f, 95.0f, 170.0f }),
492 162.0f * CalcInvL2Norm({ 178.0f, 202.0F, 162.0f }),
493 194.0f * CalcInvL2Norm({ 100.0f, 77.0f, 194.0f }),
494 89.0f * CalcInvL2Norm({ 123.0f, 114.0f, 89.0f }),
495 254.0f * CalcInvL2Norm({ 19.0f, 71.0f, 254.0f }),
496 12.0f * CalcInvL2Norm({ 172.0f, 122.0f, 12.0f }),
497 209.0f * CalcInvL2Norm({ 74.0f, 246.0f, 209.0f }),
498 200.0f * CalcInvL2Norm({ 250.0f, 166.0f, 200.0f }),
499 1.0f * CalcInvL2Norm({ 6.0f, 82.0f, 1.0f }),
500 64.0f * CalcInvL2Norm({ 195.0f, 28.0f, 64.0f }),
501 54.0f * CalcInvL2Norm({ 80.0f, 37.0f, 54.0f }),
502
503 // Batch 1, Channel 0, Height (4) x Width (3)
504 67.0f * CalcInvL2Norm({ 67.0f, 239.0f, 97.0f }),
505 90.0f * CalcInvL2Norm({ 90.0f, 104.0f, 145.0f }),
506 49.0f * CalcInvL2Norm({ 49.0f, 199.0f, 215.0f }),
507 7.0f * CalcInvL2Norm({ 7.0f, 17.0f, 115.0f }),
508 163.0f * CalcInvL2Norm({ 163.0f, 124.0f, 116.0f }),
509 18.0f * CalcInvL2Norm({ 18.0f, 153.0f, 238.0f }),
510 25.0f * CalcInvL2Norm({ 25.0f, 222.0f, 226.0f }),
511 117.0f * CalcInvL2Norm({ 117.0f, 217.0f, 16.0f }),
512 103.0f * CalcInvL2Norm({ 103.0f, 75.0f, 132.0f }),
513 247.0f * CalcInvL2Norm({ 247.0f, 32.0f, 92.0f }),
514 59.0f * CalcInvL2Norm({ 59.0f, 126.0f, 125.0f }),
515 189.0f * CalcInvL2Norm({ 189.0f, 21.0f, 88.0f }),
516
517 // Batch 1, Channel 1, Height (4) x Width (3)
518 239.0f * CalcInvL2Norm({ 67.0f, 239.0f, 97.0f }),
519 104.0f * CalcInvL2Norm({ 90.0f, 104.0f, 145.0f }),
520 199.0f * CalcInvL2Norm({ 49.0f, 199.0f, 215.0f }),
521 17.0f * CalcInvL2Norm({ 7.0f, 17.0f, 115.0f }),
522 124.0f * CalcInvL2Norm({ 163.0f, 124.0f, 116.0f }),
523 153.0f * CalcInvL2Norm({ 18.0f, 153.0f, 238.0f }),
524 222.0f * CalcInvL2Norm({ 25.0f, 222.0f, 226.0f }),
525 217.0f * CalcInvL2Norm({ 117.0f, 217.0f, 16.0f }),
526 75.0f * CalcInvL2Norm({ 103.0f, 75.0f, 132.0f }),
527 32.0f * CalcInvL2Norm({ 247.0f, 32.0f, 92.0f }),
528 126.0f * CalcInvL2Norm({ 59.0f, 126.0f, 125.0f }),
529 21.0f * CalcInvL2Norm({ 189.0f, 21.0f, 88.0f }),
530
531 // Batch 1, Channel 2, Height (4) x Width (3)
532 97.0f * CalcInvL2Norm({ 67.0f, 239.0f, 97.0f }),
533 145.0f * CalcInvL2Norm({ 90.0f, 104.0f, 145.0f }),
534 215.0f * CalcInvL2Norm({ 49.0f, 199.0f, 215.0f }),
535 115.0f * CalcInvL2Norm({ 7.0f, 17.0f, 115.0f }),
536 116.0f * CalcInvL2Norm({ 163.0f, 124.0f, 116.0f }),
537 238.0f * CalcInvL2Norm({ 18.0f, 153.0f, 238.0f }),
538 226.0f * CalcInvL2Norm({ 25.0f, 222.0f, 226.0f }),
539 16.0f * CalcInvL2Norm({ 117.0f, 217.0f, 16.0f }),
540 132.0f * CalcInvL2Norm({ 103.0f, 75.0f, 132.0f }),
541 92.0f * CalcInvL2Norm({ 247.0f, 32.0f, 92.0f }),
542 125.0f * CalcInvL2Norm({ 59.0f, 126.0f, 125.0f }),
543 88.0f * CalcInvL2Norm({ 189.0f, 21.0f, 88.0f })
544 };
545
546 return L2NormalizationTestImpl<ArmnnType>(
547 workloadFactory,
548 memoryManager,
Finn Williamsc43de6a2020-08-27 11:13:25 +0100549 tensorHandleFactory,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100550 inputOutputShape,
551 scale,
552 offset,
553 inputValues,
554 outScale,
555 outOffset,
556 expectedOutputValues,
557 layout);
558}
559
560} // anonymous namespace
561
562LayerTestResult<float, 4> L2NormalizationDefaultEpsilonTest(
563 armnn::IWorkloadFactory& workloadFactory,
564 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
Finn Williamsc43de6a2020-08-27 11:13:25 +0100565 const armnn::ITensorHandleFactory& tensorHandleFactory,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100566 const armnn::DataLayout layout)
567{
568 // Dummy descriptor to get the default value of epsilon.
569 armnn::L2NormalizationDescriptor descriptor;
570
571 return L2NormalizationEpsilonTestCommon<armnn::DataType::Float32>(
572 workloadFactory,
573 memoryManager,
Finn Williamsc43de6a2020-08-27 11:13:25 +0100574 tensorHandleFactory,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100575 0.f,
576 0,
577 0.f,
578 0,
579 layout,
580 descriptor.m_Eps);
581}
582
583LayerTestResult<float, 4> L2NormalizationNonDefaultEpsilonTest(
584 armnn::IWorkloadFactory& workloadFactory,
585 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
Finn Williamsc43de6a2020-08-27 11:13:25 +0100586 const armnn::ITensorHandleFactory& tensorHandleFactory,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100587 const armnn::DataLayout layout)
588{
589 return L2NormalizationEpsilonTestCommon<armnn::DataType::Float32>(
590 workloadFactory,
591 memoryManager,
Finn Williamsc43de6a2020-08-27 11:13:25 +0100592 tensorHandleFactory,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100593 0.f,
594 0,
595 0.f,
596 0,
597 layout,
598 1e-9f);
599}
600
601LayerTestResult<float, 4> L2Normalization1dTest(
602 armnn::IWorkloadFactory& workloadFactory,
603 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
Finn Williamsc43de6a2020-08-27 11:13:25 +0100604 const armnn::ITensorHandleFactory& tensorHandleFactory,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100605 const armnn::DataLayout layout)
606{
607 return L2Normalization1dTestCommon<armnn::DataType::Float32>(
608 workloadFactory,
609 memoryManager,
Finn Williamsc43de6a2020-08-27 11:13:25 +0100610 tensorHandleFactory,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100611 0.f,
612 0,
613 0.f,
614 0,
615 layout);
616}
617
618LayerTestResult<int16_t, 4> L2Normalization1dInt16Test(
619 armnn::IWorkloadFactory& workloadFactory,
620 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
Finn Williamsc43de6a2020-08-27 11:13:25 +0100621 const armnn::ITensorHandleFactory& tensorHandleFactory,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100622 const armnn::DataLayout layout)
623{
Derek Lambertif90c56d2020-01-10 17:14:08 +0000624 return L2Normalization1dTestCommon<armnn::DataType::QSymmS16>(
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100625 workloadFactory,
626 memoryManager,
Finn Williamsc43de6a2020-08-27 11:13:25 +0100627 tensorHandleFactory,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100628 1.f,
629 0,
630 1.f,
631 0,
632 layout);
633}
634
635LayerTestResult<uint8_t, 4> L2Normalization1dUint8Test(
636 armnn::IWorkloadFactory& workloadFactory,
637 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
Finn Williamsc43de6a2020-08-27 11:13:25 +0100638 const armnn::ITensorHandleFactory& tensorHandleFactory,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100639 const armnn::DataLayout layout)
640{
Derek Lambertif90c56d2020-01-10 17:14:08 +0000641 return L2Normalization1dTestCommon<armnn::DataType::QAsymmU8>(
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100642 workloadFactory,
643 memoryManager,
Finn Williamsc43de6a2020-08-27 11:13:25 +0100644 tensorHandleFactory,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100645 1.f,
646 0,
647 1.f / 128,
648 128,
649 layout);
650}
651
652LayerTestResult<float, 4> L2Normalization2dTest(
653 armnn::IWorkloadFactory& workloadFactory,
654 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
Finn Williamsc43de6a2020-08-27 11:13:25 +0100655 const armnn::ITensorHandleFactory& tensorHandleFactory,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100656 const armnn::DataLayout layout)
657{
658 return L2Normalization2dTestCommon<armnn::DataType::Float32>(
659 workloadFactory,
660 memoryManager,
Finn Williamsc43de6a2020-08-27 11:13:25 +0100661 tensorHandleFactory,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100662 0.f,
663 0,
664 0.f,
665 0,
666 layout);
667}
668
669LayerTestResult<int16_t, 4> L2Normalization2dInt16Test(
670 armnn::IWorkloadFactory& workloadFactory,
671 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
Finn Williamsc43de6a2020-08-27 11:13:25 +0100672 const armnn::ITensorHandleFactory& tensorHandleFactory,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100673 const armnn::DataLayout layout)
674{
Derek Lambertif90c56d2020-01-10 17:14:08 +0000675 return L2Normalization1dTestCommon<armnn::DataType::QSymmS16>(
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100676 workloadFactory,
677 memoryManager,
Finn Williamsc43de6a2020-08-27 11:13:25 +0100678 tensorHandleFactory,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100679 1.f,
680 0,
681 1.f,
682 0,
683 layout);
684}
685
686LayerTestResult<uint8_t, 4> L2Normalization2dUint8Test(
687 armnn::IWorkloadFactory& workloadFactory,
688 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
Finn Williamsc43de6a2020-08-27 11:13:25 +0100689 const armnn::ITensorHandleFactory& tensorHandleFactory,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100690 const armnn::DataLayout layout)
691{
Derek Lambertif90c56d2020-01-10 17:14:08 +0000692 return L2Normalization1dTestCommon<armnn::DataType::QAsymmU8>(
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100693 workloadFactory,
694 memoryManager,
Finn Williamsc43de6a2020-08-27 11:13:25 +0100695 tensorHandleFactory,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100696 1.f,
697 0,
698 1.f / 128,
699 128,
700 layout);
701}
702
703LayerTestResult<float, 2> L2Normalization2dShapeTest(
704 armnn::IWorkloadFactory& workloadFactory,
Finn Williamsc43de6a2020-08-27 11:13:25 +0100705 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
706 const armnn::ITensorHandleFactory& tensorHandleFactory)
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100707{
708 const armnn::DataLayout layout = armnn::DataLayout::NHWC;
709 const armnn::TensorShape inputOutputTensorShape = armnn::TensorShape({ 5, 2 });
710
711 std::vector<float> inputData
712 {
713 1.f, 2.f, 3.f, 4.f, 5.f, 6.f, 7.f, 8.f, 9.f, 10.f
714 };
715 std::vector<float> expectedOutputData
716 {
717 1.0f * CalcInvL2Norm({ 1.0f, 2.0f }),
718 2.0f * CalcInvL2Norm({ 1.0f, 2.0f }),
719 3.0f * CalcInvL2Norm({ 3.0f, 4.0f }),
720 4.0f * CalcInvL2Norm({ 3.0f, 4.0f }),
721 5.0f * CalcInvL2Norm({ 5.0f, 6.0f }),
722 6.0f * CalcInvL2Norm({ 5.0f, 6.0f }),
723 7.0f * CalcInvL2Norm({ 7.0f, 8.0f }),
724 8.0f * CalcInvL2Norm({ 7.0f, 8.0f }),
725 9.0f * CalcInvL2Norm({ 9.0f, 10.0f }),
726 10.0f * CalcInvL2Norm({ 9.0f, 10.0f })
727 };
728
729 const armnn::TensorInfo inputTensorInfo(inputOutputTensorShape, armnn::DataType::Float32, 0.f, 0);
730 const armnn::TensorInfo outputTensorInfo(inputOutputTensorShape, armnn::DataType::Float32, 0.f, 0);
731
Sadik Armagan483c8112021-06-01 09:24:52 +0100732 std::vector<float> actualOutput(outputTensorInfo.GetNumElements());
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100733
Finn Williamsc43de6a2020-08-27 11:13:25 +0100734 std::unique_ptr<armnn::ITensorHandle> inputHandle = tensorHandleFactory.CreateTensorHandle(inputTensorInfo);
735 std::unique_ptr<armnn::ITensorHandle> outputHandle = tensorHandleFactory.CreateTensorHandle(outputTensorInfo);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100736
737 armnn::L2NormalizationQueueDescriptor descriptor;
738 descriptor.m_Parameters.m_Eps = 1e-12f;
739 descriptor.m_Parameters.m_DataLayout = layout;
740 armnn::WorkloadInfo info;
741
742 AddInputToWorkload(descriptor, info, inputTensorInfo, inputHandle.get());
743 AddOutputToWorkload(descriptor, info, outputTensorInfo, outputHandle.get());
744
Teresa Charlin611c7fb2022-01-07 09:47:29 +0000745 std::unique_ptr<armnn::IWorkload> workload = workloadFactory.CreateWorkload(armnn::LayerType::L2Normalization,
746 descriptor,
747 info);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100748
749 inputHandle->Allocate();
750 outputHandle->Allocate();
751
Sadik Armagan483c8112021-06-01 09:24:52 +0100752 CopyDataToITensorHandle(inputHandle.get(), inputData.data());
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100753
754 workload->PostAllocationConfigure();
755 ExecuteWorkload(*workload, memoryManager);
756
Sadik Armagan483c8112021-06-01 09:24:52 +0100757 CopyDataFromITensorHandle(actualOutput.data(), outputHandle.get());
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100758
Sadik Armagan483c8112021-06-01 09:24:52 +0100759 return LayerTestResult<float, 2>(actualOutput,
760 expectedOutputData,
761 outputHandle->GetShape(),
762 outputTensorInfo.GetShape());
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100763}
764
765LayerTestResult<float, 4> L2Normalization3dTest(
766 armnn::IWorkloadFactory& workloadFactory,
767 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
Finn Williamsc43de6a2020-08-27 11:13:25 +0100768 const armnn::ITensorHandleFactory& tensorHandleFactory,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100769 const armnn::DataLayout layout)
770{
771 return L2Normalization3dTestCommon<armnn::DataType::Float32>(
772 workloadFactory,
773 memoryManager,
Finn Williamsc43de6a2020-08-27 11:13:25 +0100774 tensorHandleFactory,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100775 0.f,
776 0,
777 0.f,
778 0,
779 layout);
780}
781
782LayerTestResult<int16_t, 4> L2Normalization3dInt16Test(
783 armnn::IWorkloadFactory& workloadFactory,
784 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
Finn Williamsc43de6a2020-08-27 11:13:25 +0100785 const armnn::ITensorHandleFactory& tensorHandleFactory,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100786 const armnn::DataLayout layout)
787{
Derek Lambertif90c56d2020-01-10 17:14:08 +0000788 return L2Normalization1dTestCommon<armnn::DataType::QSymmS16>(
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100789 workloadFactory,
790 memoryManager,
Finn Williamsc43de6a2020-08-27 11:13:25 +0100791 tensorHandleFactory,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100792 1.f,
793 0,
794 1.f,
795 0,
796 layout);
797}
798
799LayerTestResult<uint8_t, 4> L2Normalization3dUint8Test(
800 armnn::IWorkloadFactory& workloadFactory,
801 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
Finn Williamsc43de6a2020-08-27 11:13:25 +0100802 const armnn::ITensorHandleFactory& tensorHandleFactory,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100803 const armnn::DataLayout layout)
804{
Derek Lambertif90c56d2020-01-10 17:14:08 +0000805 return L2Normalization1dTestCommon<armnn::DataType::QAsymmU8>(
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100806 workloadFactory,
807 memoryManager,
Finn Williamsc43de6a2020-08-27 11:13:25 +0100808 tensorHandleFactory,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100809 1.f,
810 0,
811 1.f / 128,
812 128,
813 layout);
814}
815
816LayerTestResult<float, 4> L2Normalization4dTest(
817 armnn::IWorkloadFactory& workloadFactory,
818 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
Finn Williamsc43de6a2020-08-27 11:13:25 +0100819 const armnn::ITensorHandleFactory& tensorHandleFactory,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100820 const armnn::DataLayout layout)
821{
822 return L2Normalization4dTestCommon<armnn::DataType::Float32>(
823 workloadFactory,
824 memoryManager,
Finn Williamsc43de6a2020-08-27 11:13:25 +0100825 tensorHandleFactory,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100826 0.f,
827 0,
828 0.f,
829 0,
830 layout);
831}
832
833LayerTestResult<int16_t, 4> L2Normalization4dInt16Test(
834 armnn::IWorkloadFactory& workloadFactory,
835 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
Finn Williamsc43de6a2020-08-27 11:13:25 +0100836 const armnn::ITensorHandleFactory& tensorHandleFactory,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100837 const armnn::DataLayout layout)
838{
Derek Lambertif90c56d2020-01-10 17:14:08 +0000839 return L2Normalization1dTestCommon<armnn::DataType::QSymmS16>(
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100840 workloadFactory,
841 memoryManager,
Finn Williamsc43de6a2020-08-27 11:13:25 +0100842 tensorHandleFactory,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100843 1.f,
844 0,
845 1.f,
846 0,
847 layout);
848}
849
850LayerTestResult<uint8_t, 4> L2Normalization4dUint8Test(
851 armnn::IWorkloadFactory& workloadFactory,
852 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
Finn Williamsc43de6a2020-08-27 11:13:25 +0100853 const armnn::ITensorHandleFactory& tensorHandleFactory,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100854 const armnn::DataLayout layout)
855{
Derek Lambertif90c56d2020-01-10 17:14:08 +0000856 return L2Normalization1dTestCommon<armnn::DataType::QAsymmU8>(
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100857 workloadFactory,
858 memoryManager,
Finn Williamsc43de6a2020-08-27 11:13:25 +0100859 tensorHandleFactory,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100860 1.f,
861 0,
862 1.f / 128,
863 128,
864 layout);
865}