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/test/OneToOneMappingTests.cpp b/src/backends/tosaCommon/test/OneToOneMappingTests.cpp
index 04d1eb4..af9f9e2 100644
--- a/src/backends/tosaCommon/test/OneToOneMappingTests.cpp
+++ b/src/backends/tosaCommon/test/OneToOneMappingTests.cpp
@@ -4,6 +4,7 @@
 //
 
 #include "TosaTestUtils.hpp"
+#include "CommonTestUtils.hpp"
 
 using namespace armnn;
 using namespace tosa;
@@ -18,7 +19,7 @@
     std::vector<std::vector<int32_t>> outputShape = {{ 1, 2, 4, 2 }};
 
     TosaSerializationBasicBlock* basicBlock =
-        GetTosaMapping(LayerType::Addition, {&info, &info}, {&info}, BaseDescriptor(), false);
+        GetTosaMapping(nullptr, LayerType::Addition, {&info, &info}, {&info}, BaseDescriptor());
     AssertTosaOneToOneMappingBasicBlock(
         basicBlock, inputShape, outputShape, Op_ADD, Attribute_NONE, BaseDescriptor(), LayerType::Addition);
 }
@@ -50,11 +51,132 @@
     std::vector<std::vector<int32_t>> outputShape = {{ 1, 2, 4, 2 }};
 
     TosaSerializationBasicBlock* basicBlock =
-        GetTosaMappingFromLayer(PolymorphicDowncast<Layer*>(add), false);
+        GetTosaMappingFromLayer(PolymorphicDowncast<Layer*>(add));
     AssertTosaOneToOneMappingBasicBlock(
         basicBlock, inputShape, outputShape, Op_ADD, Attribute_NONE, BaseDescriptor(), LayerType::Addition);
 }
 
