aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorFrancis Murtagh <francis.murtagh@arm.com>2018-08-30 17:18:37 +0100
committerMatthew Bentham <matthew.bentham@arm.com>2018-09-17 17:21:25 +0100
commit8c5e3dc9f04ac15aa926d1a1214610760830dbe2 (patch)
tree354518d6b2db9c46e4b698fcfbedb629a5569b48 /src
parente7a86a4a3363993fb41b1ea62f23b3643b8b0c78 (diff)
downloadarmnn-8c5e3dc9f04ac15aa926d1a1214610760830dbe2.tar.gz
IVGCVSW-1786 - Division by zero
* Added logic for different cases of division by zero for ref * Added DivisionByZeroTest * Updated SelectiveComparer to compare NAN and INFINITY Change-Id: Iec6f89264b17a0b03fad5d7ec4b2dafc31fea5df
Diffstat (limited to 'src')
-rw-r--r--src/armnn/backends/RefWorkloads/Division.cpp41
-rw-r--r--src/armnn/backends/test/LayerTests.cpp30
-rw-r--r--src/armnn/backends/test/LayerTests.hpp1
-rw-r--r--src/armnn/backends/test/Reference.cpp1
-rw-r--r--src/armnn/test/TensorHelpers.hpp11
5 files changed, 82 insertions, 2 deletions
diff --git a/src/armnn/backends/RefWorkloads/Division.cpp b/src/armnn/backends/RefWorkloads/Division.cpp
index 9837fea6b4..9c1142226c 100644
--- a/src/armnn/backends/RefWorkloads/Division.cpp
+++ b/src/armnn/backends/RefWorkloads/Division.cpp
@@ -8,6 +8,8 @@
#include <functional>
+#include <cmath>
+
namespace
{
@@ -18,8 +20,43 @@ void ElementwiseDivision(unsigned int numElements,
{
for (unsigned int i = 0; i < numElements; ++i)
{
- //TODO How to handle divide by 0
- outData[i] = inData0[i] / inData1[i];
+ if (inData1[i] != 0.0f)
+ {
+ outData[i] = inData0[i] / inData1[i];
+ }
+ else if (inData0[i] == 0.0f)
+ {
+ if (!std::signbit(inData1[i]))
+ {
+ outData[i]= NAN;
+ }
+ else
+ {
+ outData[i]= -NAN;
+ }
+ }
+ else if (inData0[i] < 0.0f)
+ {
+ if (!std::signbit(inData1[i]))
+ {
+ outData[i] = -INFINITY;
+ }
+ else
+ {
+ outData[i] = INFINITY;
+ }
+ }
+ else
+ {
+ if (!std::signbit(inData1[i]))
+ {
+ outData[i] = INFINITY;
+ }
+ else
+ {
+ outData[i] = -INFINITY;
+ }
+ }
}
}
diff --git a/src/armnn/backends/test/LayerTests.cpp b/src/armnn/backends/test/LayerTests.cpp
index e916c05397..36a2ad8717 100644
--- a/src/armnn/backends/test/LayerTests.cpp
+++ b/src/armnn/backends/test/LayerTests.cpp
@@ -1117,6 +1117,36 @@ namespace {
}
} // anonymous namespace
+LayerTestResult<float,4> DivisionByZeroTest(armnn::IWorkloadFactory& workloadFactory)
+{
+ const unsigned int width = 2;
+ const unsigned int height = 2;
+ const unsigned int channelCount = 2;
+ const unsigned int batchSize = 2;
+
+ unsigned int shape[] = { batchSize, channelCount, height, width };
+
+ std::vector<float> input0({
+ 1.f, 1.f, 1.f, 1.f, 0.f, 0.f, 0.f, 0.f,
+ -1.f, -1.f, -1.f, -1.f, 5.f, 5.f, 5.f, 5.f });
+
+ std::vector<float> input1({
+ 0.f, 0.f, -0.f, -0.f, 0.f, 0.f, -0.f, -0.f,
+ 0.f, 0.f, -0.f, -0.f, 5.f, 5.f, 5.f, 5.f });
+
+ std::vector<float> output({
+ INFINITY, INFINITY, -INFINITY, -INFINITY, NAN, NAN, -NAN, -NAN,
+ -INFINITY, -INFINITY, INFINITY, INFINITY, 1, 1, 1, 1 });
+
+ return DivisionTestHelper(workloadFactory,
+ shape,
+ input0,
+ shape,
+ input1,
+ shape,
+ output);
+}
+
LayerTestResult<float,4> DivisionTest(armnn::IWorkloadFactory& workloadFactory)
{
const unsigned int width = 2;
diff --git a/src/armnn/backends/test/LayerTests.hpp b/src/armnn/backends/test/LayerTests.hpp
index a59ff05c90..b74cad296c 100644
--- a/src/armnn/backends/test/LayerTests.hpp
+++ b/src/armnn/backends/test/LayerTests.hpp
@@ -193,6 +193,7 @@ LayerTestResult<float, 4> CompareActivationTest(armnn::IWorkloadFactory& worklo
unsigned int batchSize);
LayerTestResult<float, 4> DivisionTest(armnn::IWorkloadFactory& workloadFactory);
+LayerTestResult<float, 4> DivisionByZeroTest(armnn::IWorkloadFactory& workloadFactory);
LayerTestResult<float, 4> DivisionBroadcast1ElementTest(armnn::IWorkloadFactory& workloadFactory);
LayerTestResult<float, 4> DivisionBroadcast1DVectorTest(armnn::IWorkloadFactory& workloadFactory);
diff --git a/src/armnn/backends/test/Reference.cpp b/src/armnn/backends/test/Reference.cpp
index b31723c3a3..e19e4d5a2f 100644
--- a/src/armnn/backends/test/Reference.cpp
+++ b/src/armnn/backends/test/Reference.cpp
@@ -148,6 +148,7 @@ ARMNN_AUTO_TEST_CASE(AddBroadcast1ElementUint8, AdditionBroadcast1ElementUint8Te
// Div
ARMNN_AUTO_TEST_CASE(SimpleDivision, DivisionTest)
+ARMNN_AUTO_TEST_CASE(DivisionByZero, DivisionByZeroTest)
ARMNN_AUTO_TEST_CASE(DivisionBroadcast1Element, DivisionBroadcast1ElementTest)
ARMNN_AUTO_TEST_CASE(DivisionBroadcast1DVector, DivisionBroadcast1DVectorTest)
diff --git a/src/armnn/test/TensorHelpers.hpp b/src/armnn/test/TensorHelpers.hpp
index ec38940a44..13ae1008cd 100644
--- a/src/armnn/test/TensorHelpers.hpp
+++ b/src/armnn/test/TensorHelpers.hpp
@@ -44,6 +44,17 @@ struct SelectiveComparer<T, false>
{
return std::abs(a - b) <= g_FloatCloseToZeroTolerance;
}
+
+ if (std::isinf(a) && a == b)
+ {
+ return true;
+ }
+
+ if (std::isnan(a) && std::isnan(b))
+ {
+ return true;
+ }
+
// For unquantized floats we use a tolerance of 1%.
boost::math::fpc::close_at_tolerance<float> comparer(boost::math::fpc::percent_tolerance(1.0f));
return comparer(a, b);