blob: 5c75b6f5407cfc046642387f8bdc126053223fb8 [file] [log] [blame]
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001//
2// Copyright © 2017 Arm Ltd. All rights reserved.
3// SPDX-License-Identifier: MIT
4//
5
6#include "L2NormalizationTestImpl.hpp"
7
8#include <Permute.hpp>
9#include <ResolveType.hpp>
10#include <TensorUtils.hpp>
11
12#include <backendsCommon/test/TensorCopyUtils.hpp>
13#include <backendsCommon/test/WorkloadTestUtils.hpp>
14
15#include <test/TensorHelpers.hpp>
16
17namespace
18{
19
20template<armnn::DataType ArmnnType, typename T = armnn::ResolveType<ArmnnType>>
21LayerTestResult<T, 4> L2NormalizationTestImpl(
22 armnn::IWorkloadFactory& workloadFactory,
23 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
24 const armnn::TensorShape& inputOutputTensorShape,
25 float scale,
26 int32_t offset,
27 const std::vector<float>& inputValues,
28 float outScale,
29 int32_t outOffset,
30 const std::vector<float>& expectedOutputValues,
31 const armnn::DataLayout layout,
32 float epsilon = 1e-12f)
33{
34 const armnn::TensorInfo inputTensorInfo(inputOutputTensorShape, ArmnnType, scale, offset);
35 const armnn::TensorInfo outputTensorInfo(inputOutputTensorShape, ArmnnType, outScale, outOffset);
36
37 // at this point if we require it permute the input data
38 const armnn::PermutationVector NCHWToNHWC = { 0, 3, 1, 2 };
39 std::vector<float> inputData = inputValues;
40 if (layout == armnn::DataLayout::NHWC)
41 {
42 std::vector<float> tmp(inputData.size());
43 armnnUtils::Permute(inputTensorInfo.GetShape(), NCHWToNHWC, inputData.data(), tmp.data(), sizeof(float));
44 inputData = tmp;
45 }
46
47 auto inputTensor = MakeTensor<T, 4>(inputTensorInfo, QuantizedVector<T>(
48 inputTensorInfo.GetQuantizationScale(),
49 inputTensorInfo.GetQuantizationOffset(),
50 inputData));
51
52 std::vector<float> expectedOutputData = expectedOutputValues;
53 if (layout == armnn::DataLayout::NHWC)
54 {
55 std::vector<float> tmp(expectedOutputData.size());
56 armnnUtils::Permute(inputTensorInfo.GetShape(), NCHWToNHWC, expectedOutputData.data(), tmp.data(),
57 sizeof(float));
58 expectedOutputData = tmp;
59 }
60
61 LayerTestResult<T, 4> result(outputTensorInfo);
62 result.outputExpected = MakeTensor<T, 4>(outputTensorInfo, QuantizedVector<T>(
63 outputTensorInfo.GetQuantizationScale(),
64 outputTensorInfo.GetQuantizationOffset(),
65 expectedOutputData));
66
67 std::unique_ptr<armnn::ITensorHandle> inputHandle = workloadFactory.CreateTensorHandle(inputTensorInfo);
68 std::unique_ptr<armnn::ITensorHandle> outputHandle = workloadFactory.CreateTensorHandle(outputTensorInfo);
69
70 armnn::L2NormalizationQueueDescriptor descriptor;
71 descriptor.m_Parameters.m_Eps = epsilon;
72 descriptor.m_Parameters.m_DataLayout = layout;
73 armnn::WorkloadInfo info;
74
75 AddInputToWorkload(descriptor, info, inputTensorInfo, inputHandle.get());
76 AddOutputToWorkload(descriptor, info, outputTensorInfo, outputHandle.get());
77
78 std::unique_ptr<armnn::IWorkload> workload = workloadFactory.CreateL2Normalization(descriptor, info);
79
80 inputHandle->Allocate();
81 outputHandle->Allocate();
82
83 CopyDataToITensorHandle(inputHandle.get(), &inputTensor[0][0][0][0]);
84
85 workload->PostAllocationConfigure();
86 ExecuteWorkload(*workload, memoryManager);
87
88 CopyDataFromITensorHandle(&result.output[0][0][0][0], outputHandle.get());
89
90 return result;
91}
92
93float CalcInvL2Norm(std::initializer_list<float> elements)
94{
95 const float reduction = std::accumulate(elements.begin(), elements.end(), 0.0f,
96 [](float acc, float element) { return acc + element * element; });
97 return 1.0f / sqrtf(reduction);
98}
99
100template<armnn::DataType ArmnnType, typename T = armnn::ResolveType<ArmnnType>>
101LayerTestResult<T, 4> L2NormalizationEpsilonTestCommon(
102 armnn::IWorkloadFactory& workloadFactory,
103 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
104 float scale,
105 int32_t offset,
106 float outScale,
107 int32_t outOffset,
108 const armnn::DataLayout layout,
109 float epsilon)
110{
111 // Width: 1
112 // Height: 1
113 // Channels: 3
114 // BatchSize: 1
115 unsigned int numberOfBatches = 1;
116 unsigned int numberOfChannels = 3;
117 unsigned int height = 1;
118 unsigned int width = 1;
119
120 const armnn::TensorShape inputOutputShape = armnnUtils::GetTensorShape(
121 numberOfBatches, numberOfChannels, height, width, layout);
122
123 // 0.0000001^2 + 0.00000002^2 + 0.00000003^2 < 1e-12
124 std::vector<float> inputValues
125 {
126 // Batch 0, Channel 0, Height (1) x Width (1)
127 0.00000001f,
128
129 // Batch 0, Channel 1, Height (1) x Width (1)
130 0.00000002f,
131
132 // Batch 0, Channel 2, Height (1) x Width (1)
133 0.00000003f,
134 };
135
136 const float approxInvL2Norm = 1.f / sqrtf(epsilon);
137 std::vector<float> expectedOutputValues
138 {
139 // Batch 0, Channel 0, Height (1) x Width (1)
140 0.00000001f * approxInvL2Norm,
141 0.00000002f * approxInvL2Norm,
142 0.00000003f * approxInvL2Norm,
143 };
144
145 return L2NormalizationTestImpl<ArmnnType>(
146 workloadFactory,
147 memoryManager,
148 inputOutputShape,
149 scale,
150 offset,
151 inputValues,
152 outScale,
153 outOffset,
154 expectedOutputValues,
155 layout,
156 epsilon);
157}
158
159
160template<armnn::DataType ArmnnType, typename T = armnn::ResolveType<ArmnnType>>
161LayerTestResult<T, 4> L2Normalization1dTestCommon(
162 armnn::IWorkloadFactory& workloadFactory,
163 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
164 float scale,
165 int32_t offset,
166 float outScale,
167 int32_t outOffset,
168 const armnn::DataLayout layout)
169{
170 // Width: 1
171 // Height: 1
172 // Channels: 10
173 // BatchSize: 1
174 unsigned int numberOfBatches = 1;
175 unsigned int numberOfChannels = 10;
176 unsigned int height = 1;
177 unsigned int width = 1;
178
179
180 const armnn::TensorShape inputOutputShape = armnnUtils::GetTensorShape(
181 numberOfBatches, numberOfChannels, height, width, layout);
182 std::vector<float> inputValues
183 {
184 // Batch 0, Channel 0, Height (1) x Width (1)
185 1.0f,
186
187 // Batch 0, Channel 1, Height (1) x Width (1)
188 2.0f,
189
190 // Batch 0, Channel 2, Height (1) x Width (1)
191 3.0f,
192
193 // Batch 0, Channel 3, Height (1) x Width (1)
194 4.0f,
195
196 // Batch 0, Channel 4, Height (1) x Width (1)
197 5.0f,
198
199 // Batch 0, Channel 5, Height (1) x Width (1)
200 6.0f,
201
202 // Batch 0, Channel 6, Height (1) x Width (1)
203 7.0f,
204
205 // Batch 0, Channel 7, Height (1) x Width (1)
206 8.0f,
207
208 // Batch 0, Channel 8, Height (1) x Width (1)
209 9.0f,
210
211 // Batch 0, Channel 9, Height (1) x Width (1)
212 10.0f
213 };
214 const float approxInvL2Norm = 0.050964719f;
215 std::vector<float> expectedOutputValues
216 {
217 // Batch 0, Channel 0, Height (1) x Width (1)
218 1.0f * approxInvL2Norm,
219 2.0f * approxInvL2Norm,
220 3.0f * approxInvL2Norm,
221 4.0f * approxInvL2Norm,
222 5.0f * approxInvL2Norm,
223 6.0f * approxInvL2Norm,
224 7.0f * approxInvL2Norm,
225 8.0f * approxInvL2Norm,
226 9.0f * approxInvL2Norm,
227 10.0f * approxInvL2Norm
228 };
229
230
231 return L2NormalizationTestImpl<ArmnnType>(
232 workloadFactory,
233 memoryManager,
234 inputOutputShape,
235 scale,
236 offset,
237 inputValues,
238 outScale,
239 outOffset,
240 expectedOutputValues,
241 layout);
242}
243
244template<armnn::DataType ArmnnType, typename T = armnn::ResolveType<ArmnnType>>
245LayerTestResult<T, 4> L2Normalization2dTestCommon(
246 armnn::IWorkloadFactory& workloadFactory,
247 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
248 float scale,
249 int32_t offset,
250 float outScale,
251 int32_t outOffset,
252 const armnn::DataLayout layout)
253{
254 // Width: 5
255 // Height: 1
256 // Channels: 2
257 // BatchSize: 1
258 unsigned int numberOfBatches = 1;
259 unsigned int numberOfChannels = 2;
260 unsigned int height = 1;
261 unsigned int width = 5;
262
263 const armnn::TensorShape inputOutputShape = armnnUtils::GetTensorShape(
264 numberOfBatches, numberOfChannels, height, width, layout);
265 std::vector<float> inputValues
266 {
267 // Batch 0, Channel 0, Height (1) x Width (5)
268 1.0f, 3.0f, 5.0f, 7.0f, 9.0f,
269
270 // Batch 0, Channel 1, Height (1) x Width (5)
271 2.0f, 4.0f, 6.0f, 8.0f, 10.0f
272 };
273 std::vector<float> expectedOutputValues
274 {
275 // Batch 0, Channel 0, Height (1) x Width (5)
276 1.0f * CalcInvL2Norm({ 1.0f, 2.0f }),
277 3.0f * CalcInvL2Norm({ 3.0f, 4.0f }),
278 5.0f * CalcInvL2Norm({ 5.0f, 6.0f }),
279 7.0f * CalcInvL2Norm({ 7.0f, 8.0f }),
280 9.0f * CalcInvL2Norm({ 9.0f, 10.0f }),
281
282 // Batch 0, Channel 1, Height (1) x Width (5)
283 2.0f * CalcInvL2Norm({ 1.0f, 2.0f }),
284 4.0f * CalcInvL2Norm({ 3.0f, 4.0f }),
285 6.0f * CalcInvL2Norm({ 5.0f, 6.0f }),
286 8.0f * CalcInvL2Norm({ 7.0f, 8.0f }),
287 10.0f * CalcInvL2Norm({ 9.0f, 10.0f })
288 };
289
290 return L2NormalizationTestImpl<ArmnnType>(
291 workloadFactory,
292 memoryManager,
293 inputOutputShape,
294 scale,
295 offset,
296 inputValues,
297 outScale,
298 outOffset,
299 expectedOutputValues,
300 layout);
301}
302
303template<armnn::DataType ArmnnType, typename T = armnn::ResolveType<ArmnnType>>
304LayerTestResult<T, 4> L2Normalization3dTestCommon(
305 armnn::IWorkloadFactory& workloadFactory,
306 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
307 float scale,
308 int32_t offset,
309 float outScale,
310 int32_t outOffset,
311 const armnn::DataLayout layout)
312{
313 // Width: 3
314 // Height: 4
315 // Channels: 2
316 // BatchSize: 1
317 unsigned int numberOfBatches = 1;
318 unsigned int numberOfChannels = 2;
319 unsigned int height = 4;
320 unsigned int width = 3;
321
322 const armnn::TensorShape inputOutputShape = armnnUtils::GetTensorShape(
323 numberOfBatches, numberOfChannels, height, width, layout);
324 std::vector<float> inputValues
325 {
326 // Batch 0, Channel 0, Height (4) x Width (3)
327 119.0f, 21.0f, 150.0f,
328 149.0f, 32.0f, 179.0f,
329 15.0f, 227.0f, 141.0f,
330 147.0f, 199.0f, 220.0f,
331
332 // Batch 0, Channel 1, Height (4) x Width (3)
333 110.0f, 140.0f, 73.0f,
334 211.0f, 212.0f, 89.0f,
335 24.0f, 138.0f, 188.0f,
336 162.0f, 12.0f, 161.0f
337 };
338 std::vector<float> expectedOutputValues
339 {
340 // Batch 0, Channel 0, Height (4) x Width (3)
341 119.0f * CalcInvL2Norm({ 119.0f, 110.0f }),
342 21.0f * CalcInvL2Norm({ 21.0f, 140.0f }),
343 150.0f * CalcInvL2Norm({ 150.0f, 73.0f }),
344 149.0f * CalcInvL2Norm({ 149.0f, 211.0f }),
345 32.0f * CalcInvL2Norm({ 32.0f, 212.0f }),
346 179.0f * CalcInvL2Norm({ 179.0f, 89.0f }),
347 15.0f * CalcInvL2Norm({ 15.0f, 24.0f }),
348 227.0f * CalcInvL2Norm({ 227.0f, 138.0f }),
349 141.0f * CalcInvL2Norm({ 141.0f, 188.0f }),
350 147.0f * CalcInvL2Norm({ 147.0f, 162.0f }),
351 199.0f * CalcInvL2Norm({ 199.0f, 12.0f }),
352 220.0f * CalcInvL2Norm({ 220.0f, 161.0f }),
353
354 // Batch 0, Channel 1, Height (4) x Width (3)
355 110.0f * CalcInvL2Norm({ 119.0f, 110.0f }),
356 140.0f * CalcInvL2Norm({ 21.0f, 140.0f }),
357 73.0f * CalcInvL2Norm({ 150.0f, 73.0f }),
358 211.0f * CalcInvL2Norm({ 149.0f, 211.0f }),
359 212.0f * CalcInvL2Norm({ 32.0f, 212.0f }),
360 89.0f * CalcInvL2Norm({ 179.0f, 89.0f }),
361 24.0f * CalcInvL2Norm({ 15.0f, 24.0f }),
362 138.0f * CalcInvL2Norm({ 227.0f, 138.0f }),
363 188.0f * CalcInvL2Norm({ 141.0f, 188.0f }),
364 162.0f * CalcInvL2Norm({ 147.0f, 162.0f }),
365 12.0f * CalcInvL2Norm({ 199.0f, 12.0f }),
366 161.0f * CalcInvL2Norm({ 220.0f, 161.0f })
367 };
368
369 return L2NormalizationTestImpl<ArmnnType>(
370 workloadFactory,
371 memoryManager,
372 inputOutputShape,
373 scale,
374 offset,
375 inputValues,
376 outScale,
377 outOffset,
378 expectedOutputValues,
379 layout);
380}
381
382template<armnn::DataType ArmnnType, typename T = armnn::ResolveType<ArmnnType>>
383LayerTestResult<T, 4> L2Normalization4dTestCommon(
384 armnn::IWorkloadFactory& workloadFactory,
385 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
386 float scale,
387 int32_t offset,
388 float outScale,
389 int32_t outOffset,
390 const armnn::DataLayout layout)
391{
392 // Width: 3
393 // Height: 4
394 // Channels: 3
395 // BatchSize: 2
396 unsigned int numberOfBatches = 2;
397 unsigned int numberOfChannels = 3;
398 unsigned int height = 4;
399 unsigned int width = 3;
400
401 const armnn::TensorShape inputOutputShape = armnnUtils::GetTensorShape(
402 numberOfBatches, numberOfChannels, height, width, layout);
403 std::vector<float> inputValues
404 {
405 // Batch 0, Channel 0, Height (4) x Width (3)
406 235.0f, 46.0f, 178.0f,
407 100.0f, 123.0f, 19.0f,
408 172.0f, 74.0f, 250.0f,
409 6.0f, 195.0f, 80.0f,
410
411 // Batch 0, Channel 1, Height (4) x Width (3)
412 113.0f, 95.0f, 202.0f,
413 77.0f, 114.0f, 71.0f,
414 122.0f, 246.0f, 166.0f,
415 82.0f, 28.0f, 37.0f,
416
417 // Batch 0, Channel 2, Height (4) x Width (3)
418 56.0f, 170.0f, 162.0f,
419 194.0f, 89.0f, 254.0f,
420 12.0f, 209.0f, 200.0f,
421 1.0f, 64.0f, 54.0f,
422
423 // Batch 1, Channel 0, Height (4) x Width (3)
424 67.0f, 90.0f, 49.0f,
425 7.0f, 163.0f, 18.0f,
426 25.0f, 117.0f, 103.0f,
427 247.0f, 59.0f, 189.0f,
428
429 // Batch 1, Channel 1, Height (4) x Width (3)
430 239.0f, 104.0f, 199.0f,
431 17.0f, 124.0f, 153.0f,
432 222.0f, 217.0f, 75.0f,
433 32.0f, 126.0f, 21.0f,
434
435 // Batch 1, Channel 2, Height (4) x Width (3)
436 97.0f, 145.0f, 215.0f,
437 115.0f, 116.0f, 238.0f,
438 226.0f, 16.0f, 132.0f,
439 92.0f, 125.0f, 88.0f
440 };
441 std::vector<float> expectedOutputValues
442 {
443 // Batch 0, Channel 0, Height (4) x Width (3)
444 235.0f * CalcInvL2Norm({ 235.0f, 113.0f, 56.0f }),
445 46.0f * CalcInvL2Norm({ 46.0f, 95.0f, 170.0f }),
446 178.0f * CalcInvL2Norm({ 178.0f, 202.0F, 162.0f }),
447 100.0f * CalcInvL2Norm({ 100.0f, 77.0f, 194.0f }),
448 123.0f * CalcInvL2Norm({ 123.0f, 114.0f, 89.0f }),
449 19.0f * CalcInvL2Norm({ 19.0f, 71.0f, 254.0f }),
450 172.0f * CalcInvL2Norm({ 172.0f, 122.0f, 12.0f }),
451 74.0f * CalcInvL2Norm({ 74.0f, 246.0f, 209.0f }),
452 250.0f * CalcInvL2Norm({ 250.0f, 166.0f, 200.0f }),
453 6.0f * CalcInvL2Norm({ 6.0f, 82.0f, 1.0f }),
454 195.0f * CalcInvL2Norm({ 195.0f, 28.0f, 64.0f }),
455 80.0f * CalcInvL2Norm({ 80.0f, 37.0f, 54.0f }),
456
457 // Batch 0, Channel 1, Height (4) x Width (3)
458 113.0f * CalcInvL2Norm({ 235.0f, 113.0f, 56.0f }),
459 95.0f * CalcInvL2Norm({ 46.0f, 95.0f, 170.0f }),
460 202.0f * CalcInvL2Norm({ 178.0f, 202.0F, 162.0f }),
461 77.0f * CalcInvL2Norm({ 100.0f, 77.0f, 194.0f }),
462 114.0f * CalcInvL2Norm({ 123.0f, 114.0f, 89.0f }),
463 71.0f * CalcInvL2Norm({ 19.0f, 71.0f, 254.0f }),
464 122.0f * CalcInvL2Norm({ 172.0f, 122.0f, 12.0f }),
465 246.0f * CalcInvL2Norm({ 74.0f, 246.0f, 209.0f }),
466 166.0f * CalcInvL2Norm({ 250.0f, 166.0f, 200.0f }),
467 82.0f * CalcInvL2Norm({ 6.0f, 82.0f, 1.0f }),
468 28.0f * CalcInvL2Norm({ 195.0f, 28.0f, 64.0f }),
469 37.0f * CalcInvL2Norm({ 80.0f, 37.0f, 54.0f }),
470
471 // Batch 0, Channel 2, Height (4) x Width (3)
472 56.0f * CalcInvL2Norm({ 235.0f, 113.0f, 56.0f }),
473 170.0f * CalcInvL2Norm({ 46.0f, 95.0f, 170.0f }),
474 162.0f * CalcInvL2Norm({ 178.0f, 202.0F, 162.0f }),
475 194.0f * CalcInvL2Norm({ 100.0f, 77.0f, 194.0f }),
476 89.0f * CalcInvL2Norm({ 123.0f, 114.0f, 89.0f }),
477 254.0f * CalcInvL2Norm({ 19.0f, 71.0f, 254.0f }),
478 12.0f * CalcInvL2Norm({ 172.0f, 122.0f, 12.0f }),
479 209.0f * CalcInvL2Norm({ 74.0f, 246.0f, 209.0f }),
480 200.0f * CalcInvL2Norm({ 250.0f, 166.0f, 200.0f }),
481 1.0f * CalcInvL2Norm({ 6.0f, 82.0f, 1.0f }),
482 64.0f * CalcInvL2Norm({ 195.0f, 28.0f, 64.0f }),
483 54.0f * CalcInvL2Norm({ 80.0f, 37.0f, 54.0f }),
484
485 // Batch 1, Channel 0, Height (4) x Width (3)
486 67.0f * CalcInvL2Norm({ 67.0f, 239.0f, 97.0f }),
487 90.0f * CalcInvL2Norm({ 90.0f, 104.0f, 145.0f }),
488 49.0f * CalcInvL2Norm({ 49.0f, 199.0f, 215.0f }),
489 7.0f * CalcInvL2Norm({ 7.0f, 17.0f, 115.0f }),
490 163.0f * CalcInvL2Norm({ 163.0f, 124.0f, 116.0f }),
491 18.0f * CalcInvL2Norm({ 18.0f, 153.0f, 238.0f }),
492 25.0f * CalcInvL2Norm({ 25.0f, 222.0f, 226.0f }),
493 117.0f * CalcInvL2Norm({ 117.0f, 217.0f, 16.0f }),
494 103.0f * CalcInvL2Norm({ 103.0f, 75.0f, 132.0f }),
495 247.0f * CalcInvL2Norm({ 247.0f, 32.0f, 92.0f }),
496 59.0f * CalcInvL2Norm({ 59.0f, 126.0f, 125.0f }),
497 189.0f * CalcInvL2Norm({ 189.0f, 21.0f, 88.0f }),
498
499 // Batch 1, Channel 1, Height (4) x Width (3)
500 239.0f * CalcInvL2Norm({ 67.0f, 239.0f, 97.0f }),
501 104.0f * CalcInvL2Norm({ 90.0f, 104.0f, 145.0f }),
502 199.0f * CalcInvL2Norm({ 49.0f, 199.0f, 215.0f }),
503 17.0f * CalcInvL2Norm({ 7.0f, 17.0f, 115.0f }),
504 124.0f * CalcInvL2Norm({ 163.0f, 124.0f, 116.0f }),
505 153.0f * CalcInvL2Norm({ 18.0f, 153.0f, 238.0f }),
506 222.0f * CalcInvL2Norm({ 25.0f, 222.0f, 226.0f }),
507 217.0f * CalcInvL2Norm({ 117.0f, 217.0f, 16.0f }),
508 75.0f * CalcInvL2Norm({ 103.0f, 75.0f, 132.0f }),
509 32.0f * CalcInvL2Norm({ 247.0f, 32.0f, 92.0f }),
510 126.0f * CalcInvL2Norm({ 59.0f, 126.0f, 125.0f }),
511 21.0f * CalcInvL2Norm({ 189.0f, 21.0f, 88.0f }),
512
513 // Batch 1, Channel 2, Height (4) x Width (3)
514 97.0f * CalcInvL2Norm({ 67.0f, 239.0f, 97.0f }),
515 145.0f * CalcInvL2Norm({ 90.0f, 104.0f, 145.0f }),
516 215.0f * CalcInvL2Norm({ 49.0f, 199.0f, 215.0f }),
517 115.0f * CalcInvL2Norm({ 7.0f, 17.0f, 115.0f }),
518 116.0f * CalcInvL2Norm({ 163.0f, 124.0f, 116.0f }),
519 238.0f * CalcInvL2Norm({ 18.0f, 153.0f, 238.0f }),
520 226.0f * CalcInvL2Norm({ 25.0f, 222.0f, 226.0f }),
521 16.0f * CalcInvL2Norm({ 117.0f, 217.0f, 16.0f }),
522 132.0f * CalcInvL2Norm({ 103.0f, 75.0f, 132.0f }),
523 92.0f * CalcInvL2Norm({ 247.0f, 32.0f, 92.0f }),
524 125.0f * CalcInvL2Norm({ 59.0f, 126.0f, 125.0f }),
525 88.0f * CalcInvL2Norm({ 189.0f, 21.0f, 88.0f })
526 };
527
528 return L2NormalizationTestImpl<ArmnnType>(
529 workloadFactory,
530 memoryManager,
531 inputOutputShape,
532 scale,
533 offset,
534 inputValues,
535 outScale,
536 outOffset,
537 expectedOutputValues,
538 layout);
539}
540
541} // anonymous namespace
542
543LayerTestResult<float, 4> L2NormalizationDefaultEpsilonTest(
544 armnn::IWorkloadFactory& workloadFactory,
545 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
546 const armnn::DataLayout layout)
547{
548 // Dummy descriptor to get the default value of epsilon.
549 armnn::L2NormalizationDescriptor descriptor;
550
551 return L2NormalizationEpsilonTestCommon<armnn::DataType::Float32>(
552 workloadFactory,
553 memoryManager,
554 0.f,
555 0,
556 0.f,
557 0,
558 layout,
559 descriptor.m_Eps);
560}
561
562LayerTestResult<float, 4> L2NormalizationNonDefaultEpsilonTest(
563 armnn::IWorkloadFactory& workloadFactory,
564 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
565 const armnn::DataLayout layout)
566{
567 return L2NormalizationEpsilonTestCommon<armnn::DataType::Float32>(
568 workloadFactory,
569 memoryManager,
570 0.f,
571 0,
572 0.f,
573 0,
574 layout,
575 1e-9f);
576}
577
578LayerTestResult<float, 4> L2Normalization1dTest(
579 armnn::IWorkloadFactory& workloadFactory,
580 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
581 const armnn::DataLayout layout)
582{
583 return L2Normalization1dTestCommon<armnn::DataType::Float32>(
584 workloadFactory,
585 memoryManager,
586 0.f,
587 0,
588 0.f,
589 0,
590 layout);
591}
592
593LayerTestResult<int16_t, 4> L2Normalization1dInt16Test(
594 armnn::IWorkloadFactory& workloadFactory,
595 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
596 const armnn::DataLayout layout)
597{
598 return L2Normalization1dTestCommon<armnn::DataType::QuantisedSymm16>(
599 workloadFactory,
600 memoryManager,
601 1.f,
602 0,
603 1.f,
604 0,
605 layout);
606}
607
608LayerTestResult<uint8_t, 4> L2Normalization1dUint8Test(
609 armnn::IWorkloadFactory& workloadFactory,
610 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
611 const armnn::DataLayout layout)
612{
613 return L2Normalization1dTestCommon<armnn::DataType::QuantisedAsymm8>(
614 workloadFactory,
615 memoryManager,
616 1.f,
617 0,
618 1.f / 128,
619 128,
620 layout);
621}
622
623LayerTestResult<float, 4> L2Normalization2dTest(
624 armnn::IWorkloadFactory& workloadFactory,
625 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
626 const armnn::DataLayout layout)
627{
628 return L2Normalization2dTestCommon<armnn::DataType::Float32>(
629 workloadFactory,
630 memoryManager,
631 0.f,
632 0,
633 0.f,
634 0,
635 layout);
636}
637
638LayerTestResult<int16_t, 4> L2Normalization2dInt16Test(
639 armnn::IWorkloadFactory& workloadFactory,
640 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
641 const armnn::DataLayout layout)
642{
643 return L2Normalization1dTestCommon<armnn::DataType::QuantisedSymm16>(
644 workloadFactory,
645 memoryManager,
646 1.f,
647 0,
648 1.f,
649 0,
650 layout);
651}
652
653LayerTestResult<uint8_t, 4> L2Normalization2dUint8Test(
654 armnn::IWorkloadFactory& workloadFactory,
655 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
656 const armnn::DataLayout layout)
657{
658 return L2Normalization1dTestCommon<armnn::DataType::QuantisedAsymm8>(
659 workloadFactory,
660 memoryManager,
661 1.f,
662 0,
663 1.f / 128,
664 128,
665 layout);
666}
667
668LayerTestResult<float, 2> L2Normalization2dShapeTest(
669 armnn::IWorkloadFactory& workloadFactory,
670 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager)
671{
672 const armnn::DataLayout layout = armnn::DataLayout::NHWC;
673 const armnn::TensorShape inputOutputTensorShape = armnn::TensorShape({ 5, 2 });
674
675 std::vector<float> inputData
676 {
677 1.f, 2.f, 3.f, 4.f, 5.f, 6.f, 7.f, 8.f, 9.f, 10.f
678 };
679 std::vector<float> expectedOutputData
680 {
681 1.0f * CalcInvL2Norm({ 1.0f, 2.0f }),
682 2.0f * CalcInvL2Norm({ 1.0f, 2.0f }),
683 3.0f * CalcInvL2Norm({ 3.0f, 4.0f }),
684 4.0f * CalcInvL2Norm({ 3.0f, 4.0f }),
685 5.0f * CalcInvL2Norm({ 5.0f, 6.0f }),
686 6.0f * CalcInvL2Norm({ 5.0f, 6.0f }),
687 7.0f * CalcInvL2Norm({ 7.0f, 8.0f }),
688 8.0f * CalcInvL2Norm({ 7.0f, 8.0f }),
689 9.0f * CalcInvL2Norm({ 9.0f, 10.0f }),
690 10.0f * CalcInvL2Norm({ 9.0f, 10.0f })
691 };
692
693 const armnn::TensorInfo inputTensorInfo(inputOutputTensorShape, armnn::DataType::Float32, 0.f, 0);
694 const armnn::TensorInfo outputTensorInfo(inputOutputTensorShape, armnn::DataType::Float32, 0.f, 0);
695
696 auto inputTensor = MakeTensor<float, 2>(inputTensorInfo, QuantizedVector<float>(
697 inputTensorInfo.GetQuantizationScale(),
698 inputTensorInfo.GetQuantizationOffset(),
699 inputData));
700
701 LayerTestResult<float, 2> result(outputTensorInfo);
702 result.outputExpected = MakeTensor<float, 2>(outputTensorInfo, QuantizedVector<float>(
703 outputTensorInfo.GetQuantizationScale(),
704 outputTensorInfo.GetQuantizationOffset(),
705 expectedOutputData));
706
707 std::unique_ptr<armnn::ITensorHandle> inputHandle = workloadFactory.CreateTensorHandle(inputTensorInfo);
708 std::unique_ptr<armnn::ITensorHandle> outputHandle = workloadFactory.CreateTensorHandle(outputTensorInfo);
709
710 armnn::L2NormalizationQueueDescriptor descriptor;
711 descriptor.m_Parameters.m_Eps = 1e-12f;
712 descriptor.m_Parameters.m_DataLayout = layout;
713 armnn::WorkloadInfo info;
714
715 AddInputToWorkload(descriptor, info, inputTensorInfo, inputHandle.get());
716 AddOutputToWorkload(descriptor, info, outputTensorInfo, outputHandle.get());
717
718 std::unique_ptr<armnn::IWorkload> workload = workloadFactory.CreateL2Normalization(descriptor, info);
719
720 inputHandle->Allocate();
721 outputHandle->Allocate();
722
723 CopyDataToITensorHandle(inputHandle.get(), &inputTensor[0][0]);
724
725 workload->PostAllocationConfigure();
726 ExecuteWorkload(*workload, memoryManager);
727
728 CopyDataFromITensorHandle(&result.output[0][0], outputHandle.get());
729
730 return result;
731}
732
733LayerTestResult<float, 4> L2Normalization3dTest(
734 armnn::IWorkloadFactory& workloadFactory,
735 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
736 const armnn::DataLayout layout)
737{
738 return L2Normalization3dTestCommon<armnn::DataType::Float32>(
739 workloadFactory,
740 memoryManager,
741 0.f,
742 0,
743 0.f,
744 0,
745 layout);
746}
747
748LayerTestResult<int16_t, 4> L2Normalization3dInt16Test(
749 armnn::IWorkloadFactory& workloadFactory,
750 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
751 const armnn::DataLayout layout)
752{
753 return L2Normalization1dTestCommon<armnn::DataType::QuantisedSymm16>(
754 workloadFactory,
755 memoryManager,
756 1.f,
757 0,
758 1.f,
759 0,
760 layout);
761}
762
763LayerTestResult<uint8_t, 4> L2Normalization3dUint8Test(
764 armnn::IWorkloadFactory& workloadFactory,
765 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
766 const armnn::DataLayout layout)
767{
768 return L2Normalization1dTestCommon<armnn::DataType::QuantisedAsymm8>(
769 workloadFactory,
770 memoryManager,
771 1.f,
772 0,
773 1.f / 128,
774 128,
775 layout);
776}
777
778LayerTestResult<float, 4> L2Normalization4dTest(
779 armnn::IWorkloadFactory& workloadFactory,
780 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
781 const armnn::DataLayout layout)
782{
783 return L2Normalization4dTestCommon<armnn::DataType::Float32>(
784 workloadFactory,
785 memoryManager,
786 0.f,
787 0,
788 0.f,
789 0,
790 layout);
791}
792
793LayerTestResult<int16_t, 4> L2Normalization4dInt16Test(
794 armnn::IWorkloadFactory& workloadFactory,
795 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
796 const armnn::DataLayout layout)
797{
798 return L2Normalization1dTestCommon<armnn::DataType::QuantisedSymm16>(
799 workloadFactory,
800 memoryManager,
801 1.f,
802 0,
803 1.f,
804 0,
805 layout);
806}
807
808LayerTestResult<uint8_t, 4> L2Normalization4dUint8Test(
809 armnn::IWorkloadFactory& workloadFactory,
810 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
811 const armnn::DataLayout layout)
812{
813 return L2Normalization1dTestCommon<armnn::DataType::QuantisedAsymm8>(
814 workloadFactory,
815 memoryManager,
816 1.f,
817 0,
818 1.f / 128,
819 128,
820 layout);
821}