blob: f7566fd014e0d318c4675abb87b3eaccfe1167bc [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
82 std::unique_ptr<armnn::IWorkload> workload = workloadFactory.CreateL2Normalization(descriptor, info);
83
84 inputHandle->Allocate();
85 outputHandle->Allocate();
86
Sadik Armagan483c8112021-06-01 09:24:52 +010087 CopyDataToITensorHandle(inputHandle.get(), inputTensor.data());
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +010088
89 workload->PostAllocationConfigure();
90 ExecuteWorkload(*workload, memoryManager);
91
Sadik Armagan483c8112021-06-01 09:24:52 +010092 CopyDataFromITensorHandle(actualOutput.data(), outputHandle.get());
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +010093
Sadik Armagan483c8112021-06-01 09:24:52 +010094 return LayerTestResult<T, 4>(actualOutput,
95 expectedOutputData,
96 outputHandle->GetShape(),
97 outputTensorInfo.GetShape());
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +010098}
99
100float CalcInvL2Norm(std::initializer_list<float> elements)
101{
102 const float reduction = std::accumulate(elements.begin(), elements.end(), 0.0f,
103 [](float acc, float element) { return acc + element * element; });
104 return 1.0f / sqrtf(reduction);
105}
106
107template<armnn::DataType ArmnnType, typename T = armnn::ResolveType<ArmnnType>>
108LayerTestResult<T, 4> L2NormalizationEpsilonTestCommon(
109 armnn::IWorkloadFactory& workloadFactory,
110 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
Finn Williamsc43de6a2020-08-27 11:13:25 +0100111 const armnn::ITensorHandleFactory& tensorHandleFactory,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100112 float scale,
113 int32_t offset,
114 float outScale,
115 int32_t outOffset,
116 const armnn::DataLayout layout,
117 float epsilon)
118{
119 // Width: 1
120 // Height: 1
121 // Channels: 3
122 // BatchSize: 1
123 unsigned int numberOfBatches = 1;
124 unsigned int numberOfChannels = 3;
125 unsigned int height = 1;
126 unsigned int width = 1;
127
128 const armnn::TensorShape inputOutputShape = armnnUtils::GetTensorShape(
129 numberOfBatches, numberOfChannels, height, width, layout);
130
131 // 0.0000001^2 + 0.00000002^2 + 0.00000003^2 < 1e-12
132 std::vector<float> inputValues
133 {
134 // Batch 0, Channel 0, Height (1) x Width (1)
135 0.00000001f,
136
137 // Batch 0, Channel 1, Height (1) x Width (1)
138 0.00000002f,
139
140 // Batch 0, Channel 2, Height (1) x Width (1)
141 0.00000003f,
142 };
143
144 const float approxInvL2Norm = 1.f / sqrtf(epsilon);
145 std::vector<float> expectedOutputValues
146 {
147 // Batch 0, Channel 0, Height (1) x Width (1)
148 0.00000001f * approxInvL2Norm,
149 0.00000002f * approxInvL2Norm,
150 0.00000003f * approxInvL2Norm,
151 };
152
153 return L2NormalizationTestImpl<ArmnnType>(
154 workloadFactory,
155 memoryManager,
Finn Williamsc43de6a2020-08-27 11:13:25 +0100156 tensorHandleFactory,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100157 inputOutputShape,
158 scale,
159 offset,
160 inputValues,
161 outScale,
162 outOffset,
163 expectedOutputValues,
164 layout,
165 epsilon);
166}
167
168
169template<armnn::DataType ArmnnType, typename T = armnn::ResolveType<ArmnnType>>
170LayerTestResult<T, 4> L2Normalization1dTestCommon(
171 armnn::IWorkloadFactory& workloadFactory,
172 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
Finn Williamsc43de6a2020-08-27 11:13:25 +0100173 const armnn::ITensorHandleFactory& tensorHandleFactory,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100174 float scale,
175 int32_t offset,
176 float outScale,
177 int32_t outOffset,
178 const armnn::DataLayout layout)
179{
180 // Width: 1
181 // Height: 1
182 // Channels: 10
183 // BatchSize: 1
184 unsigned int numberOfBatches = 1;
185 unsigned int numberOfChannels = 10;
186 unsigned int height = 1;
187 unsigned int width = 1;
188
189
190 const armnn::TensorShape inputOutputShape = armnnUtils::GetTensorShape(
191 numberOfBatches, numberOfChannels, height, width, layout);
192 std::vector<float> inputValues
193 {
194 // Batch 0, Channel 0, Height (1) x Width (1)
195 1.0f,
196
197 // Batch 0, Channel 1, Height (1) x Width (1)
198 2.0f,
199
200 // Batch 0, Channel 2, Height (1) x Width (1)
201 3.0f,
202
203 // Batch 0, Channel 3, Height (1) x Width (1)
204 4.0f,
205
206 // Batch 0, Channel 4, Height (1) x Width (1)
207 5.0f,
208
209 // Batch 0, Channel 5, Height (1) x Width (1)
210 6.0f,
211
212 // Batch 0, Channel 6, Height (1) x Width (1)
213 7.0f,
214
215 // Batch 0, Channel 7, Height (1) x Width (1)
216 8.0f,
217
218 // Batch 0, Channel 8, Height (1) x Width (1)
219 9.0f,
220
221 // Batch 0, Channel 9, Height (1) x Width (1)
222 10.0f
223 };
224 const float approxInvL2Norm = 0.050964719f;
225 std::vector<float> expectedOutputValues
226 {
227 // Batch 0, Channel 0, Height (1) x Width (1)
228 1.0f * approxInvL2Norm,
229 2.0f * approxInvL2Norm,
230 3.0f * approxInvL2Norm,
231 4.0f * approxInvL2Norm,
232 5.0f * approxInvL2Norm,
233 6.0f * approxInvL2Norm,
234 7.0f * approxInvL2Norm,
235 8.0f * approxInvL2Norm,
236 9.0f * approxInvL2Norm,
237 10.0f * approxInvL2Norm
238 };
239
240
241 return L2NormalizationTestImpl<ArmnnType>(
242 workloadFactory,
243 memoryManager,
Finn Williamsc43de6a2020-08-27 11:13:25 +0100244 tensorHandleFactory,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100245 inputOutputShape,
246 scale,
247 offset,
248 inputValues,
249 outScale,
250 outOffset,
251 expectedOutputValues,
252 layout);
253}
254
255template<armnn::DataType ArmnnType, typename T = armnn::ResolveType<ArmnnType>>
256LayerTestResult<T, 4> L2Normalization2dTestCommon(
257 armnn::IWorkloadFactory& workloadFactory,
258 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
Finn Williamsc43de6a2020-08-27 11:13:25 +0100259 const armnn::ITensorHandleFactory& tensorHandleFactory,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100260 float scale,
261 int32_t offset,
262 float outScale,
263 int32_t outOffset,
264 const armnn::DataLayout layout)
265{
266 // Width: 5
267 // Height: 1
268 // Channels: 2
269 // BatchSize: 1
270 unsigned int numberOfBatches = 1;
271 unsigned int numberOfChannels = 2;
272 unsigned int height = 1;
273 unsigned int width = 5;
274
275 const armnn::TensorShape inputOutputShape = armnnUtils::GetTensorShape(
276 numberOfBatches, numberOfChannels, height, width, layout);
277 std::vector<float> inputValues
278 {
279 // Batch 0, Channel 0, Height (1) x Width (5)
280 1.0f, 3.0f, 5.0f, 7.0f, 9.0f,
281
282 // Batch 0, Channel 1, Height (1) x Width (5)
283 2.0f, 4.0f, 6.0f, 8.0f, 10.0f
284 };
285 std::vector<float> expectedOutputValues
286 {
287 // Batch 0, Channel 0, Height (1) x Width (5)
288 1.0f * CalcInvL2Norm({ 1.0f, 2.0f }),
289 3.0f * CalcInvL2Norm({ 3.0f, 4.0f }),
290 5.0f * CalcInvL2Norm({ 5.0f, 6.0f }),
291 7.0f * CalcInvL2Norm({ 7.0f, 8.0f }),
292 9.0f * CalcInvL2Norm({ 9.0f, 10.0f }),
293
294 // Batch 0, Channel 1, Height (1) x Width (5)
295 2.0f * CalcInvL2Norm({ 1.0f, 2.0f }),
296 4.0f * CalcInvL2Norm({ 3.0f, 4.0f }),
297 6.0f * CalcInvL2Norm({ 5.0f, 6.0f }),
298 8.0f * CalcInvL2Norm({ 7.0f, 8.0f }),
299 10.0f * CalcInvL2Norm({ 9.0f, 10.0f })
300 };
301
302 return L2NormalizationTestImpl<ArmnnType>(
303 workloadFactory,
304 memoryManager,
Finn Williamsc43de6a2020-08-27 11:13:25 +0100305 tensorHandleFactory,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100306 inputOutputShape,
307 scale,
308 offset,
309 inputValues,
310 outScale,
311 outOffset,
312 expectedOutputValues,
313 layout);
314}
315
316template<armnn::DataType ArmnnType, typename T = armnn::ResolveType<ArmnnType>>
317LayerTestResult<T, 4> L2Normalization3dTestCommon(
318 armnn::IWorkloadFactory& workloadFactory,
319 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
Finn Williamsc43de6a2020-08-27 11:13:25 +0100320 const armnn::ITensorHandleFactory& tensorHandleFactory,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100321 float scale,
322 int32_t offset,
323 float outScale,
324 int32_t outOffset,
325 const armnn::DataLayout layout)
326{
327 // Width: 3
328 // Height: 4
329 // Channels: 2
330 // BatchSize: 1
331 unsigned int numberOfBatches = 1;
332 unsigned int numberOfChannels = 2;
333 unsigned int height = 4;
334 unsigned int width = 3;
335
336 const armnn::TensorShape inputOutputShape = armnnUtils::GetTensorShape(
337 numberOfBatches, numberOfChannels, height, width, layout);
338 std::vector<float> inputValues
339 {
340 // Batch 0, Channel 0, Height (4) x Width (3)
341 119.0f, 21.0f, 150.0f,
342 149.0f, 32.0f, 179.0f,
343 15.0f, 227.0f, 141.0f,
344 147.0f, 199.0f, 220.0f,
345
346 // Batch 0, Channel 1, Height (4) x Width (3)
347 110.0f, 140.0f, 73.0f,
348 211.0f, 212.0f, 89.0f,
349 24.0f, 138.0f, 188.0f,
350 162.0f, 12.0f, 161.0f
351 };
352 std::vector<float> expectedOutputValues
353 {
354 // Batch 0, Channel 0, Height (4) x Width (3)
355 119.0f * CalcInvL2Norm({ 119.0f, 110.0f }),
356 21.0f * CalcInvL2Norm({ 21.0f, 140.0f }),
357 150.0f * CalcInvL2Norm({ 150.0f, 73.0f }),
358 149.0f * CalcInvL2Norm({ 149.0f, 211.0f }),
359 32.0f * CalcInvL2Norm({ 32.0f, 212.0f }),
360 179.0f * CalcInvL2Norm({ 179.0f, 89.0f }),
361 15.0f * CalcInvL2Norm({ 15.0f, 24.0f }),
362 227.0f * CalcInvL2Norm({ 227.0f, 138.0f }),
363 141.0f * CalcInvL2Norm({ 141.0f, 188.0f }),
364 147.0f * CalcInvL2Norm({ 147.0f, 162.0f }),
365 199.0f * CalcInvL2Norm({ 199.0f, 12.0f }),
366 220.0f * CalcInvL2Norm({ 220.0f, 161.0f }),
367
368 // Batch 0, Channel 1, Height (4) x Width (3)
369 110.0f * CalcInvL2Norm({ 119.0f, 110.0f }),
370 140.0f * CalcInvL2Norm({ 21.0f, 140.0f }),
371 73.0f * CalcInvL2Norm({ 150.0f, 73.0f }),
372 211.0f * CalcInvL2Norm({ 149.0f, 211.0f }),
373 212.0f * CalcInvL2Norm({ 32.0f, 212.0f }),
374 89.0f * CalcInvL2Norm({ 179.0f, 89.0f }),
375 24.0f * CalcInvL2Norm({ 15.0f, 24.0f }),
376 138.0f * CalcInvL2Norm({ 227.0f, 138.0f }),
377 188.0f * CalcInvL2Norm({ 141.0f, 188.0f }),
378 162.0f * CalcInvL2Norm({ 147.0f, 162.0f }),
379 12.0f * CalcInvL2Norm({ 199.0f, 12.0f }),
380 161.0f * CalcInvL2Norm({ 220.0f, 161.0f })
381 };
382
383 return L2NormalizationTestImpl<ArmnnType>(
384 workloadFactory,
385 memoryManager,
Finn Williamsc43de6a2020-08-27 11:13:25 +0100386 tensorHandleFactory,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100387 inputOutputShape,
388 scale,
389 offset,
390 inputValues,
391 outScale,
392 outOffset,
393 expectedOutputValues,
394 layout);
395}
396
397template<armnn::DataType ArmnnType, typename T = armnn::ResolveType<ArmnnType>>
398LayerTestResult<T, 4> L2Normalization4dTestCommon(
399 armnn::IWorkloadFactory& workloadFactory,
400 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
Finn Williamsc43de6a2020-08-27 11:13:25 +0100401 const armnn::ITensorHandleFactory& tensorHandleFactory,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100402 float scale,
403 int32_t offset,
404 float outScale,
405 int32_t outOffset,
406 const armnn::DataLayout layout)
407{
408 // Width: 3
409 // Height: 4
410 // Channels: 3
411 // BatchSize: 2
412 unsigned int numberOfBatches = 2;
413 unsigned int numberOfChannels = 3;
414 unsigned int height = 4;
415 unsigned int width = 3;
416
417 const armnn::TensorShape inputOutputShape = armnnUtils::GetTensorShape(
418 numberOfBatches, numberOfChannels, height, width, layout);
419 std::vector<float> inputValues
420 {
421 // Batch 0, Channel 0, Height (4) x Width (3)
422 235.0f, 46.0f, 178.0f,
423 100.0f, 123.0f, 19.0f,
424 172.0f, 74.0f, 250.0f,
425 6.0f, 195.0f, 80.0f,
426
427 // Batch 0, Channel 1, Height (4) x Width (3)
428 113.0f, 95.0f, 202.0f,
429 77.0f, 114.0f, 71.0f,
430 122.0f, 246.0f, 166.0f,
431 82.0f, 28.0f, 37.0f,
432
433 // Batch 0, Channel 2, Height (4) x Width (3)
434 56.0f, 170.0f, 162.0f,
435 194.0f, 89.0f, 254.0f,
436 12.0f, 209.0f, 200.0f,
437 1.0f, 64.0f, 54.0f,
438
439 // Batch 1, Channel 0, Height (4) x Width (3)
440 67.0f, 90.0f, 49.0f,
441 7.0f, 163.0f, 18.0f,
442 25.0f, 117.0f, 103.0f,
443 247.0f, 59.0f, 189.0f,
444
445 // Batch 1, Channel 1, Height (4) x Width (3)
446 239.0f, 104.0f, 199.0f,
447 17.0f, 124.0f, 153.0f,
448 222.0f, 217.0f, 75.0f,
449 32.0f, 126.0f, 21.0f,
450
451 // Batch 1, Channel 2, Height (4) x Width (3)
452 97.0f, 145.0f, 215.0f,
453 115.0f, 116.0f, 238.0f,
454 226.0f, 16.0f, 132.0f,
455 92.0f, 125.0f, 88.0f
456 };
457 std::vector<float> expectedOutputValues
458 {
459 // Batch 0, Channel 0, Height (4) x Width (3)
460 235.0f * CalcInvL2Norm({ 235.0f, 113.0f, 56.0f }),
461 46.0f * CalcInvL2Norm({ 46.0f, 95.0f, 170.0f }),
462 178.0f * CalcInvL2Norm({ 178.0f, 202.0F, 162.0f }),
463 100.0f * CalcInvL2Norm({ 100.0f, 77.0f, 194.0f }),
464 123.0f * CalcInvL2Norm({ 123.0f, 114.0f, 89.0f }),
465 19.0f * CalcInvL2Norm({ 19.0f, 71.0f, 254.0f }),
466 172.0f * CalcInvL2Norm({ 172.0f, 122.0f, 12.0f }),
467 74.0f * CalcInvL2Norm({ 74.0f, 246.0f, 209.0f }),
468 250.0f * CalcInvL2Norm({ 250.0f, 166.0f, 200.0f }),
469 6.0f * CalcInvL2Norm({ 6.0f, 82.0f, 1.0f }),
470 195.0f * CalcInvL2Norm({ 195.0f, 28.0f, 64.0f }),
471 80.0f * CalcInvL2Norm({ 80.0f, 37.0f, 54.0f }),
472
473 // Batch 0, Channel 1, Height (4) x Width (3)
474 113.0f * CalcInvL2Norm({ 235.0f, 113.0f, 56.0f }),
475 95.0f * CalcInvL2Norm({ 46.0f, 95.0f, 170.0f }),
476 202.0f * CalcInvL2Norm({ 178.0f, 202.0F, 162.0f }),
477 77.0f * CalcInvL2Norm({ 100.0f, 77.0f, 194.0f }),
478 114.0f * CalcInvL2Norm({ 123.0f, 114.0f, 89.0f }),
479 71.0f * CalcInvL2Norm({ 19.0f, 71.0f, 254.0f }),
480 122.0f * CalcInvL2Norm({ 172.0f, 122.0f, 12.0f }),
481 246.0f * CalcInvL2Norm({ 74.0f, 246.0f, 209.0f }),
482 166.0f * CalcInvL2Norm({ 250.0f, 166.0f, 200.0f }),
483 82.0f * CalcInvL2Norm({ 6.0f, 82.0f, 1.0f }),
484 28.0f * CalcInvL2Norm({ 195.0f, 28.0f, 64.0f }),
485 37.0f * CalcInvL2Norm({ 80.0f, 37.0f, 54.0f }),
486
487 // Batch 0, Channel 2, Height (4) x Width (3)
488 56.0f * CalcInvL2Norm({ 235.0f, 113.0f, 56.0f }),
489 170.0f * CalcInvL2Norm({ 46.0f, 95.0f, 170.0f }),
490 162.0f * CalcInvL2Norm({ 178.0f, 202.0F, 162.0f }),
491 194.0f * CalcInvL2Norm({ 100.0f, 77.0f, 194.0f }),
492 89.0f * CalcInvL2Norm({ 123.0f, 114.0f, 89.0f }),
493 254.0f * CalcInvL2Norm({ 19.0f, 71.0f, 254.0f }),
494 12.0f * CalcInvL2Norm({ 172.0f, 122.0f, 12.0f }),
495 209.0f * CalcInvL2Norm({ 74.0f, 246.0f, 209.0f }),
496 200.0f * CalcInvL2Norm({ 250.0f, 166.0f, 200.0f }),
497 1.0f * CalcInvL2Norm({ 6.0f, 82.0f, 1.0f }),
498 64.0f * CalcInvL2Norm({ 195.0f, 28.0f, 64.0f }),
499 54.0f * CalcInvL2Norm({ 80.0f, 37.0f, 54.0f }),
500
501 // Batch 1, Channel 0, Height (4) x Width (3)
502 67.0f * CalcInvL2Norm({ 67.0f, 239.0f, 97.0f }),
503 90.0f * CalcInvL2Norm({ 90.0f, 104.0f, 145.0f }),
504 49.0f * CalcInvL2Norm({ 49.0f, 199.0f, 215.0f }),
505 7.0f * CalcInvL2Norm({ 7.0f, 17.0f, 115.0f }),
506 163.0f * CalcInvL2Norm({ 163.0f, 124.0f, 116.0f }),
507 18.0f * CalcInvL2Norm({ 18.0f, 153.0f, 238.0f }),
508 25.0f * CalcInvL2Norm({ 25.0f, 222.0f, 226.0f }),
509 117.0f * CalcInvL2Norm({ 117.0f, 217.0f, 16.0f }),
510 103.0f * CalcInvL2Norm({ 103.0f, 75.0f, 132.0f }),
511 247.0f * CalcInvL2Norm({ 247.0f, 32.0f, 92.0f }),
512 59.0f * CalcInvL2Norm({ 59.0f, 126.0f, 125.0f }),
513 189.0f * CalcInvL2Norm({ 189.0f, 21.0f, 88.0f }),
514
515 // Batch 1, Channel 1, Height (4) x Width (3)
516 239.0f * CalcInvL2Norm({ 67.0f, 239.0f, 97.0f }),
517 104.0f * CalcInvL2Norm({ 90.0f, 104.0f, 145.0f }),
518 199.0f * CalcInvL2Norm({ 49.0f, 199.0f, 215.0f }),
519 17.0f * CalcInvL2Norm({ 7.0f, 17.0f, 115.0f }),
520 124.0f * CalcInvL2Norm({ 163.0f, 124.0f, 116.0f }),
521 153.0f * CalcInvL2Norm({ 18.0f, 153.0f, 238.0f }),
522 222.0f * CalcInvL2Norm({ 25.0f, 222.0f, 226.0f }),
523 217.0f * CalcInvL2Norm({ 117.0f, 217.0f, 16.0f }),
524 75.0f * CalcInvL2Norm({ 103.0f, 75.0f, 132.0f }),
525 32.0f * CalcInvL2Norm({ 247.0f, 32.0f, 92.0f }),
526 126.0f * CalcInvL2Norm({ 59.0f, 126.0f, 125.0f }),
527 21.0f * CalcInvL2Norm({ 189.0f, 21.0f, 88.0f }),
528
529 // Batch 1, Channel 2, Height (4) x Width (3)
530 97.0f * CalcInvL2Norm({ 67.0f, 239.0f, 97.0f }),
531 145.0f * CalcInvL2Norm({ 90.0f, 104.0f, 145.0f }),
532 215.0f * CalcInvL2Norm({ 49.0f, 199.0f, 215.0f }),
533 115.0f * CalcInvL2Norm({ 7.0f, 17.0f, 115.0f }),
534 116.0f * CalcInvL2Norm({ 163.0f, 124.0f, 116.0f }),
535 238.0f * CalcInvL2Norm({ 18.0f, 153.0f, 238.0f }),
536 226.0f * CalcInvL2Norm({ 25.0f, 222.0f, 226.0f }),
537 16.0f * CalcInvL2Norm({ 117.0f, 217.0f, 16.0f }),
538 132.0f * CalcInvL2Norm({ 103.0f, 75.0f, 132.0f }),
539 92.0f * CalcInvL2Norm({ 247.0f, 32.0f, 92.0f }),
540 125.0f * CalcInvL2Norm({ 59.0f, 126.0f, 125.0f }),
541 88.0f * CalcInvL2Norm({ 189.0f, 21.0f, 88.0f })
542 };
543
544 return L2NormalizationTestImpl<ArmnnType>(
545 workloadFactory,
546 memoryManager,
Finn Williamsc43de6a2020-08-27 11:13:25 +0100547 tensorHandleFactory,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100548 inputOutputShape,
549 scale,
550 offset,
551 inputValues,
552 outScale,
553 outOffset,
554 expectedOutputValues,
555 layout);
556}
557
558} // anonymous namespace
559
560LayerTestResult<float, 4> L2NormalizationDefaultEpsilonTest(
561 armnn::IWorkloadFactory& workloadFactory,
562 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
Finn Williamsc43de6a2020-08-27 11:13:25 +0100563 const armnn::ITensorHandleFactory& tensorHandleFactory,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100564 const armnn::DataLayout layout)
565{
566 // Dummy descriptor to get the default value of epsilon.
567 armnn::L2NormalizationDescriptor descriptor;
568
569 return L2NormalizationEpsilonTestCommon<armnn::DataType::Float32>(
570 workloadFactory,
571 memoryManager,
Finn Williamsc43de6a2020-08-27 11:13:25 +0100572 tensorHandleFactory,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100573 0.f,
574 0,
575 0.f,
576 0,
577 layout,
578 descriptor.m_Eps);
579}
580
581LayerTestResult<float, 4> L2NormalizationNonDefaultEpsilonTest(
582 armnn::IWorkloadFactory& workloadFactory,
583 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
Finn Williamsc43de6a2020-08-27 11:13:25 +0100584 const armnn::ITensorHandleFactory& tensorHandleFactory,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100585 const armnn::DataLayout layout)
586{
587 return L2NormalizationEpsilonTestCommon<armnn::DataType::Float32>(
588 workloadFactory,
589 memoryManager,
Finn Williamsc43de6a2020-08-27 11:13:25 +0100590 tensorHandleFactory,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100591 0.f,
592 0,
593 0.f,
594 0,
595 layout,
596 1e-9f);
597}
598
599LayerTestResult<float, 4> L2Normalization1dTest(
600 armnn::IWorkloadFactory& workloadFactory,
601 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
Finn Williamsc43de6a2020-08-27 11:13:25 +0100602 const armnn::ITensorHandleFactory& tensorHandleFactory,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100603 const armnn::DataLayout layout)
604{
605 return L2Normalization1dTestCommon<armnn::DataType::Float32>(
606 workloadFactory,
607 memoryManager,
Finn Williamsc43de6a2020-08-27 11:13:25 +0100608 tensorHandleFactory,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100609 0.f,
610 0,
611 0.f,
612 0,
613 layout);
614}
615
616LayerTestResult<int16_t, 4> L2Normalization1dInt16Test(
617 armnn::IWorkloadFactory& workloadFactory,
618 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
Finn Williamsc43de6a2020-08-27 11:13:25 +0100619 const armnn::ITensorHandleFactory& tensorHandleFactory,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100620 const armnn::DataLayout layout)
621{
Derek Lambertif90c56d2020-01-10 17:14:08 +0000622 return L2Normalization1dTestCommon<armnn::DataType::QSymmS16>(
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100623 workloadFactory,
624 memoryManager,
Finn Williamsc43de6a2020-08-27 11:13:25 +0100625 tensorHandleFactory,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100626 1.f,
627 0,
628 1.f,
629 0,
630 layout);
631}
632
633LayerTestResult<uint8_t, 4> L2Normalization1dUint8Test(
634 armnn::IWorkloadFactory& workloadFactory,
635 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
Finn Williamsc43de6a2020-08-27 11:13:25 +0100636 const armnn::ITensorHandleFactory& tensorHandleFactory,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100637 const armnn::DataLayout layout)
638{
Derek Lambertif90c56d2020-01-10 17:14:08 +0000639 return L2Normalization1dTestCommon<armnn::DataType::QAsymmU8>(
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100640 workloadFactory,
641 memoryManager,
Finn Williamsc43de6a2020-08-27 11:13:25 +0100642 tensorHandleFactory,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100643 1.f,
644 0,
645 1.f / 128,
646 128,
647 layout);
648}
649
650LayerTestResult<float, 4> L2Normalization2dTest(
651 armnn::IWorkloadFactory& workloadFactory,
652 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
Finn Williamsc43de6a2020-08-27 11:13:25 +0100653 const armnn::ITensorHandleFactory& tensorHandleFactory,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100654 const armnn::DataLayout layout)
655{
656 return L2Normalization2dTestCommon<armnn::DataType::Float32>(
657 workloadFactory,
658 memoryManager,
Finn Williamsc43de6a2020-08-27 11:13:25 +0100659 tensorHandleFactory,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100660 0.f,
661 0,
662 0.f,
663 0,
664 layout);
665}
666
667LayerTestResult<int16_t, 4> L2Normalization2dInt16Test(
668 armnn::IWorkloadFactory& workloadFactory,
669 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
Finn Williamsc43de6a2020-08-27 11:13:25 +0100670 const armnn::ITensorHandleFactory& tensorHandleFactory,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100671 const armnn::DataLayout layout)
672{
Derek Lambertif90c56d2020-01-10 17:14:08 +0000673 return L2Normalization1dTestCommon<armnn::DataType::QSymmS16>(
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100674 workloadFactory,
675 memoryManager,
Finn Williamsc43de6a2020-08-27 11:13:25 +0100676 tensorHandleFactory,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100677 1.f,
678 0,
679 1.f,
680 0,
681 layout);
682}
683
684LayerTestResult<uint8_t, 4> L2Normalization2dUint8Test(
685 armnn::IWorkloadFactory& workloadFactory,
686 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
Finn Williamsc43de6a2020-08-27 11:13:25 +0100687 const armnn::ITensorHandleFactory& tensorHandleFactory,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100688 const armnn::DataLayout layout)
689{
Derek Lambertif90c56d2020-01-10 17:14:08 +0000690 return L2Normalization1dTestCommon<armnn::DataType::QAsymmU8>(
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100691 workloadFactory,
692 memoryManager,
Finn Williamsc43de6a2020-08-27 11:13:25 +0100693 tensorHandleFactory,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100694 1.f,
695 0,
696 1.f / 128,
697 128,
698 layout);
699}
700
701LayerTestResult<float, 2> L2Normalization2dShapeTest(
702 armnn::IWorkloadFactory& workloadFactory,
Finn Williamsc43de6a2020-08-27 11:13:25 +0100703 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
704 const armnn::ITensorHandleFactory& tensorHandleFactory)
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100705{
706 const armnn::DataLayout layout = armnn::DataLayout::NHWC;
707 const armnn::TensorShape inputOutputTensorShape = armnn::TensorShape({ 5, 2 });
708
709 std::vector<float> inputData
710 {
711 1.f, 2.f, 3.f, 4.f, 5.f, 6.f, 7.f, 8.f, 9.f, 10.f
712 };
713 std::vector<float> expectedOutputData
714 {
715 1.0f * CalcInvL2Norm({ 1.0f, 2.0f }),
716 2.0f * CalcInvL2Norm({ 1.0f, 2.0f }),
717 3.0f * CalcInvL2Norm({ 3.0f, 4.0f }),
718 4.0f * CalcInvL2Norm({ 3.0f, 4.0f }),
719 5.0f * CalcInvL2Norm({ 5.0f, 6.0f }),
720 6.0f * CalcInvL2Norm({ 5.0f, 6.0f }),
721 7.0f * CalcInvL2Norm({ 7.0f, 8.0f }),
722 8.0f * CalcInvL2Norm({ 7.0f, 8.0f }),
723 9.0f * CalcInvL2Norm({ 9.0f, 10.0f }),
724 10.0f * CalcInvL2Norm({ 9.0f, 10.0f })
725 };
726
727 const armnn::TensorInfo inputTensorInfo(inputOutputTensorShape, armnn::DataType::Float32, 0.f, 0);
728 const armnn::TensorInfo outputTensorInfo(inputOutputTensorShape, armnn::DataType::Float32, 0.f, 0);
729
Sadik Armagan483c8112021-06-01 09:24:52 +0100730 std::vector<float> actualOutput(outputTensorInfo.GetNumElements());
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100731
Finn Williamsc43de6a2020-08-27 11:13:25 +0100732 std::unique_ptr<armnn::ITensorHandle> inputHandle = tensorHandleFactory.CreateTensorHandle(inputTensorInfo);
733 std::unique_ptr<armnn::ITensorHandle> outputHandle = tensorHandleFactory.CreateTensorHandle(outputTensorInfo);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100734
735 armnn::L2NormalizationQueueDescriptor descriptor;
736 descriptor.m_Parameters.m_Eps = 1e-12f;
737 descriptor.m_Parameters.m_DataLayout = layout;
738 armnn::WorkloadInfo info;
739
740 AddInputToWorkload(descriptor, info, inputTensorInfo, inputHandle.get());
741 AddOutputToWorkload(descriptor, info, outputTensorInfo, outputHandle.get());
742
743 std::unique_ptr<armnn::IWorkload> workload = workloadFactory.CreateL2Normalization(descriptor, info);
744
745 inputHandle->Allocate();
746 outputHandle->Allocate();
747
Sadik Armagan483c8112021-06-01 09:24:52 +0100748 CopyDataToITensorHandle(inputHandle.get(), inputData.data());
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100749
750 workload->PostAllocationConfigure();
751 ExecuteWorkload(*workload, memoryManager);
752
Sadik Armagan483c8112021-06-01 09:24:52 +0100753 CopyDataFromITensorHandle(actualOutput.data(), outputHandle.get());
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100754
Sadik Armagan483c8112021-06-01 09:24:52 +0100755 return LayerTestResult<float, 2>(actualOutput,
756 expectedOutputData,
757 outputHandle->GetShape(),
758 outputTensorInfo.GetShape());
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100759}
760
761LayerTestResult<float, 4> L2Normalization3dTest(
762 armnn::IWorkloadFactory& workloadFactory,
763 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
Finn Williamsc43de6a2020-08-27 11:13:25 +0100764 const armnn::ITensorHandleFactory& tensorHandleFactory,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100765 const armnn::DataLayout layout)
766{
767 return L2Normalization3dTestCommon<armnn::DataType::Float32>(
768 workloadFactory,
769 memoryManager,
Finn Williamsc43de6a2020-08-27 11:13:25 +0100770 tensorHandleFactory,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100771 0.f,
772 0,
773 0.f,
774 0,
775 layout);
776}
777
778LayerTestResult<int16_t, 4> L2Normalization3dInt16Test(
779 armnn::IWorkloadFactory& workloadFactory,
780 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
Finn Williamsc43de6a2020-08-27 11:13:25 +0100781 const armnn::ITensorHandleFactory& tensorHandleFactory,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100782 const armnn::DataLayout layout)
783{
Derek Lambertif90c56d2020-01-10 17:14:08 +0000784 return L2Normalization1dTestCommon<armnn::DataType::QSymmS16>(
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100785 workloadFactory,
786 memoryManager,
Finn Williamsc43de6a2020-08-27 11:13:25 +0100787 tensorHandleFactory,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100788 1.f,
789 0,
790 1.f,
791 0,
792 layout);
793}
794
795LayerTestResult<uint8_t, 4> L2Normalization3dUint8Test(
796 armnn::IWorkloadFactory& workloadFactory,
797 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
Finn Williamsc43de6a2020-08-27 11:13:25 +0100798 const armnn::ITensorHandleFactory& tensorHandleFactory,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100799 const armnn::DataLayout layout)
800{
Derek Lambertif90c56d2020-01-10 17:14:08 +0000801 return L2Normalization1dTestCommon<armnn::DataType::QAsymmU8>(
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100802 workloadFactory,
803 memoryManager,
Finn Williamsc43de6a2020-08-27 11:13:25 +0100804 tensorHandleFactory,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100805 1.f,
806 0,
807 1.f / 128,
808 128,
809 layout);
810}
811
812LayerTestResult<float, 4> L2Normalization4dTest(
813 armnn::IWorkloadFactory& workloadFactory,
814 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
Finn Williamsc43de6a2020-08-27 11:13:25 +0100815 const armnn::ITensorHandleFactory& tensorHandleFactory,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100816 const armnn::DataLayout layout)
817{
818 return L2Normalization4dTestCommon<armnn::DataType::Float32>(
819 workloadFactory,
820 memoryManager,
Finn Williamsc43de6a2020-08-27 11:13:25 +0100821 tensorHandleFactory,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100822 0.f,
823 0,
824 0.f,
825 0,
826 layout);
827}
828
829LayerTestResult<int16_t, 4> L2Normalization4dInt16Test(
830 armnn::IWorkloadFactory& workloadFactory,
831 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
Finn Williamsc43de6a2020-08-27 11:13:25 +0100832 const armnn::ITensorHandleFactory& tensorHandleFactory,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100833 const armnn::DataLayout layout)
834{
Derek Lambertif90c56d2020-01-10 17:14:08 +0000835 return L2Normalization1dTestCommon<armnn::DataType::QSymmS16>(
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100836 workloadFactory,
837 memoryManager,
Finn Williamsc43de6a2020-08-27 11:13:25 +0100838 tensorHandleFactory,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100839 1.f,
840 0,
841 1.f,
842 0,
843 layout);
844}
845
846LayerTestResult<uint8_t, 4> L2Normalization4dUint8Test(
847 armnn::IWorkloadFactory& workloadFactory,
848 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
Finn Williamsc43de6a2020-08-27 11:13:25 +0100849 const armnn::ITensorHandleFactory& tensorHandleFactory,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100850 const armnn::DataLayout layout)
851{
Derek Lambertif90c56d2020-01-10 17:14:08 +0000852 return L2Normalization1dTestCommon<armnn::DataType::QAsymmU8>(
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100853 workloadFactory,
854 memoryManager,
Finn Williamsc43de6a2020-08-27 11:13:25 +0100855 tensorHandleFactory,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100856 1.f,
857 0,
858 1.f / 128,
859 128,
860 layout);
861}