aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFrancis Murtagh <francis.murtagh@arm.com>2022-12-21 09:10:04 +0000
committerFrancis Murtagh <francis.murtagh@arm.com>2023-01-12 11:11:28 +0000
commit01f72693d39ed966ad06adadc8aac141bc395659 (patch)
treed619d2c112bff714d38025b57370aa4095935e36
parent05b6a3e5946a3f58b6f5b0caface9153a1c2b364 (diff)
downloadarmnn-01f72693d39ed966ad06adadc8aac141bc395659.tar.gz
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
-rw-r--r--include/armnn/backends/SubgraphView.hpp13
-rw-r--r--src/armnn/Graph.cpp2
-rw-r--r--src/armnn/SubgraphView.cpp56
-rw-r--r--src/armnn/SubgraphViewSelector.cpp5
-rw-r--r--src/armnn/SubgraphViewSelector.hpp5
-rw-r--r--src/armnn/test/SubgraphViewTests.cpp138
-rw-r--r--src/backends/backendsCommon/test/OptimizationViewsTests.cpp36
-rw-r--r--src/backends/backendsCommon/test/OptimizeSubgraphViewTests.cpp14
8 files changed, 206 insertions, 63 deletions
diff --git a/include/armnn/backends/SubgraphView.hpp b/include/armnn/backends/SubgraphView.hpp
index 777311747a..24f8958930 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 @@ class OutputSlot;
/// 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 @@ public:
}
}
- 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 @@ public:
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 e5d123830c..6943076ada 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 b48529c523..fef6390bf2 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 @@ void AssertIfNullsOrDuplicates(const C& container, const std::string& errorMessa
} // 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 @@ SubgraphView::SubgraphView(Graph& graph)
/// 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(InputSlots&& inputs, OutputSlots&& outputs, Layers&&
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::SubgraphView(SubgraphView::IConnectableLayers&& layers,
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(SubgraphView::IConnectableLayers&& layers,
}
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(const SubgraphView& subgraph)
}
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(SubgraphView&& subgraph)
}
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 @@ struct SubgraphView::SubgraphViewWorkingCopy
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 @@ SubgraphView SubgraphView::GetWorkingCopy() const
// 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 @@ void SubgraphView::SubstituteSubgraph(SubgraphView& patternSubgraph, const Subgr
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 b632149924..9fa8252790 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 @@ SubgraphViewSelector::SelectSubgraphs(SubgraphView& subgraph, const LayerSelecto
// 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 0a05bc259e..4808a99fb9 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 Graph;
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 9bb5e69bbb..48f4a7fc01 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 @@ SubgraphView::IOutputSlots CreateIOutputsFrom(const std::vector<armnn::IConnecta
// 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 @@ void CompareVectors(const std::vector<T>& result, const std::vector<T>& expected
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 @@ TEST_CASE("SubgraphViewSlots")
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 @@ TEST_CASE("SubgraphViewConstructors")
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 @@ TEST_CASE("SingleInputSingleOutput")
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 @@ TEST_CASE("SingleInputSingleOutputAddPrecompiledLayerSubstituteSubgraph1")
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 @@ TEST_CASE("SingleInputSingleOutputAddPrecompiledLayerSubstituteSubgraph2")
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 @@ TEST_CASE("SingleInputSingleOutputSubstituteGraph")
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 @@ TEST_CASE("SingleInputSingleOutputSubstituteGraph")
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 @@ TEST_CASE("SingleInputMultiOutput")
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 @@ TEST_CASE("MultiInputMultiOutput")
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 @@ TEST_CASE("EraseReplacedIConnectableLayers")
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 @@ TEST_CASE("Random")
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 @@ TEST_CASE("Random")
// 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 @@ TEST_CASE("SubgraphViewPartialWorkingCopySubstituteSubgraph")
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 @@ TEST_CASE("MultipleOutputSlotsSubstituteGraph")
}
// pattern subgraph creation
- SubgraphViewSelector::SubgraphViewPtr subgraph =
+ SubgraphView::SubgraphViewPtr subgraph =
CreateSubgraphViewFrom({convCopyLayer},
{&convCopyLayer->GetInputSlot(0)},
{&convCopyLayer->GetOutputSlot(0)});
@@ -2491,7 +2591,7 @@ TEST_CASE("MultipleInputMultipleOutputSlots_SubstituteGraph")
// 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 ff84eea2de..ff3217911a 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 @@ TEST_CASE("OptimizedViewsSubgraphLayerCount")
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 @@ TEST_CASE("OptimizedViewsSubgraphLayerCount")
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 @@ TEST_CASE("OptimizedViewsSubgraphLayerCount")
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 @@ TEST_CASE("OptimizedViewsSubgraphLayerCountUsingGetINetwork")
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 @@ TEST_CASE("OptimizedViewsSubgraphLayerCountUsingGetINetwork")
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 @@ TEST_CASE("OptimizedViewsSubgraphLayerCountUsingGetINetwork")
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 @@ TEST_CASE("OptimizedViewsSubgraphLayerCountFailValidate")
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 @@ TEST_CASE("OptimizedViewsSubgraphLayerCountFailValidate")
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 @@ TEST_CASE("OptimizedViewsSubgraphLayerCountFailValidate")
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 @@ TEST_CASE("OptimizedViewsReturnsINetworkReference")
}
-} \ No newline at end of file
+}
diff --git a/src/backends/backendsCommon/test/OptimizeSubgraphViewTests.cpp b/src/backends/backendsCommon/test/OptimizeSubgraphViewTests.cpp
index 997fe9850d..f5a6c4217b 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 @@ void FullyOptimizableSubgraphTestImpl1()
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 @@ void FullyOptimizableSubgraphTestImpl2()
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 @@ void PartiallySupportedSubgraphTestImpl()
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 @@ void FullyUnoptimizableSubgraphTestImpl1()
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 @@ void PartiallyOptimizableSubgraphTestImpl1()
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 @@ void PartiallyOptimizableSubgraphTestImpl2()
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();