diff options
author | Francis Murtagh <francis.murtagh@arm.com> | 2018-08-30 17:18:37 +0100 |
---|---|---|
committer | Matthew Bentham <matthew.bentham@arm.com> | 2018-09-17 17:21:25 +0100 |
commit | 8c5e3dc9f04ac15aa926d1a1214610760830dbe2 (patch) | |
tree | 354518d6b2db9c46e4b698fcfbedb629a5569b48 /src | |
parent | e7a86a4a3363993fb41b1ea62f23b3643b8b0c78 (diff) | |
download | armnn-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.cpp | 41 | ||||
-rw-r--r-- | src/armnn/backends/test/LayerTests.cpp | 30 | ||||
-rw-r--r-- | src/armnn/backends/test/LayerTests.hpp | 1 | ||||
-rw-r--r-- | src/armnn/backends/test/Reference.cpp | 1 | ||||
-rw-r--r-- | src/armnn/test/TensorHelpers.hpp | 11 |
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); |