aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFerran Balaguer <ferran.balaguer@arm.com>2019-06-17 12:23:52 +0100
committerFerran Balaguer Arm <ferran.balaguer@arm.com>2019-06-17 14:53:05 +0000
commite52211e1544a30d24b29523c389116a9e4446e8c (patch)
tree8d2cce39db4c89509a8b6c8569e85edb6d348b4b
parent0b679f03ead8848edc225d44afbbcc54d112e433 (diff)
downloadarmnn-e52211e1544a30d24b29523c389116a9e4446e8c.tar.gz
IVGCVSW-3286 Add epsilon Reference workload support
Change-Id: I5cabbf9d1ef3858be68d6820d14845e512128c5b Signed-off-by: Ferran Balaguer <ferran.balaguer@arm.com>
-rw-r--r--include/armnn/Descriptors.hpp5
-rw-r--r--src/backends/backendsCommon/test/LayerTests.cpp75
-rw-r--r--src/backends/backendsCommon/test/LayerTests.hpp10
-rw-r--r--src/backends/reference/test/RefLayerTests.cpp3
-rw-r--r--src/backends/reference/workloads/RefL2NormalizationWorkload.cpp4
5 files changed, 94 insertions, 3 deletions
diff --git a/include/armnn/Descriptors.hpp b/include/armnn/Descriptors.hpp
index 9479db3571..dd1991d569 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 55e799e1be..115b5ecf41 100644
--- a/src/backends/backendsCommon/test/LayerTests.cpp
+++ b/src/backends/backendsCommon/test/LayerTests.cpp
@@ -5294,7 +5294,8 @@ LayerTestResult<T, 4> L2NormalizationTestImpl(
float outScale,
int32_t outOffset,
const std::vector<float>& 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<T, 4> L2NormalizationTestImpl(
std::unique_ptr<armnn::ITensorHandle> 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<float, 4> PadFloat324dTest(
}
template<armnn::DataType ArmnnType, typename T = armnn::ResolveType<ArmnnType>>
+LayerTestResult<T, 4> 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<float> 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<float> expectedOutputValues
+ {
+ // Batch 0, Channel 0, Height (1) x Width (1)
+ 0.00000001f * approxInvL2Norm,
+ 0.00000002f * approxInvL2Norm,
+ 0.00000003f * approxInvL2Norm,
+ };
+
+ return L2NormalizationTestImpl<ArmnnType>(workloadFactory, memoryManager, inputOutputShape, scale, offset,
+ inputValues, outScale, outOffset, expectedOutputValues, layout,
+ epsilon);
+}
+
+
+template<armnn::DataType ArmnnType, typename T = armnn::ResolveType<ArmnnType>>
LayerTestResult<T, 4> L2Normalization1dTestCommon(
armnn::IWorkloadFactory& workloadFactory,
const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
@@ -5872,6 +5925,26 @@ LayerTestResult<T, 4> L2Normalization1dTestCommon(
inputValues, outScale, outOffset, expectedOutputValues, layout);
}
+LayerTestResult<float, 4> 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<armnn::DataType::Float32>(workloadFactory, memoryManager, 0.f, 0, 0.f, 0,
+ layout, descriptor.m_Eps);
+}
+
+LayerTestResult<float, 4> L2NormalizationNonDefaultEpsilonTest(
+ armnn::IWorkloadFactory& workloadFactory,
+ const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
+ const armnn::DataLayout layout)
+{
+ return L2NormalizationEpsilonTestCommon<armnn::DataType::Float32>(workloadFactory, memoryManager, 0.f, 0, 0.f, 0,
+ layout, 1e-9f);
+}
LayerTestResult<float, 4> L2Normalization1dTest(
armnn::IWorkloadFactory& workloadFactory,
diff --git a/src/backends/backendsCommon/test/LayerTests.hpp b/src/backends/backendsCommon/test/LayerTests.hpp
index 704e88ef6b..4c340447b9 100644
--- a/src/backends/backendsCommon/test/LayerTests.hpp
+++ b/src/backends/backendsCommon/test/LayerTests.hpp
@@ -922,6 +922,16 @@ LayerTestResult<float, 2> FakeQuantizationTest(
armnn::IWorkloadFactory& workloadFactory,
const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager);
+LayerTestResult<float, 4> L2NormalizationDefaultEpsilonTest(
+ armnn::IWorkloadFactory& workloadFactory,
+ const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
+ const armnn::DataLayout layout);
+
+LayerTestResult<float, 4> L2NormalizationNonDefaultEpsilonTest(
+ armnn::IWorkloadFactory& workloadFactory,
+ const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
+ const armnn::DataLayout layout);
+
LayerTestResult<float, 4> 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 7540f1d4c1..cf4d9fd6f9 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 ce5699ef0b..3b2ab50c8b 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];