+TEST_CASE("GetTosaMapping_ConstantLayer")
+{
+    TensorInfo outputInfo = TensorInfo({ 1, 2, 4, 2 }, DataType::Float32, 0.0f, 0, true);
+    std::vector<std::vector<int32_t>> outputShape = {{ 1, 2, 4, 2 }};
+
+    TosaSerializationBasicBlock* basicBlock =
+            GetTosaMapping(nullptr, LayerType::Constant, {}, {&outputInfo}, BaseDescriptor());
+    AssertTosaOneToOneMappingBasicBlock(
+            basicBlock, {}, outputShape, Op_CONST, Attribute_NONE, BaseDescriptor(), LayerType::Constant);
+}
+
+TEST_CASE("GetTosaMappingFromLayer_ConstantLayer")
+{
+    IRuntime::CreationOptions options;
+    IRuntimePtr runtime(IRuntime::Create(options));
+
+    // Builds up the structure of the network.
+    INetworkPtr net(INetwork::Create());
+
+    TensorInfo info = TensorInfo({ 1, 2, 4, 2 }, DataType::Float32, 0.0f, 0, true);
+    std::vector<std::vector<int32_t>> outputShape = {{ 1, 2, 4, 2 }};
+
+    std::vector<float> data = GenerateRandomData<float>(info.GetNumElements());
+    armnn::ConstTensor constTensor(info, data);
+
+    IConnectableLayer* constant = net->AddConstantLayer(constTensor, "constant");
+    IConnectableLayer* output = net->AddOutputLayer(0, "output");
+
+    constant->GetOutputSlot(0).Connect(output->GetInputSlot(0));
+    constant->GetOutputSlot(0).SetTensorInfo(info);
+
+    TosaSerializationBasicBlock* basicBlock =
+            GetTosaMappingFromLayer(PolymorphicDowncast<Layer*>(constant));
+    AssertTosaOneToOneMappingBasicBlock(
+            basicBlock, {}, outputShape, Op_CONST, Attribute_NONE, BaseDescriptor(), LayerType::Constant);
+}
+
+TEST_CASE("GetTosaMapping_Conv2dLayer")
+{
+    armnn::Convolution2dDescriptor descriptor;
+    descriptor.m_PadLeft     = 1;
+    descriptor.m_PadRight    = 1;
+    descriptor.m_PadTop      = 1;
+    descriptor.m_PadBottom   = 1;
+    descriptor.m_StrideX     = 2;
+    descriptor.m_StrideY     = 2;
+    descriptor.m_DilationX   = 2;
+    descriptor.m_DilationY   = 2;
+    descriptor.m_BiasEnabled = true;
+
+    const armnn::TensorInfo inputInfo ({ 1, 5, 5, 1 }, armnn::DataType::Float32);
+    const armnn::TensorInfo outputInfo({ 1, 3, 3, 1 }, armnn::DataType::Float32);
+    const armnn::TensorInfo weightsInfo({ 1, 3, 3, 1 }, armnn::DataType::Float32, 0.0f, 0, true);
+    const armnn::TensorInfo biasesInfo ({ 1 }, armnn::DataType::Float32, 0.0f, 0, true);
+
+    std::vector<std::vector<int32_t>> inputShape  = {{ 1, 5, 5, 1 }, { 1, 3, 3, 1 }, { 1 }};
+    std::vector<std::vector<int32_t>> outputShape = {{ 1, 3, 3, 1 }};
+
+    TosaSerializationBasicBlock* basicBlock = GetTosaMapping(nullptr,
+                                                             LayerType::Convolution2d,
+                                                             {&inputInfo, &weightsInfo, &biasesInfo},
+                                                             {&outputInfo},
+                                                             descriptor);
+    AssertTosaOneToOneMappingBasicBlock(
+        basicBlock, inputShape, outputShape, Op_CONV2D, Attribute_ConvAttribute, descriptor, LayerType::Convolution2d);
+}
+
+TEST_CASE("GetTosaMappingFromLayer_Conv2dLayer")
+{
+    IRuntime::CreationOptions options;
+    IRuntimePtr runtime(IRuntime::Create(options));
+
+    // Builds up the structure of the network.
+    INetworkPtr net(INetwork::Create());
+
+    armnn::Convolution2dDescriptor descriptor;
+    descriptor.m_PadLeft     = 1;
+    descriptor.m_PadRight    = 1;
+    descriptor.m_PadTop      = 1;
+    descriptor.m_PadBottom   = 1;
+    descriptor.m_StrideX     = 2;
+    descriptor.m_StrideY     = 2;
+    descriptor.m_DilationX   = 2;
+    descriptor.m_DilationY   = 2;
+    descriptor.m_BiasEnabled = true;
+
+    const armnn::TensorInfo inputInfo ({ 1, 5, 5, 1 }, armnn::DataType::Float32);
+    const armnn::TensorInfo outputInfo({ 1, 3, 3, 1 }, armnn::DataType::Float32);
+    const armnn::TensorInfo weightsInfo({ 1, 3, 3, 1 }, armnn::DataType::Float32, 0.0f, 0, true);
+    const armnn::TensorInfo biasesInfo ({ 1 }, armnn::DataType::Float32, 0.0f, 0, true);
+
+    std::vector<std::vector<int32_t>> inputShape  = {{ 1, 5, 5, 1 }};
+    std::vector<std::vector<int32_t>> outputShape = {{ 1, 3, 3, 1 }};
+
+    std::vector<float> weightsData = GenerateRandomData<float>(weightsInfo.GetNumElements());
+    armnn::ConstTensor weights(weightsInfo, weightsData);
+
+    std::vector<float> biasesData = GenerateRandomData<float>(biasesInfo.GetNumElements());
+    armnn::ConstTensor biases(biasesInfo, biasesData);
+
+    armnn::IConnectableLayer* const inputLayer  = net->AddInputLayer(0, "input0");
+    armnn::IConnectableLayer* const weightsLayer = net->AddConstantLayer(weights, "weights");
+    armnn::IConnectableLayer* const biasesLayer = net->AddConstantLayer(biases, "biases");
+    armnn::IConnectableLayer* const convLayer   = net->AddConvolution2dLayer(descriptor, "conv2d");
+    armnn::IConnectableLayer* const outputLayer = net->AddOutputLayer(0);
+
+    inputLayer->GetOutputSlot(0).Connect(convLayer->GetInputSlot(0));
+    weightsLayer->GetOutputSlot(0).Connect(convLayer->GetInputSlot(1));
+    biasesLayer->GetOutputSlot(0).Connect(convLayer->GetInputSlot(2));
+    convLayer->GetOutputSlot(0).Connect(outputLayer->GetInputSlot(0));
+
+    inputLayer->GetOutputSlot(0).SetTensorInfo(inputInfo);
+    weightsLayer->GetOutputSlot(0).SetTensorInfo(weightsInfo);
+    biasesLayer->GetOutputSlot(0).SetTensorInfo(biasesInfo);
+    convLayer->GetOutputSlot(0).SetTensorInfo(outputInfo);
+
+    TosaSerializationBasicBlock* basicBlock = GetTosaMappingFromLayer(PolymorphicDowncast<Layer*>(convLayer));
+    AssertTosaOneToOneMappingBasicBlock(
+        basicBlock, inputShape, outputShape, Op_CONV2D, Attribute_ConvAttribute, descriptor, LayerType::Convolution2d);
+}
+
 TEST_CASE("GetTosaMapping_MaxPool2DLayer")
 {
     armnn::Pooling2dDescriptor descriptor;
@@ -74,7 +196,7 @@
     std::vector<std::vector<int32_t>> outputShape = {{ 1, 1, 3, 3 }};
 
     TosaSerializationBasicBlock* basicBlock =
-        GetTosaMapping(LayerType::Pooling2d, {&inputTensorInfo}, {&outputTensorInfo}, descriptor, false);
+        GetTosaMapping(nullptr, LayerType::Pooling2d, {&inputTensorInfo}, {&outputTensorInfo}, descriptor);
     AssertTosaOneToOneMappingBasicBlock(
         basicBlock, inputShape, outputShape, Op_MAX_POOL2D, Attribute_PoolAttribute, descriptor, LayerType::Pooling2d);
 }
