From: Ferran Balaguer Date: Mon, 17 Jun 2019 11:23:52 +0000 (+0100) Subject: IVGCVSW-3286 Add epsilon Reference workload support X-Git-Tag: submit/tizen/20200316.035456~531 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=e52211e1544a30d24b29523c389116a9e4446e8c;p=platform%2Fupstream%2Farmnn.git IVGCVSW-3286 Add epsilon Reference workload support Change-Id: I5cabbf9d1ef3858be68d6820d14845e512128c5b Signed-off-by: Ferran Balaguer --- diff --git a/include/armnn/Descriptors.hpp b/include/armnn/Descriptors.hpp index 9479db3..dd1991d 100644 --- a/include/armnn/Descriptors.hpp +++ b/include/armnn/Descriptors.hpp @@ -424,9 +424,12 @@ struct NormalizationDescriptor struct L2NormalizationDescriptor { L2NormalizationDescriptor() - : m_DataLayout(DataLayout::NCHW) + : m_Eps(1e-12f) + , m_DataLayout(DataLayout::NCHW) {} + /// Used to avoid dividing by zero. + float m_Eps; /// The data layout to be used (NCHW, NHWC). DataLayout m_DataLayout; }; diff --git a/src/backends/backendsCommon/test/LayerTests.cpp b/src/backends/backendsCommon/test/LayerTests.cpp index 55e799e..115b5ec 100644 --- a/src/backends/backendsCommon/test/LayerTests.cpp +++ b/src/backends/backendsCommon/test/LayerTests.cpp @@ -5294,7 +5294,8 @@ LayerTestResult L2NormalizationTestImpl( float outScale, int32_t outOffset, const std::vector& expectedOutputValues, - const armnn::DataLayout layout) + const armnn::DataLayout layout, + float epsilon = 1e-12f) { const armnn::TensorInfo inputTensorInfo(inputOutputTensorShape, ArmnnType, scale, offset); const armnn::TensorInfo outputTensorInfo(inputOutputTensorShape, ArmnnType, outScale, outOffset); @@ -5333,6 +5334,7 @@ LayerTestResult L2NormalizationTestImpl( std::unique_ptr outputHandle = workloadFactory.CreateTensorHandle(outputTensorInfo); armnn::L2NormalizationQueueDescriptor descriptor; + descriptor.m_Parameters.m_Eps = epsilon; descriptor.m_Parameters.m_DataLayout = layout; armnn::WorkloadInfo info; @@ -5798,6 +5800,57 @@ LayerTestResult PadFloat324dTest( } template> +LayerTestResult L2NormalizationEpsilonTestCommon( + armnn::IWorkloadFactory& workloadFactory, + const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager, + 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, inputOutputShape, scale, offset, + inputValues, outScale, outOffset, expectedOutputValues, layout, + epsilon); +} + + +template> LayerTestResult L2Normalization1dTestCommon( armnn::IWorkloadFactory& workloadFactory, const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager, @@ -5872,6 +5925,26 @@ LayerTestResult L2Normalization1dTestCommon( inputValues, outScale, outOffset, expectedOutputValues, layout); } +LayerTestResult L2NormalizationDefaultEpsilonTest( + armnn::IWorkloadFactory& workloadFactory, + const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager, + const armnn::DataLayout layout) +{ + // Dummy descriptor to get the default value of epsilon. + armnn::L2NormalizationDescriptor descriptor; + + return L2NormalizationEpsilonTestCommon(workloadFactory, memoryManager, 0.f, 0, 0.f, 0, + layout, descriptor.m_Eps); +} + +LayerTestResult L2NormalizationNonDefaultEpsilonTest( + armnn::IWorkloadFactory& workloadFactory, + const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager, + const armnn::DataLayout layout) +{ + return L2NormalizationEpsilonTestCommon(workloadFactory, memoryManager, 0.f, 0, 0.f, 0, + layout, 1e-9f); +} LayerTestResult L2Normalization1dTest( armnn::IWorkloadFactory& workloadFactory, diff --git a/src/backends/backendsCommon/test/LayerTests.hpp b/src/backends/backendsCommon/test/LayerTests.hpp index 704e88e..4c34044 100644 --- a/src/backends/backendsCommon/test/LayerTests.hpp +++ b/src/backends/backendsCommon/test/LayerTests.hpp @@ -922,6 +922,16 @@ LayerTestResult FakeQuantizationTest( armnn::IWorkloadFactory& workloadFactory, const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager); +LayerTestResult L2NormalizationDefaultEpsilonTest( + armnn::IWorkloadFactory& workloadFactory, + const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager, + const armnn::DataLayout layout); + +LayerTestResult L2NormalizationNonDefaultEpsilonTest( + armnn::IWorkloadFactory& workloadFactory, + const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager, + const armnn::DataLayout layout); + LayerTestResult L2Normalization1dTest( armnn::IWorkloadFactory& workloadFactory, const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager, diff --git a/src/backends/reference/test/RefLayerTests.cpp b/src/backends/reference/test/RefLayerTests.cpp index 7540f1d..cf4d9fd 100644 --- a/src/backends/reference/test/RefLayerTests.cpp +++ b/src/backends/reference/test/RefLayerTests.cpp @@ -528,6 +528,9 @@ ARMNN_AUTO_TEST_CASE(L2Normalization2dUint8Nhwc, L2Normalization2dUint8Test, arm ARMNN_AUTO_TEST_CASE(L2Normalization3dUint8Nhwc, L2Normalization3dUint8Test, armnn::DataLayout::NHWC) ARMNN_AUTO_TEST_CASE(L2Normalization4dUint8Nhwc, L2Normalization4dUint8Test, armnn::DataLayout::NHWC) +ARMNN_AUTO_TEST_CASE(L2NormalizationDefaultEpsilon, L2NormalizationDefaultEpsilonTest, armnn::DataLayout::NCHW) +ARMNN_AUTO_TEST_CASE(L2NormalizationNonDefaultEpsilon, L2NormalizationNonDefaultEpsilonTest, armnn::DataLayout::NCHW) + // Pad ARMNN_AUTO_TEST_CASE(PadFloat322d, PadFloat322dTest) ARMNN_AUTO_TEST_CASE(PadFloat323d, PadFloat323dTest) diff --git a/src/backends/reference/workloads/RefL2NormalizationWorkload.cpp b/src/backends/reference/workloads/RefL2NormalizationWorkload.cpp index ce5699e..3b2ab50 100644 --- a/src/backends/reference/workloads/RefL2NormalizationWorkload.cpp +++ b/src/backends/reference/workloads/RefL2NormalizationWorkload.cpp @@ -61,7 +61,9 @@ RefL2NormalizationWorkload::RefL2NormalizationWorkload( unsigned int index = dataLayout.GetIndex(inputInfo.GetShape(), n, c, h, w); - const float scale = 1.0f / sqrtf(reduction); + float maximum = reduction < m_Data.m_Parameters.m_Eps ? m_Data.m_Parameters.m_Eps : reduction; + + const float scale = 1.0f / sqrtf(maximum); (*inputDecoder)[index]; (*outputEncoder)[index];