IVGCVSW-7168 Add Conv2d and Constant support to TOSA Reference Backend

 * Added TOSA Conv2d and Constant mappings.
 * Added unique naming to mappings based on previous and following
   layers, so they are connected correctly.
 * Updated existing mappings with new naming convention.
 * Added all mappings to one main block in OptimizeSubgraphView.
 * Removed isMain from mapping functions.
 * Added Conv2d EndToEnd test.

Signed-off-by: Matthew Sloyan <matthew.sloyan@arm.com>
Change-Id: I27c3e238407c32379ce25a1f01dad11523ef5d2b
diff --git a/src/backends/tosaCommon/operatorMappings/AdditionOperator.cpp b/src/backends/tosaCommon/operatorMappings/AdditionOperator.cpp
index 7967977..66ca869 100644
--- a/src/backends/tosaCommon/operatorMappings/AdditionOperator.cpp
+++ b/src/backends/tosaCommon/operatorMappings/AdditionOperator.cpp
@@ -5,28 +5,36 @@
 
 #include "AdditionOperator.hpp"
 
-TosaSerializationBasicBlock* ConvertAdditionToTosaOperator(const std::vector<const TensorInfo*>& inputs,
-                                                           const std::vector<const TensorInfo*>& outputs,
-                                                           bool isMain)
+TosaSerializationBasicBlock* ConvertAdditionToTosaOperator(const Layer* layer,
+                                                           const std::vector<const TensorInfo*>& inputs,
+                                                           const std::vector<const TensorInfo*>& outputs)
 {
-    // A helper function with static global variables ensures uniqueness
-    // for dynamically generating input, output and block names
-    std::string input0Name = std::string("Op_ADD_input0_")  + GetUniqueTosaMappingID();
-    std::string input1Name = std::string("Op_ADD_input1_")  + GetUniqueTosaMappingID();
-    std::string outputName = std::string("Op_ADD_output0_") + GetUniqueTosaMappingID();
-    std::string blockName  = std::string("Op_ADD_block_")   + GetUniqueTosaMappingID();
+    std::string input0Name = std::string("input0_");
+    std::string input1Name = std::string("input1_");
+    std::string outputName = std::string("output0_");
+    std::string blockName  = std::string("Op_ADD_block_") + GetUniqueTosaMappingID();
 
-    // If it's the first block, overwrite block name with main.
-    if (isMain)
+    // If a layer is present then the block will be used for execution, so input and output names need to be determined
+    // using the previous and following layers so the graph is connected correctly. For validation this doesn't matter.
+    if(layer != nullptr)
     {
-        blockName = std::string("main");
+        // Get the layers connected to the input slots and determine unique layer names.
+        Layer& connectedLayer0 = layer->GetInputSlot(0).GetConnectedOutputSlot()->GetOwningLayer();
+        input0Name = GenerateUniqueName(connectedLayer0, 0);
+
+        Layer& connectedLayer1 = layer->GetInputSlot(1).GetConnectedOutputSlot()->GetOwningLayer();
+        input1Name = GenerateUniqueName(connectedLayer1, 1);
+
+        // Get the layer connected to the output slot and determine unique layer name.
+        Layer& connectedOutputLayer = layer->GetOutputSlot().GetConnection(0)->GetOwningLayer();
+        outputName = GenerateUniqueName(connectedOutputLayer, 0);
     }
 
-    TosaSerializationOperator* op = new TosaSerializationOperator(Op_ADD,
-                                                                  Attribute_NONE,
-                                                                  nullptr,
-                                                                  {input0Name, input1Name},
-                                                                  {outputName});
+    auto* op = new TosaSerializationOperator(Op_ADD,
+                                             Attribute_NONE,
+                                             nullptr,
+                                             {input0Name, input1Name},
+                                             {outputName});
 
     std::vector<int32_t> inputShape0 = GetTosaTensorShape(inputs[0]->GetShape());
     DType inputDType0 = ArmNNToDType(inputs[0]->GetDataType());
@@ -37,9 +45,9 @@
     std::vector<int32_t> outputShape0 = GetTosaTensorShape(outputs[0]->GetShape());
     DType outputDType0 = ArmNNToDType(outputs[0]->GetDataType());
 
-    TosaSerializationTensor* inputTensor0  = new TosaSerializationTensor(input0Name, inputShape0, inputDType0, {});
-    TosaSerializationTensor* inputTensor1  = new TosaSerializationTensor(input1Name, inputShape1, inputDType1, {});
-    TosaSerializationTensor* outputTensor0 = new TosaSerializationTensor(outputName, outputShape0, outputDType0, {});
+    auto* inputTensor0  = new TosaSerializationTensor(input0Name, inputShape0, inputDType0, {});
+    auto* inputTensor1  = new TosaSerializationTensor(input1Name, inputShape1, inputDType1, {});
+    auto* outputTensor0 = new TosaSerializationTensor(outputName, outputShape0, outputDType0, {});
 
     // operatorInputNames/operatorOutputNames ends up being the same as
     // blockInputNames/blockOutputNames for one-to-one ArmNN to Tosa mappings