IVGCVSW-2401 & IVGCVSW-2402 Add end-to-end test for Greater/Equal Operator

 * Add Arithmetic end-to-end test implementation
 * Enable tests for float, Uint8 and Broadcast

Change-Id: I81c7096e9b6ad29eaa935b74ad5f30f823be2331
diff --git a/src/backends/backendsCommon/test/ArithmeticTestImpl.hpp b/src/backends/backendsCommon/test/ArithmeticTestImpl.hpp
new file mode 100644
index 0000000..f70bf48
--- /dev/null
+++ b/src/backends/backendsCommon/test/ArithmeticTestImpl.hpp
@@ -0,0 +1,105 @@
+//
+// Copyright © 2017 Arm Ltd. All rights reserved.
+// SPDX-License-Identifier: MIT
+//
+#pragma once
+
+#include <armnn/INetwork.hpp>
+
+#include <backendsCommon/test/CommonTestUtils.hpp>
+
+#include <boost/test/unit_test.hpp>
+
+#include <vector>
+
+namespace
+{
+
+template<typename armnn::DataType DataType>
+INetworkPtr CreateArithmeticNetwork(const std::vector<TensorShape>& inputShapes,
+                                    const TensorShape& outputShape,
+                                    const LayerType type,
+                                    const float qScale = 1.0f,
+                                    const int32_t qOffset = 0)
+{
+    using namespace armnn;
+
+    // Builds up the structure of the network.
+    INetworkPtr net(INetwork::Create());
+
+    IConnectableLayer* arithmeticLayer = nullptr;
+
+    switch(type){
+        case LayerType::Equal: arithmeticLayer = net->AddEqualLayer("equal"); break;
+        case LayerType::Greater: arithmeticLayer = net->AddGreaterLayer("greater"); break;
+        default: BOOST_TEST_FAIL("Non-Arithmetic layer type called.");
+    }
+
+    for (unsigned int i = 0; i < inputShapes.size(); ++i)
+    {
+        TensorInfo inputTensorInfo(inputShapes[i], DataType, qScale, qOffset);
+        IConnectableLayer* input = net->AddInputLayer(boost::numeric_cast<LayerBindingId>(i));
+        Connect(input, arithmeticLayer, inputTensorInfo, 0, i);
+    }
+
+    TensorInfo outputTensorInfo(outputShape, DataType, qScale, qOffset);
+    IConnectableLayer* output = net->AddOutputLayer(0, "output");
+    Connect(arithmeticLayer, output, outputTensorInfo, 0, 0);
+
+    return net;
+}
+
+template<typename T>
+void ArithmeticSimpleEndToEnd(const std::vector<BackendId>& backends,
+                              const LayerType type,
+                              const std::vector<T> expectedOutput)
+{
+    using namespace armnn;
+
+    const std::vector<TensorShape> inputShapes{{ 2, 2, 2, 2 }, { 2, 2, 2, 2 }};
+    const TensorShape& outputShape = { 2, 2, 2, 2 };
+
+    // Builds up the structure of the network
+    INetworkPtr net = CreateArithmeticNetwork<GetDataType<T>()>(inputShapes, outputShape, type);
+
+    BOOST_TEST_CHECKPOINT("create a network");
+
+    const std::vector<T> input0({ 1, 1, 1, 1,  5, 5, 5, 5,
+                                  3, 3, 3, 3,  4, 4, 4, 4 });
+
+    const std::vector<T> input1({ 1, 1, 1, 1,  3, 3, 3, 3,
+                                  5, 5, 5, 5,  4, 4, 4, 4 });
+
+    std::map<int, std::vector<T>> inputTensorData = {{ 0, input0 }, { 1, input1 }};
+    std::map<int, std::vector<T>> expectedOutputData = {{ 0, expectedOutput }};
+
+    EndToEndLayerTestImpl<T>(move(net), inputTensorData, expectedOutputData, backends);
+}
+
+template<typename T>
+void ArithmeticBroadcastEndToEnd(const std::vector<BackendId>& backends,
+                                 const LayerType type,
+                                 const std::vector<T> expectedOutput)
+{
+    using namespace armnn;
+
+    const std::vector<TensorShape> inputShapes{{ 1, 2, 2, 3 }, { 1, 1, 1, 3 }};
+    const TensorShape& outputShape = { 1, 2, 2, 3 };
+
+    // Builds up the structure of the network
+    INetworkPtr net = CreateArithmeticNetwork<GetDataType<T>()>(inputShapes, outputShape, type);
+
+    BOOST_TEST_CHECKPOINT("create a network");
+
+    const std::vector<T> input0({ 1, 2, 3, 1, 0, 6,
+                                  7, 8, 9, 10, 11, 12 });
+
+    const std::vector<T> input1({ 1, 1, 3 });
+
+    std::map<int, std::vector<T>> inputTensorData = {{ 0, input0 }, { 1, input1 }};
+    std::map<int, std::vector<T>> expectedOutputData = {{ 0, expectedOutput }};
+
+    EndToEndLayerTestImpl<T>(move(net), inputTensorData, expectedOutputData, backends);
+}
+
+} // anonymous namespace
diff --git a/src/backends/reference/test/RefEndToEndTests.cpp b/src/backends/reference/test/RefEndToEndTests.cpp
index 8ad6f5a..9a4e601 100644
--- a/src/backends/reference/test/RefEndToEndTests.cpp
+++ b/src/backends/reference/test/RefEndToEndTests.cpp
@@ -5,6 +5,7 @@
 
 #include <backendsCommon/test/EndToEndTestImpl.hpp>
 #include <backendsCommon/test/MergerTestImpl.hpp>
