// // Copyright © 2017 Arm Ltd and Contributors. All rights reserved. // SPDX-License-Identifier: MIT // #include "L2NormalizationTestImpl.hpp" #include #include #include #include #include #include #include #include namespace { template> LayerTestResult L2NormalizationTestImpl( armnn::IWorkloadFactory& workloadFactory, const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager, const armnn::ITensorHandleFactory& tensorHandleFactory, const armnn::TensorShape& inputOutputTensorShape, float scale, int32_t offset, const std::vector& inputValues, float outScale, int32_t outOffset, std::vector& expectedOutputValues, const armnn::DataLayout layout, float epsilon = 1e-12f) { IgnoreUnused(memoryManager); const armnn::TensorInfo inputTensorInfo(inputOutputTensorShape, ArmnnType, scale, offset); const armnn::TensorInfo outputTensorInfo(inputOutputTensorShape, ArmnnType, outScale, outOffset); // at this point if we require it permute the input data const armnn::PermutationVector NCHWToNHWC = { 0, 3, 1, 2 }; std::vector inputData = inputValues; if (layout == armnn::DataLayout::NHWC) { std::vector tmp(inputData.size()); armnnUtils::Permute(inputTensorInfo.GetShape(), NCHWToNHWC, inputData.data(), tmp.data(), sizeof(float)); inputData = tmp; } auto inputTensor = armnnUtils::QuantizedVector(inputData, inputTensorInfo.GetQuantizationScale(), inputTensorInfo.GetQuantizationOffset()); std::vector actualOutput(outputTensorInfo.GetNumElements()); if (layout == armnn::DataLayout::NHWC) { std::vector tmp(expectedOutputValues.size()); armnnUtils::Permute(inputTensorInfo.GetShape(), NCHWToNHWC, expectedOutputValues.data(), tmp.data(), sizeof(float)); expectedOutputValues = tmp; } std::vector expectedOutputData = armnnUtils::QuantizedVector(expectedOutputValues, outputTensorInfo.GetQuantizationScale(), outputTensorInfo.GetQuantizationOffset()); std::unique_ptr inputHandle = tensorHandleFactory.CreateTensorHandle(inputTensorInfo); std::unique_ptr outputHandle = tensorHandleFactory.CreateTensorHandle(outputTensorInfo); armnn::L2NormalizationQueueDescriptor descriptor; descriptor.m_Parameters.m_Eps = epsilon; descriptor.m_Parameters.m_DataLayout = layout; armnn::WorkloadInfo info; AddInputToWorkload(descriptor, info, inputTensorInfo, inputHandle.get()); AddOutputToWorkload(descriptor, info, outputTensorInfo, outputHandle.get()); std::unique_ptr workload = workloadFactory.CreateWorkload(armnn::LayerType::L2Normalization, descriptor, info); inputHandle->Allocate(); outputHandle->Allocate(); CopyDataToITensorHandle(inputHandle.get(), inputTensor.data()); workload->PostAllocationConfigure(); ExecuteWorkload(*workload, memoryManager); CopyDataFromITensorHandle(actualOutput.data(), outputHandle.get()); return LayerTestResult(actualOutput, expectedOutputData, outputHandle->GetShape(), outputTensorInfo.GetShape()); } float CalcInvL2Norm(std::initializer_list elements) { const float reduction = std::accumulate(elements.begin(), elements.end(), 0.0f, [](float acc, float element) { return acc + element * element; }); return 1.0f / sqrtf(reduction); } template> LayerTestResult L2NormalizationEpsilonTestCommon( armnn::IWorkloadFactory& workloadFactory, const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager, const armnn::ITensorHandleFactory& tensorHandleFactory, float scale, int32_t offset, float outScale, int32_t outOffset, const armnn::DataLayout layout, float epsilon) { // Width: 1 // Height: 1 // Channels: 3 // BatchSize: 1 unsigned int numberOfBatches = 1; unsigned int numberOfChannels = 3; unsigned int height = 1; unsigned int width = 1; const armnn::TensorShape inputOutputShape = armnnUtils::GetTensorShape( numberOfBatches, numberOfChannels, height, width, layout); // 0.0000001^2 + 0.00000002^2 + 0.00000003^2 < 1e-12 std::vector inputValues { // Batch 0, Channel 0, Height (1) x Width (1) 0.00000001f, // Batch 0, Channel 1, Height (1) x Width (1) 0.00000002f, // Batch 0, Channel 2, Height (1) x Width (1) 0.00000003f, }; const float approxInvL2Norm = 1.f / sqrtf(epsilon); std::vector expectedOutputValues { // Batch 0, Channel 0, Height (1) x Width (1) 0.00000001f * approxInvL2Norm, 0.00000002f * approxInvL2Norm, 0.00000003f * approxInvL2Norm, }; return L2NormalizationTestImpl( workloadFactory, memoryManager, tensorHandleFactory, inputOutputShape, scale, offset, inputValues, outScale, outOffset, expectedOutputValues, layout, epsilon); } template> LayerTestResult L2Normalization1dTestCommon( armnn::IWorkloadFactory& workloadFactory, const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager, const armnn::ITensorHandleFactory& tensorHandleFactory, float scale, int32_t offset, float outScale, int32_t outOffset, const armnn::DataLayout layout) { // Width: 1 // Height: 1 // Channels: 10 // BatchSize: 1 unsigned int numberOfBatches = 1; unsigned int numberOfChannels = 10; unsigned int height = 1; unsigned int width = 1; const armnn::TensorShape inputOutputShape = armnnUtils::GetTensorShape( numberOfBatches, numberOfChannels, height, width, layout); std::vector inputValues { // Batch 0, Channel 0, Height (1) x Width (1) 1.0f, // Batch 0, Channel 1, Height (1) x Width (1) 2.0f, // Batch 0, Channel 2, Height (1) x Width (1) 3.0f, // Batch 0, Channel 3, Height (1) x Width (1) 4.0f, // Batch 0, Channel 4, Height (1) x Width (1) 5.0f, // Batch 0, Channel 5, Height (1) x Width (1) 6.0f, // Batch 0, Channel 6, Height (1) x Width (1) 7.0f, // Batch 0, Channel 7, Height (1) x Width (1) 8.0f, // Batch 0, Channel 8, Height (1) x Width (1) 9.0f, // Batch 0, Channel 9, Height (1) x Width (1) 10.0f }; const float approxInvL2Norm = 0.050964719f; std::vector expectedOutputValues { // Batch 0, Channel 0, Height (1) x Width (1) 1.0f * approxInvL2Norm, 2.0f * approxInvL2Norm, 3.0f * approxInvL2Norm, 4.0f * approxInvL2Norm, 5.0f * approxInvL2Norm, 6.0f * approxInvL2Norm, 7.0f * approxInvL2Norm, 8.0f * approxInvL2Norm, 9.0f * approxInvL2Norm, 10.0f * approxInvL2Norm }; return L2NormalizationTestImpl( workloadFactory, memoryManager, tensorHandleFactory, inputOutputShape, scale, offset, inputValues, outScale, outOffset, expectedOutputValues, layout); } template> LayerTestResult L2Normalization2dTestCommon( armnn::IWorkloadFactory& workloadFactory, const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager, const armnn::ITensorHandleFactory& tensorHandleFactory, float scale, int32_t offset, float outScale, int32_t outOffset, const armnn::DataLayout layout) { // Width: 5 // Height: 1 // Channels: 2 // BatchSize: 1 unsigned int numberOfBatches = 1; unsigned int numberOfChannels = 2; unsigned int height = 1; unsigned int width = 5; const armnn::TensorShape inputOutputShape = armnnUtils::GetTensorShape( numberOfBatches, numberOfChannels, height, width, layout); std::vector inputValues { // Batch 0, Channel 0, Height (1) x Width (5) 1.0f, 3.0f, 5.0f, 7.0f, 9.0f, // Batch 0, Channel 1, Height (1) x Width (5) 2.0f, 4.0f, 6.0f, 8.0f, 10.0f }; std::vector expectedOutputValues { // Batch 0, Channel 0, Height (1) x Width (5) 1.0f * CalcInvL2Norm({ 1.0f, 2.0f }), 3.0f * CalcInvL2Norm({ 3.0f, 4.0f }), 5.0f * CalcInvL2Norm({ 5.0f, 6.0f }), 7.0f * CalcInvL2Norm({ 7.0f, 8.0f }), 9.0f * CalcInvL2Norm({ 9.0f, 10.0f }), // Batch 0, Channel 1, Height (1) x Width (5) 2.0f * CalcInvL2Norm({ 1.0f, 2.0f }), 4.0f * CalcInvL2Norm({ 3.0f, 4.0f }), 6.0f * CalcInvL2Norm({ 5.0f, 6.0f }), 8.0f * CalcInvL2Norm({ 7.0f, 8.0f }), 10.0f * CalcInvL2Norm({ 9.0f, 10.0f }) }; return L2NormalizationTestImpl( workloadFactory, memoryManager, tensorHandleFactory, inputOutputShape, scale, offset, inputValues, outScale, outOffset, expectedOutputValues, layout); } template> LayerTestResult L2Normalization3dTestCommon( armnn::IWorkloadFactory& workloadFactory, const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager, const armnn::ITensorHandleFactory& tensorHandleFactory, float scale, int32_t offset, float outScale, int32_t outOffset, const armnn::DataLayout layout) { // Width: 3 // Height: 4 // Channels: 2 // BatchSize: 1 unsigned int numberOfBatches = 1; unsigned int numberOfChannels = 2; unsigned int height = 4; unsigned int width = 3; const armnn::TensorShape inputOutputShape = armnnUtils::GetTensorShape( numberOfBatches, numberOfChannels, height, width, layout); std::vector inputValues { // Batch 0, Channel 0, Height (4) x Width (3) 119.0f, 21.0f, 150.0f, 149.0f, 32.0f, 179.0f, 15.0f, 227.0f, 141.0f, 147.0f, 199.0f, 220.0f, // Batch 0, Channel 1, Height (4) x Width (3) 110.0f, 140.0f, 73.0f, 211.0f, 212.0f, 89.0f, 24.0f, 138.0f, 188.0f, 162.0f, 12.0f, 161.0f }; std::vector expectedOutputValues { // Batch 0, Channel 0, Height (4) x Width (3) 119.0f * CalcInvL2Norm({ 119.0f, 110.0f }), 21.0f * CalcInvL2Norm({ 21.0f, 140.0f }), 150.0f * CalcInvL2Norm({ 150.0f, 73.0f }), 149.0f * CalcInvL2Norm({ 149.0f, 211.0f }), 32.0f * CalcInvL2Norm({ 32.0f, 212.0f }), 179.0f * CalcInvL2Norm({ 179.0f, 89.0f }), 15.0f * CalcInvL2Norm({ 15.0f, 24.0f }), 227.0f * CalcInvL2Norm({ 227.0f, 138.0f }), 141.0f * CalcInvL2Norm({ 141.0f, 188.0f }), 147.0f * CalcInvL2Norm({ 147.0f, 162.0f }), 199.0f * CalcInvL2Norm({ 199.0f, 12.0f }), 220.0f * CalcInvL2Norm({ 220.0f, 161.0f }), // Batch 0, Channel 1, Height (4) x Width (3) 110.0f * CalcInvL2Norm({ 119.0f, 110.0f }), 140.0f * CalcInvL2Norm({ 21.0f, 140.0f }), 73.0f * CalcInvL2Norm({ 150.0f, 73.0f }), 211.0f * CalcInvL2Norm({ 149.0f, 211.0f }), 212.0f * CalcInvL2Norm({ 32.0f, 212.0f }), 89.0f * CalcInvL2Norm({ 179.0f, 89.0f }), 24.0f * CalcInvL2Norm({ 15.0f, 24.0f }), 138.0f * CalcInvL2Norm({ 227.0f, 138.0f }), 188.0f * CalcInvL2Norm({ 141.0f, 188.0f }), 162.0f * CalcInvL2Norm({ 147.0f, 162.0f }), 12.0f * CalcInvL2Norm({ 199.0f, 12.0f }), 161.0f * CalcInvL2Norm({ 220.0f, 161.0f }) }; return L2NormalizationTestImpl( workloadFactory, memoryManager, tensorHandleFactory, inputOutputShape, scale, offset, inputValues, outScale, outOffset, expectedOutputValues, layout); } template> LayerTestResult L2Normalization4dTestCommon( armnn::IWorkloadFactory& workloadFactory, const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager, const armnn::ITensorHandleFactory& tensorHandleFactory, float scale, int32_t offset, float outScale, int32_t outOffset, const armnn::DataLayout layout) { // Width: 3 // Height: 4 // Channels: 3 // BatchSize: 2 unsigned int numberOfBatches = 2; unsigned int numberOfChannels = 3; unsigned int height = 4; unsigned int width = 3; const armnn::TensorShape inputOutputShape = armnnUtils::GetTensorShape( numberOfBatches, numberOfChannels, height, width, layout); std::vector inputValues { // Batch 0, Channel 0, Height (4) x Width (3) 235.0f, 46.0f, 178.0f, 100.0f, 123.0f, 19.0f, 172.0f, 74.0f, 250.0f, 6.0f, 195.0f, 80.0f, // Batch 0, Channel 1, Height (4) x Width (3) 113.0f, 95.0f, 202.0f, 77.0f, 114.0f, 71.0f, 122.0f, 246.0f, 166.0f, 82.0f, 28.0f, 37.0f, // Batch 0, Channel 2, Height (4) x Width (3) 56.0f, 170.0f, 162.0f, 194.0f, 89.0f, 254.0f, 12.0f, 209.0f, 200.0f, 1.0f, 64.0f, 54.0f, // Batch 1, Channel 0, Height (4) x Width (3) 67.0f, 90.0f, 49.0f, 7.0f, 163.0f, 18.0f, 25.0f, 117.0f, 103.0f, 247.0f, 59.0f, 189.0f, // Batch 1, Channel 1, Height (4) x Width (3) 239.0f, 104.0f, 199.0f, 17.0f, 124.0f, 153.0f, 222.0f, 217.0f, 75.0f, 32.0f, 126.0f, 21.0f, // Batch 1, Channel 2, Height (4) x Width (3) 97.0f, 145.0f, 215.0f, 115.0f, 116.0f, 238.0f, 226.0f, 16.0f, 132.0f, 92.0f, 125.0f, 88.0f }; std::vector expectedOutputValues { // Batch 0, Channel 0, Height (4) x Width (3) 235.0f * CalcInvL2Norm({ 235.0f, 113.0f, 56.0f }), 46.0f * CalcInvL2Norm({ 46.0f, 95.0f, 170.0f }), 178.0f * CalcInvL2Norm({ 178.0f, 202.0F, 162.0f }), 100.0f * CalcInvL2Norm({ 100.0f, 77.0f, 194.0f }), 123.0f * CalcInvL2Norm({ 123.0f, 114.0f, 89.0f }), 19.0f * CalcInvL2Norm({ 19.0f, 71.0f, 254.0f }), 172.0f * CalcInvL2Norm({ 172.0f, 122.0f, 12.0f }), 74.0f * CalcInvL2Norm({ 74.0f, 246.0f, 209.0f }), 250.0f * CalcInvL2Norm({ 250.0f, 166.0f, 200.0f }), 6.0f * CalcInvL2Norm({ 6.0f, 82.0f, 1.0f }), 195.0f * CalcInvL2Norm({ 195.0f, 28.0f, 64.0f }), 80.0f * CalcInvL2Norm({ 80.0f, 37.0f, 54.0f }), // Batch 0, Channel 1, Height (4) x Width (3) 113.0f * CalcInvL2Norm({ 235.0f, 113.0f, 56.0f }), 95.0f * CalcInvL2Norm({ 46.0f, 95.0f, 170.0f }), 202.0f * CalcInvL2Norm({ 178.0f, 202.0F, 162.0f }), 77.0f * CalcInvL2Norm({ 100.0f, 77.0f, 194.0f }), 114.0f * CalcInvL2Norm({ 123.0f, 114.0f, 89.0f }), 71.0f * CalcInvL2Norm({ 19.0f, 71.0f, 254.0f }), 122.0f * CalcInvL2Norm({ 172.0f, 122.0f, 12.0f }), 246.0f * CalcInvL2Norm({ 74.0f, 246.0f, 209.0f }), 166.0f * CalcInvL2Norm({ 250.0f, 166.0f, 200.0f }), 82.0f * CalcInvL2Norm({ 6.0f, 82.0f, 1.0f }), 28.0f * CalcInvL2Norm({ 195.0f, 28.0f, 64.0f }), 37.0f * CalcInvL2Norm({ 80.0f, 37.0f, 54.0f }), // Batch 0, Channel 2, Height (4) x Width (3) 56.0f * CalcInvL2Norm({ 235.0f, 113.0f, 56.0f }), 170.0f * CalcInvL2Norm({ 46.0f, 95.0f, 170.0f }), 162.0f * CalcInvL2Norm({ 178.0f, 202.0F, 162.0f }), 194.0f * CalcInvL2Norm({ 100.0f, 77.0f, 194.0f }), 89.0f * CalcInvL2Norm({ 123.0f, 114.0f, 89.0f }), 254.0f * CalcInvL2Norm({ 19.0f, 71.0f, 254.0f }), 12.0f * CalcInvL2Norm({ 172.0f, 122.0f, 12.0f }), 209.0f * CalcInvL2Norm({ 74.0f, 246.0f, 209.0f }), 200.0f * CalcInvL2Norm({ 250.0f, 166.0f, 200.0f }), 1.0f * CalcInvL2Norm({ 6.0f, 82.0f, 1.0f }), 64.0f * CalcInvL2Norm({ 195.0f, 28.0f, 64.0f }), 54.0f * CalcInvL2Norm({ 80.0f, 37.0f, 54.0f }), // Batch 1, Channel 0, Height (4) x Width (3) 67.0f * CalcInvL2Norm({ 67.0f, 239.0f, 97.0f }), 90.0f * CalcInvL2Norm({ 90.0f, 104.0f, 145.0f }), 49.0f * CalcInvL2Norm({ 49.0f, 199.0f, 215.0f }), 7.0f * CalcInvL2Norm({ 7.0f, 17.0f, 115.0f }), 163.0f * CalcInvL2Norm({ 163.0f, 124.0f, 116.0f }), 18.0f * CalcInvL2Norm({ 18.0f, 153.0f, 238.0f }), 25.0f * CalcInvL2Norm({ 25.0f, 222.0f, 226.0f }), 117.0f * CalcInvL2Norm({ 117.0f, 217.0f, 16.0f }), 103.0f * CalcInvL2Norm({ 103.0f, 75.0f, 132.0f }), 247.0f * CalcInvL2Norm({ 247.0f, 32.0f, 92.0f }), 59.0f * CalcInvL2Norm({ 59.0f, 126.0f, 125.0f }), 189.0f * CalcInvL2Norm({ 189.0f, 21.0f, 88.0f }), // Batch 1, Channel 1, Height (4) x Width (3) 239.0f * CalcInvL2Norm({ 67.0f, 239.0f, 97.0f }), 104.0f * CalcInvL2Norm({ 90.0f, 104.0f, 145.0f }), 199.0f * CalcInvL2Norm({ 49.0f, 199.0f, 215.0f }), 17.0f * CalcInvL2Norm({ 7.0f, 17.0f, 115.0f }), 124.0f * CalcInvL2Norm({ 163.0f, 124.0f, 116.0f }), 153.0f * CalcInvL2Norm({ 18.0f, 153.0f, 238.0f }), 222.0f * CalcInvL2Norm({ 25.0f, 222.0f, 226.0f }), 217.0f * CalcInvL2Norm({ 117.0f, 217.0f, 16.0f }), 75.0f * CalcInvL2Norm({ 103.0f, 75.0f, 132.0f }), 32.0f * CalcInvL2Norm({ 247.0f, 32.0f, 92.0f }), 126.0f * CalcInvL2Norm({ 59.0f, 126.0f, 125.0f }), 21.0f * CalcInvL2Norm({ 189.0f, 21.0f, 88.0f }), // Batch 1, Channel 2, Height (4) x Width (3) 97.0f * CalcInvL2Norm({ 67.0f, 239.0f, 97.0f }), 145.0f * CalcInvL2Norm({ 90.0f, 104.0f, 145.0f }), 215.0f * CalcInvL2Norm({ 49.0f, 199.0f, 215.0f }), 115.0f * CalcInvL2Norm({ 7.0f, 17.0f, 115.0f }), 116.0f * CalcInvL2Norm({ 163.0f, 124.0f, 116.0f }), 238.0f * CalcInvL2Norm({ 18.0f, 153.0f, 238.0f }), 226.0f * CalcInvL2Norm({ 25.0f, 222.0f, 226.0f }), 16.0f * CalcInvL2Norm({ 117.0f, 217.0f, 16.0f }), 132.0f * CalcInvL2Norm({ 103.0f, 75.0f, 132.0f }), 92.0f * CalcInvL2Norm({ 247.0f, 32.0f, 92.0f }), 125.0f * CalcInvL2Norm({ 59.0f, 126.0f, 125.0f }), 88.0f * CalcInvL2Norm({ 189.0f, 21.0f, 88.0f }) }; return L2NormalizationTestImpl( workloadFactory, memoryManager, tensorHandleFactory, inputOutputShape, scale, offset, inputValues, outScale, outOffset, expectedOutputValues, layout); } } // anonymous namespace LayerTestResult L2NormalizationDefaultEpsilonTest( armnn::IWorkloadFactory& workloadFactory, const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager, const armnn::ITensorHandleFactory& tensorHandleFactory, const armnn::DataLayout layout) { // Dummy descriptor to get the default value of epsilon. armnn::L2NormalizationDescriptor descriptor; return L2NormalizationEpsilonTestCommon( workloadFactory, memoryManager, tensorHandleFactory, 0.f, 0, 0.f, 0, layout, descriptor.m_Eps); } LayerTestResult L2NormalizationNonDefaultEpsilonTest( armnn::IWorkloadFactory& workloadFactory, const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager, const armnn::ITensorHandleFactory& tensorHandleFactory, const armnn::DataLayout layout) { return L2NormalizationEpsilonTestCommon( workloadFactory, memoryManager, tensorHandleFactory, 0.f, 0, 0.f, 0, layout, 1e-9f); } LayerTestResult L2Normalization1dTest( armnn::IWorkloadFactory& workloadFactory, const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager, const armnn::ITensorHandleFactory& tensorHandleFactory, const armnn::DataLayout layout) { return L2Normalization1dTestCommon( workloadFactory, memoryManager, tensorHandleFactory, 0.f, 0, 0.f, 0, layout); } LayerTestResult L2Normalization1dInt16Test( armnn::IWorkloadFactory& workloadFactory, const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager, const armnn::ITensorHandleFactory& tensorHandleFactory, const armnn::DataLayout layout) { return L2Normalization1dTestCommon( workloadFactory, memoryManager, tensorHandleFactory, 1.f, 0, 1.f, 0, layout); } LayerTestResult L2Normalization1dUint8Test( armnn::IWorkloadFactory& workloadFactory, const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager, const armnn::ITensorHandleFactory& tensorHandleFactory, const armnn::DataLayout layout) { return L2Normalization1dTestCommon( workloadFactory, memoryManager, tensorHandleFactory, 1.f, 0, 1.f / 128, 128, layout); } LayerTestResult L2Normalization2dTest( armnn::IWorkloadFactory& workloadFactory, const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager, const armnn::ITensorHandleFactory& tensorHandleFactory, const armnn::DataLayout layout) { return L2Normalization2dTestCommon( workloadFactory, memoryManager, tensorHandleFactory, 0.f, 0, 0.f, 0, layout); } LayerTestResult L2Normalization2dInt16Test( armnn::IWorkloadFactory& workloadFactory, const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager, const armnn::ITensorHandleFactory& tensorHandleFactory, const armnn::DataLayout layout) { return L2Normalization1dTestCommon( workloadFactory, memoryManager, tensorHandleFactory, 1.f, 0, 1.f, 0, layout); } LayerTestResult L2Normalization2dUint8Test( armnn::IWorkloadFactory& workloadFactory, const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager, const armnn::ITensorHandleFactory& tensorHandleFactory, const armnn::DataLayout layout) { return L2Normalization1dTestCommon( workloadFactory, memoryManager, tensorHandleFactory, 1.f, 0, 1.f / 128, 128, layout); } LayerTestResult L2Normalization2dShapeTest( armnn::IWorkloadFactory& workloadFactory, const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager, const armnn::ITensorHandleFactory& tensorHandleFactory) { const armnn::DataLayout layout = armnn::DataLayout::NHWC; const armnn::TensorShape inputOutputTensorShape = armnn::TensorShape({ 5, 2 }); std::vector inputData { 1.f, 2.f, 3.f, 4.f, 5.f, 6.f, 7.f, 8.f, 9.f, 10.f }; std::vector expectedOutputData { 1.0f * CalcInvL2Norm({ 1.0f, 2.0f }), 2.0f * CalcInvL2Norm({ 1.0f, 2.0f }), 3.0f * CalcInvL2Norm({ 3.0f, 4.0f }), 4.0f * CalcInvL2Norm({ 3.0f, 4.0f }), 5.0f * CalcInvL2Norm({ 5.0f, 6.0f }), 6.0f * CalcInvL2Norm({ 5.0f, 6.0f }), 7.0f * CalcInvL2Norm({ 7.0f, 8.0f }), 8.0f * CalcInvL2Norm({ 7.0f, 8.0f }), 9.0f * CalcInvL2Norm({ 9.0f, 10.0f }), 10.0f * CalcInvL2Norm({ 9.0f, 10.0f }) }; const armnn::TensorInfo inputTensorInfo(inputOutputTensorShape, armnn::DataType::Float32, 0.f, 0); const armnn::TensorInfo outputTensorInfo(inputOutputTensorShape, armnn::DataType::Float32, 0.f, 0); std::vector actualOutput(outputTensorInfo.GetNumElements()); std::unique_ptr inputHandle = tensorHandleFactory.CreateTensorHandle(inputTensorInfo); std::unique_ptr outputHandle = tensorHandleFactory.CreateTensorHandle(outputTensorInfo); armnn::L2NormalizationQueueDescriptor descriptor; descriptor.m_Parameters.m_Eps = 1e-12f; descriptor.m_Parameters.m_DataLayout = layout; armnn::WorkloadInfo info; AddInputToWorkload(descriptor, info, inputTensorInfo, inputHandle.get()); AddOutputToWorkload(descriptor, info, outputTensorInfo, outputHandle.get()); std::unique_ptr workload = workloadFactory.CreateWorkload(armnn::LayerType::L2Normalization, descriptor, info); inputHandle->Allocate(); outputHandle->Allocate(); CopyDataToITensorHandle(inputHandle.get(), inputData.data()); workload->PostAllocationConfigure(); ExecuteWorkload(*workload, memoryManager); CopyDataFromITensorHandle(actualOutput.data(), outputHandle.get()); return LayerTestResult(actualOutput, expectedOutputData, outputHandle->GetShape(), outputTensorInfo.GetShape()); } LayerTestResult L2Normalization3dTest( armnn::IWorkloadFactory& workloadFactory, const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager, const armnn::ITensorHandleFactory& tensorHandleFactory, const armnn::DataLayout layout) { return L2Normalization3dTestCommon( workloadFactory, memoryManager, tensorHandleFactory, 0.f, 0, 0.f, 0, layout); } LayerTestResult L2Normalization3dInt16Test( armnn::IWorkloadFactory& workloadFactory, const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager, const armnn::ITensorHandleFactory& tensorHandleFactory, const armnn::DataLayout layout) { return L2Normalization1dTestCommon( workloadFactory, memoryManager, tensorHandleFactory, 1.f, 0, 1.f, 0, layout); } LayerTestResult L2Normalization3dUint8Test( armnn::IWorkloadFactory& workloadFactory, const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager, const armnn::ITensorHandleFactory& tensorHandleFactory, const armnn::DataLayout layout) { return L2Normalization1dTestCommon( workloadFactory, memoryManager, tensorHandleFactory, 1.f, 0, 1.f / 128, 128, layout); } LayerTestResult L2Normalization4dTest( armnn::IWorkloadFactory& workloadFactory, const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager, const armnn::ITensorHandleFactory& tensorHandleFactory, const armnn::DataLayout layout) { return L2Normalization4dTestCommon( workloadFactory, memoryManager, tensorHandleFactory, 0.f, 0, 0.f, 0, layout); } LayerTestResult L2Normalization4dInt16Test( armnn::IWorkloadFactory& workloadFactory, const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager, const armnn::ITensorHandleFactory& tensorHandleFactory, const armnn::DataLayout layout) { return L2Normalization1dTestCommon( workloadFactory, memoryManager, tensorHandleFactory, 1.f, 0, 1.f, 0, layout); } LayerTestResult L2Normalization4dUint8Test( armnn::IWorkloadFactory& workloadFactory, const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager, const armnn::ITensorHandleFactory& tensorHandleFactory, const armnn::DataLayout layout) { return L2Normalization1dTestCommon( workloadFactory, memoryManager, tensorHandleFactory, 1.f, 0, 1.f / 128, 128, layout); }