//
// Copyright © 2017, 2022-2023 Arm Ltd and Contributors. All rights reserved.
// SPDX-License-Identifier: MIT
//

#include <CommonTestUtils.hpp>
#include "MockBackendId.hpp"

#include <Graph.hpp>
#include <Network.hpp>

#include <armnn/BackendRegistry.hpp>
#include <armnnTestUtils/MockBackend.hpp>

#include <doctest/doctest.h>
#include <unordered_map>

using namespace armnn;

namespace
{

// The expected number of layers, input and output slots in a subgraph after a test
struct ExpectedSubgraphSize
{
    size_t m_NumInputSlots  = 0;
    size_t m_NumOutputSlots = 0;
    size_t m_NumLayers      = 0;
};

// Keep the layers organized by layer name
using LayerNameToLayerMap = std::unordered_map<std::string, Layer*>;

// Used to convert input and output slots from reference type (as stored in graphs) to
// pointer type (as stored in subgraphs)
template <typename SlotType>
SlotType* ConvertReferenceTypeToPointerType(const SlotType& input)
{
    return const_cast<SlotType*>(&input);
}

// Used to convert input and output slots from reference type (as stored in graphs) to
// pointer type (as stored in subgraphs), array version
template <typename SlotType>
std::vector<SlotType*> ConvertReferenceTypeToPointerType(const std::vector<SlotType>& input)
{
    std::vector<SlotType*> output;
    std::transform(input.begin(),
                   input.end(),
                   std::back_inserter(output),
                   [](const SlotType& inputItem)
    {
        return ConvertReferenceTypeToPointerType(inputItem);
    });

    return output;
}

// Convert from vector of Slots* (Input/Output) to vector of ISlots* (IInput/IOutput)
template <typename SlotType, typename ResultSlotType>
std::vector<ResultSlotType*> ConvertSlotsToISlots(const std::vector<SlotType*> input)
{
    std::vector<ResultSlotType*> output;
    for (auto slot : input)
    {
        output.push_back(PolymorphicDowncast<ResultSlotType*>(slot));
    }
    return output;
}

// Convenience function to add an input layer to a graph
Layer* AddInputLayer(Graph& graph,
                     const std::string& layerName,
                     const TensorInfo& inputInfo,
                     LayerBindingId inputId = 0)
{
    Layer* const inputLayer = graph.AddLayer<InputLayer>(inputId, layerName.c_str());
    CHECK(inputLayer);
    inputLayer->GetOutputSlot(0).SetTensorInfo(inputInfo);
    return inputLayer;
}

// Convenience function to add an output layer to a graph
Layer* AddOutputLayer(Graph& graph,
                      const std::string& layerName)
{
    Layer* const outputLayer = graph.AddLayer<OutputLayer>(0, layerName.c_str());
    CHECK(outputLayer);
    return outputLayer;
}

// Convenience function to add a convolution layer to a graph
Convolution2dLayer* AddConvolutionLayer(Graph& graph,
                                        LayerNameToLayerMap& layersInGraph,
                                        const Convolution2dDescriptor& convolutionDescriptor,
                                        const std::string& layerName,
                                        const TensorInfo& outputInfo)
{
    Convolution2dLayer* const convLayer = graph.AddLayer<Convolution2dLayer>(convolutionDescriptor, layerName.c_str());
    CHECK(convLayer);
    convLayer->GetOutputSlot(0).SetTensorInfo(outputInfo);
    layersInGraph.insert(std::make_pair(convLayer->GetName(), convLayer));
    return convLayer;
}

// Convenience function to add a constant layer to a graph
ConstantLayer* AddConstantLayer(Graph& graph,
                                LayerNameToLayerMap& layersInGraph,
                                const std::string& layerName,
                                const ConstTensor& constTensor,
                                const TensorInfo& outputInfo)
{
    ConstantLayer* const constantLayer = graph.AddLayer<ConstantLayer>(layerName.c_str());
    CHECK(constantLayer);
    constantLayer->m_LayerOutput = std::make_shared<ScopedTensorHandle>(constTensor);
    constantLayer->GetOutputSlot(0).SetTensorInfo(outputInfo);
    layersInGraph.insert(std::make_pair(constantLayer->GetName(), constantLayer));
    return constantLayer;
}

// Convenience function to add a pooling layer to a graph
Pooling2dLayer* AddPoolingLayer(Graph& graph,
                                LayerNameToLayerMap& layersInGraph,
                                const Pooling2dDescriptor& poolingDescriptor,
                                const std::string& layerName,
                                const TensorInfo& outputInfo)
{
    Pooling2dLayer* const poolingLayer = graph.AddLayer<Pooling2dLayer>(poolingDescriptor, layerName.c_str());
    CHECK(poolingLayer);
    poolingLayer->GetOutputSlot(0).SetTensorInfo(outputInfo);
    layersInGraph.insert(std::make_pair(poolingLayer->GetName(), poolingLayer));
    return poolingLayer;
}

// Convenience function to add an addition layer to a graph
ARMNN_NO_DEPRECATE_WARN_BEGIN
AdditionLayer* AddAdditionaLayer(Graph& graph,
                                 LayerNameToLayerMap& layersInGraph,
                                 const std::string& layerName,
                                 const TensorInfo& outputInfo)
{
    AdditionLayer* const additionLayer = graph.AddLayer<AdditionLayer>(layerName.c_str());
    CHECK(additionLayer);
    additionLayer->GetOutputSlot(0).SetTensorInfo(outputInfo);
    layersInGraph.insert(std::make_pair(additionLayer->GetName(), additionLayer));
    return additionLayer;
}
ARMNN_NO_DEPRECATE_WARN_END

// Convenience function to check that the given substitution matches the specified expected values
void CheckSubstitution(const OptimizationViews::SubstitutionPair& substitution,
                       const ExpectedSubgraphSize& expectedSubstitutableSubgraphSize,
                       const ExpectedSubgraphSize& expectedReplacementSubgraphSize,
                       const SubgraphView::IInputSlots& expectedSubstitutableInputSlots,
                       const SubgraphView::IOutputSlots& expectedSubstitutableOutputSlots,
                       const SubgraphView::IConnectableLayers& expectedSubstitutableLayers)
{
    const SubgraphView& substitutableSubgraph = substitution.m_SubstitutableSubgraph;
    const SubgraphView::IInputSlots& substitutableSubgraphInputSlots = substitutableSubgraph.GetIInputSlots();
    const SubgraphView::IOutputSlots& substitutableSubgraphOutputSlots = substitutableSubgraph.GetIOutputSlots();
    const SubgraphView::IConnectableLayers& substitutableSubgraphLayers =
            substitutableSubgraph.GetIConnectableLayers();

    const SubgraphView& replacementSubgraph                          = substitution.m_ReplacementSubgraph;
    const SubgraphView::IInputSlots& replacementSubgraphInputSlots   = replacementSubgraph.GetIInputSlots();
    const SubgraphView::IOutputSlots& replacementSubgraphOutputSlots = replacementSubgraph.GetIOutputSlots();
    const SubgraphView::IConnectableLayers& replacementSubgraphLayers = replacementSubgraph.GetIConnectableLayers();

    CHECK(substitutableSubgraphInputSlots.size()  == expectedSubstitutableSubgraphSize.m_NumInputSlots);
    CHECK(substitutableSubgraphOutputSlots.size() == expectedSubstitutableSubgraphSize.m_NumOutputSlots);
    CHECK(substitutableSubgraphLayers.size()      == expectedSubstitutableSubgraphSize.m_NumLayers);

    CHECK(AreEqual(substitutableSubgraphInputSlots,  expectedSubstitutableInputSlots));
    CHECK(AreEqual(substitutableSubgraphOutputSlots, expectedSubstitutableOutputSlots));
    CHECK(AreEqual(substitutableSubgraphLayers,      expectedSubstitutableLayers));

    CHECK(replacementSubgraphInputSlots.size()  == expectedReplacementSubgraphSize.m_NumInputSlots);
    CHECK(replacementSubgraphOutputSlots.size() == expectedReplacementSubgraphSize.m_NumOutputSlots);
    CHECK(replacementSubgraphLayers.size()      == expectedReplacementSubgraphSize.m_NumLayers);

    CHECK(!AreEqual(replacementSubgraphInputSlots,  expectedSubstitutableInputSlots));
    CHECK(!AreEqual(replacementSubgraphOutputSlots, expectedSubstitutableOutputSlots));
    CHECK(!AreEqual(replacementSubgraphLayers,      expectedSubstitutableLayers));

    CHECK(std::all_of(replacementSubgraphLayers.begin(),
                           replacementSubgraphLayers.end(),
                           [](const IConnectableLayer* layer)
    {
        return layer->GetType() == LayerType::PreCompiled;
    }));
}

// Convenience function to check that the given failed subgraph matches the specified expected values
void CheckFailedSubgraph(const SubgraphView& failedSubgraph,
                         const ExpectedSubgraphSize& expectedFailedSubgraphSize,
                         const SubgraphView::IInputSlots& expectedFailedInputSlots,
                         const SubgraphView::IOutputSlots& expectedFailedOutputSlots,
                         const SubgraphView::IConnectableLayers& expectedFailedLayers)
{
    const SubgraphView::IInputSlots&  failedSubgraphInputSlots  = failedSubgraph.GetIInputSlots();
    const SubgraphView::IOutputSlots& failedSubgraphOutputSlots = failedSubgraph.GetIOutputSlots();
    const SubgraphView::IConnectableLayers& failedSubgraphLayers = failedSubgraph.GetIConnectableLayers();

    CHECK(failedSubgraphInputSlots.size()  == expectedFailedSubgraphSize.m_NumInputSlots);
    CHECK(failedSubgraphOutputSlots.size() == expectedFailedSubgraphSize.m_NumOutputSlots);
    CHECK(failedSubgraphLayers.size()      == expectedFailedSubgraphSize.m_NumLayers);

    CHECK(AreEqual(failedSubgraphInputSlots,  expectedFailedInputSlots));
    CHECK(AreEqual(failedSubgraphOutputSlots, expectedFailedOutputSlots));
    CHECK(AreEqual(failedSubgraphLayers,      expectedFailedLayers));
}

// Convenience function to check that the given untouched subgraph matches the specified expected values
void CheckUntouchedSubgraph(const SubgraphView& untouchedSubgraph,
                            const ExpectedSubgraphSize& expectedUntouchedSubgraphSize,
                            const SubgraphView::IInputSlots& expectedUntouchedInputSlots,
                            const SubgraphView::IOutputSlots& expectedUntouchedOutputSlots,
                            const SubgraphView::IConnectableLayers& expectedUntouchedLayers)
{
    const SubgraphView::IInputSlots& untouchedSubgraphInputSlots = untouchedSubgraph.GetIInputSlots();
    const SubgraphView::IOutputSlots& untouchedSubgraphOutputSlots = untouchedSubgraph.GetIOutputSlots();
    const SubgraphView::IConnectableLayers& untouchedSubgraphLayers = untouchedSubgraph.GetIConnectableLayers();

    CHECK(untouchedSubgraphInputSlots.size()  == expectedUntouchedSubgraphSize.m_NumInputSlots);
    CHECK(untouchedSubgraphOutputSlots.size() == expectedUntouchedSubgraphSize.m_NumOutputSlots);
    CHECK(untouchedSubgraphLayers.size()      == expectedUntouchedSubgraphSize.m_NumLayers);

    CHECK(AreEqual(untouchedSubgraphInputSlots,  expectedUntouchedInputSlots));
    CHECK(AreEqual(untouchedSubgraphOutputSlots, expectedUntouchedOutputSlots));
    CHECK(AreEqual(untouchedSubgraphLayers,      expectedUntouchedLayers));
}

// Creates a subgraph containing only a single unsupported layer (only convolutions are unsupported by the mock backend)
SubgraphView::SubgraphViewPtr BuildFullyUnsupportedSubgraph1(Graph& graph, LayerNameToLayerMap& layersInGraph)
{
    const TensorInfo inputInfo ({  1, 16, 16, 16 }, DataType::QAsymmU8, 1.0f, 0);
    const TensorInfo outputInfo({  1, 16, 16, 16 }, DataType::QAsymmU8, 1.0f, 0);

    Pooling2dDescriptor poolingDescriptor;
    poolingDescriptor.m_PoolType      = armnn::PoolingAlgorithm::Average;
    poolingDescriptor.m_PoolWidth     = 2;
    poolingDescriptor.m_PoolHeight    = 2;
    poolingDescriptor.m_StrideX       = 2;
    poolingDescriptor.m_StrideY       = 2;
    poolingDescriptor.m_PadLeft       = 1;
    poolingDescriptor.m_PadRight      = 1;
    poolingDescriptor.m_PadTop        = 1;
    poolingDescriptor.m_PadBottom     = 1;
    poolingDescriptor.m_PaddingMethod = armnn::PaddingMethod::Exclude;
    poolingDescriptor.m_DataLayout    = DataLayout::NHWC;

    // Construct the graph
    Layer* const inputLayer = AddInputLayer(graph, "input layer", inputInfo);
    Pooling2dLayer* const poolingLayer = AddPoolingLayer(graph, layersInGraph, poolingDescriptor,
                                                         "pooling layer", outputInfo);
    Layer* const outputLayer = AddOutputLayer(graph, "output layer");

    // Connect the network
    inputLayer->GetOutputSlot(0).Connect(poolingLayer->GetInputSlot(0));
    poolingLayer->GetOutputSlot(0).Connect(outputLayer->GetInputSlot(0));

    // Create the subgraph view for the whole network
    return CreateSubgraphViewFrom(CreateInputsFrom(poolingLayer),
                                  CreateOutputsFrom({poolingLayer}),
                                  {poolingLayer});
}

// Creates a subgraph containing only unsupported layers (only convolutions are unsupported by the mock backend)
SubgraphView::SubgraphViewPtr BuildFullyUnsupportedSubgraph2(Graph& graph, LayerNameToLayerMap& layersInGraph)
{
    const TensorInfo inputInfo ({  1, 16, 16, 16 }, DataType::QAsymmU8, 1.0f, 0);
    const TensorInfo outputInfo({  1, 16, 16, 16 }, DataType::QAsymmU8, 1.0f, 0);

    Pooling2dDescriptor poolingDescriptor;
    poolingDescriptor.m_PoolType      = armnn::PoolingAlgorithm::Average;
    poolingDescriptor.m_PoolWidth     = 2;
    poolingDescriptor.m_PoolHeight    = 2;
    poolingDescriptor.m_StrideX       = 2;
    poolingDescriptor.m_StrideY       = 2;
    poolingDescriptor.m_PadLeft       = 1;
    poolingDescriptor.m_PadRight      = 1;
    poolingDescriptor.m_PadTop        = 1;
    poolingDescriptor.m_PadBottom     = 1;
    poolingDescriptor.m_PaddingMethod = armnn::PaddingMethod::Exclude;
    poolingDescriptor.m_DataLayout    = DataLayout::NHWC;

    // Construct the graph
    Layer* const inputLayer = AddInputLayer(graph, "input layer", inputInfo);
    Pooling2dLayer* const pooling1Layer = AddPoolingLayer(graph, layersInGraph, poolingDescriptor,
                                                          "pooling1 layer", outputInfo);
    Pooling2dLayer* const pooling2Layer = AddPoolingLayer(graph, layersInGraph, poolingDescriptor,
                                                          "pooling2 layer", outputInfo);
    Pooling2dLayer* const pooling3Layer = AddPoolingLayer(graph, layersInGraph, poolingDescriptor,
                                                          "pooling3 layer", outputInfo);
    Layer* const outputLayer = AddOutputLayer(graph, "output layer");

    // Connect the network
    inputLayer->GetOutputSlot(0).Connect(pooling1Layer->GetInputSlot(0));
    pooling1Layer->GetOutputSlot(0).Connect(pooling2Layer->GetInputSlot(0));
    pooling2Layer->GetOutputSlot(0).Connect(pooling3Layer->GetInputSlot(0));
    pooling3Layer->GetOutputSlot(0).Connect(outputLayer->GetInputSlot(0));

    // Create the subgraph view for the whole network
    return CreateSubgraphViewFrom(CreateInputsFrom(pooling1Layer),
                                  CreateOutputsFrom({pooling3Layer}),
                                  {pooling1Layer,
                                   pooling2Layer,
                                   pooling3Layer});
}

// Creates a simple subgraph with only one convolution layer, supported by the mock backend
SubgraphView::SubgraphViewPtr BuildFullyOptimizableSubgraph1(Graph& graph, LayerNameToLayerMap& layersInGraph)
{
    const TensorInfo inputInfo ({  1, 16, 16, 16 }, DataType::QAsymmU8, 1.0f, 0);
    const TensorInfo outputInfo({  1, 16, 16, 16 }, DataType::QAsymmU8, 1.0f, 0);
    TensorInfo weightInfo({ 16,  1,  1, 16 }, DataType::QAsymmU8, 0.9f, 0);
    TensorInfo biasInfo({ 1, 1, 1, 16 }, DataType::Signed32, 0.9f, 0);

    weightInfo.SetConstant(true);
    biasInfo.SetConstant(true);

    Convolution2dDescriptor convolutionDescriptor;
    convolutionDescriptor.m_StrideX     = 1;
    convolutionDescriptor.m_StrideY     = 1;
    convolutionDescriptor.m_BiasEnabled = true;
    convolutionDescriptor.m_DataLayout  = DataLayout::NHWC;

    std::vector<float> weightsVector(64);
    ConstTensor constWeightsTensor(weightInfo, weightsVector);

    std::vector<float> biasVector(16);
    ConstTensor constBiasTensor(biasInfo, biasVector);

    // Construct the graph
    Layer* const inputLayer = AddInputLayer(graph, "input layer", inputInfo);
    Convolution2dLayer* const convLayer = AddConvolutionLayer(graph, layersInGraph, convolutionDescriptor,
                                                              "conv layer", outputInfo);

  ConstantLayer* const weightsLayer =
      AddConstantLayer(graph, layersInGraph, "Weights Layer", constWeightsTensor, weightInfo);
  ConstantLayer* const biasLayer = AddConstantLayer(graph, layersInGraph, "Bias Layer", constBiasTensor, biasInfo);

    Layer* const outputLayer = AddOutputLayer(graph, "output layer");

    // Connect the network
    inputLayer->GetOutputSlot(0).Connect(convLayer->GetInputSlot(0));
    weightsLayer->GetOutputSlot(0).Connect(convLayer->GetInputSlot(1));
    biasLayer->GetOutputSlot(0).Connect(convLayer->GetInputSlot(2));
    convLayer->GetOutputSlot(0).Connect(outputLayer->GetInputSlot(0));

    std::vector<unsigned int> ignoreSlots = {1, 2};
    // Create the subgraph view for the whole network
    return CreateSubgraphViewFrom(CreateInputsFrom(convLayer, ignoreSlots),
                                  CreateOutputsFrom({convLayer}),
                                  {convLayer, weightsLayer, biasLayer});
}

// Creates a subgraph with five convolutions layers, all supported by the mock backend
SubgraphView::SubgraphViewPtr BuildFullyOptimizableSubgraph2(Graph& graph, LayerNameToLayerMap& layersInGraph)
{
    const TensorInfo inputInfo ({  1, 16, 16, 16 }, DataType::QAsymmU8, 1.0f, 0);
    const TensorInfo outputInfo({  1, 16, 16, 16 }, DataType::QAsymmU8, 1.0f, 0);
    TensorInfo weightInfo({ 16,  1,  1, 16 }, DataType::QAsymmU8, 0.9f, 0);
    TensorInfo biasInfo  ({  1,  1,  1, 16 }, DataType::Signed32,        0.9f, 0);

    weightInfo.SetConstant(true);
    biasInfo.SetConstant(true);

    std::vector<float> weightsVector(64);
    ConstTensor constWeightsTensor(weightInfo, weightsVector);

    std::vector<float> biasVector(16);
    ConstTensor constBiasTensor(biasInfo, biasVector);

    Convolution2dDescriptor convolutionDescriptor;
    convolutionDescriptor.m_StrideX     = 1;
    convolutionDescriptor.m_StrideY     = 1;
    convolutionDescriptor.m_BiasEnabled = true;
    convolutionDescriptor.m_DataLayout  = DataLayout::NHWC;

    // Construct the graph
    Layer* const inputLayer = AddInputLayer(graph, "input layer", inputInfo);
    Convolution2dLayer* const conv1Layer = AddConvolutionLayer(graph, layersInGraph, convolutionDescriptor,
                                                               "conv1 layer", outputInfo);
    ConstantLayer* const weightsLayer1 =
        AddConstantLayer(graph, layersInGraph, "Weights Layer 1", constWeightsTensor, weightInfo);
    ConstantLayer* const biasLayer1 =
        AddConstantLayer(graph, layersInGraph, "Bias Layer 1", constBiasTensor, biasInfo);

    Convolution2dLayer* const conv2Layer = AddConvolutionLayer(graph, layersInGraph, convolutionDescriptor,
                                                               "conv2 layer", outputInfo);
    ConstantLayer* const weightsLayer2 =
        AddConstantLayer(graph, layersInGraph, "Weights Layer 2", constWeightsTensor, weightInfo);
    ConstantLayer* const biasLayer2 =
        AddConstantLayer(graph, layersInGraph, "Bias Layer 2", constBiasTensor, biasInfo);


    Convolution2dLayer* const conv3Layer = AddConvolutionLayer(graph, layersInGraph, convolutionDescriptor,
                                                               "conv3 layer", outputInfo);
    ConstantLayer* const weightsLayer3 =
        AddConstantLayer(graph, layersInGraph, "Weights Layer 3", constWeightsTensor, weightInfo);
    ConstantLayer* const biasLayer3 =
        AddConstantLayer(graph, layersInGraph, "Bias Layer 3", constBiasTensor, biasInfo);

    Convolution2dLayer* const conv4Layer = AddConvolutionLayer(graph, layersInGraph, convolutionDescriptor,
                                                               "conv4 layer", outputInfo);
    ConstantLayer* const weightsLayer4 =
        AddConstantLayer(graph, layersInGraph, "Weights Layer 4", constWeightsTensor, weightInfo);
    ConstantLayer* const biasLayer4 =
        AddConstantLayer(graph, layersInGraph, "Bias Layer 4", constBiasTensor, biasInfo);

    Convolution2dLayer* const conv5Layer = AddConvolutionLayer(graph, layersInGraph, convolutionDescriptor,
                                                               "conv5 layer", outputInfo);
    ConstantLayer* const weightsLayer5 =
        AddConstantLayer(graph, layersInGraph, "Weights Layer 5", constWeightsTensor, weightInfo);
    ConstantLayer* const biasLayer5 =
        AddConstantLayer(graph, layersInGraph, "Bias Layer 5", constBiasTensor, biasInfo);


    Layer* const outputLayer = AddOutputLayer(graph, "output layer");

    // Connect the network
    inputLayer->GetOutputSlot(0).Connect(conv1Layer->GetInputSlot(0));
    weightsLayer1->GetOutputSlot(0).Connect(conv1Layer->GetInputSlot(1));
    biasLayer1->GetOutputSlot(0).Connect(conv1Layer->GetInputSlot(2));

    conv1Layer->GetOutputSlot(0).Connect(conv2Layer->GetInputSlot(0));
    weightsLayer2->GetOutputSlot(0).Connect(conv2Layer->GetInputSlot(1));
    biasLayer2->GetOutputSlot(0).Connect(conv2Layer->GetInputSlot(2));

    conv2Layer->GetOutputSlot(0).Connect(conv3Layer->GetInputSlot(0));
    weightsLayer3->GetOutputSlot(0).Connect(conv3Layer->GetInputSlot(1));
    biasLayer3->GetOutputSlot(0).Connect(conv3Layer->GetInputSlot(2));

    conv3Layer->GetOutputSlot(0).Connect(conv4Layer->GetInputSlot(0));
    weightsLayer4->GetOutputSlot(0).Connect(conv4Layer->GetInputSlot(1));
    biasLayer4->GetOutputSlot(0).Connect(conv4Layer->GetInputSlot(2));

    conv4Layer->GetOutputSlot(0).Connect(conv5Layer->GetInputSlot(0));
    weightsLayer5->GetOutputSlot(0).Connect(conv5Layer->GetInputSlot(1));
    biasLayer5->GetOutputSlot(0).Connect(conv5Layer->GetInputSlot(2));

    conv5Layer->GetOutputSlot(0).Connect(outputLayer->GetInputSlot(0));
    std::vector<unsigned int> ignoreSlots = {1, 2};
    // Create the subgraph view for the whole network
    return CreateSubgraphViewFrom(CreateInputsFrom(conv1Layer, ignoreSlots),
                                  CreateOutputsFrom({ conv5Layer }),
                                  { weightsLayer1,
                                    biasLayer1,
                                    conv1Layer,
                                    weightsLayer2,
                                    biasLayer2,
                                    conv2Layer,
                                    weightsLayer3,
                                    biasLayer3,
                                    conv3Layer,
                                    weightsLayer4,
                                    biasLayer4,
                                    conv4Layer,
                                    weightsLayer5,
                                    biasLayer5,
                                    conv5Layer });
}

// Creates a subgraph with both supported and unsupported layers
// (only convolutions are unsupported by the mock backend)
SubgraphView::SubgraphViewPtr BuildPartiallySupportedSubgraph(Graph& graph, LayerNameToLayerMap& layersInGraph)
{
    const TensorInfo inputInfo ({  1, 16, 16, 16 }, DataType::QAsymmU8, 1.0f, 0);
    const TensorInfo outputInfo({  1, 16, 16, 16 }, DataType::QAsymmU8, 1.0f, 0);
    TensorInfo weightInfo({ 16,  1,  1, 16 }, DataType::QAsymmU8, 0.9f, 0);
    TensorInfo biasInfo  ({  1,  1,  1, 16 }, DataType::Signed32,        0.9f, 0);

    weightInfo.SetConstant(true);
    biasInfo.SetConstant(true);

    std::vector<float> weightsVector(64);
    ConstTensor constWeightsTensor(weightInfo, weightsVector);

    std::vector<float> biasVector(16);
    ConstTensor constBiasTensor(biasInfo, biasVector);

    Convolution2dDescriptor convolutionDescriptor;
    convolutionDescriptor.m_StrideX     = 1;
    convolutionDescriptor.m_StrideY     = 1;
    convolutionDescriptor.m_BiasEnabled = true;
    convolutionDescriptor.m_DataLayout  = DataLayout::NHWC;

    Pooling2dDescriptor poolingDescriptor;
    poolingDescriptor.m_PoolType      = armnn::PoolingAlgorithm::Average;
    poolingDescriptor.m_PoolWidth     = 2;
    poolingDescriptor.m_PoolHeight    = 2;
    poolingDescriptor.m_StrideX       = 2;
    poolingDescriptor.m_StrideY       = 2;
    poolingDescriptor.m_PadLeft       = 1;
    poolingDescriptor.m_PadRight      = 1;
    poolingDescriptor.m_PadTop        = 1;
    poolingDescriptor.m_PadBottom     = 1;
    poolingDescriptor.m_PaddingMethod = armnn::PaddingMethod::Exclude;
    poolingDescriptor.m_DataLayout    = DataLayout::NHWC;

    // Construct the graph
    Layer* const inputLayer = AddInputLayer(graph, "input layer", inputInfo);
    ConstantLayer* const weightsLayer1 =
        AddConstantLayer(graph, layersInGraph, "Weights Layer 1", constWeightsTensor, weightInfo);

    ConstantLayer* const biasLayer1 =
        AddConstantLayer(graph, layersInGraph, "Bias Layer 1", constBiasTensor, biasInfo);

    Convolution2dLayer* const conv1Layer = AddConvolutionLayer(graph, layersInGraph, convolutionDescriptor,
                                                               "conv1 layer", outputInfo);
    Pooling2dLayer* const pooling1Layer = AddPoolingLayer(graph, layersInGraph, poolingDescriptor,
                                                          "pooling1 layer", outputInfo);
    Pooling2dLayer* const pooling2Layer = AddPoolingLayer(graph, layersInGraph, poolingDescriptor,
                                                          "pooling2 layer", outputInfo);

    ConstantLayer* const weightsLayer2 =
        AddConstantLayer(graph, layersInGraph, "Weights Layer 2", constWeightsTensor, weightInfo);

    ConstantLayer* const biasLayer2 =
        AddConstantLayer(graph, layersInGraph, "Bias Layer 2", constBiasTensor, biasInfo);

    Convolution2dLayer* const conv2Layer = AddConvolutionLayer(graph, layersInGraph, convolutionDescriptor,
                                                               "conv2 layer", outputInfo);
    Pooling2dLayer* const pooling3Layer = AddPoolingLayer(graph, layersInGraph, poolingDescriptor,
                                                          "pooling3 layer", outputInfo);
    Layer* const outputLayer = AddOutputLayer(graph, "output layer");

    // Connect the network
    inputLayer->GetOutputSlot(0).Connect(conv1Layer->GetInputSlot(0));
    weightsLayer1->GetOutputSlot(0).Connect(conv1Layer->GetInputSlot(1));
    biasLayer1->GetOutputSlot(0).Connect(conv1Layer->GetInputSlot(2));
    conv1Layer->GetOutputSlot(0).Connect(pooling1Layer->GetInputSlot(0));
    pooling1Layer->GetOutputSlot(0).Connect(pooling2Layer->GetInputSlot(0));
    pooling2Layer->GetOutputSlot(0).Connect(conv2Layer->GetInputSlot(0));
    weightsLayer2->GetOutputSlot(0).Connect(conv2Layer->GetInputSlot(1));
    biasLayer2->GetOutputSlot(0).Connect(conv2Layer->GetInputSlot(2));
    conv2Layer->GetOutputSlot(0).Connect(pooling3Layer->GetInputSlot(0));
    pooling3Layer->GetOutputSlot(0).Connect(outputLayer->GetInputSlot(0));

    std::vector<unsigned int> ignoreSlots = {1, 2};
    // Create the subgraph view for the whole network
    return CreateSubgraphViewFrom(CreateInputsFrom(conv1Layer, ignoreSlots),
                                  CreateOutputsFrom({pooling3Layer}),
                                  {weightsLayer1,
                                   biasLayer1,
                                   conv1Layer,
                                   pooling1Layer,
                                   pooling2Layer,
                                   weightsLayer2,
                                   biasLayer2,
                                   conv2Layer,
                                   pooling3Layer});
}

// Creates a subgraph with only unoptimizable layers ("unoptimizable" is added to the layer's name)
SubgraphView::SubgraphViewPtr BuildFullyUnoptimizableSubgraph1(Graph& graph, LayerNameToLayerMap& layersInGraph)
{
    const TensorInfo inputInfo ({  1, 16, 16, 16 }, DataType::QAsymmU8, 1.0f, 0);
    const TensorInfo outputInfo({  1, 16, 16, 16 }, DataType::QAsymmU8, 1.0f, 0);
    TensorInfo weightInfo({ 16,  1,  1, 16 }, DataType::QAsymmU8, 0.9f, 0);
    TensorInfo biasInfo  ({  1,  1,  1, 16 }, DataType::Signed32,        0.9f, 0);

    weightInfo.SetConstant(true);
    biasInfo.SetConstant(true);

    std::vector<float> weightsVector(64);
    ConstTensor constWeightsTensor(weightInfo, weightsVector);

    std::vector<float> biasVector(16);
    ConstTensor constBiasTensor(biasInfo, biasVector);
    Convolution2dDescriptor convolutionDescriptor;
    convolutionDescriptor.m_StrideX     = 1;
    convolutionDescriptor.m_StrideY     = 1;
    convolutionDescriptor.m_BiasEnabled = true;
    convolutionDescriptor.m_DataLayout  = DataLayout::NHWC;

    // Construct the graph
    Layer* const inputLayer = AddInputLayer(graph, "input layer", inputInfo);

    ConstantLayer* const weightsLayer =
        AddConstantLayer(graph, layersInGraph, "Weights Layer unoptimizable", constWeightsTensor, weightInfo);

    ConstantLayer* const biasLayer =
        AddConstantLayer(graph, layersInGraph, "Bias Layer unoptimizable", constBiasTensor, biasInfo);

    Convolution2dLayer* const convLayer = AddConvolutionLayer(graph, layersInGraph, convolutionDescriptor,
                                                               "conv layer unoptimizable", outputInfo);
    Layer* const outputLayer = AddOutputLayer(graph, "output layer");

    // Connect the network
    inputLayer->GetOutputSlot(0).Connect(convLayer->GetInputSlot(0));
    weightsLayer->GetOutputSlot(0).Connect(convLayer->GetInputSlot(1));
    biasLayer->GetOutputSlot(0).Connect(convLayer->GetInputSlot(2));
    convLayer->GetOutputSlot(0).Connect(outputLayer->GetInputSlot(0));

    std::vector<unsigned int> ignoreSlots = {1, 2};
    // Create the subgraph view for the whole network
    return CreateSubgraphViewFrom(CreateInputsFrom(convLayer, ignoreSlots),
                                  CreateOutputsFrom({convLayer}),
                                  {convLayer, weightsLayer, biasLayer});
}

// Creates a subgraph with some unoptimizable layers ("unoptimizable" is added to the layer's name)
SubgraphView::SubgraphViewPtr BuildPartiallyOptimizableSubgraph1(Graph& graph, LayerNameToLayerMap& layersInGraph)
{
    const TensorInfo inputInfo ({  1, 16, 16, 16 }, DataType::QAsymmU8, 1.0f, 0);
    const TensorInfo outputInfo({  1, 16, 16, 16 }, DataType::QAsymmU8, 1.0f, 0);
    TensorInfo weightInfo({ 16,  1,  1, 16 }, DataType::QAsymmU8, 0.9f, 0);
    TensorInfo biasInfo  ({  1,  1,  1, 16 }, DataType::Signed32,        0.9f, 0);

    weightInfo.SetConstant(true);
    biasInfo.SetConstant(true);

    std::vector<float> weightsVector(64);
    ConstTensor constWeightsTensor(weightInfo, weightsVector);

    std::vector<float> biasVector(16);
    ConstTensor constBiasTensor(biasInfo, biasVector);

    Convolution2dDescriptor convolutionDescriptor;
    convolutionDescriptor.m_StrideX     = 1;
    convolutionDescriptor.m_StrideY     = 1;
    convolutionDescriptor.m_BiasEnabled = true;
    convolutionDescriptor.m_DataLayout  = DataLayout::NHWC;

    // Construct the graph
    Layer* const inputLayer = AddInputLayer(graph, "input layer", inputInfo);

    ConstantLayer* const weightsLayer1 =
        AddConstantLayer(graph, layersInGraph, "Weights Layer 1", constWeightsTensor, weightInfo);
    ConstantLayer* const biasLayer1 =
        AddConstantLayer(graph, layersInGraph, "Bias Layer 1", constBiasTensor, biasInfo);
    ConstantLayer* const weightsLayer2 =
        AddConstantLayer(graph, layersInGraph, "Weights Layer 2 unoptimizable", constWeightsTensor, weightInfo);
    ConstantLayer* const biasLayer2 =
        AddConstantLayer(graph, layersInGraph, "Bias Layer 2 unoptimizable", constBiasTensor, biasInfo);
    ConstantLayer* const weightsLayer3 =
        AddConstantLayer(graph, layersInGraph, "Weights Layer 3", constWeightsTensor, weightInfo);
    ConstantLayer* const biasLayer3 =
        AddConstantLayer(graph, layersInGraph, "Bias Layer 3", constBiasTensor, biasInfo);
    ConstantLayer* const weightsLayer4 =
        AddConstantLayer(graph, layersInGraph, "Weights Layer 4 unoptimizable", constWeightsTensor, weightInfo);
    ConstantLayer* const biasLayer4 =
        AddConstantLayer(graph, layersInGraph, "Bias Layer 4 unoptimizable", constBiasTensor, biasInfo);
    ConstantLayer* const weightsLayer5 =
        AddConstantLayer(graph, layersInGraph, "Weights Layer 5", constWeightsTensor, weightInfo);
    ConstantLayer* const biasLayer5 =
        AddConstantLayer(graph, layersInGraph, "Bias Layer 5", constBiasTensor, biasInfo);

  Convolution2dLayer* const conv1Layer = AddConvolutionLayer(graph, layersInGraph, convolutionDescriptor,
                                                             "conv1 layer", outputInfo);
  Convolution2dLayer* const conv2Layer = AddConvolutionLayer(graph, layersInGraph, convolutionDescriptor,
                                                             "conv2 layer unoptimizable", outputInfo);
  Convolution2dLayer* const conv3Layer = AddConvolutionLayer(graph, layersInGraph, convolutionDescriptor,
                                                             "conv3 layer", outputInfo);
  Convolution2dLayer* const conv4Layer = AddConvolutionLayer(graph, layersInGraph, convolutionDescriptor,
                                                             "conv4 layer unoptimizable", outputInfo);
  Convolution2dLayer* const conv5Layer = AddConvolutionLayer(graph, layersInGraph, convolutionDescriptor,
                                                             "conv5 layer", outputInfo);

  Layer* const outputLayer = AddOutputLayer(graph, "output layer");

    // Connect the network
    inputLayer->GetOutputSlot(0).Connect(conv1Layer->GetInputSlot(0));
    weightsLayer1->GetOutputSlot(0).Connect(conv1Layer->GetInputSlot(1));
    biasLayer1->GetOutputSlot(0).Connect(conv1Layer->GetInputSlot(2));

    conv1Layer->GetOutputSlot(0).Connect(conv2Layer->GetInputSlot(0));
    weightsLayer2->GetOutputSlot(0).Connect(conv2Layer->GetInputSlot(1));
    biasLayer2->GetOutputSlot(0).Connect(conv2Layer->GetInputSlot(2));

    conv2Layer->GetOutputSlot(0).Connect(conv3Layer->GetInputSlot(0));
    weightsLayer3->GetOutputSlot(0).Connect(conv3Layer->GetInputSlot(1));
    biasLayer3->GetOutputSlot(0).Connect(conv3Layer->GetInputSlot(2));

    conv3Layer->GetOutputSlot(0).Connect(conv4Layer->GetInputSlot(0));
    weightsLayer4->GetOutputSlot(0).Connect(conv4Layer->GetInputSlot(1));
    biasLayer4->GetOutputSlot(0).Connect(conv4Layer->GetInputSlot(2));

    conv4Layer->GetOutputSlot(0).Connect(conv5Layer->GetInputSlot(0));
    weightsLayer5->GetOutputSlot(0).Connect(conv5Layer->GetInputSlot(1));
    biasLayer5->GetOutputSlot(0).Connect(conv5Layer->GetInputSlot(2));

    conv5Layer->GetOutputSlot(0).Connect(outputLayer->GetInputSlot(0));

    std::vector<unsigned int> ignoreSlots = {1, 2};
    // Create the subgraph view for the whole network
    return CreateSubgraphViewFrom(CreateInputsFrom(conv1Layer, ignoreSlots),
                                  CreateOutputsFrom({conv5Layer}),
                                  {weightsLayer1,
                                    biasLayer1,
                                    conv1Layer,
                                    weightsLayer2,
                                    biasLayer2,
                                    conv2Layer,
                                    weightsLayer3,
                                    biasLayer3,
                                    conv3Layer,
                                    weightsLayer4,
                                    biasLayer4,
                                    conv4Layer,
                                    weightsLayer5,
                                    biasLayer5,
                                    conv5Layer});
}

// Creates a subgraph with some input unoptimizable layers ("unoptimizable" is added to the layer's name),
// this is meant to test input slots coming from different layers
SubgraphView::SubgraphViewPtr BuildPartiallyOptimizableSubgraph2(Graph& graph, LayerNameToLayerMap& layersInGraph)
{
    const TensorInfo inputInfo ({  1, 16, 16, 16 }, DataType::QAsymmU8, 1.0f, 0);
    const TensorInfo outputInfo({  1, 16, 16, 16 }, DataType::QAsymmU8, 1.0f, 0);
    TensorInfo weightInfo({ 16,  1,  1, 16 }, DataType::QAsymmU8, 0.9f, 0);
    TensorInfo biasInfo  ({  1,  1,  1, 16 }, DataType::Signed32,        0.9f, 0);

    weightInfo.SetConstant(true);
    biasInfo.SetConstant(true);

    std::vector<float> weightsVector(64);
    ConstTensor constWeightsTensor(weightInfo, weightsVector);

    std::vector<float> biasVector(16);
    ConstTensor constBiasTensor(biasInfo, biasVector);

    Convolution2dDescriptor convolutionDescriptor;
    convolutionDescriptor.m_StrideX     = 1;
    convolutionDescriptor.m_StrideY     = 1;
    convolutionDescriptor.m_BiasEnabled = true;
    convolutionDescriptor.m_DataLayout  = DataLayout::NHWC;

    // Construct the graph
    Layer* const input1Layer = AddInputLayer(graph, "input1 layer", inputInfo, 0);
    Layer* const input2Layer = AddInputLayer(graph, "input2 layer", inputInfo, 1);

    ConstantLayer* const weightsLayer1 =
        AddConstantLayer(graph, layersInGraph, "Weights Layer 1", constWeightsTensor, weightInfo);
    ConstantLayer* const biasLayer1 =
        AddConstantLayer(graph, layersInGraph, "Bias Layer 1", constBiasTensor, biasInfo);
    ConstantLayer* const weightsLayer2 =
        AddConstantLayer(graph, layersInGraph, "Weights Layer 2 unoptimizable", constWeightsTensor, weightInfo);
    ConstantLayer* const biasLayer2 =
        AddConstantLayer(graph, layersInGraph, "Bias Layer 2 unoptimizable", constBiasTensor, biasInfo);
    ConstantLayer* const weightsLayer3 =
        AddConstantLayer(graph, layersInGraph, "Weights Layer 3", constWeightsTensor, weightInfo);
    ConstantLayer* const biasLayer3 =
        AddConstantLayer(graph, layersInGraph, "Bias Layer 3", constBiasTensor, biasInfo);

    Convolution2dLayer* const conv1Layer = AddConvolutionLayer(graph, layersInGraph, convolutionDescriptor,
                                                               "conv1 layer", outputInfo);
    Convolution2dLayer* const conv2Layer = AddConvolutionLayer(graph, layersInGraph, convolutionDescriptor,
                                                               "conv2 layer unoptimizable", outputInfo);
    Convolution2dLayer* const conv3Layer = AddConvolutionLayer(graph, layersInGraph, convolutionDescriptor,
                                                               "conv3 layer", outputInfo);
    ARMNN_NO_DEPRECATE_WARN_BEGIN
    AdditionLayer* const addLayer = AddAdditionaLayer(graph, layersInGraph, "add layer", outputInfo);
    ARMNN_NO_DEPRECATE_WARN_END
    Layer* const outputLayer = AddOutputLayer(graph, "output layer");

    // Connect the network
    input1Layer->GetOutputSlot(0).Connect(conv1Layer->GetInputSlot(0));
    weightsLayer1->GetOutputSlot(0).Connect(conv1Layer->GetInputSlot(1));
    biasLayer1->GetOutputSlot(0).Connect(conv1Layer->GetInputSlot(2));
    conv1Layer->GetOutputSlot(0).Connect(addLayer->GetInputSlot(0));

    input2Layer->GetOutputSlot(0).Connect(conv2Layer->GetInputSlot(0));
    weightsLayer2->GetOutputSlot(0).Connect(conv2Layer->GetInputSlot(1));
    biasLayer2->GetOutputSlot(0).Connect(conv2Layer->GetInputSlot(2));
    conv2Layer->GetOutputSlot(0).Connect(conv3Layer->GetInputSlot(0));
    weightsLayer3->GetOutputSlot(0).Connect(conv3Layer->GetInputSlot(1));
    biasLayer3->GetOutputSlot(0).Connect(conv3Layer->GetInputSlot(2));
    conv3Layer->GetOutputSlot(0).Connect(addLayer->GetInputSlot(1));

    addLayer->GetOutputSlot(0).Connect(outputLayer->GetInputSlot(0));

    // Create the subgraph view for the whole network
    std::vector<unsigned int> ignoreSlots = {1, 2};
    return CreateSubgraphViewFrom(CreateInputsFrom({conv1Layer,
                                                    conv2Layer}, ignoreSlots),
                                  CreateOutputsFrom({addLayer}),
                                  { weightsLayer1,
                                    biasLayer1,
                                    weightsLayer2,
                                    biasLayer2,
                                    weightsLayer3,
                                    biasLayer3,
                                    conv1Layer,
                                    conv2Layer,
                                    conv3Layer,
                                    addLayer });
}

// The input subgraph contains only a single unsupported layer (only convolutions are unsupported by the mock backend)
void FullyUnsupporteSubgraphTestImpl1()
{
    Graph graph;
    LayerNameToLayerMap layersInGraph;

    // Create an unsupported subgraph
    SubgraphView::SubgraphViewPtr subgraphPtr = BuildFullyUnsupportedSubgraph1(graph, layersInGraph);
    CHECK((subgraphPtr != nullptr));

    const SubgraphView::IInputSlots& subgraphInputSlots = subgraphPtr->GetIInputSlots();
    const SubgraphView::IOutputSlots& subgraphOutputSlots = subgraphPtr->GetIOutputSlots();
    const SubgraphView::IConnectableLayers& subgraphLayers = subgraphPtr->GetIConnectableLayers();

    CHECK(subgraphInputSlots.size()  == 1);
    CHECK(subgraphOutputSlots.size() == 1);
    CHECK(subgraphLayers.size()      == 1);

    CHECK(Contains(layersInGraph, "pooling layer"));

    // Create a mock backend object
    MockBackendInitialiser initialiser; // Register the Mock Backend
    auto backendObjPtr = CreateBackendObject(MockBackendId());
    CHECK((backendObjPtr != nullptr));

    // Optimize the subgraph
    OptimizationViews optimizationViews;

    // Check that the optimization is carried out correctly, but no optimization is performed
    CHECK_NOTHROW(optimizationViews = backendObjPtr->OptimizeSubgraphView(*subgraphPtr));

    // =======================================================================
    // The expected results are:
    //  - No substitutions
    //  - Exactly one failed subgraph, corresponding to the whole original one
    //  - No untouched subgraphs
    // =======================================================================

    // -----------------------
    // Check the substitutions
    // -----------------------

    CHECK(optimizationViews.GetSubstitutions().empty());

    // --------------------------
    // Check the failed subgraphs
    // --------------------------

    const OptimizationViews::Subgraphs& failedSubgraphs = optimizationViews.GetFailedSubgraphs();
    CHECK(failedSubgraphs.size() == 1);

    CheckFailedSubgraph(failedSubgraphs.at(0),
                        { subgraphInputSlots.size(), subgraphOutputSlots.size(), subgraphLayers.size() },
                        subgraphInputSlots,
                        subgraphOutputSlots,
                        subgraphLayers);

    // -----------------------------
    // Check the untouched subgraphs
    // -----------------------------

    CHECK(optimizationViews.GetUntouchedSubgraphs().empty());
}

// The input subgraph contains only unsupported layers (only convolutions are unsupported by the mock backend)
void FullyUnsupporteSubgraphTestImpl2()
{
    Graph graph;
    LayerNameToLayerMap layersInGraph;

    // Create an unsupported subgraph
    SubgraphView::SubgraphViewPtr subgraphPtr = BuildFullyUnsupportedSubgraph2(graph, layersInGraph);
    CHECK((subgraphPtr != nullptr));

    const SubgraphView::IInputSlots& subgraphInputSlots = subgraphPtr->GetIInputSlots();
    const SubgraphView::IOutputSlots& subgraphOutputSlots = subgraphPtr->GetIOutputSlots();
    const SubgraphView::IConnectableLayers& subgraphLayers = subgraphPtr->GetIConnectableLayers();

    CHECK(subgraphInputSlots.size()  == 1);
    CHECK(subgraphOutputSlots.size() == 1);
    CHECK(subgraphLayers.size()      == 3);

    CHECK(Contains(layersInGraph, "pooling1 layer"));
    CHECK(Contains(layersInGraph, "pooling2 layer"));
    CHECK(Contains(layersInGraph, "pooling3 layer"));

    // Create a mock backend object
    MockBackendInitialiser initialiser; // Register the Mock Backend
    auto backendObjPtr = CreateBackendObject(MockBackendId());
    CHECK((backendObjPtr != nullptr));

    // Optimize the subgraph
    OptimizationViews optimizationViews;

    // Check that the optimization is carried out correctly, but no optimization is performed
    CHECK_NOTHROW(optimizationViews = backendObjPtr->OptimizeSubgraphView(*subgraphPtr));

    // =======================================================================
    // The expected results are:
    //  - No substitutions
    //  - Exactly one failed subgraph, corresponding to the whole original one
    //  - No untouched subgraphs
    // =======================================================================

    // -----------------------
    // Check the substitutions
    // -----------------------

    CHECK(optimizationViews.GetSubstitutions().empty());

    // --------------------------
    // Check the failed subgraphs
    // --------------------------

    const OptimizationViews::Subgraphs& failedSubgraphs = optimizationViews.GetFailedSubgraphs();
    CHECK(failedSubgraphs.size() == 1);

    std::list<IConnectableLayer*> expectedFailedLayers{ layersInGraph.at("pooling1 layer"),
                                            layersInGraph.at("pooling2 layer"),
                                            layersInGraph.at("pooling3 layer") };

    const SubgraphView& failedSubgraph = failedSubgraphs.at(0);

    CheckFailedSubgraph(failedSubgraph,
                        { subgraphInputSlots.size(), subgraphOutputSlots.size(), subgraphLayers.size() },
                        subgraphInputSlots,
                        subgraphOutputSlots,
                        subgraphLayers);

    const SubgraphView::IConnectableLayers& failedSubgraphLayers = failedSubgraph.GetIConnectableLayers();

    CHECK_EQ(failedSubgraphLayers.front() + 0, expectedFailedLayers.front() + 0);
    CHECK_EQ(failedSubgraphLayers.front() + 1, expectedFailedLayers.front() + 1);
    CHECK_EQ(failedSubgraphLayers.front() + 2, expectedFailedLayers.front() + 2);

    // -----------------------------
    // Check the untouched subgraphs
    // -----------------------------

    CHECK(optimizationViews.GetUntouchedSubgraphs().empty());
}

// A simple case with only one layer (convolution) to optimize, supported by the mock backend
void FullyOptimizableSubgraphTestImpl1()
{
    Graph graph;
    LayerNameToLayerMap layersInGraph;

    // Create a fully optimizable subgraph
    SubgraphView::SubgraphViewPtr subgraphPtr = BuildFullyOptimizableSubgraph1(graph, layersInGraph);
    CHECK((subgraphPtr != nullptr));

    const SubgraphView::IInputSlots& subgraphInputSlots = subgraphPtr->GetIInputSlots();
    const SubgraphView::IOutputSlots& subgraphOutputSlots = subgraphPtr->GetIOutputSlots();
    const SubgraphView::IConnectableLayers& subgraphLayers = subgraphPtr->GetIConnectableLayers();

    CHECK(subgraphInputSlots.size()  == 1);
    CHECK(subgraphOutputSlots.size() == 1);
    CHECK(subgraphLayers.size()      == 3);

    CHECK(Contains(layersInGraph, "conv layer"));
    CHECK(Contains(layersInGraph, "Weights Layer"));
    CHECK(Contains(layersInGraph, "Bias Layer"));

    // Create a mock backend object
    MockBackendInitialiser initialiser; // Register the Mock Backend
    auto backendObjPtr = CreateBackendObject(MockBackendId());
    CHECK((backendObjPtr != nullptr));

    // Optimize the subgraph
    OptimizationViews optimizationViews;

    // Check that the optimization is carried out correctly
    CHECK_NOTHROW(optimizationViews = backendObjPtr->OptimizeSubgraphView(*subgraphPtr));

    // ===========================================================================================
    // The expected results are:
    //  - Exactly one substitution, mapping the whole input subgraph to a new replacement subgraph
    //  - No failed subgraphs
    //  - No untouched subgraphs
    // ===========================================================================================

    // -----------------------
    // Check the substitutions
    // -----------------------

    const OptimizationViews::Substitutions& substitutions = optimizationViews.GetSubstitutions();
    CHECK(substitutions.size() == 1);

    CheckSubstitution(substitutions.at(0),
                      { subgraphInputSlots.size(), subgraphOutputSlots.size(), subgraphLayers.size() },
                      { subgraphInputSlots.size(), subgraphOutputSlots.size(), 1 },
                      subgraphInputSlots,
                      subgraphOutputSlots,
                      subgraphLayers);

    // --------------------------
    // Check the failed subgraphs
    // --------------------------

    CHECK(optimizationViews.GetFailedSubgraphs().empty());

    // -----------------------------
    // Check the untouched subgraphs
    // -----------------------------

    CHECK(optimizationViews.GetUntouchedSubgraphs().empty());
}

// A case with five layers (all convolutions) to optimize, all supported by the mock backend
void FullyOptimizableSubgraphTestImpl2()
{
    Graph graph;
    LayerNameToLayerMap layersInGraph;

    // Create a fully optimizable subgraph
    SubgraphView::SubgraphViewPtr subgraphPtr = BuildFullyOptimizableSubgraph2(graph, layersInGraph);
    CHECK((subgraphPtr != nullptr));

    const SubgraphView::IInputSlots& subgraphInputSlots = subgraphPtr->GetIInputSlots();
    const SubgraphView::IOutputSlots& subgraphOutputSlots = subgraphPtr->GetIOutputSlots();
    const SubgraphView::IConnectableLayers& subgraphLayers = subgraphPtr->GetIConnectableLayers();

    CHECK(subgraphInputSlots.size()  == 1);
    CHECK(subgraphOutputSlots.size() == 1);
    CHECK(subgraphPtr->GetIConnectableLayers().size() == 15);

    CHECK(Contains(layersInGraph, "conv1 layer"));
    CHECK(Contains(layersInGraph, "conv2 layer"));
    CHECK(Contains(layersInGraph, "conv3 layer"));
    CHECK(Contains(layersInGraph, "conv4 layer"));
    CHECK(Contains(layersInGraph, "conv5 layer"));
    CHECK(Contains(layersInGraph, "Weights Layer 1"));
    CHECK(Contains(layersInGraph, "Weights Layer 2"));
    CHECK(Contains(layersInGraph, "Weights Layer 3"));
    CHECK(Contains(layersInGraph, "Weights Layer 4"));
    CHECK(Contains(layersInGraph, "Weights Layer 5"));
    CHECK(Contains(layersInGraph, "Bias Layer 1"));
    CHECK(Contains(layersInGraph, "Bias Layer 2"));
    CHECK(Contains(layersInGraph, "Bias Layer 3"));
    CHECK(Contains(layersInGraph, "Bias Layer 4"));
    CHECK(Contains(layersInGraph, "Bias Layer 5"));

    // Create a mock backend object
    MockBackendInitialiser initialiser; // Register the Mock Backend
    auto backendObjPtr = CreateBackendObject(MockBackendId());
    CHECK((backendObjPtr != nullptr));

    // Optimize the subgraph
    OptimizationViews optimizationViews;

    // Check that the optimization is carried out correctly
    CHECK_NOTHROW(optimizationViews = backendObjPtr->OptimizeSubgraphView(*subgraphPtr));

    // ===========================================================================================
    // The expected results are:
    //  - Exactly one substitution, mapping the whole input subgraph to a new replacement subgraph
    //  - No failed subgraphs
    //  - No untouched subgraphs
    // ===========================================================================================

    // -----------------------
    // Check the substitutions
    // -----------------------

    const OptimizationViews::Substitutions& substitutions = optimizationViews.GetSubstitutions();
    CHECK(substitutions.size() == 1);

    std::list<IConnectableLayer*> expectedSubstitutableLayers{
                                                   layersInGraph.at("Weights Layer 1"),
                                                   layersInGraph.at("Weights Layer 2"),
                                                   layersInGraph.at("Weights Layer 3"),
                                                   layersInGraph.at("Weights Layer 4"),
                                                   layersInGraph.at("Weights Layer 5"),
                                                   layersInGraph.at("Bias Layer 1"),
                                                   layersInGraph.at("Bias Layer 2"),
                                                   layersInGraph.at("Bias Layer 3"),
                                                   layersInGraph.at("Bias Layer 4"),
                                                   layersInGraph.at("Bias Layer 5"),
                                                   layersInGraph.at("conv1 layer"),
                                                   layersInGraph.at("conv2 layer"),
                                                   layersInGraph.at("conv3 layer"),
                                                   layersInGraph.at("conv4 layer"),
                                                   layersInGraph.at("conv5 layer")};

    const OptimizationViews::SubstitutionPair& substitution = substitutions.at(0);

    CheckSubstitution(
        substitution,
        {subgraphInputSlots.size(), subgraphOutputSlots.size(),
         subgraphLayers.size()},
        {subgraphInputSlots.size(), subgraphOutputSlots.size(), 1},
        subgraphInputSlots, subgraphOutputSlots, expectedSubstitutableLayers);

    const SubgraphView::IConnectableLayers& substitutableSubgraphLayers =
            substitution.m_SubstitutableSubgraph.GetIConnectableLayers();

    CHECK_EQ(substitutableSubgraphLayers.front() + 0, expectedSubstitutableLayers.front() + 0);
    CHECK_EQ(substitutableSubgraphLayers.front() + 1, expectedSubstitutableLayers.front() + 1);
    CHECK_EQ(substitutableSubgraphLayers.front() + 2, expectedSubstitutableLayers.front() + 2);
    CHECK_EQ(substitutableSubgraphLayers.front() + 3, expectedSubstitutableLayers.front() + 3);
    CHECK_EQ(substitutableSubgraphLayers.front() + 4, expectedSubstitutableLayers.front() + 4);

    // --------------------------
    // Check the failed subgraphs
    // --------------------------

    CHECK(optimizationViews.GetFailedSubgraphs().empty());

    // -----------------------------
    // Check the untouched subgraphs
    // -----------------------------

    CHECK(optimizationViews.GetUntouchedSubgraphs().empty());
}

// The input subgraph contaions both supported and unsupported layers
// (but only convolutions are unsupported by the mock backend)
void PartiallySupportedSubgraphTestImpl()
{
    Graph graph;
    LayerNameToLayerMap layersInGraph;

    // Create a fully optimizable subgraph
    SubgraphView::SubgraphViewPtr subgraphPtr = BuildPartiallySupportedSubgraph(graph, layersInGraph);
    CHECK((subgraphPtr != nullptr));

    const SubgraphView::IInputSlots& subgraphInputSlots = subgraphPtr->GetIInputSlots();
    const SubgraphView::IOutputSlots& subgraphOutputSlots = subgraphPtr->GetIOutputSlots();
    const SubgraphView::IConnectableLayers& subgraphLayers = subgraphPtr->GetIConnectableLayers();

    CHECK(subgraphInputSlots.size()  == 1);
    CHECK(subgraphOutputSlots.size() == 1);
    CHECK(subgraphLayers.size()      == 9);

    CHECK(Contains(layersInGraph, "Weights Layer 1"));
    CHECK(Contains(layersInGraph, "Bias Layer 1"));
    CHECK(Contains(layersInGraph, "conv1 layer"));
    CHECK(Contains(layersInGraph, "pooling1 layer"));
    CHECK(Contains(layersInGraph, "pooling2 layer"));
    CHECK(Contains(layersInGraph, "Weights Layer 2"));
    CHECK(Contains(layersInGraph, "Bias Layer 2"));
    CHECK(Contains(layersInGraph, "conv2 layer"));
    CHECK(Contains(layersInGraph, "pooling3 layer"));

    // Create a mock backend object
    MockBackendInitialiser initialiser; // Register the Mock Backend
    auto backendObjPtr = CreateBackendObject(MockBackendId());
    CHECK((backendObjPtr != nullptr));

    // Optimize the subgraph
    OptimizationViews optimizationViews;

    // Check that the optimization is carried out correctly
    CHECK_NOTHROW(optimizationViews = backendObjPtr->OptimizeSubgraphView(*subgraphPtr));

    // ========================================================================
    // The expected results are:
    //  - Exactly two substitution, corresponding to the supported layers
    //  - Exactly two failed subgraphs, corresponding to the unsupported layers
    //  - No untouched subgraphs
    // ========================================================================

    // -----------------------
    // Check the substitutions
    // -----------------------

    OptimizationViews::Substitutions substitutions = optimizationViews.GetSubstitutions();
    CHECK(substitutions.size() == 2);
    // Sort into a consistent order
    std::sort(substitutions.begin(), substitutions.end(), [](auto s1, auto s2) {
        return strcmp(s1.m_SubstitutableSubgraph.GetIConnectableLayers().front()->GetName(),
                      s2.m_SubstitutableSubgraph.GetIConnectableLayers().front()->GetName()) < 0;
    });

    std::vector<ExpectedSubgraphSize> expectedSubstitutableSubgraphSizes{ { 1, 1, 3 },
                                                                          { 1, 1, 3 } };
    std::vector<ExpectedSubgraphSize> expectedReplacementSubgraphSizes{ { 1, 1, 1 },
                                                                        { 1, 1, 1 } };
    std::vector<SubgraphView::IInputSlots> expectedSubstitutableInputSlots
    {
            ConvertSlotsToISlots<InputSlot, IInputSlot>(
                {ConvertReferenceTypeToPointerType(layersInGraph.at("conv1 layer")->GetInputSlot(0))}),
            ConvertSlotsToISlots<InputSlot, IInputSlot>(
                {ConvertReferenceTypeToPointerType(layersInGraph.at("conv2 layer")->GetInputSlot(0))})
    };

    std::vector<SubgraphView::IOutputSlots> expectedSubstitutableOutputSlots
    {
        ConvertSlotsToISlots<OutputSlot, IOutputSlot>(
                ConvertReferenceTypeToPointerType(layersInGraph.at("conv1 layer")->GetOutputSlots())),
        ConvertSlotsToISlots<OutputSlot, IOutputSlot>(
                ConvertReferenceTypeToPointerType(layersInGraph.at("conv2 layer")->GetOutputSlots()))
    };
    std::vector<SubgraphView::IConnectableLayers> expectedSubstitutableLayers
    {
        { layersInGraph.at("Weights Layer 1"), layersInGraph.at("Bias Layer 1"), layersInGraph.at("conv1 layer") },
        { layersInGraph.at("Weights Layer 2"), layersInGraph.at("Bias Layer 2"), layersInGraph.at("conv2 layer") }
    };

    for (size_t substitutionIndex = 0; substitutionIndex < substitutions.size(); substitutionIndex++)
    {
        CheckSubstitution(substitutions.at(substitutionIndex),
                          expectedSubstitutableSubgraphSizes.at(substitutionIndex),
                          expectedReplacementSubgraphSizes.at(substitutionIndex),
                          expectedSubstitutableInputSlots.at(substitutionIndex),
                          expectedSubstitutableOutputSlots.at(substitutionIndex),
                          expectedSubstitutableLayers.at(substitutionIndex));
    }

    // --------------------------
    // Check the failed subgraphs
    // --------------------------

    OptimizationViews::Subgraphs failedSubgraphs = optimizationViews.GetFailedSubgraphs();
    CHECK(failedSubgraphs.size() == 2);
    // Sort into a consistent order
    std::sort(failedSubgraphs.begin(), failedSubgraphs.end(), [](auto s1, auto s2) {
        return strcmp(s1.GetIConnectableLayers().front()->GetName(),
                      s2.GetIConnectableLayers().front()->GetName()) < 0;
    });

    std::vector<ExpectedSubgraphSize> expectedFailedSubgraphSizes{ { 1, 1, 2 },
                                                                   { 1, 1, 1 } };
    std::vector<SubgraphView::IInputSlots> expectedFailedInputSlots
    {
        ConvertSlotsToISlots<InputSlot, IInputSlot>(
        ConvertReferenceTypeToPointerType(layersInGraph.at("pooling1 layer")->GetInputSlots())),
        ConvertSlotsToISlots<InputSlot, IInputSlot>(
        ConvertReferenceTypeToPointerType(layersInGraph.at("pooling3 layer")->GetInputSlots()))
    };
    std::vector<SubgraphView::IOutputSlots> expectedFailedOutputSlots
    {
        ConvertSlotsToISlots<OutputSlot, IOutputSlot>(
        ConvertReferenceTypeToPointerType(layersInGraph.at("pooling2 layer")->GetOutputSlots())),
        ConvertSlotsToISlots<OutputSlot, IOutputSlot>(
        ConvertReferenceTypeToPointerType(layersInGraph.at("pooling3 layer")->GetOutputSlots()))
    };
    std::vector<SubgraphView::IConnectableLayers> expectedFailedLayers
    {
        { layersInGraph.at("pooling1 layer"),
          layersInGraph.at("pooling2 layer") },
        { layersInGraph.at("pooling3 layer") }
    };

    for (size_t failedIndex = 0; failedIndex < failedSubgraphs.size(); failedIndex++)
    {
        CheckFailedSubgraph(failedSubgraphs.at(failedIndex),
                            expectedFailedSubgraphSizes.at(failedIndex),
                            expectedFailedInputSlots.at(failedIndex),
                            expectedFailedOutputSlots.at(failedIndex),
                            expectedFailedLayers.at(failedIndex));
    }

    // -----------------------------
    // Check the untouched subgraphs
    // -----------------------------

    CHECK(optimizationViews.GetUntouchedSubgraphs().empty());
}

// The input subgraph contains only unoptimizable layers ("unoptimizable" is added to the layer's name)
void FullyUnoptimizableSubgraphTestImpl1()
{
    Graph graph;
    LayerNameToLayerMap layersInGraph;

    // Create a fully optimizable subgraph
    SubgraphView::SubgraphViewPtr subgraphPtr = BuildFullyUnoptimizableSubgraph1(graph, layersInGraph);
    CHECK((subgraphPtr != nullptr));

    const SubgraphView::IInputSlots& subgraphInputSlots = subgraphPtr->GetIInputSlots();
    const SubgraphView::IOutputSlots& subgraphOutputSlots = subgraphPtr->GetIOutputSlots();
    const SubgraphView::IConnectableLayers& subgraphLayers = subgraphPtr->GetIConnectableLayers();

    CHECK(subgraphInputSlots.size()  == 1);
    CHECK(subgraphOutputSlots.size() == 1);
    CHECK(subgraphLayers.size()      == 3);

    CHECK(Contains(layersInGraph, "conv layer unoptimizable"));

    // Create a mock backend object
    MockBackendInitialiser initialiser; // Register the Mock Backend
    auto backendObjPtr = CreateBackendObject(MockBackendId());
    CHECK((backendObjPtr != nullptr));

    // Optimize the subgraph
    OptimizationViews optimizationViews;

    // Check that the optimization is carried out correctly
    CHECK_NOTHROW(optimizationViews = backendObjPtr->OptimizeSubgraphView(*subgraphPtr));

    // ============================================================================
    // The expected results are:
    //  - No substitutions
    //  - No failed subgraphs
    //  - Exactly one untouched subgraph, corresponding to the whole input subgraph
    // ============================================================================

    // -----------------------
    // Check the substitutions
    // -----------------------

    CHECK(optimizationViews.GetSubstitutions().empty());

    // --------------------------
    // Check the failed subgraphs
    // --------------------------

    CHECK(optimizationViews.GetFailedSubgraphs().empty());

    // -----------------------------
    // Check the untouched subgraphs
    // -----------------------------

    const OptimizationViews::Subgraphs& untouchedSubgraphs = optimizationViews.GetUntouchedSubgraphs();
    CHECK(untouchedSubgraphs.size() == 1);

    CheckUntouchedSubgraph(untouchedSubgraphs.at(0),
                           {subgraphInputSlots.size(),
                            subgraphOutputSlots.size(), subgraphLayers.size()},
                           subgraphInputSlots, subgraphOutputSlots,
                           subgraphLayers);
}

// The input subgraph contains some unoptimizable layers ("unoptimizable" is added to the layer's name)
void PartiallyOptimizableSubgraphTestImpl1()
{
    Graph graph;
    LayerNameToLayerMap layersInGraph;

    // Create a fully optimizable subgraph
    SubgraphView::SubgraphViewPtr subgraphPtr = BuildPartiallyOptimizableSubgraph1(graph, layersInGraph);
    CHECK((subgraphPtr != nullptr));

    const SubgraphView::IInputSlots& subgraphInputSlots = subgraphPtr->GetIInputSlots();
    const SubgraphView::IOutputSlots& subgraphOutputSlots = subgraphPtr->GetIOutputSlots();
    const SubgraphView::IConnectableLayers& subgraphLayers = subgraphPtr->GetIConnectableLayers();

    CHECK(subgraphInputSlots.size()  == 1);
    CHECK(subgraphOutputSlots.size() == 1);
    CHECK(subgraphLayers.size()      == 15);

    CHECK(Contains(layersInGraph, "conv1 layer"));
    CHECK(Contains(layersInGraph, "conv2 layer unoptimizable"));
    CHECK(Contains(layersInGraph, "conv3 layer"));
    CHECK(Contains(layersInGraph, "conv4 layer unoptimizable"));
    CHECK(Contains(layersInGraph, "conv5 layer"));

    // Create a mock backend object
    MockBackendInitialiser initialiser; // Register the Mock Backend
    auto backendObjPtr = CreateBackendObject(MockBackendId());
    CHECK((backendObjPtr != nullptr));

    // Optimize the subgraph
    OptimizationViews optimizationViews;

    // Check that the optimization is carried out correctly
    CHECK_NOTHROW(optimizationViews = backendObjPtr->OptimizeSubgraphView(*subgraphPtr));

    // ===============================================================================
    // The expected results are:
    //  - Exactly three substitutions, corresponding to the optimizable layers
    //  - No failed subgraphs
    //  - Exactly two untouched subgraphs, corresponding to the non-optimizable layers
    // ===============================================================================

    // -----------------------
    // Check the substitutions
    // -----------------------

    OptimizationViews::Substitutions substitutions = optimizationViews.GetSubstitutions();
    CHECK(substitutions.size() == 3);
    // Sort into a consistent order
    std::sort(substitutions.begin(), substitutions.end(),
        [](auto s1, auto s2)
        { return strcmp(s1.m_SubstitutableSubgraph.GetIConnectableLayers().front()->GetName(),
                        s2.m_SubstitutableSubgraph.GetIConnectableLayers().front()->GetName()) < 0; });

    std::vector<ExpectedSubgraphSize> expectedSubstitutableSubgraphSizes{ { 1, 1, 3 },
                                                                          { 1, 1, 3 },
                                                                          { 1, 1, 3 } };
    std::vector<ExpectedSubgraphSize> expectedReplacementSubgraphSizes{ { 1, 1, 1 },
                                                                        { 1, 1, 1 },
                                                                        { 1, 1, 1 } };
    std::vector<SubgraphView::IInputSlots> expectedSubstitutableInputSlots
    {
        ConvertSlotsToISlots<InputSlot, IInputSlot>(
            {ConvertReferenceTypeToPointerType(layersInGraph.at("conv1 layer")->GetInputSlot(0))}),
        ConvertSlotsToISlots<InputSlot, IInputSlot>(
        {ConvertReferenceTypeToPointerType(layersInGraph.at("conv3 layer")->GetInputSlot(0))}),
        ConvertSlotsToISlots<InputSlot, IInputSlot>(
        {ConvertReferenceTypeToPointerType(layersInGraph.at("conv5 layer")->GetInputSlot(0))})
    };
    std::vector<SubgraphView::IOutputSlots> expectedSubstitutableOutputSlots
    {
        ConvertSlotsToISlots<OutputSlot, IOutputSlot>(
        ConvertReferenceTypeToPointerType(layersInGraph.at("conv1 layer")->GetOutputSlots())),
        ConvertSlotsToISlots<OutputSlot, IOutputSlot>(
        ConvertReferenceTypeToPointerType(layersInGraph.at("conv3 layer")->GetOutputSlots())),
        ConvertSlotsToISlots<OutputSlot, IOutputSlot>(
        ConvertReferenceTypeToPointerType(layersInGraph.at("conv5 layer")->GetOutputSlots()))
    };
    std::vector<SubgraphView::IConnectableLayers> expectedSubstitutableLayers
    {
        { layersInGraph.at("Weights Layer 1"), layersInGraph.at("Bias Layer 1"), layersInGraph.at("conv1 layer") },
        { layersInGraph.at("Weights Layer 3"), layersInGraph.at("Bias Layer 3"), layersInGraph.at("conv3 layer") },
        { layersInGraph.at("Weights Layer 5"), layersInGraph.at("Bias Layer 5"), layersInGraph.at("conv5 layer") }
    };

    for (size_t substitutionIndex = 0; substitutionIndex < substitutions.size(); substitutionIndex++)
    {
        CheckSubstitution(substitutions.at(substitutionIndex),
                          expectedSubstitutableSubgraphSizes.at(substitutionIndex),
                          expectedReplacementSubgraphSizes.at(substitutionIndex),
                          expectedSubstitutableInputSlots.at(substitutionIndex),
                          expectedSubstitutableOutputSlots.at(substitutionIndex),
                          expectedSubstitutableLayers.at(substitutionIndex));
    }

    // --------------------------
    // Check the failed subgraphs
    // --------------------------

    CHECK(optimizationViews.GetFailedSubgraphs().empty());

    // -----------------------------
    // Check the untouched subgraphs
    // -----------------------------

    OptimizationViews::Subgraphs untouchedSubgraphs = optimizationViews.GetUntouchedSubgraphs();
    CHECK(untouchedSubgraphs.size() == 2);
    // Sort into a consistent order
    std::sort(untouchedSubgraphs.begin(), untouchedSubgraphs.end(), [](auto s1, auto s2) {
        return strcmp(s1.GetIConnectableLayers().front()->GetName(),
                      s2.GetIConnectableLayers().front()->GetName()) < 0;
    });

    std::vector<ExpectedSubgraphSize> expectedUntouchedSubgraphSizes{ { 1, 1, 3 },
                                                                      { 1, 1, 3 } };
    std::vector<SubgraphView::IInputSlots> expectedUntouchedInputSlots{
        ConvertSlotsToISlots<InputSlot,
                             IInputSlot>({ConvertReferenceTypeToPointerType(
            layersInGraph.at("conv2 layer unoptimizable")->GetInputSlot(0))}),
        ConvertSlotsToISlots<InputSlot,
                             IInputSlot>({ConvertReferenceTypeToPointerType(
            layersInGraph.at("conv4 layer unoptimizable")->GetInputSlot(0))})};

    std::vector<SubgraphView::IOutputSlots> expectedUntouchedOutputSlots
        {
            ConvertSlotsToISlots<OutputSlot, IOutputSlot>(
                ConvertReferenceTypeToPointerType(layersInGraph.at("conv2 layer unoptimizable")->GetOutputSlots())),
            ConvertSlotsToISlots<OutputSlot, IOutputSlot>(
                ConvertReferenceTypeToPointerType(layersInGraph.at("conv4 layer unoptimizable")->GetOutputSlots()))
        };

    std::vector<SubgraphView::IConnectableLayers> expectedUntouchedLayers
        {
            { layersInGraph.at("Weights Layer 2 unoptimizable"),
              layersInGraph.at("Bias Layer 2 unoptimizable"),
              layersInGraph.at("conv2 layer unoptimizable") },
            { layersInGraph.at("Weights Layer 4 unoptimizable"),
              layersInGraph.at("Bias Layer 4 unoptimizable"),
              layersInGraph.at("conv4 layer unoptimizable") }
        };

    for (size_t untouchedIndex = 0; untouchedIndex < untouchedSubgraphs.size(); untouchedIndex++)
    {
        CheckUntouchedSubgraph(untouchedSubgraphs.at(untouchedIndex),
                               expectedUntouchedSubgraphSizes.at(untouchedIndex),
                               expectedUntouchedInputSlots.at(untouchedIndex),
                               expectedUntouchedOutputSlots.at(untouchedIndex),
                               expectedUntouchedLayers.at(untouchedIndex));
    }
}

// The input subgraph contains some unoptimizable layers ("unoptimizable" is added to the layer's name),
// this is meant to test input slots coming from different layers
void PartiallyOptimizableSubgraphTestImpl2()
{
    Graph graph;
    LayerNameToLayerMap layersInGraph;

    // Create a partially optimizable subgraph
    SubgraphView::SubgraphViewPtr subgraphPtr = BuildPartiallyOptimizableSubgraph2(graph, layersInGraph);
    CHECK((subgraphPtr != nullptr));

    const SubgraphView::IInputSlots& subgraphInputSlots = subgraphPtr->GetIInputSlots();
    const SubgraphView::IOutputSlots& subgraphOutputSlots = subgraphPtr->GetIOutputSlots();
    const SubgraphView::IConnectableLayers& subgraphLayers = subgraphPtr->GetIConnectableLayers();

    CHECK(subgraphInputSlots.size()  == 2);
    CHECK(subgraphOutputSlots.size() == 1);
    CHECK(subgraphLayers.size()      == 10);

    CHECK(Contains(layersInGraph, "conv1 layer"));
    CHECK(Contains(layersInGraph, "conv2 layer unoptimizable"));
    CHECK(Contains(layersInGraph, "conv3 layer"));
    CHECK(Contains(layersInGraph, "add layer"));

    // Create a mock backend object
    MockBackendInitialiser initialiser; // Register the Mock Backend
    auto backendObjPtr = CreateBackendObject(MockBackendId());
    CHECK((backendObjPtr != nullptr));

    // Optimize the subgraph
    OptimizationViews optimizationViews;

    // Check that the optimization is carried out correctly
    CHECK_NOTHROW(optimizationViews = backendObjPtr->OptimizeSubgraphView(*subgraphPtr));

    // ==============================================================================
    // The expected results are:
    //  - Exactly one substitution, corresponding to the optimizable layers
    //  - No failed subgraphs
    //  - Exactly two untouched subgraphs, corresponding to the non-optimizable layer
    // ==============================================================================

    // -----------------------
    // Check the substitutions
    // -----------------------

    const OptimizationViews::Substitutions& substitutions = optimizationViews.GetSubstitutions();
    CHECK(substitutions.size() == 1);

    ExpectedSubgraphSize expectedSubstitutableSubgraphSizes{ 2, 1, 7 };
    ExpectedSubgraphSize expectedReplacementSubgraphSizes{ 2, 1, 1 };

    SubgraphView::IInputSlots expectedSubstitutableInputSlots
    {
            ConvertSlotsToISlots<InputSlot, IInputSlot>({
                    ConvertReferenceTypeToPointerType(layersInGraph.at("conv1 layer")->GetInputSlots()[0])})[0],
            ConvertSlotsToISlots<InputSlot, IInputSlot>({
                    ConvertReferenceTypeToPointerType(layersInGraph.at("conv3 layer")->GetInputSlots()[0])})[0]
    };

    SubgraphView::IOutputSlots expectedSubstitutableOutputSlots
    {
            ConvertSlotsToISlots<OutputSlot, IOutputSlot>(
                    ConvertReferenceTypeToPointerType(layersInGraph.at("add layer")->GetOutputSlots()))
    };

    SubgraphView::IConnectableLayers expectedSubstitutableLayers
    {
        layersInGraph.at("Weights Layer 1"),
        layersInGraph.at("Weights Layer 3"),
        layersInGraph.at("Bias Layer 1"),
        layersInGraph.at("Bias Layer 3"),
        layersInGraph.at("conv1 layer"),
        layersInGraph.at("conv3 layer"),
        layersInGraph.at("add layer")
    };

    CheckSubstitution(substitutions[0],
                      expectedSubstitutableSubgraphSizes,
                      expectedReplacementSubgraphSizes,
                      expectedSubstitutableInputSlots,
                      expectedSubstitutableOutputSlots,
                      expectedSubstitutableLayers);

    // --------------------------
    // Check the failed subgraphs
    // --------------------------

    CHECK(optimizationViews.GetFailedSubgraphs().empty());

    // -----------------------------
    // Check the untouched subgraphs
    // -----------------------------

    const OptimizationViews::Subgraphs& untouchedSubgraphs = optimizationViews.GetUntouchedSubgraphs();
    CHECK(untouchedSubgraphs.size() == 1);

    std::vector<ExpectedSubgraphSize> expectedUntouchedSubgraphSizes{ { 1, 1, 3 } };
    std::vector<SubgraphView::IInputSlots> expectedUntouchedInputSlots
    {
        ConvertSlotsToISlots<InputSlot,
                             IInputSlot>({ConvertReferenceTypeToPointerType(
            layersInGraph.at("conv2 layer unoptimizable")->GetInputSlot(0))})};
    std::vector<SubgraphView::IOutputSlots> expectedUntouchedOutputSlots
    {
            ConvertSlotsToISlots<OutputSlot, IOutputSlot>(
        ConvertReferenceTypeToPointerType(layersInGraph.at("conv2 layer unoptimizable")->GetOutputSlots()))
    };
    std::vector<SubgraphView::IConnectableLayers> expectedUntouchedLayers
    {
        { layersInGraph.at("conv2 layer unoptimizable"), layersInGraph.at("Weights Layer 2 unoptimizable"),
        layersInGraph.at("Bias Layer 2 unoptimizable") }
    };

    for (size_t untouchedIndex = 0; untouchedIndex < untouchedSubgraphs.size(); untouchedIndex++)
    {
        CheckUntouchedSubgraph(untouchedSubgraphs.at(untouchedIndex),
                               expectedUntouchedSubgraphSizes.at(untouchedIndex),
                               expectedUntouchedInputSlots.at(untouchedIndex),
                               expectedUntouchedOutputSlots.at(untouchedIndex),
                               expectedUntouchedLayers.at(untouchedIndex));
    }
}

} // Anonymous namespace

TEST_SUITE("OptimizeSubGraph")
{
TEST_CASE("FullyUnsupportedSubgraph1")     { FullyUnsupporteSubgraphTestImpl1();      }
TEST_CASE("FullyUnsupportedSubgraph2")     { FullyUnsupporteSubgraphTestImpl2();      }
TEST_CASE("FullyOptimizableSubgraph1")     { FullyOptimizableSubgraphTestImpl1();     }
TEST_CASE("FullyOptimizableSubgraph2")     { FullyOptimizableSubgraphTestImpl2();     }
TEST_CASE("PartiallySupportedSubgraph")    { PartiallySupportedSubgraphTestImpl();    }
TEST_CASE("FullyUnoptimizableSubgraph")    { FullyUnoptimizableSubgraphTestImpl1();   }
TEST_CASE("PartiallyOptimizableSubgraph1") { PartiallyOptimizableSubgraphTestImpl1(); }
TEST_CASE("PartiallyOptimizableSubgraph2") { PartiallyOptimizableSubgraphTestImpl2(); }

}