+#include <backendsCommon/test/ArithmeticTestImpl.hpp>
 
 #include <boost/test/unit_test.hpp>
 #include <boost/test/execution_monitor.hpp>
@@ -311,6 +312,69 @@
     BOOST_TEST(outputData[3] == 2);
 }
 
+BOOST_AUTO_TEST_CASE(RefEqualSimpleEndToEndTest)
+{
+    const std::vector<float > expectedOutput({ 1, 1, 1, 1,  0, 0, 0, 0,
+                                               0, 0, 0, 0,  1, 1, 1, 1 });
+
+    ArithmeticSimpleEndToEnd<float>(defaultBackends, LayerType::Equal, expectedOutput);
+}
+
+BOOST_AUTO_TEST_CASE(RefGreaterSimpleEndToEndTest)
+{
+    const std::vector<float> expectedOutput({ 0, 0, 0, 0,  1, 1, 1, 1,
+                                              0, 0, 0, 0,  0, 0, 0, 0 });
+
+    ArithmeticSimpleEndToEnd<float>(defaultBackends, LayerType::Greater, expectedOutput);
+}
+
+BOOST_AUTO_TEST_CASE(RefEqualSimpleEndToEndUint8Test)
+{
+    const std::vector<uint8_t> expectedOutput({ 1, 1, 1, 1,  0, 0, 0, 0,
+                                                0, 0, 0, 0,  1, 1, 1, 1 });
+
+    ArithmeticSimpleEndToEnd<uint8_t>(defaultBackends, LayerType::Equal, expectedOutput);
+}
+
+BOOST_AUTO_TEST_CASE(RefGreaterSimpleEndToEndUint8Test)
+{
+    const std::vector<uint8_t> expectedOutput({ 0, 0, 0, 0,  1, 1, 1, 1,
+                                                0, 0, 0, 0,  0, 0, 0, 0 });
+
+    ArithmeticSimpleEndToEnd<uint8_t>(defaultBackends, LayerType::Greater, expectedOutput);
+}
+
+BOOST_AUTO_TEST_CASE(RefEqualBroadcastEndToEndTest)
+{
+    const std::vector<float > expectedOutput({ 1, 0, 1, 1, 0, 0,
+                                               0, 0, 0, 0, 0, 0 });
+
+    ArithmeticBroadcastEndToEnd<float>(defaultBackends, LayerType::Equal, expectedOutput);
+}
+
+BOOST_AUTO_TEST_CASE(RefGreaterBroadcastEndToEndTest)
+{
+    const std::vector<float> expectedOutput({ 0, 1, 0, 0, 0, 1,
+                                              1, 1, 1, 1, 1, 1 });
+
+    ArithmeticBroadcastEndToEnd<float>(defaultBackends, LayerType::Greater, expectedOutput);
+}
+
+BOOST_AUTO_TEST_CASE(RefEqualBroadcastEndToEndUint8Test)
+{
+    const std::vector<uint8_t > expectedOutput({ 1, 0, 1, 1, 0, 0,
+                                                 0, 0, 0, 0, 0, 0 });
+
+    ArithmeticBroadcastEndToEnd<uint8_t>(defaultBackends, LayerType::Equal, expectedOutput);
+}
+
+BOOST_AUTO_TEST_CASE(RefGreaterBroadcastEndToEndUint8Test)
+{
+    const std::vector<uint8_t> expectedOutput({ 0, 1, 0, 0, 0, 1,
+                                                1, 1, 1, 1, 1, 1 });
+
+    ArithmeticBroadcastEndToEnd<uint8_t>(defaultBackends, LayerType::Greater, expectedOutput);
+}
 
 BOOST_AUTO_TEST_CASE(RefMergerEndToEndDim0Test)
 {