IVGCVSW-3808 Add ElementwiseBinaryLayer

!android-nn-driver:9329

 * Added ElementwiseBinaryLayer that can represent all ElementwiseBinary
   operations including Add, Div, Sub, Maximum, Mul and Minimum.
 * Updated Delegate to use ElementwiseBinaryLayer instead of the Add,
   Div, Sub, Maximum, Mul and Minimum layers.
 * Updated Deserializer to use ElementwiseBinaryLayer instead of the Add,
   Div, Sub, Maximum, Mul and Minimum layers.
 * Updated OnnxParser to use ElementwiseBinaryLayer instead of the Add
   layer.
 * Updated TfLiteParser to use ElementwiseBinaryLayer instead of the Add,
   Div, Sub, Maximum, Mul and Minimum layers.
 * Updated CL and Neon tests to use ElementwiseBinaryLayer.
 * Updated CL and Neon Backend Specific Optimizations to accept
   ElementBinaryLayers as well as Add, Div, Mul, Sub, Maximum and Minimum
   layers.

Signed-off-by: Teresa Charlin <teresa.charlinreyes@arm.com>
Signed-off-by: Mike Kelly <mike.kelly@arm.com>
Change-Id: I7cbb96b60eb01f0e2b57b0541016d48a08b86c75
diff --git a/src/armnnSerializer/test/SerializerTests.cpp b/src/armnnSerializer/test/SerializerTests.cpp
index 3573a81..6ddc971 100644
--- a/src/armnnSerializer/test/SerializerTests.cpp
+++ b/src/armnnSerializer/test/SerializerTests.cpp
@@ -1,5 +1,5 @@
 //
-// Copyright © 2017 Arm Ltd and Contributors. All rights reserved.
+// Copyright © 2017,2020-2023 Arm Ltd and Contributors. All rights reserved.
 // SPDX-License-Identifier: MIT
 //
 
@@ -331,6 +331,7 @@
                 case armnn::LayerType::Input: break;
                 case armnn::LayerType::Output: break;
                 case armnn::LayerType::Addition: break;
+                case armnn::LayerType::ElementwiseBinary: break;
                 default:
                 {
                     this->VerifyNameAndConnections(layer, name);
@@ -972,6 +973,47 @@
     deserializedNetwork->ExecuteStrategy(verifier);
 }
 
+void SerializeElementwiseBinaryTest(armnn::BinaryOperation binaryOperation)
+{
+    auto layerName = GetBinaryOperationAsCString(binaryOperation);
+    const armnn::TensorInfo tensorInfo({ 1, 5, 2, 3 }, armnn::DataType::Float32);
+    armnn::ElementwiseBinaryDescriptor descriptor(binaryOperation);
+
+    armnn::INetworkPtr network = armnn::INetwork::Create();
+    armnn::IConnectableLayer* const inputLayer0 = network->AddInputLayer(0);
+    armnn::IConnectableLayer* const inputLayer1 = network->AddInputLayer(1);
+    armnn::IConnectableLayer* const elementwiseBinaryLayer = network->AddElementwiseBinaryLayer(descriptor,
+                                                                                                layerName);
+    armnn::IConnectableLayer* const outputLayer = network->AddOutputLayer(0);
+
+    inputLayer0->GetOutputSlot(0).Connect(elementwiseBinaryLayer->GetInputSlot(0));
+    inputLayer1->GetOutputSlot(0).Connect(elementwiseBinaryLayer->GetInputSlot(1));
+    elementwiseBinaryLayer->GetOutputSlot(0).Connect(outputLayer->GetInputSlot(0));
+
+    inputLayer0->GetOutputSlot(0).SetTensorInfo(tensorInfo);
+    inputLayer1->GetOutputSlot(0).SetTensorInfo(tensorInfo);
+    elementwiseBinaryLayer->GetOutputSlot(0).SetTensorInfo(tensorInfo);
+
+    std::string serializedNetwork = SerializeNetwork(*network);
+    armnn::INetworkPtr deserializedNetwork = DeserializeNetwork(serializedNetwork);
+    CHECK(deserializedNetwork);
+
+    LayerVerifierBaseWithDescriptor<armnn::ElementwiseBinaryDescriptor>
+            verifier(layerName, { tensorInfo, tensorInfo }, { tensorInfo }, descriptor);
+    deserializedNetwork->ExecuteStrategy(verifier);
+}
+
+TEST_CASE("SerializeElementwiseBinary")
+{
+    using op = armnn::BinaryOperation;
+    std::initializer_list<op> allBinaryOperations = {op::Add, op::Div, op::Maximum, op::Minimum, op::Mul, op::Sub};
+
+    for (auto binaryOperation : allBinaryOperations)
+    {
+        SerializeElementwiseBinaryTest(binaryOperation);
+    }
+}
+
 void SerializeElementwiseUnaryTest(armnn::UnaryOperation unaryOperation)
 {
     auto layerName = GetUnaryOperationAsCString(unaryOperation);
@@ -2883,6 +2925,7 @@
                     CompareConstTensor(constants.at(0), m_LayerInput);
                     break;
                 }
+                case armnn::LayerType::ElementwiseBinary: break;
                 default:
                 {
                     throw armnn::Exception("Unexpected layer type in test model");