IVGCVSW-7418 Allow working copy SubgraphView to get Original Slots

 * API to remove need for workaround so backend users can get slots
 * OutputSlots outside the SubgraphView needed to obtain TensorInfo
 * Fix a few Copyright headers
 * Add shared_ptr back to original subgraph view using
   std::enable_shared_from_this

Signed-off-by: Francis Murtagh <francis.murtagh@arm.com>
Change-Id: I033a00d6fc4020619d406ac06a156b7e380a426a
diff --git a/include/armnn/backends/SubgraphView.hpp b/include/armnn/backends/SubgraphView.hpp
index 7773117..24f8958 100644
--- a/include/armnn/backends/SubgraphView.hpp
+++ b/include/armnn/backends/SubgraphView.hpp
@@ -1,5 +1,5 @@
 //
-// Copyright © 2017,2022 Arm Ltd and Contributors. All rights reserved.
+// Copyright © 2017, 2022-2023 Arm Ltd and Contributors. All rights reserved.
 // SPDX-License-Identifier: MIT
 //
 
@@ -28,7 +28,7 @@
 /// the contents of the SubgraphView become invalid when the Layers are destroyed
 /// or changed.
 ///
-class SubgraphView final
+class SubgraphView final : public std::enable_shared_from_this<SubgraphView>
 {
 public:
     template <typename Func>
@@ -53,7 +53,7 @@
         }
     }
 
-    using SubgraphViewPtr = std::unique_ptr<SubgraphView>;
+    using SubgraphViewPtr = std::shared_ptr<SubgraphView>;
     using InputSlots = std::vector<InputSlot*>;
     using IInputSlots = std::vector<IInputSlot*>;
     using OutputSlots = std::vector<OutputSlot*>;
@@ -171,6 +171,13 @@
     void SubstituteSubgraph(SubgraphView&, IConnectableLayer*);
     void SubstituteSubgraph(SubgraphView&, const SubgraphView&);
 
+    /// These methods should be called on a working copy subgraph created from GetWorkingCopy.
+    /// They return pointers to the input and output Slots belonging to the original SubgraphView
+    /// that the working copy was created from.
+    /// This may be used to find the original TensorInfo of connected boundary OutputSlots.
+    const IInputSlots& GetOriginalInputSlots() const;
+    const IOutputSlots& GetOriginalOutputSlots() const;
+
 private:
     struct SubgraphViewWorkingCopy;
 
diff --git a/src/armnn/Graph.cpp b/src/armnn/Graph.cpp
index e5d1238..6943076 100644
--- a/src/armnn/Graph.cpp
+++ b/src/armnn/Graph.cpp
@@ -1,5 +1,5 @@
 //
-// Copyright © 2017 Arm Ltd and Contributors. All rights reserved.
+// Copyright © 2017-2023 Arm Ltd and Contributors. All rights reserved.
 // SPDX-License-Identifier: MIT
 //
 
diff --git a/src/armnn/SubgraphView.cpp b/src/armnn/SubgraphView.cpp
index b48529c..fef6390 100644
--- a/src/armnn/SubgraphView.cpp
+++ b/src/armnn/SubgraphView.cpp
@@ -1,5 +1,5 @@
 //
-// Copyright © 2017 Arm Ltd. All rights reserved.
+// Copyright © 2017, 2019-2023 Arm Ltd and Contributors. All rights reserved.
 // SPDX-License-Identifier: MIT
 //
 
@@ -42,7 +42,8 @@
 } // anonymous namespace
 
 SubgraphView::SubgraphView(Graph& graph)
-    : m_InputSlots{}
+    : enable_shared_from_this()
+    , m_InputSlots{}
     , m_OutputSlots{}
     , m_Layers(graph.begin(), graph.end())
     , m_IConnectableLayers(graph.begin(), graph.end())
@@ -53,7 +54,8 @@
 
 /// IConnectable Duplication to maintain backwards compatibility
 SubgraphView::SubgraphView(InputSlots&& inputs, OutputSlots&& outputs, Layers&& layers)
-    : m_InputSlots{InputSlots{inputs.begin(), inputs.end()}}
+    : enable_shared_from_this()
+    , m_InputSlots{InputSlots{inputs.begin(), inputs.end()}}
     , m_IInputSlots{IInputSlots{inputs.begin(), inputs.end()}}
     , m_OutputSlots{OutputSlots{outputs.begin(), outputs.end()}}
     , m_IOutputSlots{IOutputSlots{outputs.begin(), outputs.end()}}
@@ -68,7 +70,8 @@
 SubgraphView::SubgraphView(SubgraphView::IConnectableLayers&& layers,
                            SubgraphView::IInputSlots&& inputs,
                            SubgraphView::IOutputSlots&& outputs)
