From 602af090a6b7285dc1041e3d8424836e5fa12cef Mon Sep 17 00:00:00 2001 From: Matteo Martincigh Date: Wed, 1 May 2019 10:31:27 +0100 Subject: IVGCVSW-3029 Remove any AddLayer capabilities from SubgraphView * Removed the reference to the parent graph in SubgraphView * Removed the AddLayer method in SubgraphView * Updated the code where necessary to adapt to the new changes in SubgraphView * Fixed a check in the CreatePreCompiledWorkloadTest test function Change-Id: I4d3af87f11ec3cd8f18a21b250a2d295da56e1a0 Signed-off-by: Matteo Martincigh --- src/armnn/Graph.cpp | 2 +- src/armnn/Network.cpp | 17 ++++---- src/armnn/SubgraphView.cpp | 47 +++------------------ src/armnn/SubgraphView.hpp | 36 +++------------- src/armnn/SubgraphViewSelector.cpp | 6 +-- src/armnn/test/CreateWorkload.hpp | 2 +- src/armnn/test/SubgraphViewTests.cpp | 52 ++++++++---------------- src/backends/backendsCommon/IBackendInternal.hpp | 1 + 8 files changed, 40 insertions(+), 123 deletions(-) diff --git a/src/armnn/Graph.cpp b/src/armnn/Graph.cpp index 335f1951bb..9827b70de9 100644 --- a/src/armnn/Graph.cpp +++ b/src/armnn/Graph.cpp @@ -321,7 +321,7 @@ void Graph::ReplaceSubgraphConnections(const SubgraphView& subgraph, IConnectabl // Create a new sub-graph with only the given layer, using // the given sub-graph as a reference of which parent graph to use - SubgraphView substituteSubgraph(subgraph, substituteLayer); + SubgraphView substituteSubgraph(substituteLayer); ReplaceSubgraphConnections(subgraph, substituteSubgraph); } diff --git a/src/armnn/Network.cpp b/src/armnn/Network.cpp index 9ef0c568a3..1047567cc4 100644 --- a/src/armnn/Network.cpp +++ b/src/armnn/Network.cpp @@ -348,13 +348,13 @@ OptimizationResult ApplyBackendOptimizations(OptimizedNetwork* optNetObjPtr, // Select sub-graphs based on backend SubgraphViewSelector::Subgraphs subgraphs = SubgraphViewSelector::SelectSubgraphs(mainSubgraph, - // Select layers assigned to the requested backend - [&backendObjPtr](const Layer& layer) - { - return layer.GetType() != LayerType::Input && - layer.GetType() != LayerType::Output && - layer.GetBackendId() == backendObjPtr->GetId(); - }); + // Select layers assigned to the requested backend + [&backendObjPtr](const Layer& layer) + { + return layer.GetType() != LayerType::Input && + layer.GetType() != LayerType::Output && + layer.GetBackendId() == backendObjPtr->GetId(); + }); if (subgraphs.empty()) { // No sub-graphs found, try with next selected backend @@ -388,9 +388,6 @@ OptimizationResult ApplyBackendOptimizations(OptimizedNetwork* optNetObjPtr, BOOST_ASSERT(l); l->SetBackendId(selectedBackend); }); - - // Recreate the sub-graph representing the entire graph - mainSubgraph.Update(optGraph); } else { diff --git a/src/armnn/SubgraphView.cpp b/src/armnn/SubgraphView.cpp index 23f969d8ee..9426f1eefc 100644 --- a/src/armnn/SubgraphView.cpp +++ b/src/armnn/SubgraphView.cpp @@ -42,28 +42,14 @@ SubgraphView::SubgraphView(Graph& graph) : m_InputSlots{} , m_OutputSlots{} , m_Layers(graph.begin(), graph.end()) - , m_ParentGraph(&graph) { CheckSubgraph(); } -SubgraphView::SubgraphView(Graph* parentGraph, InputSlots&& inputs, OutputSlots&& outputs, Layers&& layers) +SubgraphView::SubgraphView(InputSlots&& inputs, OutputSlots&& outputs, Layers&& layers) : m_InputSlots{inputs} , m_OutputSlots{outputs} , m_Layers{layers} - , m_ParentGraph(parentGraph) -{ - CheckSubgraph(); -} - -SubgraphView::SubgraphView(const SubgraphView& referenceSubgraph, - InputSlots&& inputs, - OutputSlots&& outputs, - Layers&& layers) - : m_InputSlots{inputs} - , m_OutputSlots{outputs} - , m_Layers{layers} - , m_ParentGraph(referenceSubgraph.m_ParentGraph) { CheckSubgraph(); } @@ -72,7 +58,6 @@ SubgraphView::SubgraphView(const SubgraphView& subgraph) : m_InputSlots(subgraph.m_InputSlots.begin(), subgraph.m_InputSlots.end()) , m_OutputSlots(subgraph.m_OutputSlots.begin(), subgraph.m_OutputSlots.end()) , m_Layers(subgraph.m_Layers.begin(), subgraph.m_Layers.end()) - , m_ParentGraph(subgraph.m_ParentGraph) { CheckSubgraph(); } @@ -81,16 +66,14 @@ SubgraphView::SubgraphView(SubgraphView&& subgraph) : m_InputSlots(std::move(subgraph.m_InputSlots)) , m_OutputSlots(std::move(subgraph.m_OutputSlots)) , m_Layers(std::move(subgraph.m_Layers)) - , m_ParentGraph(std::exchange(subgraph.m_ParentGraph, nullptr)) { CheckSubgraph(); } -SubgraphView::SubgraphView(const SubgraphView& referenceSubgraph, IConnectableLayer* layer) +SubgraphView::SubgraphView(IConnectableLayer* layer) : m_InputSlots{} , m_OutputSlots{} , m_Layers{boost::polymorphic_downcast(layer)} - , m_ParentGraph(referenceSubgraph.m_ParentGraph) { unsigned int numInputSlots = layer->GetNumInputSlots(); m_InputSlots.resize(numInputSlots); @@ -111,9 +94,6 @@ SubgraphView::SubgraphView(const SubgraphView& referenceSubgraph, IConnectableLa void SubgraphView::CheckSubgraph() { - // Check that the sub-graph has a valid parent graph - BOOST_ASSERT_MSG(m_ParentGraph, "Sub-graphs must have a parent graph"); - // Check for invalid or duplicate input slots AssertIfNullsOrDuplicates(m_InputSlots, "Sub-graphs cannot contain null or duplicate input slots"); @@ -122,23 +102,6 @@ void SubgraphView::CheckSubgraph() // Check for invalid or duplicate layers AssertIfNullsOrDuplicates(m_Layers, "Sub-graphs cannot contain null or duplicate layers"); - - // Check that all the layers of the sub-graph belong to the parent graph - std::for_each(m_Layers.begin(), m_Layers.end(), [&](const Layer* l) - { - BOOST_ASSERT_MSG(std::find(m_ParentGraph->begin(), m_ParentGraph->end(), l) != m_ParentGraph->end(), - "Sub-graph layer is not a member of the parent graph"); - }); -} - -void SubgraphView::Update(Graph &graph) -{ - m_InputSlots.clear(); - m_OutputSlots.clear(); - m_Layers.assign(graph.begin(), graph.end()); - m_ParentGraph = &graph; - - CheckSubgraph(); } const SubgraphView::InputSlots& SubgraphView::GetInputSlots() const @@ -158,7 +121,7 @@ const InputSlot* SubgraphView::GetInputSlot(unsigned int index) const InputSlot* SubgraphView::GetInputSlot(unsigned int index) { - return m_InputSlots.at(index); + return m_InputSlots.at(index); } const OutputSlot* SubgraphView::GetOutputSlot(unsigned int index) const @@ -181,12 +144,12 @@ unsigned int SubgraphView::GetNumOutputSlots() const return boost::numeric_cast(m_OutputSlots.size()); } -const SubgraphView::Layers & SubgraphView::GetLayers() const +const SubgraphView::Layers& SubgraphView::GetLayers() const { return m_Layers; } -SubgraphView::Layers::iterator SubgraphView::begin() +SubgraphView::Iterator SubgraphView::begin() { return m_Layers.begin(); } diff --git a/src/armnn/SubgraphView.hpp b/src/armnn/SubgraphView.hpp index b211ad4046..d4d92bbf6c 100644 --- a/src/armnn/SubgraphView.hpp +++ b/src/armnn/SubgraphView.hpp @@ -17,7 +17,7 @@ namespace armnn /// /// The SubgraphView class represents a subgraph of a Graph. /// The data it holds, points to data held by layers of the Graph, so the -/// the contents of the SubgraphView becomes invalid when the Layers are destroyed +/// the contents of the SubgraphView become invalid when the Layers are destroyed /// or changed. /// class SubgraphView final @@ -30,18 +30,11 @@ public: using Iterator = Layers::iterator; using ConstIterator = Layers::const_iterator; - /// Empty subgraphs are not allowed, they must at least have a parent graph. - SubgraphView() = delete; - /// Constructs a sub-graph from the entire given graph. SubgraphView(Graph& graph); - /// Constructs a sub-graph with the given arguments and binds it to the specified parent graph. - SubgraphView(Graph* parentGraph, InputSlots&& inputs, OutputSlots&& outputs, Layers&& layers); - - /// Constructs a sub-graph with the given arguments and uses the specified sub-graph to get a reference - /// to the parent graph. - SubgraphView(const SubgraphView& referenceSubgraph, InputSlots&& inputs, OutputSlots&& outputs, Layers&& layers); + /// Constructs a sub-graph with the given arguments. + SubgraphView(InputSlots&& inputs, OutputSlots&& outputs, Layers&& layers); /// Copy-constructor. SubgraphView(const SubgraphView& subgraph); @@ -49,16 +42,8 @@ public: /// Move-constructor. SubgraphView(SubgraphView&& subgraph); - /// Constructs a sub-graph with only the given layer and uses the specified sub-graph to get a reference - /// to the parent graph. - SubgraphView(const SubgraphView& referenceSubgraph, IConnectableLayer* layer); - - /// Updates this sub-graph with the contents of the whole given graph. - void Update(Graph& graph); - - /// Adds a new layer, of type LayerType, to the parent graph of this sub-graph. - template - LayerT* AddLayer(Args&&... args) const; + /// Constructs a sub-graph with only the given layer. + SubgraphView(IConnectableLayer* layer); const InputSlots& GetInputSlots() const; const OutputSlots& GetOutputSlots() const; @@ -93,17 +78,6 @@ private: /// The list of pointers to the layers of the parent graph. Layers m_Layers; - - /// Pointer to the graph this sub-graph is a view of. - Graph* m_ParentGraph; }; -template -LayerT* SubgraphView::AddLayer(Args&&... args) const -{ - BOOST_ASSERT(m_ParentGraph); - - return m_ParentGraph->AddLayer(args...); -} - } // namespace armnn diff --git a/src/armnn/SubgraphViewSelector.cpp b/src/armnn/SubgraphViewSelector.cpp index 7663c31173..e8919c1e12 100644 --- a/src/armnn/SubgraphViewSelector.cpp +++ b/src/armnn/SubgraphViewSelector.cpp @@ -182,10 +182,8 @@ SubgraphViewSelector::SelectSubgraphs(SubgraphView& subgraph, const LayerSelecto infoPtr->CollectNonSelectedOutputSlots(outputs, selector); layers.push_back(infoPtr->m_Layer); } - // Create a new sub-graph with the new lists of input/output slots and layer, using - // the given sub-graph as a reference of which parent graph to use - result.emplace_back(std::make_unique(subgraph, - std::move(inputs), + // Create a new sub-graph with the new lists of input/output slots and layer + result.emplace_back(std::make_unique(std::move(inputs), std::move(outputs), std::move(layers))); } diff --git a/src/armnn/test/CreateWorkload.hpp b/src/armnn/test/CreateWorkload.hpp index bdec766067..a68a6e3f42 100644 --- a/src/armnn/test/CreateWorkload.hpp +++ b/src/armnn/test/CreateWorkload.hpp @@ -1203,7 +1203,7 @@ std::pair> Cre preCompiledLayer = layer; } } - BOOST_TEST(preCompiledLayer); + BOOST_CHECK(preCompiledLayer != nullptr); // Create the TensorHandles. CreateTensorHandles(optimisedGraph, factory); diff --git a/src/armnn/test/SubgraphViewTests.cpp b/src/armnn/test/SubgraphViewTests.cpp index 603bb159d0..4a9316428b 100644 --- a/src/armnn/test/SubgraphViewTests.cpp +++ b/src/armnn/test/SubgraphViewTests.cpp @@ -65,14 +65,13 @@ SubgraphView::OutputSlots CreateOutputsFrom(const std::vector& layers) // // this takes the inputs, outputs and layers as a copy and the move these copies into the -// resulting subgraph, so the pass bay value is intentional +// resulting subgraph, so the pass by value is intentional // -SubgraphViewSelector::SubgraphViewPtr CreateSubgraphViewFrom(Graph& graph, - SubgraphView::InputSlots&& inputs, +SubgraphViewSelector::SubgraphViewPtr CreateSubgraphViewFrom(SubgraphView::InputSlots&& inputs, SubgraphView::OutputSlots&& outputs, SubgraphView::Layers&& layers) { - return std::make_unique(&graph, std::move(inputs), std::move(outputs), std::move(layers)); + return std::make_unique(std::move(inputs), std::move(outputs), std::move(layers)); } template @@ -147,8 +146,7 @@ BOOST_AUTO_TEST_CASE(SingleInputSingleOutput) convLayer2->GetOutputSlot(0).Connect(outputLayer->GetInputSlot(0)); // Construct sub-graph - SubgraphViewSelector::SubgraphViewPtr subgraph = CreateSubgraphViewFrom(graph, - CreateInputsFrom({convLayer1}), + SubgraphViewSelector::SubgraphViewPtr subgraph = CreateSubgraphViewFrom(CreateInputsFrom({convLayer1}), CreateOutputsFrom({convLayer2}), {}); @@ -195,8 +193,7 @@ BOOST_AUTO_TEST_CASE(MultiInputSingleOutput) mergerLayer->GetOutputSlot(0).Connect(outputLayer->GetInputSlot(0)); // Construct sub-graph - SubgraphViewSelector::SubgraphViewPtr subgraph = CreateSubgraphViewFrom(graph, - CreateInputsFrom({convLayer1, convLayer2}), + SubgraphViewSelector::SubgraphViewPtr subgraph = CreateSubgraphViewFrom(CreateInputsFrom({convLayer1, convLayer2}), CreateOutputsFrom({mergerLayer}), {}); @@ -245,8 +242,7 @@ BOOST_AUTO_TEST_CASE(SingleInputMultiOutput) mergerLayer->GetOutputSlot(0).Connect(outputLayer->GetInputSlot(0)); // Construct sub-graph - SubgraphViewSelector::SubgraphViewPtr subgraph = CreateSubgraphViewFrom(graph, - CreateInputsFrom({splitterLayer}), + SubgraphViewSelector::SubgraphViewPtr subgraph = CreateSubgraphViewFrom(CreateInputsFrom({splitterLayer}), CreateOutputsFrom({convLayer1, convLayer2}), {}); @@ -297,8 +293,7 @@ BOOST_AUTO_TEST_CASE(MultiInputMultiOutput) mergerLayer->GetOutputSlot(0).Connect(outputLayer->GetInputSlot(0)); // Construct sub-graph - SubgraphViewSelector::SubgraphViewPtr subgraph = CreateSubgraphViewFrom(graph, - CreateInputsFrom({convLayer1, convLayer2}), + SubgraphViewSelector::SubgraphViewPtr subgraph = CreateSubgraphViewFrom(CreateInputsFrom({convLayer1, convLayer2}), CreateOutputsFrom({convLayer1, convLayer2}), {}); @@ -344,8 +339,7 @@ BOOST_AUTO_TEST_CASE(EraseReplacedLayers) graph.AddLayer(0, "output"); // Construct sub-graph - SubgraphViewSelector::SubgraphViewPtr subgraph = CreateSubgraphViewFrom(graph, - {}, + SubgraphViewSelector::SubgraphViewPtr subgraph = CreateSubgraphViewFrom({}, {}, {splitterLayer, convLayer1, @@ -433,8 +427,7 @@ BOOST_AUTO_TEST_CASE(OneSubgraphsSelectedASingleMatch) BOOST_TEST(subgraphs.size() == 1); if (subgraphs.size() == 1) { - auto expected = CreateSubgraphViewFrom(graph, - CreateInputsFrom({output}), + auto expected = CreateSubgraphViewFrom(CreateInputsFrom({output}), // outputs of 'output' will be empty CreateOutputsFrom({output}), {output}); @@ -469,8 +462,7 @@ BOOST_AUTO_TEST_CASE(MultipleLayersSelectedInTheMiddle) BOOST_TEST(subgraphs.size() == 1); if (subgraphs.size() == 1) { - auto expected = CreateSubgraphViewFrom(graph, - CreateInputsFrom({mid1}), + auto expected = CreateSubgraphViewFrom(CreateInputsFrom({mid1}), CreateOutputsFrom({mid0}), {mid1, mid0}); @@ -541,13 +533,11 @@ BOOST_AUTO_TEST_CASE(IslandInTheMiddle) }); // expected results to test against - auto largerSubgraph = CreateSubgraphViewFrom(graph, - CreateInputsFrom({m1, m4}), + auto largerSubgraph = CreateSubgraphViewFrom(CreateInputsFrom({m1, m4}), CreateOutputsFrom({m3, m4}), {m1, m4, m2, m3}); - auto smallerSubgraph = CreateSubgraphViewFrom(graph, - CreateInputsFrom({m5}), + auto smallerSubgraph = CreateSubgraphViewFrom(CreateInputsFrom({m5}), CreateOutputsFrom({m5}), {m5}); @@ -619,13 +609,11 @@ BOOST_AUTO_TEST_CASE(MultipleSimpleSubgraphs) }); // expected results to test against - auto largerSubgraph = CreateSubgraphViewFrom(graph, - CreateInputsFrom({m1}), + auto largerSubgraph = CreateSubgraphViewFrom(CreateInputsFrom({m1}), CreateOutputsFrom({m2}), {m1, m2}); - auto smallerSubgraph = CreateSubgraphViewFrom(graph, - CreateInputsFrom({m3}), + auto smallerSubgraph = CreateSubgraphViewFrom(CreateInputsFrom({m3}), CreateOutputsFrom({m3}), {m3}); @@ -693,8 +681,7 @@ BOOST_AUTO_TEST_CASE(SimpleLinearTest) BOOST_CHECK(subgraphs.size() == 1); if(subgraphs.size() == 1) { - auto expected = CreateSubgraphViewFrom(graph, - CreateInputsFrom({layerM1}), + auto expected = CreateSubgraphViewFrom(CreateInputsFrom({layerM1}), CreateOutputsFrom({layerM2}), {layerM1, layerM2}); @@ -749,8 +736,7 @@ BOOST_AUTO_TEST_CASE(MultiInputSingleOutput) BOOST_CHECK(subgraphs.size() == 1); if (subgraphs.size() == 1) { - auto expected = CreateSubgraphViewFrom(graph, - CreateInputsFrom({layerM1, layerM2}), + auto expected = CreateSubgraphViewFrom(CreateInputsFrom({layerM1, layerM2}), CreateOutputsFrom({layerM3}), {layerM1, layerM2, layerM3}); @@ -806,8 +792,7 @@ BOOST_AUTO_TEST_CASE(SingleInputMultiOutput) BOOST_CHECK(subgraphs.size() == 1); if(subgraphs.size() == 1) { - auto expected = CreateSubgraphViewFrom(graph, - CreateInputsFrom({layerM1}), + auto expected = CreateSubgraphViewFrom(CreateInputsFrom({layerM1}), CreateOutputsFrom({layerM2, layerM3}), {layerM1, layerM2, layerM3}); @@ -871,8 +856,7 @@ BOOST_AUTO_TEST_CASE(MultiInputMultiOutput) BOOST_CHECK(subgraphs.size() == 1); if (subgraphs.size() == 1) { - auto expected = CreateSubgraphViewFrom(graph, - CreateInputsFrom({m1, m2}), + auto expected = CreateSubgraphViewFrom(CreateInputsFrom({m1, m2}), CreateOutputsFrom({m4, m5}), {m1, m2, m3, m4, m5}); diff --git a/src/backends/backendsCommon/IBackendInternal.hpp b/src/backends/backendsCommon/IBackendInternal.hpp index 108e66e6a8..d23209e838 100644 --- a/src/backends/backendsCommon/IBackendInternal.hpp +++ b/src/backends/backendsCommon/IBackendInternal.hpp @@ -43,6 +43,7 @@ public: using ISubgraphViewConverterPtr = std::unique_ptr; + using GraphUniquePtr = std::unique_ptr; using SubgraphViewUniquePtr = std::unique_ptr; virtual IMemoryManagerUniquePtr CreateMemoryManager() const = 0; -- cgit v1.2.1