@@ -114,7 +236,7 @@
     pool->GetOutputSlot(0).SetTensorInfo(outputTensorInfo);
 
     TosaSerializationBasicBlock* basicBlock =
-        GetTosaMappingFromLayer(PolymorphicDowncast<Layer*>(pool), false);
+        GetTosaMappingFromLayer(PolymorphicDowncast<Layer*>(pool));
     AssertTosaOneToOneMappingBasicBlock(
         basicBlock, inputShape, outputShape, Op_MAX_POOL2D, Attribute_PoolAttribute, descriptor, LayerType::Pooling2d);
 }
@@ -138,7 +260,7 @@
     std::vector<std::vector<int32_t>> outputShape = {{ 1, 1, 3, 3 }};
 
     TosaSerializationBasicBlock* basicBlock =
-        GetTosaMapping(LayerType::Pooling2d, {&inputTensorInfo}, {&outputTensorInfo}, descriptor, false);
+        GetTosaMapping(nullptr, LayerType::Pooling2d, {&inputTensorInfo}, {&outputTensorInfo}, descriptor);
     AssertTosaOneToOneMappingBasicBlock(basicBlock,
                                         inputShape,
                                         outputShape,
@@ -183,7 +305,7 @@
     pool->GetOutputSlot(0).SetTensorInfo(outputTensorInfo);
 
     TosaSerializationBasicBlock* basicBlock =
-        GetTosaMappingFromLayer(PolymorphicDowncast<Layer*>(pool), false);
+        GetTosaMappingFromLayer(PolymorphicDowncast<Layer*>(pool));
     AssertTosaOneToOneMappingBasicBlock(basicBlock,
                                         inputShape,
                                         outputShape,
@@ -196,7 +318,7 @@
 TEST_CASE("GetTosaMapping_Unimplemented")
 {
     TosaSerializationBasicBlock* basicBlock =
-        GetTosaMapping(LayerType::UnidirectionalSequenceLstm, {}, {}, BaseDescriptor(), false);
+        GetTosaMapping(nullptr, LayerType::UnidirectionalSequenceLstm, {}, {}, BaseDescriptor());
 
     CHECK(basicBlock->GetName() == "");
     CHECK(basicBlock->GetTensors().size() == 0);