-        : m_IInputSlots{inputs}
+        : enable_shared_from_this()
+        , m_IInputSlots{inputs}
         , m_IOutputSlots{outputs}
         , m_IConnectableLayers(IConnectableLayers{layers.begin(), layers.end()})
 {
@@ -104,7 +107,8 @@
                            SubgraphView::IInputSlots&& inputs,
                            SubgraphView::IOutputSlots&& outputs,
                            std::shared_ptr<SubgraphViewWorkingCopy> ptr)
-        : m_IInputSlots{inputs}
+        : enable_shared_from_this()
+        , m_IInputSlots{inputs}
         , m_IOutputSlots{outputs}
         , m_IConnectableLayers(IConnectableLayers{layers.begin(), layers.end()})
         , p_WorkingCopyImpl(std::move(ptr))
@@ -137,7 +141,8 @@
 }
 
 SubgraphView::SubgraphView(const SubgraphView& subgraph)
-    : m_InputSlots(subgraph.m_InputSlots.begin(), subgraph.m_InputSlots.end())
+    : enable_shared_from_this()
+    , m_InputSlots(subgraph.m_InputSlots.begin(), subgraph.m_InputSlots.end())
     , m_IInputSlots(subgraph.m_IInputSlots.begin(), subgraph.m_IInputSlots.end())
     , m_OutputSlots(subgraph.m_OutputSlots.begin(), subgraph.m_OutputSlots.end())
     , m_IOutputSlots(subgraph.m_IOutputSlots.begin(), subgraph.m_IOutputSlots.end())
@@ -150,7 +155,8 @@
 }
 
 SubgraphView::SubgraphView(SubgraphView&& subgraph)
-    : m_InputSlots(std::move(subgraph.m_InputSlots))
+    : enable_shared_from_this()
+    , m_InputSlots(std::move(subgraph.m_InputSlots))
     , m_IInputSlots(std::move(subgraph.m_IInputSlots))
     , m_OutputSlots(std::move(subgraph.m_OutputSlots))
     , m_IOutputSlots(std::move(subgraph.m_IOutputSlots))
@@ -162,7 +168,8 @@
 }
 
 SubgraphView::SubgraphView(IConnectableLayer* layer)
-    : m_Layers{PolymorphicDowncast<Layer*>(layer)}
+    : enable_shared_from_this()
+    , m_Layers{PolymorphicDowncast<Layer*>(layer)}
     , m_IConnectableLayers{layer}
 {
     unsigned int numInputSlots = layer->GetNumInputSlots();
@@ -408,11 +415,13 @@
 public:
 
     SubgraphViewWorkingCopy() = default;
-    SubgraphViewWorkingCopy(Graph graph)
+    SubgraphViewWorkingCopy(Graph graph, std::shared_ptr<const SubgraphView> originalSubgraphView)
                             : m_Graph(graph)
+                            , m_OriginalSubgraphView(originalSubgraphView)
     {};
 
     Graph m_Graph;
+    std::shared_ptr<const SubgraphView> m_OriginalSubgraphView;
 
 };
 
@@ -426,7 +435,7 @@
 
     // Create a cut down SubgraphView with underlying graph containing only the relevant layers.
     // It needs its own underlying layers so that they can be replaced safely.
-    auto ptr = std::make_shared<SubgraphViewWorkingCopy>(Graph());
+    auto ptr = std::make_shared<SubgraphViewWorkingCopy>(Graph(), shared_from_this());
 
     std::unordered_map<const IConnectableLayer*, IConnectableLayer*> originalToClonedLayerMap;
     std::list<armnn::IConnectableLayer*> originalSubgraphLayers = GetIConnectableLayers();
@@ -607,5 +616,32 @@
                                                workingCopyGraph->m_Layers.end() };
 }
 
+const SubgraphView::IInputSlots& SubgraphView::GetOriginalInputSlots() const
+{
+    if (!p_WorkingCopyImpl)
+    {
+        throw NullPointerException("The SubgraphView calling GetOriginalInputSlots is not a working copy. "
+                                   "Call this function on SubgraphView returned from SubgraphView::GetWorkingCopy()");
+    }
+    if (!p_WorkingCopyImpl->m_OriginalSubgraphView)
+    {
+        throw NullPointerException("The working copy SubgraphView pointer to its original SubgraphView is null.");
+    }
+    return p_WorkingCopyImpl->m_OriginalSubgraphView->GetIInputSlots();
+}
+const SubgraphView::IOutputSlots& SubgraphView::GetOriginalOutputSlots() const
+{
+    if (!p_WorkingCopyImpl)
+    {
+        throw NullPointerException("The SubgraphView calling GetOriginalOutputSlots is not a working copy. "
+                                   "Call this function on SubgraphView returned from SubgraphView::GetWorkingCopy()");
+    }
+    if (!p_WorkingCopyImpl->m_OriginalSubgraphView)
+    {
+        throw NullPointerException("The working copy SubgraphView pointer to its original SubgraphView is null.");
+    }
+    return p_WorkingCopyImpl->m_OriginalSubgraphView->GetIOutputSlots();
+}
+
 
 } // namespace armnn
diff --git a/src/armnn/SubgraphViewSelector.cpp b/src/armnn/SubgraphViewSelector.cpp
index b632149..9fa8252 100644
--- a/src/armnn/SubgraphViewSelector.cpp
+++ b/src/armnn/SubgraphViewSelector.cpp
@@ -1,5 +1,5 @@
 //
-// Copyright © 2017 Arm Ltd. All rights reserved.
+// Copyright © 2017, 2023 Arm Ltd and Contributors. All rights reserved.
 // SPDX-License-Identifier: MIT
 //
 
@@ -524,7 +524,8 @@
     // Sort subgraphs list into deterministic order, not relying on pointer values which may be different on each 
     // execution. This makes debugging the optimised graph much easier as subsequent stages can also be 
     // deterministic.
-    std::sort(result.begin(), result.end(), [](const SubgraphViewPtr& a, const SubgraphViewPtr& b)
+    std::sort(result.begin(), result.end(), [](const SubgraphView::SubgraphViewPtr& a,
+                                               const SubgraphView::SubgraphViewPtr& b)
     {
         return a->GetIConnectableLayers().front()->GetGuid() < b->GetIConnectableLayers().front()->GetGuid();
     });
diff --git a/src/armnn/SubgraphViewSelector.hpp b/src/armnn/SubgraphViewSelector.hpp
index 0a05bc2..4808a99 100644
--- a/src/armnn/SubgraphViewSelector.hpp
+++ b/src/armnn/SubgraphViewSelector.hpp
@@ -1,5 +1,5 @@
 //
-// Copyright © 2017 Arm Ltd. All rights reserved.
+// Copyright © 2017, 2023 Arm Ltd and Contributors. All rights reserved.
 // SPDX-License-Identifier: MIT
 //
 #pragma once
@@ -21,8 +21,7 @@
 class SubgraphViewSelector final
 {
 public:
-    using SubgraphViewPtr = std::unique_ptr<SubgraphView>;
-    using Subgraphs = std::vector<SubgraphViewPtr>;
+    using Subgraphs = std::vector<SubgraphView::SubgraphViewPtr>;
     using LayerSelectorFunction = std::function<bool(const Layer&)>;
 
     /// Selects subgraphs from a graph based on the selector function and the algorithm.
diff --git a/src/armnn/test/SubgraphViewTests.cpp b/src/armnn/test/SubgraphViewTests.cpp
index 9bb5e69..48f4a7f 100644
--- a/src/armnn/test/SubgraphViewTests.cpp
+++ b/src/armnn/test/SubgraphViewTests.cpp
@@ -1,5 +1,5 @@
 //
-// Copyright © 2017 Arm Ltd. All rights reserved.
+// Copyright © 2017, 2019-2023 Arm Ltd and Contributors. All rights reserved.
 // SPDX-License-Identifier: MIT
 //
 
@@ -119,14 +119,14 @@
 // this takes the inputs, outputs and layers as a copy and the move these copies into the
 // resulting subgraph, so the pass by value is intentional
 //
-SubgraphViewSelector::SubgraphViewPtr CreateSubgraphViewFrom(SubgraphView::InputSlots&& inputs,
+SubgraphView::SubgraphViewPtr CreateSubgraphViewFrom(SubgraphView::InputSlots&& inputs,
                                                              SubgraphView::OutputSlots&& outputs,
                                                              SubgraphView::Layers&& layers)
 {
     return std::make_unique<SubgraphView>(std::move(inputs), std::move(outputs), std::move(layers));
 }
 
-SubgraphViewSelector::SubgraphViewPtr CreateSubgraphViewFrom(SubgraphView::IConnectableLayers&& layers,
+SubgraphView::SubgraphViewPtr CreateSubgraphViewFrom(SubgraphView::IConnectableLayers&& layers,
                                                              SubgraphView::IInputSlots&& inputs,
                                                              SubgraphView::IOutputSlots&& outputs)
 {
@@ -147,8 +147,8 @@
     CHECK(std::equal(result.begin(), result.end(), expected.begin(), expected.end()));
 }
 
-void CompareSubgraphViews(SubgraphViewSelector::SubgraphViewPtr& result,
-                          SubgraphViewSelector::SubgraphViewPtr& expected)
+void CompareSubgraphViews(SubgraphView::SubgraphViewPtr& result,
+                          SubgraphView::SubgraphViewPtr& expected)
 {
     // expect both to be valid subgraphs
     CHECK((result.get() != nullptr));
@@ -256,7 +256,7 @@
     convLayer2->GetOutputSlot(0).Connect(outputLayer->GetInputSlot(0));
 
     // Construct sub-graph
-    SubgraphViewSelector::SubgraphViewPtr subgraph = CreateSubgraphViewFrom({},
+    SubgraphView::SubgraphViewPtr subgraph = CreateSubgraphViewFrom({},
                                                                             CreateIInputsFrom({convLayer1}, {1, 2}),
                                                                             CreateIOutputsFrom({convLayer2}));
 
@@ -293,7 +293,7 @@
     convLayer2->GetOutputSlot(0).Connect(outputLayer->GetInputSlot(0));
 
     // Construct sub-graph
-    SubgraphViewSelector::SubgraphViewPtr subgraph =
+    SubgraphView::SubgraphViewPtr subgraph =
             CreateSubgraphViewFrom({inputLayer, convLayer1, convLayer2, outputLayer},
                                    CreateIInputsFrom({convLayer1}),
                                    CreateIOutputsFrom({convLayer2}));
@@ -354,7 +354,7 @@
     convLayer2->GetOutputSlot(0).Connect(outputLayer->GetInputSlot(0));
 
     // Construct sub-graph
-    SubgraphViewSelector::SubgraphViewPtr subgraph =
+    SubgraphView::SubgraphViewPtr subgraph =
             CreateSubgraphViewFrom({},
                                    CreateIInputsFrom({convLayer1}, {1}),
                                    CreateIOutputsFrom({convLayer2}));
@@ -396,7 +396,7 @@
     convLayer2->GetOutputSlot(0).Connect(outputLayer->GetInputSlot(0));
 
     // Construct sub-graph
-    SubgraphViewSelector::SubgraphViewPtr subgraph = CreateSubgraphViewFrom(CreateInputsFrom({convLayer1}, {1}),
+    SubgraphView::SubgraphViewPtr subgraph = CreateSubgraphViewFrom(CreateInputsFrom({convLayer1}, {1}),
                                                                             CreateOutputsFrom({convLayer2}),
                                                                             {});
 
@@ -440,7 +440,7 @@
     convLayer2->GetOutputSlot(0).Connect(outputLayer->GetInputSlot(0));
 
     // Construct sub-graph
-    SubgraphViewSelector::SubgraphViewPtr subgraph = CreateSubgraphViewFrom(CreateInputsFrom({convLayer1}, {1}),
+    SubgraphView::SubgraphViewPtr subgraph = CreateSubgraphViewFrom(CreateInputsFrom({convLayer1}, {1}),
                                                                             CreateOutputsFrom({convLayer2}),
                                                                             {});
 
@@ -485,7 +485,7 @@
     convLayer2->GetOutputSlot(0).Connect(outputLayer->GetInputSlot(0));
 
     // Construct sub-graph
-    SubgraphViewSelector::SubgraphViewPtr subgraph =
+    SubgraphView::SubgraphViewPtr subgraph =
             CreateSubgraphViewFrom(CreateInputsFrom({convLayer1}, {1}),
                                    CreateOutputsFrom({convLayer2}),
                                    {});
@@ -499,7 +499,7 @@
     PreCompiledDescriptor preCompiledDescriptor(1, 1);
     Layer* const preCompiledLayer = substituteGraph.AddLayer<PreCompiledLayer>(preCompiledDescriptor, "pre-compiled");
 
-    SubgraphViewSelector::SubgraphViewPtr substituteSubgraph =
+    SubgraphView::SubgraphViewPtr substituteSubgraph =
                                           CreateSubgraphViewFrom(CreateInputsFrom({preCompiledLayer}),
                                                                  CreateOutputsFrom({preCompiledLayer}),
                                                                  {preCompiledLayer});
@@ -587,7 +587,7 @@
     concatLayer->GetOutputSlot(0).Connect(outputLayer->GetInputSlot(0));
 
     // Construct sub-graph
-    SubgraphViewSelector::SubgraphViewPtr subgraph =
+    SubgraphView::SubgraphViewPtr subgraph =
             CreateSubgraphViewFrom(CreateInputsFrom({splitterLayer}),
                                    CreateOutputsFrom({convLayer1, convLayer2}),
                                    {});
@@ -639,7 +639,7 @@
     concatLayer->GetOutputSlot(0).Connect(outputLayer->GetInputSlot(0));
 
     // Construct sub-graph
-    SubgraphViewSelector::SubgraphViewPtr subgraph =
+    SubgraphView::SubgraphViewPtr subgraph =
             CreateSubgraphViewFrom(CreateInputsFrom({convLayer1, convLayer2}, {1}),
                                    CreateOutputsFrom({convLayer1, convLayer2}),
                                    {});
@@ -686,7 +686,7 @@
     graph.AddLayer<OutputLayer>(0, "output");
 
     // Construct sub-graph
-    SubgraphViewSelector::SubgraphViewPtr subgraph = CreateSubgraphViewFrom({splitterLayer,
+    SubgraphView::SubgraphViewPtr subgraph = CreateSubgraphViewFrom({splitterLayer,
                                                                              convLayer1,
                                                                              convLayer2,
                                                                              concatLayer},
@@ -1514,7 +1514,7 @@
         for (Layer* layer : graph)
         {
             size_t i = 0;
-            for (std::unique_ptr<SubgraphView>& subgraph : subgraphs)
+            for (auto& subgraph : subgraphs)
             {
                 std::string name = std::to_string(i++);
                 if (std::find(subgraph->cbeginIConnectable(), subgraph->cendIConnectable(), layer)
@@ -1551,7 +1551,7 @@
         // Check the dependencies between subgraphs to make sure that the algorithm has produced a valid result.
         // Starting from each of the input slots of each subgraph, recurse up the graph and ensure that we never
         // encounter a layer that belongs to the subgraph that we started from.
-        for (std::unique_ptr<SubgraphView>& subgraph : subgraphs)
+        for (auto& subgraph : subgraphs)
         {
             for (IInputSlot* inSlot : subgraph->GetIInputSlots())
             {
@@ -2092,6 +2092,106 @@
     CHECK(std::string((*workingCopy.beginIConnectable())->GetName()) == "Activation2");
 }
 
+// Workaround function used to get the original OutputSlot connected to the InputSlot of a SubgraphView
+// As working copy SubgraphViews do not have connections on boundary it finds the corresponding InputSlot
+// on the Original SubgraphView and then returns the OutputSlot connected to it.
+// Using this function to test against the simpler API: SubgraphView::GetOriginalInputSlots().
+const IOutputSlot* GetConnection(IInputSlot* inputSlot,
+                                 const SubgraphView& workingCopy,
+                                 const SubgraphView& original)
+{
+    const IOutputSlot* res = inputSlot->GetConnection();
+    if (res)
+    {
+        return res;
+    }
+
+    const SubgraphView::IInputSlots& workingCopyInputSlots = workingCopy.GetIInputSlots();
+    const SubgraphView::IInputSlots& originalInputSlots = original.GetIInputSlots();
+    for (SubgraphView::InputSlots::size_type i = 0; i < workingCopyInputSlots.size(); i++)
+    {
+        if (workingCopyInputSlots[i] == inputSlot)
+        {
+            return originalInputSlots[i]->GetConnection();
+        }
+    }
+    return nullptr;
+}
+
+// Workaround function used to get the original InputSlot connected to the OutputSlot of a SubgraphView
+// As working copy SubgraphViews do not have connections on boundary it finds the corresponding OutputSlot
+// on the Original SubgraphView and then returns the InputSlot connected to it using index parameter.
+// Using this function to test against the simpler API: SubgraphView::GetOriginalOutputSlots().
+const IInputSlot* GetConnection(IOutputSlot* outputSlot,
+                                unsigned int index,
+                                const SubgraphView& workingCopy,
+                                const SubgraphView& original)
+{
+    const IInputSlot* res;
+    // Check within range
+    if (index < outputSlot->GetNumConnections() && outputSlot->GetNumConnections() > 0)
+    {
+        res = outputSlot->GetConnection(index);
+        return res;
+    }
+
+    const SubgraphView::IOutputSlots& workingCopyOutputSlots = workingCopy.GetIOutputSlots();
+    const SubgraphView::IOutputSlots& originalOutputSlots = original.GetIOutputSlots();
+    for (SubgraphView::OutputSlots::size_type i = 0; i < workingCopyOutputSlots.size(); i++)
+    {
+        if (workingCopyOutputSlots[i] == outputSlot)
+        {
+            // Check within range
+            if (index < originalOutputSlots[i]->GetNumConnections() && originalOutputSlots[i]->GetNumConnections() > 0)
+            {
+                return originalOutputSlots[i]->GetConnection(index);
+            }
+        }
+    }
+    return nullptr;
+}
+
+SubgraphView CheckOutOfScopeWorkingCopy()
+{
+    Graph graph;
+
+    auto input = graph.AddLayer<InputLayer>(0, "Input");
+    auto activation = graph.AddLayer<ActivationLayer>(ActivationDescriptor{}, "Activation");
+    auto output = graph.AddLayer<OutputLayer>(1, "Output");
+
+    input->GetOutputSlot(0).Connect(activation->GetInputSlot(0));
+    activation->GetOutputSlot(0).Connect(output->GetInputSlot(0));
+
+    //Add in out of order
+    auto shared = CreateSubgraphViewFrom({activation},
+                                       {&activation->GetInputSlot(0)},
+                                       {&activation->GetOutputSlot(0)});
+
+    auto workingCopy = shared->GetWorkingCopy();
+
+    // Check InputSlots are same as original
+    auto boundaryOutputSlot = GetConnection(workingCopy.GetIInputSlots()[0], workingCopy, *shared);
+    CHECK(boundaryOutputSlot);
+
+    auto inputSlots = workingCopy.GetOriginalInputSlots();
+    CHECK(inputSlots[0]->GetConnection() == boundaryOutputSlot);
+
+    // Check OutputSlots are same as original
+    auto boundaryInputSlot = GetConnection(workingCopy.GetIOutputSlots()[0], 0U, workingCopy, *shared);
+    CHECK(boundaryInputSlot);
+
+    auto outputSlots = workingCopy.GetOriginalOutputSlots();
+    CHECK(outputSlots[0]->GetConnection(0) == boundaryInputSlot);
+
+    return workingCopy;
+}
+
+TEST_CASE("SubgraphViewWorkingCopyOriginalSlots")
+{
+    auto result = CheckOutOfScopeWorkingCopy();
+    auto outputSlots = result.GetOriginalOutputSlots();
+}
+
 TEST_CASE("SubgraphViewWorkingCopyOptimizationViews")
 {
     Graph graph;
@@ -2394,7 +2494,7 @@
     }
 
     // pattern subgraph creation
-    SubgraphViewSelector::SubgraphViewPtr subgraph =
+    SubgraphView::SubgraphViewPtr subgraph =
         CreateSubgraphViewFrom({convCopyLayer},
                                {&convCopyLayer->GetInputSlot(0)},
                                {&convCopyLayer->GetOutputSlot(0)});
@@ -2491,7 +2591,7 @@
 
     // pattern subgraph creation
     IConnectableLayer* constCopyLayer = &addCopyLayer->GetInputSlot(0).GetConnection()->GetOwningIConnectableLayer();
-    SubgraphViewSelector::SubgraphViewPtr subgraph = CreateSubgraphViewFrom({addCopyLayer, constCopyLayer},
+    SubgraphView::SubgraphViewPtr subgraph = CreateSubgraphViewFrom({addCopyLayer, constCopyLayer},
                                                                             {&addCopyLayer->GetInputSlot(0)},
                                                                             {&addCopyLayer->GetOutputSlot(0)});
 
diff --git a/src/backends/backendsCommon/test/OptimizationViewsTests.cpp b/src/backends/backendsCommon/test/OptimizationViewsTests.cpp
index ff84eea..ff32179 100644
--- a/src/backends/backendsCommon/test/OptimizationViewsTests.cpp
+++ b/src/backends/backendsCommon/test/OptimizationViewsTests.cpp
@@ -1,5 +1,5 @@
 //
-// Copyright © 2017, 2019-2022  Arm Ltd and Contributors. All rights reserved.
+// Copyright © 2017, 2019-2023  Arm Ltd and Contributors. All rights reserved.
 // SPDX-License-Identifier: MIT
 //
 
@@ -78,17 +78,17 @@
     convLayer2->GetOutputSlot(0).Connect(outputLayer->GetInputSlot(0));
 
     // Subgraph for a failed layer
-    SubgraphViewSelector::SubgraphViewPtr failedSubgraph =
+    SubgraphView::SubgraphViewPtr failedSubgraph =
         CreateSubgraphViewFrom(CreateInputsFrom(convLayer1),
                                CreateOutputsFrom({convLayer1}),
                                {convLayer1});
     // Subgraph for an untouched layer
-    SubgraphViewSelector::SubgraphViewPtr untouchedSubgraph =
+    SubgraphView::SubgraphViewPtr untouchedSubgraph =
             CreateSubgraphViewFrom(CreateInputsFrom(convLayer2),
                                    CreateOutputsFrom({convLayer2}),
                                    {convLayer2});
     // Subgraph for a substitutable layer
-    SubgraphViewSelector::SubgraphViewPtr substitutableSubgraph =
+    SubgraphView::SubgraphViewPtr substitutableSubgraph =
             CreateSubgraphViewFrom(CreateInputsFrom(convLayer1),
                                    CreateOutputsFrom({convLayer2}),
                                    {substitutableCompiledLayer});
@@ -98,7 +98,7 @@
             substitutableGraph.AddLayer<PreCompiledLayer>(substitutionLayerDescriptor, "pre-compiled");
 
     // Subgraph for a substitution layer
-    SubgraphViewSelector::SubgraphViewPtr substitutionSubgraph =
+    SubgraphView::SubgraphViewPtr substitutionSubgraph =
             CreateSubgraphViewFrom(CreateInputsFrom(substitutionpreCompiledLayer),
                                    CreateOutputsFrom({substitutionpreCompiledLayer}),
                                    {substitutionpreCompiledLayer});
@@ -109,14 +109,14 @@
     view.AddFailedSubgraph(SubgraphView(*failedSubgraph));
     view.AddUntouchedSubgraph(SubgraphView(*untouchedSubgraph));
 
-    SubgraphViewSelector::SubgraphViewPtr baseSubgraph =
+    SubgraphView::SubgraphViewPtr baseSubgraph =
             CreateSubgraphViewFrom(CreateInputsFrom(convLayer1),
                                    CreateOutputsFrom({convLayer2}),
                                    {substitutionpreCompiledLayer});
     view.AddSubstitution({*baseSubgraph, *substitutionSubgraph});
 
     // Construct original subgraph to compare against
-    SubgraphViewSelector::SubgraphViewPtr originalSubgraph =
+    SubgraphView::SubgraphViewPtr originalSubgraph =
             CreateSubgraphViewFrom(CreateInputsFrom(convLayer1),
             CreateOutputsFrom({convLayer2}),
             {convLayer1, convLayer2, substitutionpreCompiledLayer});
@@ -151,11 +151,11 @@
     convLayer2->GetOutputSlot(0).Connect(outputLayer->GetInputSlot(0));
 
     // Subgraph for a failed layer
-    SubgraphViewSelector::SubgraphViewPtr failedSubgraph = CreateSubgraphViewFrom(CreateInputsFrom(convLayer1),
+    SubgraphView::SubgraphViewPtr failedSubgraph = CreateSubgraphViewFrom(CreateInputsFrom(convLayer1),
                                                                                   CreateOutputsFrom({convLayer1}),
                                                                                   {convLayer1});
     // Subgraph for an untouched layer
-    SubgraphViewSelector::SubgraphViewPtr untouchedSubgraph = CreateSubgraphViewFrom(CreateInputsFrom(convLayer2),
+    SubgraphView::SubgraphViewPtr untouchedSubgraph = CreateSubgraphViewFrom(CreateInputsFrom(convLayer2),
                                                                                      CreateOutputsFrom({convLayer2}),
                                                                                      {convLayer2});
 
@@ -165,7 +165,7 @@
         net.AddPrecompiledLayer(substitutionLayerDescriptor, std::move(blobPtr), backend));
 
     // Subgraph for a substitution layer
-    SubgraphViewSelector::SubgraphViewPtr substitutionSubgraph =
+    SubgraphView::SubgraphViewPtr substitutionSubgraph =
         CreateSubgraphViewFrom(CreateInputsFrom(substitutionpreCompiledLayer),
                                                 CreateOutputsFrom({substitutionpreCompiledLayer}),
                                                 {substitutionpreCompiledLayer});
@@ -173,13 +173,13 @@
     view.AddFailedSubgraph(SubgraphView(*failedSubgraph));
     view.AddUntouchedSubgraph(SubgraphView(*untouchedSubgraph));
 
-    SubgraphViewSelector::SubgraphViewPtr baseSubgraph = CreateSubgraphViewFrom(CreateInputsFrom(convLayer1),
+    SubgraphView::SubgraphViewPtr baseSubgraph = CreateSubgraphViewFrom(CreateInputsFrom(convLayer1),
                                                                                 CreateOutputsFrom({convLayer2}),
                                                                                 {substitutionpreCompiledLayer});
     view.AddSubstitution({*baseSubgraph, *substitutionSubgraph});
 
     // Construct original subgraph to compare against
-    SubgraphViewSelector::SubgraphViewPtr originalSubgraph =
+    SubgraphView::SubgraphViewPtr originalSubgraph =
         CreateSubgraphViewFrom(CreateInputsFrom(convLayer1),
                                                 CreateOutputsFrom({convLayer2}),
                                                 {convLayer1, convLayer2, substitutionpreCompiledLayer});
@@ -214,12 +214,12 @@
     convLayer2->GetOutputSlot(0).Connect(outputLayer->GetInputSlot(0));
 
     // Subgraph for an untouched layer
-    SubgraphViewSelector::SubgraphViewPtr untouchedSubgraph =
+    SubgraphView::SubgraphViewPtr untouchedSubgraph =
             CreateSubgraphViewFrom(CreateInputsFrom(convLayer2),
                                    CreateOutputsFrom({convLayer2}),
                                    {convLayer2});
     // Subgraph for a substitutable layer
-    SubgraphViewSelector::SubgraphViewPtr substitutableSubgraph =
+    SubgraphView::SubgraphViewPtr substitutableSubgraph =
             CreateSubgraphViewFrom(CreateInputsFrom(convLayer1),
                                    CreateOutputsFrom({convLayer2}),
                                    {substitutableCompiledLayer});
@@ -229,7 +229,7 @@
             substitutableGraph.AddLayer<PreCompiledLayer>(substitutionLayerDescriptor, "pre-compiled");
 
     // Subgraph for a substitution layer
-    SubgraphViewSelector::SubgraphViewPtr substitutionSubgraph =
+    SubgraphView::SubgraphViewPtr substitutionSubgraph =
             CreateSubgraphViewFrom(CreateInputsFrom(substitutionpreCompiledLayer),
                                    CreateOutputsFrom({substitutionpreCompiledLayer}),
                                    {substitutionpreCompiledLayer});
@@ -239,14 +239,14 @@
 
     view.AddUntouchedSubgraph(SubgraphView(*untouchedSubgraph));
 
-    SubgraphViewSelector::SubgraphViewPtr baseSubgraph =
+    SubgraphView::SubgraphViewPtr baseSubgraph =
             CreateSubgraphViewFrom(CreateInputsFrom(convLayer1),
                                    CreateOutputsFrom({convLayer2}),
                                    {substitutionpreCompiledLayer});
     view.AddSubstitution({*baseSubgraph, *substitutionSubgraph});
 
     // Construct original subgraph to compare against
-    SubgraphViewSelector::SubgraphViewPtr originalSubgraph =
+    SubgraphView::SubgraphViewPtr originalSubgraph =
             CreateSubgraphViewFrom(CreateInputsFrom(convLayer1),
                                    CreateOutputsFrom({convLayer2}),
                                    {convLayer1, convLayer2, substitutionpreCompiledLayer});
@@ -299,4 +299,4 @@
 }
 
 
-}
\ No newline at end of file
+}
diff --git a/src/backends/backendsCommon/test/OptimizeSubgraphViewTests.cpp b/src/backends/backendsCommon/test/OptimizeSubgraphViewTests.cpp
index 997fe98..f5a6c42 100644
--- a/src/backends/backendsCommon/test/OptimizeSubgraphViewTests.cpp
+++ b/src/backends/backendsCommon/test/OptimizeSubgraphViewTests.cpp
@@ -1,5 +1,5 @@
 //
-// Copyright © 2017,2022 Arm Ltd and Contributors. All rights reserved.
+// Copyright © 2017, 2022-2023 Arm Ltd and Contributors. All rights reserved.
 // SPDX-License-Identifier: MIT
 //
 
@@ -935,7 +935,7 @@
     LayerNameToLayerMap layersInGraph;
 
     // Create a fully optimizable subgraph
-    SubgraphViewSelector::SubgraphViewPtr subgraphPtr = BuildFullyOptimizableSubgraph1(graph, layersInGraph);
+    SubgraphView::SubgraphViewPtr subgraphPtr = BuildFullyOptimizableSubgraph1(graph, layersInGraph);
     CHECK((subgraphPtr != nullptr));
 
     const SubgraphView::IInputSlots& subgraphInputSlots = subgraphPtr->GetIInputSlots();
@@ -1002,7 +1002,7 @@
     LayerNameToLayerMap layersInGraph;
 
     // Create a fully optimizable subgraph
-    SubgraphViewSelector::SubgraphViewPtr subgraphPtr = BuildFullyOptimizableSubgraph2(graph, layersInGraph);
+    SubgraphView::SubgraphViewPtr subgraphPtr = BuildFullyOptimizableSubgraph2(graph, layersInGraph);
     CHECK((subgraphPtr != nullptr));
 
     const SubgraphView::IInputSlots& subgraphInputSlots = subgraphPtr->GetIInputSlots();
@@ -1110,7 +1110,7 @@
     LayerNameToLayerMap layersInGraph;
 
     // Create a fully optimizable subgraph
-    SubgraphViewSelector::SubgraphViewPtr subgraphPtr = BuildPartiallySupportedSubgraph(graph, layersInGraph);
+    SubgraphView::SubgraphViewPtr subgraphPtr = BuildPartiallySupportedSubgraph(graph, layersInGraph);
     CHECK((subgraphPtr != nullptr));
 
     const SubgraphView::IInputSlots& subgraphInputSlots = subgraphPtr->GetIInputSlots();
@@ -1254,7 +1254,7 @@
     LayerNameToLayerMap layersInGraph;
 
     // Create a fully optimizable subgraph
-    SubgraphViewSelector::SubgraphViewPtr subgraphPtr = BuildFullyUnoptimizableSubgraph1(graph, layersInGraph);
+    SubgraphView::SubgraphViewPtr subgraphPtr = BuildFullyUnoptimizableSubgraph1(graph, layersInGraph);
     CHECK((subgraphPtr != nullptr));
 
     const SubgraphView::IInputSlots& subgraphInputSlots = subgraphPtr->GetIInputSlots();
@@ -1318,7 +1318,7 @@
     LayerNameToLayerMap layersInGraph;
 
     // Create a fully optimizable subgraph
-    SubgraphViewSelector::SubgraphViewPtr subgraphPtr = BuildPartiallyOptimizableSubgraph1(graph, layersInGraph);
+    SubgraphView::SubgraphViewPtr subgraphPtr = BuildPartiallyOptimizableSubgraph1(graph, layersInGraph);
     CHECK((subgraphPtr != nullptr));
 
     const SubgraphView::IInputSlots& subgraphInputSlots = subgraphPtr->GetIInputSlots();
@@ -1470,7 +1470,7 @@
     LayerNameToLayerMap layersInGraph;
 
     // Create a partially optimizable subgraph
-    SubgraphViewSelector::SubgraphViewPtr subgraphPtr = BuildPartiallyOptimizableSubgraph2(graph, layersInGraph);
+    SubgraphView::SubgraphViewPtr subgraphPtr = BuildPartiallyOptimizableSubgraph2(graph, layersInGraph);
     CHECK((subgraphPtr != nullptr));
 
     const SubgraphView::IInputSlots& subgraphInputSlots = subgraphPtr->GetIInputSlots();