diff options
Diffstat (limited to 'src/armnn')
-rw-r--r-- | src/armnn/Graph.cpp | 74 | ||||
-rw-r--r-- | src/armnn/Graph.hpp | 12 | ||||
-rw-r--r-- | src/armnn/ISubgraphViewConverter.hpp (renamed from src/armnn/ISubGraphConverter.hpp) | 4 | ||||
-rw-r--r-- | src/armnn/Network.cpp | 33 | ||||
-rw-r--r-- | src/armnn/NetworkUtils.cpp | 2 | ||||
-rw-r--r-- | src/armnn/SubGraphSelector.hpp | 38 | ||||
-rw-r--r-- | src/armnn/SubgraphView.cpp (renamed from src/armnn/SubGraph.cpp) | 85 | ||||
-rw-r--r-- | src/armnn/SubgraphView.hpp (renamed from src/armnn/SubGraph.hpp) | 26 | ||||
-rw-r--r-- | src/armnn/SubgraphViewSelector.cpp (renamed from src/armnn/SubGraphSelector.cpp) | 42 | ||||
-rw-r--r-- | src/armnn/SubgraphViewSelector.hpp | 38 | ||||
-rw-r--r-- | src/armnn/layers/PreCompiledLayer.cpp | 2 | ||||
-rw-r--r-- | src/armnn/test/SubgraphViewTests.cpp (renamed from src/armnn/test/SubGraphTests.cpp) | 461 |
12 files changed, 412 insertions, 405 deletions
diff --git a/src/armnn/Graph.cpp b/src/armnn/Graph.cpp index be0dd5f2ce..335f1951bb 100644 --- a/src/armnn/Graph.cpp +++ b/src/armnn/Graph.cpp @@ -4,7 +4,7 @@ // #include "Graph.hpp" -#include "SubGraph.hpp" +#include "SubgraphView.hpp" #include "LayersFwd.hpp" #include <armnn/Utils.hpp> @@ -298,88 +298,88 @@ void Graph::AddCopyLayers() } } -void Graph::SubstituteSubGraph(std::unique_ptr<SubGraph> subGraph, IConnectableLayer* substituteLayer) +void Graph::SubstituteSubgraph(std::unique_ptr<SubgraphView> subgraph, IConnectableLayer* substituteLayer) { - BOOST_ASSERT(subGraph != nullptr); + BOOST_ASSERT(subgraph != nullptr); BOOST_ASSERT(substituteLayer != nullptr); - ReplaceSubGraphConnections(*subGraph, substituteLayer); - EraseSubGraphLayers(*subGraph); + ReplaceSubgraphConnections(*subgraph, substituteLayer); + EraseSubgraphLayers(*subgraph); } -void Graph::SubstituteSubGraph(std::unique_ptr<SubGraph> subGraph, const SubGraph& substituteSubGraph) +void Graph::SubstituteSubgraph(std::unique_ptr<SubgraphView> subgraph, const SubgraphView& substituteSubgraph) { - BOOST_ASSERT(subGraph); + BOOST_ASSERT(subgraph); - ReplaceSubGraphConnections(*subGraph, substituteSubGraph); - EraseSubGraphLayers(*subGraph); + ReplaceSubgraphConnections(*subgraph, substituteSubgraph); + EraseSubgraphLayers(*subgraph); } -void Graph::ReplaceSubGraphConnections(const SubGraph& subGraph, IConnectableLayer* substituteLayer) +void Graph::ReplaceSubgraphConnections(const SubgraphView& subgraph, IConnectableLayer* substituteLayer) { BOOST_ASSERT(substituteLayer != nullptr); // Create a new sub-graph with only the given layer, using // the given sub-graph as a reference of which parent graph to use - SubGraph substituteSubGraph(subGraph, substituteLayer); - ReplaceSubGraphConnections(subGraph, substituteSubGraph); + SubgraphView substituteSubgraph(subgraph, substituteLayer); + ReplaceSubgraphConnections(subgraph, substituteSubgraph); } -void Graph::ReplaceSubGraphConnections(const SubGraph& subGraph, const SubGraph& substituteSubGraph) +void Graph::ReplaceSubgraphConnections(const SubgraphView& subgraph, const SubgraphView& substituteSubgraph) { - BOOST_ASSERT_MSG(!substituteSubGraph.GetLayers().empty(), "New sub-graph used for substitution must not be empty"); + BOOST_ASSERT_MSG(!substituteSubgraph.GetLayers().empty(), "New sub-graph used for substitution must not be empty"); - const SubGraph::Layers& substituteSubGraphLayers = substituteSubGraph.GetLayers(); - std::for_each(substituteSubGraphLayers.begin(), substituteSubGraphLayers.end(), [&](Layer* layer) + const SubgraphView::Layers& substituteSubgraphLayers = substituteSubgraph.GetLayers(); + std::for_each(substituteSubgraphLayers.begin(), substituteSubgraphLayers.end(), [&](Layer* layer) { BOOST_ASSERT_MSG(std::find(m_Layers.begin(), m_Layers.end(), layer) != m_Layers.end(), "Substitute layer is not a member of graph"); }); - const SubGraph::InputSlots& subGraphInputSlots = subGraph.GetInputSlots(); - const SubGraph::OutputSlots& subGraphOutputSlots = subGraph.GetOutputSlots(); + const SubgraphView::InputSlots& subgraphInputSlots = subgraph.GetInputSlots(); + const SubgraphView::OutputSlots& subgraphOutputSlots = subgraph.GetOutputSlots(); - unsigned int subGraphNumInputSlots = boost::numeric_cast<unsigned int>(subGraphInputSlots.size()); - unsigned int subGraphNumOutputSlots = boost::numeric_cast<unsigned int>(subGraphOutputSlots.size()); + unsigned int subgraphNumInputSlots = boost::numeric_cast<unsigned int>(subgraphInputSlots.size()); + unsigned int subgraphNumOutputSlots = boost::numeric_cast<unsigned int>(subgraphOutputSlots.size()); - const SubGraph::InputSlots& substituteSubGraphInputSlots = substituteSubGraph.GetInputSlots(); - const SubGraph::OutputSlots& substituteSubGraphOutputSlots = substituteSubGraph.GetOutputSlots(); + const SubgraphView::InputSlots& substituteSubgraphInputSlots = substituteSubgraph.GetInputSlots(); + const SubgraphView::OutputSlots& substituteSubgraphOutputSlots = substituteSubgraph.GetOutputSlots(); - BOOST_ASSERT(subGraphNumInputSlots == substituteSubGraphInputSlots.size()); - BOOST_ASSERT(subGraphNumOutputSlots == substituteSubGraphOutputSlots.size()); + BOOST_ASSERT(subgraphNumInputSlots == substituteSubgraphInputSlots.size()); + BOOST_ASSERT(subgraphNumOutputSlots == substituteSubgraphOutputSlots.size()); // Disconnect the sub-graph and replace it with the substitute sub-graph // Step 1: process input slots - for (unsigned int inputSlotIdx = 0; inputSlotIdx < subGraphNumInputSlots; ++inputSlotIdx) + for (unsigned int inputSlotIdx = 0; inputSlotIdx < subgraphNumInputSlots; ++inputSlotIdx) { - InputSlot* subGraphInputSlot = subGraphInputSlots.at(inputSlotIdx); - BOOST_ASSERT(subGraphInputSlot); + InputSlot* subgraphInputSlot = subgraphInputSlots.at(inputSlotIdx); + BOOST_ASSERT(subgraphInputSlot); - IOutputSlot* connectedOutputSlot = subGraphInputSlot->GetConnection(); + IOutputSlot* connectedOutputSlot = subgraphInputSlot->GetConnection(); BOOST_ASSERT(connectedOutputSlot); - connectedOutputSlot->Disconnect(*subGraphInputSlot); + connectedOutputSlot->Disconnect(*subgraphInputSlot); - IInputSlot* substituteInputSlot = substituteSubGraphInputSlots.at(inputSlotIdx); + IInputSlot* substituteInputSlot = substituteSubgraphInputSlots.at(inputSlotIdx); BOOST_ASSERT(substituteInputSlot); connectedOutputSlot->Connect(*substituteInputSlot); } // Step 2: process output slots - for(unsigned int outputSlotIdx = 0; outputSlotIdx < subGraphNumOutputSlots; ++outputSlotIdx) + for(unsigned int outputSlotIdx = 0; outputSlotIdx < subgraphNumOutputSlots; ++outputSlotIdx) { - OutputSlot* subGraphOutputSlot = subGraphOutputSlots.at(outputSlotIdx); - BOOST_ASSERT(subGraphOutputSlot); + OutputSlot* subgraphOutputSlot = subgraphOutputSlots.at(outputSlotIdx); + BOOST_ASSERT(subgraphOutputSlot); - OutputSlot* substituteOutputSlot = substituteSubGraphOutputSlots.at(outputSlotIdx); + OutputSlot* substituteOutputSlot = substituteSubgraphOutputSlots.at(outputSlotIdx); BOOST_ASSERT(substituteOutputSlot); - subGraphOutputSlot->MoveAllConnections(*substituteOutputSlot); + subgraphOutputSlot->MoveAllConnections(*substituteOutputSlot); } } -void Graph::EraseSubGraphLayers(const SubGraph &subGraph) +void Graph::EraseSubgraphLayers(const SubgraphView &subgraph) { - for (auto layer : subGraph.GetLayers()) + for (auto layer : subgraph.GetLayers()) { EraseLayer(layer); } diff --git a/src/armnn/Graph.hpp b/src/armnn/Graph.hpp index dd6a825f57..cc0ccaea77 100644 --- a/src/armnn/Graph.hpp +++ b/src/armnn/Graph.hpp @@ -24,7 +24,7 @@ namespace armnn { -class SubGraph; +class SubgraphView; class Graph { @@ -163,8 +163,8 @@ public: /// Substitutes the given sub-graph with either a new layer or a new sub-graph. /// In either case, the given layer or all the layers in the given sub-graph must belong to this graph. - void SubstituteSubGraph(std::unique_ptr<SubGraph> subGraph, IConnectableLayer* substituteLayer); - void SubstituteSubGraph(std::unique_ptr<SubGraph> subGraph, const SubGraph& substituteSubGraph); + void SubstituteSubgraph(std::unique_ptr<SubgraphView> subgraph, IConnectableLayer* substituteLayer); + void SubstituteSubgraph(std::unique_ptr<SubgraphView> subgraph, const SubgraphView& substituteSubgraph); void InferTensorInfos(); @@ -217,9 +217,9 @@ private: std::unordered_set<LayerBindingId> m_OutputIds; std::unordered_map<const Layer*, Iterator> m_PosInGraphMap; - void ReplaceSubGraphConnections(const SubGraph& subGraph, IConnectableLayer* substituteLayer); - void ReplaceSubGraphConnections(const SubGraph& subGraph, const SubGraph& substituteSubGraph); - void EraseSubGraphLayers(const SubGraph &subGraph); + void ReplaceSubgraphConnections(const SubgraphView& subgraph, IConnectableLayer* substituteLayer); + void ReplaceSubgraphConnections(const SubgraphView& subgraph, const SubgraphView& substituteSubgraph); + void EraseSubgraphLayers(const SubgraphView &subgraph); /// Mutable to allow sorting on const object. mutable LayerList m_Layers; diff --git a/src/armnn/ISubGraphConverter.hpp b/src/armnn/ISubgraphViewConverter.hpp index 3a6866e102..1f4b4e5de1 100644 --- a/src/armnn/ISubGraphConverter.hpp +++ b/src/armnn/ISubgraphViewConverter.hpp @@ -15,10 +15,10 @@ namespace armnn using CompiledBlobDeleter = std::function<void(const void*)>; using CompiledBlobPtr = std::unique_ptr<void, CompiledBlobDeleter>; -class ISubGraphConverter +class ISubgraphViewConverter { public: - virtual ~ISubGraphConverter() {} + virtual ~ISubgraphViewConverter() {} virtual std::vector<CompiledBlobPtr> GetOutput() = 0; }; diff --git a/src/armnn/Network.cpp b/src/armnn/Network.cpp index a38bcf1910..9ef0c568a3 100644 --- a/src/armnn/Network.cpp +++ b/src/armnn/Network.cpp @@ -8,7 +8,7 @@ #include "Layer.hpp" #include "DeviceSpec.hpp" #include "Optimizer.hpp" -#include "SubGraphSelector.hpp" +#include "SubgraphViewSelector.hpp" #include "BackendSettings.hpp" #include "optimizations/All.hpp" @@ -311,11 +311,11 @@ OptimizationResult AssignBackends(OptimizedNetwork* optNetObjPtr, OptimizationResult AssignBackends(OptimizedNetwork* optNetObjPtr, BackendSettings& backendSettings, - SubGraph& subGraph, + SubgraphView& subgraph, Optional<std::vector<std::string>&> errMessages) { - Graph::Iterator firstLayer = subGraph.begin(); - Graph::Iterator lastLayer = subGraph.end(); + Graph::Iterator firstLayer = subgraph.begin(); + Graph::Iterator lastLayer = subgraph.end(); return AssignBackends(optNetObjPtr, backendSettings, firstLayer, @@ -335,7 +335,7 @@ OptimizationResult ApplyBackendOptimizations(OptimizedNetwork* optNetObjPtr, Graph& optGraph = optNetObjPtr->GetGraph(); // Get the entire graph as a sub-graph - SubGraph mainSubGraph(optGraph); + SubgraphView mainSubgraph(optGraph); // Run backend specific optimizations auto const& backendRegistry = BackendRegistryInstance(); @@ -346,8 +346,8 @@ OptimizationResult ApplyBackendOptimizations(OptimizedNetwork* optNetObjPtr, BOOST_ASSERT(backendObjPtr); // Select sub-graphs based on backend - SubGraphSelector::SubGraphs subGraphs = - SubGraphSelector::SelectSubGraphs(mainSubGraph, + SubgraphViewSelector::Subgraphs subgraphs = + SubgraphViewSelector::SelectSubgraphs(mainSubgraph, // Select layers assigned to the requested backend [&backendObjPtr](const Layer& layer) { @@ -355,18 +355,19 @@ OptimizationResult ApplyBackendOptimizations(OptimizedNetwork* optNetObjPtr, layer.GetType() != LayerType::Output && layer.GetBackendId() == backendObjPtr->GetId(); }); - if (subGraphs.empty()) + if (subgraphs.empty()) { // No sub-graphs found, try with next selected backend continue; } // Try to optimize each sub-graph - for (auto& subGraph : subGraphs) + for (auto& subgraph : subgraphs) { // Try to optimize the current sub-graph bool optimizationAttempted = false; - SubGraph::SubGraphPtr optSubGraph = backendObjPtr->OptimizeSubGraph(*subGraph, optimizationAttempted); + SubgraphView::SubgraphViewPtr optSubgraph = backendObjPtr->OptimizeSubgraphView(*subgraph, + optimizationAttempted); // Check if the optimization has been attempted if (!optimizationAttempted) @@ -376,27 +377,27 @@ OptimizationResult ApplyBackendOptimizations(OptimizedNetwork* optNetObjPtr, } // Optimization attempted, check the resulting optimized sub-graph - if (optSubGraph) + if (optSubgraph) { // Sub-graph optimized, substitute the sub-graph with the new optimized one in the main optimized graph - optGraph.SubstituteSubGraph(std::move(subGraph), *optSubGraph); + optGraph.SubstituteSubgraph(std::move(subgraph), *optSubgraph); // Assign the current backend to the optimized sub-graph - std::for_each(optSubGraph->begin(), optSubGraph->end(), [&selectedBackend](Layer* l) + std::for_each(optSubgraph->begin(), optSubgraph->end(), [&selectedBackend](Layer* l) { BOOST_ASSERT(l); l->SetBackendId(selectedBackend); }); // Recreate the sub-graph representing the entire graph - mainSubGraph.Update(optGraph); + mainSubgraph.Update(optGraph); } else { // An error occurred: the optimization was attempted but not performed, try different backends std::stringstream warningMsg; warningMsg << "Sub-graph failed to get optimized on " << backendObjPtr->GetId() << ". " - << "Re-assigning backends to " << subGraph->GetLayers().size() << " layers inside sub-graph"; + << "Re-assigning backends to " << subgraph->GetLayers().size() << " layers inside sub-graph"; ReportWarning(warningMsg.str(), errMessages); // Failed to optimize the given sub-graph, re-assign the sub-graph layers to other available backends @@ -407,7 +408,7 @@ OptimizationResult ApplyBackendOptimizations(OptimizedNetwork* optNetObjPtr, } OptimizationResult reassignmentResult = AssignBackends(optNetObjPtr, backendSettings, - *subGraph, + *subgraph, errMessages); if (reassignmentResult.m_Error) { diff --git a/src/armnn/NetworkUtils.cpp b/src/armnn/NetworkUtils.cpp index 126b56b084..66940e4eb5 100644 --- a/src/armnn/NetworkUtils.cpp +++ b/src/armnn/NetworkUtils.cpp @@ -5,7 +5,7 @@ #include "NetworkUtils.hpp" -#include "SubGraphSelector.hpp" +#include "SubgraphViewSelector.hpp" #include <armnn/Exceptions.hpp> diff --git a/src/armnn/SubGraphSelector.hpp b/src/armnn/SubGraphSelector.hpp deleted file mode 100644 index 371ba78f18..0000000000 --- a/src/armnn/SubGraphSelector.hpp +++ /dev/null @@ -1,38 +0,0 @@ -// -// Copyright © 2017 Arm Ltd. All rights reserved. -// SPDX-License-Identifier: MIT -// -#pragma once - -#include "SubGraph.hpp" -#include <functional> -#include <memory> - -namespace armnn -{ - -class Layer; -class Graph; - -class SubGraphSelector final -{ -public: - using SubGraphPtr = std::unique_ptr<SubGraph>; - using SubGraphs = std::vector<SubGraphPtr>; - using LayerSelectorFunction = std::function<bool(const Layer&)>; - - /// Selects subgraphs from a graph based on the selector function and the algorithm. - /// Since the SubGraphs object returns modifiable pointers to the input and output slots of the graph: - /// 1) the graph/sub-graph cannot be const - /// 2) the caller needs to make sure that the SubGraphs lifetime is shorter than the parent graph's - static SubGraphs SelectSubGraphs(Graph& graph, const LayerSelectorFunction& selector); - static SubGraphs SelectSubGraphs(SubGraph& subGraph, const LayerSelectorFunction& selector); - -private: - // this is a utility class, don't construct or copy - SubGraphSelector() = delete; - SubGraphSelector(const SubGraphSelector&) = delete; - SubGraphSelector & operator=(const SubGraphSelector&) = delete; -}; - -} // namespace armnn diff --git a/src/armnn/SubGraph.cpp b/src/armnn/SubgraphView.cpp index d0fc760c15..23f969d8ee 100644 --- a/src/armnn/SubGraph.cpp +++ b/src/armnn/SubgraphView.cpp @@ -3,7 +3,7 @@ // SPDX-License-Identifier: MIT // -#include "SubGraph.hpp" +#include "SubgraphView.hpp" #include "Graph.hpp" #include <boost/numeric/conversion/cast.hpp> @@ -38,56 +38,59 @@ void AssertIfNullsOrDuplicates(const C& container, const std::string& errorMessa } // anonymous namespace -SubGraph::SubGraph(Graph& graph) +SubgraphView::SubgraphView(Graph& graph) : m_InputSlots{} , m_OutputSlots{} , m_Layers(graph.begin(), graph.end()) , m_ParentGraph(&graph) { - CheckSubGraph(); + CheckSubgraph(); } -SubGraph::SubGraph(Graph* parentGraph, InputSlots&& inputs, OutputSlots&& outputs, Layers&& layers) +SubgraphView::SubgraphView(Graph* parentGraph, InputSlots&& inputs, OutputSlots&& outputs, Layers&& layers) : m_InputSlots{inputs} , m_OutputSlots{outputs} , m_Layers{layers} , m_ParentGraph(parentGraph) { - CheckSubGraph(); + CheckSubgraph(); } -SubGraph::SubGraph(const SubGraph& referenceSubGraph, InputSlots&& inputs, OutputSlots&& outputs, Layers&& layers) +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) + , m_ParentGraph(referenceSubgraph.m_ParentGraph) { - CheckSubGraph(); + CheckSubgraph(); } -SubGraph::SubGraph(const SubGraph& 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) +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(); + CheckSubgraph(); } -SubGraph::SubGraph(SubGraph&& 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)) +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(); + CheckSubgraph(); } -SubGraph::SubGraph(const SubGraph& referenceSubGraph, IConnectableLayer* layer) +SubgraphView::SubgraphView(const SubgraphView& referenceSubgraph, IConnectableLayer* layer) : m_InputSlots{} , m_OutputSlots{} , m_Layers{boost::polymorphic_downcast<Layer*>(layer)} - , m_ParentGraph(referenceSubGraph.m_ParentGraph) + , m_ParentGraph(referenceSubgraph.m_ParentGraph) { unsigned int numInputSlots = layer->GetNumInputSlots(); m_InputSlots.resize(numInputSlots); @@ -103,10 +106,10 @@ SubGraph::SubGraph(const SubGraph& referenceSubGraph, IConnectableLayer* layer) m_OutputSlots.at(i) = boost::polymorphic_downcast<OutputSlot*>(&(layer->GetOutputSlot(i))); } - CheckSubGraph(); + CheckSubgraph(); } -void SubGraph::CheckSubGraph() +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"); @@ -128,87 +131,87 @@ void SubGraph::CheckSubGraph() }); } -void SubGraph::Update(Graph &graph) +void SubgraphView::Update(Graph &graph) { m_InputSlots.clear(); m_OutputSlots.clear(); m_Layers.assign(graph.begin(), graph.end()); m_ParentGraph = &graph; - CheckSubGraph(); + CheckSubgraph(); } -const SubGraph::InputSlots& SubGraph::GetInputSlots() const +const SubgraphView::InputSlots& SubgraphView::GetInputSlots() const { return m_InputSlots; } -const SubGraph::OutputSlots& SubGraph::GetOutputSlots() const +const SubgraphView::OutputSlots& SubgraphView::GetOutputSlots() const { return m_OutputSlots; } -const InputSlot* SubGraph::GetInputSlot(unsigned int index) const +const InputSlot* SubgraphView::GetInputSlot(unsigned int index) const { return m_InputSlots.at(index); } -InputSlot* SubGraph::GetInputSlot(unsigned int index) +InputSlot* SubgraphView::GetInputSlot(unsigned int index) { return m_InputSlots.at(index); } -const OutputSlot* SubGraph::GetOutputSlot(unsigned int index) const +const OutputSlot* SubgraphView::GetOutputSlot(unsigned int index) const { return m_OutputSlots.at(index); } -OutputSlot* SubGraph::GetOutputSlot(unsigned int index) +OutputSlot* SubgraphView::GetOutputSlot(unsigned int index) { return m_OutputSlots.at(index); } -unsigned int SubGraph::GetNumInputSlots() const +unsigned int SubgraphView::GetNumInputSlots() const { return boost::numeric_cast<unsigned int>(m_InputSlots.size()); } -unsigned int SubGraph::GetNumOutputSlots() const +unsigned int SubgraphView::GetNumOutputSlots() const { return boost::numeric_cast<unsigned int>(m_OutputSlots.size()); } -const SubGraph::Layers & SubGraph::GetLayers() const +const SubgraphView::Layers & SubgraphView::GetLayers() const { return m_Layers; } -SubGraph::Layers::iterator SubGraph::begin() +SubgraphView::Layers::iterator SubgraphView::begin() { return m_Layers.begin(); } -SubGraph::Iterator SubGraph::end() +SubgraphView::Iterator SubgraphView::end() { return m_Layers.end(); } -SubGraph::ConstIterator SubGraph::begin() const +SubgraphView::ConstIterator SubgraphView::begin() const { return m_Layers.begin(); } -SubGraph::ConstIterator SubGraph::end() const +SubgraphView::ConstIterator SubgraphView::end() const { return m_Layers.end(); } -SubGraph::ConstIterator SubGraph::cbegin() const +SubgraphView::ConstIterator SubgraphView::cbegin() const { return begin(); } -SubGraph::ConstIterator SubGraph::cend() const +SubgraphView::ConstIterator SubgraphView::cend() const { return end(); } diff --git a/src/armnn/SubGraph.hpp b/src/armnn/SubgraphView.hpp index cb44f8ce3d..b211ad4046 100644 --- a/src/armnn/SubGraph.hpp +++ b/src/armnn/SubgraphView.hpp @@ -15,15 +15,15 @@ namespace armnn { /// -/// The SubGraph class represents a subgraph of a Graph. +/// 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 SubGraph becomes invalid when the Layers are destroyed +/// the contents of the SubgraphView becomes invalid when the Layers are destroyed /// or changed. /// -class SubGraph final +class SubgraphView final { public: - using SubGraphPtr = std::unique_ptr<SubGraph>; + using SubgraphViewPtr = std::unique_ptr<SubgraphView>; using InputSlots = std::vector<InputSlot*>; using OutputSlots = std::vector<OutputSlot*>; using Layers = std::list<Layer*>; @@ -31,27 +31,27 @@ public: using ConstIterator = Layers::const_iterator; /// Empty subgraphs are not allowed, they must at least have a parent graph. - SubGraph() = delete; + SubgraphView() = delete; /// Constructs a sub-graph from the entire given graph. - SubGraph(Graph& graph); + SubgraphView(Graph& graph); /// Constructs a sub-graph with the given arguments and binds it to the specified parent graph. - SubGraph(Graph* parentGraph, InputSlots&& inputs, OutputSlots&& outputs, Layers&& layers); + 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. - SubGraph(const SubGraph& referenceSubGraph, InputSlots&& inputs, OutputSlots&& outputs, Layers&& layers); + SubgraphView(const SubgraphView& referenceSubgraph, InputSlots&& inputs, OutputSlots&& outputs, Layers&& layers); /// Copy-constructor. - SubGraph(const SubGraph& subGraph); + SubgraphView(const SubgraphView& subgraph); /// Move-constructor. - SubGraph(SubGraph&& subGraph); + 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. - SubGraph(const SubGraph& referenceSubGraph, IConnectableLayer* layer); + SubgraphView(const SubgraphView& referenceSubgraph, IConnectableLayer* layer); /// Updates this sub-graph with the contents of the whole given graph. void Update(Graph& graph); @@ -83,7 +83,7 @@ public: ConstIterator cend() const; private: - void CheckSubGraph(); + void CheckSubgraph(); /// The list of pointers to the input slots of the parent graph. InputSlots m_InputSlots; @@ -99,7 +99,7 @@ private: }; template <typename LayerT, typename... Args> -LayerT* SubGraph::AddLayer(Args&&... args) const +LayerT* SubgraphView::AddLayer(Args&&... args) const { BOOST_ASSERT(m_ParentGraph); diff --git a/src/armnn/SubGraphSelector.cpp b/src/armnn/SubgraphViewSelector.cpp index be51a7d4e3..7663c31173 100644 --- a/src/armnn/SubGraphSelector.cpp +++ b/src/armnn/SubgraphViewSelector.cpp @@ -3,7 +3,7 @@ // SPDX-License-Identifier: MIT // -#include "SubGraphSelector.hpp" +#include "SubgraphViewSelector.hpp" #include "Graph.hpp" #include <boost/assert.hpp> #include <algorithm> @@ -20,7 +20,7 @@ struct LayerSelectionInfo using LayerInfoContainer = std::unordered_map<Layer*, LayerSelectionInfo>; static constexpr uint32_t InitialSplitId() { return 1; } - LayerSelectionInfo(Layer* layer, const SubGraphSelector::LayerSelectorFunction& selector) + LayerSelectionInfo(Layer* layer, const SubgraphViewSelector::LayerSelectorFunction& selector) : m_Layer{layer} , m_SplitId{0} , m_IsSelected{selector(*layer)} @@ -76,8 +76,8 @@ struct LayerSelectionInfo return m_Layer->GetType() == armnn::LayerType::Input; } - void CollectNonSelectedInputs(SubGraph::InputSlots& inputSlots, - const SubGraphSelector::LayerSelectorFunction& selector) + void CollectNonSelectedInputs(SubgraphView::InputSlots& inputSlots, + const SubgraphViewSelector::LayerSelectorFunction& selector) { for (auto&& slot = m_Layer->BeginInputSlots(); slot != m_Layer->EndInputSlots(); ++slot) { @@ -94,8 +94,8 @@ struct LayerSelectionInfo } } - void CollectNonSelectedOutputSlots(SubGraph::OutputSlots& outputSlots, - const SubGraphSelector::LayerSelectorFunction& selector) + void CollectNonSelectedOutputSlots(SubgraphView::OutputSlots& outputSlots, + const SubgraphViewSelector::LayerSelectorFunction& selector) { for (auto&& slot = m_Layer->BeginOutputSlots(); slot != m_Layer->EndOutputSlots(); ++slot) { @@ -119,19 +119,19 @@ struct LayerSelectionInfo } // namespace <anonymous> -SubGraphSelector::SubGraphs -SubGraphSelector::SelectSubGraphs(Graph& graph, const LayerSelectorFunction& selector) +SubgraphViewSelector::Subgraphs +SubgraphViewSelector::SelectSubgraphs(Graph& graph, const LayerSelectorFunction& selector) { - SubGraph subGraph(graph); - return SubGraphSelector::SelectSubGraphs(subGraph, selector); + SubgraphView subgraph(graph); + return SubgraphViewSelector::SelectSubgraphs(subgraph, selector); } -SubGraphSelector::SubGraphs -SubGraphSelector::SelectSubGraphs(SubGraph& subGraph, const LayerSelectorFunction& selector) +SubgraphViewSelector::Subgraphs +SubgraphViewSelector::SelectSubgraphs(SubgraphView& subgraph, const LayerSelectorFunction& selector) { LayerSelectionInfo::LayerInfoContainer layerInfo; - for (auto& layer : subGraph) + for (auto& layer : subgraph) { layerInfo.emplace(layer, LayerSelectionInfo{layer, selector}); } @@ -168,14 +168,14 @@ SubGraphSelector::SelectSubGraphs(SubGraph& subGraph, const LayerSelectorFunctio } // Now each non-empty split id represents a subgraph - SubGraphs result; + Subgraphs result; for (auto& splitGraph : splitMap) { if (splitGraph.second.empty() == false) { - SubGraph::InputSlots inputs; - SubGraph::OutputSlots outputs; - SubGraph::Layers layers; + SubgraphView::InputSlots inputs; + SubgraphView::OutputSlots outputs; + SubgraphView::Layers layers; for (auto&& infoPtr : splitGraph.second) { infoPtr->CollectNonSelectedInputs(inputs, selector); @@ -184,10 +184,10 @@ SubGraphSelector::SelectSubGraphs(SubGraph& subGraph, const LayerSelectorFunctio } // 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>(subGraph, - std::move(inputs), - std::move(outputs), - std::move(layers))); + result.emplace_back(std::make_unique<SubgraphView>(subgraph, + std::move(inputs), + std::move(outputs), + std::move(layers))); } } diff --git a/src/armnn/SubgraphViewSelector.hpp b/src/armnn/SubgraphViewSelector.hpp new file mode 100644 index 0000000000..9d881faa7c --- /dev/null +++ b/src/armnn/SubgraphViewSelector.hpp @@ -0,0 +1,38 @@ +// +// Copyright © 2017 Arm Ltd. All rights reserved. +// SPDX-License-Identifier: MIT +// +#pragma once + +#include "SubgraphView.hpp" +#include <functional> +#include <memory> + +namespace armnn +{ + +class Layer; +class Graph; + +class SubgraphViewSelector final +{ +public: + using SubgraphViewPtr = std::unique_ptr<SubgraphView>; + using Subgraphs = std::vector<SubgraphViewPtr>; + using LayerSelectorFunction = std::function<bool(const Layer&)>; + + /// Selects subgraphs from a graph based on the selector function and the algorithm. + /// Since the Subgraphs object returns modifiable pointers to the input and output slots of the graph: + /// 1) the graph/sub-graph cannot be const + /// 2) the caller needs to make sure that the Subgraphs lifetime is shorter than the parent graph's + static Subgraphs SelectSubgraphs(Graph& graph, const LayerSelectorFunction& selector); + static Subgraphs SelectSubgraphs(SubgraphView& subgraph, const LayerSelectorFunction& selector); + +private: + // this is a utility class, don't construct or copy + SubgraphViewSelector() = delete; + SubgraphViewSelector(const SubgraphViewSelector&) = delete; + SubgraphViewSelector & operator=(const SubgraphViewSelector&) = delete; +}; + +} // namespace armnn diff --git a/src/armnn/layers/PreCompiledLayer.cpp b/src/armnn/layers/PreCompiledLayer.cpp index 29b35147f6..963924ded5 100644 --- a/src/armnn/layers/PreCompiledLayer.cpp +++ b/src/armnn/layers/PreCompiledLayer.cpp @@ -38,7 +38,7 @@ std::unique_ptr<IWorkload> PreCompiledLayer::CreateWorkload(const armnn::Graph& void PreCompiledLayer::ValidateTensorShapesFromInputs() { - // NOTE: since the PreCompiledLayer is an internal layer created from a valid SubGraph, + // NOTE: since the PreCompiledLayer is an internal layer created from a valid SubgraphView, // we do not need to validate its input shapes } diff --git a/src/armnn/test/SubGraphTests.cpp b/src/armnn/test/SubgraphViewTests.cpp index e5b444a076..603bb159d0 100644 --- a/src/armnn/test/SubGraphTests.cpp +++ b/src/armnn/test/SubgraphViewTests.cpp @@ -7,8 +7,8 @@ #include <armnn/ArmNN.hpp> #include <Graph.hpp> -#include <SubGraph.hpp> -#include <SubGraphSelector.hpp> +#include <SubgraphView.hpp> +#include <SubgraphViewSelector.hpp> #include <backendsCommon/CpuTensorHandle.hpp> @@ -17,9 +17,9 @@ using namespace armnn; namespace { -bool AreAnySubGraphLayersPresentInGraph(const SubGraph::Layers &subGraphLayers, const Graph &graph) +bool AreAnySubgraphLayersPresentInGraph(const SubgraphView::Layers &subgraphLayers, const Graph &graph) { - for(auto&& layer : subGraphLayers) + for(auto&& layer : subgraphLayers) { auto posInGraph = std::find(graph.begin(), graph.end(), layer); if(posInGraph != graph.end()) @@ -34,9 +34,9 @@ bool AreAnySubGraphLayersPresentInGraph(const SubGraph::Layers &subGraphLayers, // // this helper only works if all layers where the inputs connect to are not selected // -SubGraph::InputSlots CreateInputsFrom(const std::vector<Layer*>& layers) +SubgraphView::InputSlots CreateInputsFrom(const std::vector<Layer*>& layers) { - SubGraph::InputSlots result; + SubgraphView::InputSlots result; for (auto&& layer : layers) { for (auto&& it = layer->BeginInputSlots(); it != layer->EndInputSlots(); ++it) @@ -50,9 +50,9 @@ SubGraph::InputSlots CreateInputsFrom(const std::vector<Layer*>& layers) // // this helper only works if all layers where the outputs connect to are not selected // -SubGraph::OutputSlots CreateOutputsFrom(const std::vector<Layer*>& layers) +SubgraphView::OutputSlots CreateOutputsFrom(const std::vector<Layer*>& layers) { - SubGraph::OutputSlots result; + SubgraphView::OutputSlots result; for (auto && layer : layers) { for (auto&& it = layer->BeginOutputSlots(); it != layer->EndOutputSlots(); ++it) @@ -67,12 +67,12 @@ SubGraph::OutputSlots CreateOutputsFrom(const std::vector<Layer*>& 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 // -SubGraphSelector::SubGraphPtr CreateSubGraphFrom(Graph& graph, - SubGraph::InputSlots&& inputs, - SubGraph::OutputSlots&& outputs, - SubGraph::Layers&& layers) +SubgraphViewSelector::SubgraphViewPtr CreateSubgraphViewFrom(Graph& graph, + SubgraphView::InputSlots&& inputs, + SubgraphView::OutputSlots&& outputs, + SubgraphView::Layers&& layers) { - return std::make_unique<SubGraph>(&graph, std::move(inputs), std::move(outputs), std::move(layers)); + return std::make_unique<SubgraphView>(&graph, std::move(inputs), std::move(outputs), std::move(layers)); } template <typename T, typename Iterator> @@ -84,13 +84,13 @@ std::vector<T> ToSortedArray(Iterator begin, Iterator end) } template <typename T> -void CompareVectors(const std::vector<T> & result, const std::vector<T> & expected) +void CompareVectors(const std::vector<T>& result, const std::vector<T>& expected) { BOOST_CHECK_EQUAL_COLLECTIONS(result.begin(), result.end(), expected.begin(), expected.end()); } -void CompareSubGraphs(SubGraphSelector::SubGraphPtr & result, - SubGraphSelector::SubGraphPtr & expected) +void CompareSubgraphViews(SubgraphViewSelector::SubgraphViewPtr& result, + SubgraphViewSelector::SubgraphViewPtr& expected) { // expect both to be valid subgraphs BOOST_TEST((result.get() != nullptr)); @@ -127,7 +127,7 @@ void CompareSubGraphs(SubGraphSelector::SubGraphPtr & result, } // namespace <anonymous> -BOOST_AUTO_TEST_SUITE(SubGraphSubstitution) +BOOST_AUTO_TEST_SUITE(SubgraphSubstitution) BOOST_AUTO_TEST_CASE(SingleInputSingleOutput) { @@ -147,25 +147,25 @@ BOOST_AUTO_TEST_CASE(SingleInputSingleOutput) convLayer2->GetOutputSlot(0).Connect(outputLayer->GetInputSlot(0)); // Construct sub-graph - SubGraphSelector::SubGraphPtr subGraph = CreateSubGraphFrom(graph, - CreateInputsFrom({convLayer1}), - CreateOutputsFrom({convLayer2}), - {}); + SubgraphViewSelector::SubgraphViewPtr subgraph = CreateSubgraphViewFrom(graph, + CreateInputsFrom({convLayer1}), + CreateOutputsFrom({convLayer2}), + {}); // Save sub-graph connections for comparison after substitution - IOutputSlot* subGraphInputConn = subGraph->GetInputSlot(0)->GetConnection(); - IInputSlot* subGraphOutputConn = subGraph->GetOutputSlot(0)->GetConnection(0); + IOutputSlot* subgraphInputConn = subgraph->GetInputSlot(0)->GetConnection(); + IInputSlot* subgraphOutputConn = subgraph->GetOutputSlot(0)->GetConnection(0); // Construct dummy pre-compiled layer PreCompiledDescriptor preCompiledDescriptor(1, 1); Layer* const preCompiledLayer = graph.AddLayer<PreCompiledLayer>(preCompiledDescriptor, "pre-compiled"); // Substitute sub-graph with pre-compiled layer - graph.SubstituteSubGraph(std::move(subGraph), preCompiledLayer); + graph.SubstituteSubgraph(std::move(subgraph), preCompiledLayer); // Check that connections are correct after substitution - BOOST_CHECK_EQUAL(preCompiledLayer->GetInputSlot(0).GetConnection(), subGraphInputConn); - BOOST_CHECK_EQUAL(preCompiledLayer->GetOutputSlot(0).GetConnection(0), subGraphOutputConn); + BOOST_CHECK_EQUAL(preCompiledLayer->GetInputSlot(0).GetConnection(), subgraphInputConn); + BOOST_CHECK_EQUAL(preCompiledLayer->GetOutputSlot(0).GetConnection(0), subgraphOutputConn); } BOOST_AUTO_TEST_CASE(MultiInputSingleOutput) @@ -195,29 +195,29 @@ BOOST_AUTO_TEST_CASE(MultiInputSingleOutput) mergerLayer->GetOutputSlot(0).Connect(outputLayer->GetInputSlot(0)); // Construct sub-graph - SubGraphSelector::SubGraphPtr subGraph = CreateSubGraphFrom(graph, - CreateInputsFrom({convLayer1, convLayer2}), - CreateOutputsFrom({mergerLayer}), - {}); + SubgraphViewSelector::SubgraphViewPtr subgraph = CreateSubgraphViewFrom(graph, + CreateInputsFrom({convLayer1, convLayer2}), + CreateOutputsFrom({mergerLayer}), + {}); // Save sub-graph connections for comparison after substitution - IOutputSlot* subGraphInputConn1 = subGraph->GetInputSlot(0)->GetConnection(); - IOutputSlot* subGraphInputConn2 = subGraph->GetInputSlot(1)->GetConnection(); + IOutputSlot* subgraphInputConn1 = subgraph->GetInputSlot(0)->GetConnection(); + IOutputSlot* subgraphInputConn2 = subgraph->GetInputSlot(1)->GetConnection(); - IInputSlot* subGraphOutputConn = subGraph->GetOutputSlot(0)->GetConnection(0); + IInputSlot* subgraphOutputConn = subgraph->GetOutputSlot(0)->GetConnection(0); // Construct dummy pre-compiled layer PreCompiledDescriptor preCompiledDescriptor(2, 1); Layer* const preCompiledLayer = graph.AddLayer<PreCompiledLayer>(preCompiledDescriptor, "pre-compiled"); // Substitute sub-graph with pre-compiled layer - graph.SubstituteSubGraph(std::move(subGraph), preCompiledLayer); + graph.SubstituteSubgraph(std::move(subgraph), preCompiledLayer); // Check that connections are correct after substitution - BOOST_CHECK_EQUAL(preCompiledLayer->GetInputSlot(0).GetConnection(), subGraphInputConn1); - BOOST_CHECK_EQUAL(preCompiledLayer->GetInputSlot(1).GetConnection(), subGraphInputConn2); + BOOST_CHECK_EQUAL(preCompiledLayer->GetInputSlot(0).GetConnection(), subgraphInputConn1); + BOOST_CHECK_EQUAL(preCompiledLayer->GetInputSlot(1).GetConnection(), subgraphInputConn2); - BOOST_CHECK_EQUAL(preCompiledLayer->GetOutputSlot(0).GetConnection(0), subGraphOutputConn); + BOOST_CHECK_EQUAL(preCompiledLayer->GetOutputSlot(0).GetConnection(0), subgraphOutputConn); } BOOST_AUTO_TEST_CASE(SingleInputMultiOutput) @@ -245,29 +245,29 @@ BOOST_AUTO_TEST_CASE(SingleInputMultiOutput) mergerLayer->GetOutputSlot(0).Connect(outputLayer->GetInputSlot(0)); // Construct sub-graph - SubGraphSelector::SubGraphPtr subGraph = CreateSubGraphFrom(graph, - CreateInputsFrom({splitterLayer}), - CreateOutputsFrom({convLayer1, convLayer2}), - {}); + SubgraphViewSelector::SubgraphViewPtr subgraph = CreateSubgraphViewFrom(graph, + CreateInputsFrom({splitterLayer}), + CreateOutputsFrom({convLayer1, convLayer2}), + {}); // Save sub-graph connections for comparison after substitution - IOutputSlot* subGraphInputConn1 = subGraph->GetInputSlot(0)->GetConnection(); + IOutputSlot* subgraphInputConn1 = subgraph->GetInputSlot(0)->GetConnection(); - IInputSlot* subGraphOutputConn1 = subGraph->GetOutputSlot(0)->GetConnection(0); - IInputSlot* subGraphOutputConn2 = subGraph->GetOutputSlot(1)->GetConnection(0); + IInputSlot* subgraphOutputConn1 = subgraph->GetOutputSlot(0)->GetConnection(0); + IInputSlot* subgraphOutputConn2 = subgraph->GetOutputSlot(1)->GetConnection(0); // Construct dummy pre-compiled layer PreCompiledDescriptor preCompiledDescriptor(1, 2); Layer* const preCompiledLayer = graph.AddLayer<PreCompiledLayer>(preCompiledDescriptor, "pre-compiled"); // Substitute sub-graph with pre-compiled layer - graph.SubstituteSubGraph(std::move(subGraph), preCompiledLayer); + graph.SubstituteSubgraph(std::move(subgraph), preCompiledLayer); // Check that connections are correct after substitution - BOOST_CHECK_EQUAL(preCompiledLayer->GetInputSlot(0).GetConnection(), subGraphInputConn1); + BOOST_CHECK_EQUAL(preCompiledLayer->GetInputSlot(0).GetConnection(), subgraphInputConn1); - BOOST_CHECK_EQUAL(preCompiledLayer->GetOutputSlot(0).GetConnection(0), subGraphOutputConn1); - BOOST_CHECK_EQUAL(preCompiledLayer->GetOutputSlot(1).GetConnection(0), subGraphOutputConn2); + BOOST_CHECK_EQUAL(preCompiledLayer->GetOutputSlot(0).GetConnection(0), subgraphOutputConn1); + BOOST_CHECK_EQUAL(preCompiledLayer->GetOutputSlot(1).GetConnection(0), subgraphOutputConn2); } BOOST_AUTO_TEST_CASE(MultiInputMultiOutput) @@ -297,31 +297,31 @@ BOOST_AUTO_TEST_CASE(MultiInputMultiOutput) mergerLayer->GetOutputSlot(0).Connect(outputLayer->GetInputSlot(0)); // Construct sub-graph - SubGraphSelector::SubGraphPtr subGraph = CreateSubGraphFrom(graph, - CreateInputsFrom({convLayer1, convLayer2}), - CreateOutputsFrom({convLayer1, convLayer2}), - {}); + SubgraphViewSelector::SubgraphViewPtr subgraph = CreateSubgraphViewFrom(graph, + CreateInputsFrom({convLayer1, convLayer2}), + CreateOutputsFrom({convLayer1, convLayer2}), + {}); // Save sub-graph connections for comparison after substitution - IOutputSlot* subGraphInputConn1 = subGraph->GetInputSlot(0)->GetConnection(); - IOutputSlot* subGraphInputConn2 = subGraph->GetInputSlot(1)->GetConnection(); + IOutputSlot* subgraphInputConn1 = subgraph->GetInputSlot(0)->GetConnection(); + IOutputSlot* subgraphInputConn2 = subgraph->GetInputSlot(1)->GetConnection(); - IInputSlot* subGraphOutputConn1 = subGraph->GetOutputSlot(0)->GetConnection(0); - IInputSlot* subGraphOutputConn2 = subGraph->GetOutputSlot(1)->GetConnection(0); + IInputSlot* subgraphOutputConn1 = subgraph->GetOutputSlot(0)->GetConnection(0); + IInputSlot* subgraphOutputConn2 = subgraph->GetOutputSlot(1)->GetConnection(0); // Construct dummy pre-compiled layer PreCompiledDescriptor preCompiledDescriptor(2, 2); Layer* const preCompiledLayer = graph.AddLayer<PreCompiledLayer>(preCompiledDescriptor, "pre-compiled"); // Substitute sub-graph with pre-compiled layer - graph.SubstituteSubGraph(std::move(subGraph), preCompiledLayer); + graph.SubstituteSubgraph(std::move(subgraph), preCompiledLayer); // Check that connections are correct after substitution - BOOST_CHECK_EQUAL(preCompiledLayer->GetInputSlot(0).GetConnection(), subGraphInputConn1); - BOOST_CHECK_EQUAL(preCompiledLayer->GetInputSlot(1).GetConnection(), subGraphInputConn2); + BOOST_CHECK_EQUAL(preCompiledLayer->GetInputSlot(0).GetConnection(), subgraphInputConn1); + BOOST_CHECK_EQUAL(preCompiledLayer->GetInputSlot(1).GetConnection(), subgraphInputConn2); - BOOST_CHECK_EQUAL(preCompiledLayer->GetOutputSlot(0).GetConnection(0), subGraphOutputConn1); - BOOST_CHECK_EQUAL(preCompiledLayer->GetOutputSlot(1).GetConnection(0), subGraphOutputConn2); + BOOST_CHECK_EQUAL(preCompiledLayer->GetOutputSlot(0).GetConnection(0), subgraphOutputConn1); + BOOST_CHECK_EQUAL(preCompiledLayer->GetOutputSlot(1).GetConnection(0), subgraphOutputConn2); } BOOST_AUTO_TEST_CASE(EraseReplacedLayers) @@ -344,40 +344,43 @@ BOOST_AUTO_TEST_CASE(EraseReplacedLayers) graph.AddLayer<OutputLayer>(0, "output"); // Construct sub-graph - SubGraphSelector::SubGraphPtr subGraph = CreateSubGraphFrom(graph, - {}, - {}, - {splitterLayer, convLayer1, convLayer2, mergerLayer}); + SubgraphViewSelector::SubgraphViewPtr subgraph = CreateSubgraphViewFrom(graph, + {}, + {}, + {splitterLayer, + convLayer1, + convLayer2, + mergerLayer}); // Construct dummy pre-compiled layer PreCompiledDescriptor preCompiledDescriptor(0, 0); Layer* const preCompiledLayer = graph.AddLayer<PreCompiledLayer>(preCompiledDescriptor, "pre-compiled"); // Save sub-graph layers for later verification - const SubGraph::Layers subGraphLayers = subGraph->GetLayers(); + const SubgraphView::Layers subgraphLayers = subgraph->GetLayers(); // Substitute sub-graph with pre-compiled layer - graph.SubstituteSubGraph(std::move(subGraph), preCompiledLayer); + graph.SubstituteSubgraph(std::move(subgraph), preCompiledLayer); // Check that the layers belonging to the sub-graph have been erased from the graph after substitution - BOOST_CHECK(!AreAnySubGraphLayersPresentInGraph(subGraphLayers, graph)); + BOOST_CHECK(!AreAnySubgraphLayersPresentInGraph(subgraphLayers, graph)); } BOOST_AUTO_TEST_SUITE_END() -BOOST_AUTO_TEST_SUITE(SubGraphSelection) +BOOST_AUTO_TEST_SUITE(SubgraphSelection) -BOOST_AUTO_TEST_CASE(SubGraphForEmptyGraph) +BOOST_AUTO_TEST_CASE(SubgraphForEmptyGraph) { Graph graph; - SubGraph subGraph(graph); + SubgraphView subgraph(graph); - BOOST_TEST(subGraph.GetInputSlots().empty()); - BOOST_TEST(subGraph.GetOutputSlots().empty()); - BOOST_TEST(subGraph.GetLayers().empty()); + BOOST_TEST(subgraph.GetInputSlots().empty()); + BOOST_TEST(subgraph.GetOutputSlots().empty()); + BOOST_TEST(subgraph.GetLayers().empty()); } -BOOST_AUTO_TEST_CASE(SubGraphForEntireGraph) +BOOST_AUTO_TEST_CASE(SubgraphForEntireGraph) { Graph graph; @@ -390,35 +393,35 @@ BOOST_AUTO_TEST_CASE(SubGraphForEntireGraph) "mid1"); graph.InsertNewLayer<InputLayer>(mid1->GetInputSlot(0), 0, "input"); - SubGraph subGraph(graph); + SubgraphView subgraph(graph); - BOOST_TEST(subGraph.GetInputSlots().empty()); - BOOST_TEST(subGraph.GetOutputSlots().empty()); - BOOST_TEST(subGraph.GetLayers().size() == graph.GetNumLayers()); + BOOST_TEST(subgraph.GetInputSlots().empty()); + BOOST_TEST(subgraph.GetOutputSlots().empty()); + BOOST_TEST(subgraph.GetLayers().size() == graph.GetNumLayers()); } -BOOST_AUTO_TEST_CASE(NoSubGraphsForNoMatch) +BOOST_AUTO_TEST_CASE(NoSubgraphsForNoMatch) { Graph graph; auto output = graph.AddLayer<OutputLayer>(0, "output"); graph.InsertNewLayer<InputLayer>(output->GetInputSlot(0), 0, "input"); - SubGraphSelector::SubGraphs subGraphs = - SubGraphSelector::SelectSubGraphs(graph, [](const Layer &) { return false; }); + SubgraphViewSelector::Subgraphs subgraphs = + SubgraphViewSelector::SelectSubgraphs(graph, [](const Layer &) { return false; }); - BOOST_TEST(subGraphs.empty()); + BOOST_TEST(subgraphs.empty()); } -BOOST_AUTO_TEST_CASE(OneSubGraphsSelectedASingleMatch) +BOOST_AUTO_TEST_CASE(OneSubgraphsSelectedASingleMatch) { Graph graph; auto output = graph.AddLayer<OutputLayer>(0, "output"); graph.InsertNewLayer<InputLayer>(output->GetInputSlot(0), 0, "input"); - SubGraphSelector::SubGraphs subGraphs = - SubGraphSelector::SelectSubGraphs( + SubgraphViewSelector::Subgraphs subgraphs = + SubgraphViewSelector::SelectSubgraphs( graph, // select the output layer only [](const Layer & l) @@ -427,16 +430,16 @@ BOOST_AUTO_TEST_CASE(OneSubGraphsSelectedASingleMatch) return isOutput; }); - BOOST_TEST(subGraphs.size() == 1); - if (subGraphs.size() == 1) + BOOST_TEST(subgraphs.size() == 1); + if (subgraphs.size() == 1) { - auto expected = CreateSubGraphFrom(graph, - CreateInputsFrom({output}), - // outputs of 'output' will be empty - CreateOutputsFrom({output}), - {output}); + auto expected = CreateSubgraphViewFrom(graph, + CreateInputsFrom({output}), + // outputs of 'output' will be empty + CreateOutputsFrom({output}), + {output}); - CompareSubGraphs(subGraphs[0], expected); + CompareSubgraphViews(subgraphs[0], expected); } } @@ -453,8 +456,8 @@ BOOST_AUTO_TEST_CASE(MultipleLayersSelectedInTheMiddle) "mid1"); graph.InsertNewLayer<InputLayer>(mid1->GetInputSlot(0), 0, "input"); - SubGraphSelector::SubGraphs subGraphs = - SubGraphSelector::SelectSubGraphs( + SubgraphViewSelector::Subgraphs subgraphs = + SubgraphViewSelector::SelectSubgraphs( graph, // select the middle layers only [](const Layer & l) @@ -463,15 +466,15 @@ BOOST_AUTO_TEST_CASE(MultipleLayersSelectedInTheMiddle) return toSelect; }); - BOOST_TEST(subGraphs.size() == 1); - if (subGraphs.size() == 1) + BOOST_TEST(subgraphs.size() == 1); + if (subgraphs.size() == 1) { - auto expected = CreateSubGraphFrom(graph, - CreateInputsFrom({mid1}), - CreateOutputsFrom({mid0}), - {mid1, mid0}); + auto expected = CreateSubgraphViewFrom(graph, + CreateInputsFrom({mid1}), + CreateOutputsFrom({mid0}), + {mid1, mid0}); - CompareSubGraphs(subGraphs[0], expected); + CompareSubgraphViews(subgraphs[0], expected); } } @@ -527,8 +530,8 @@ BOOST_AUTO_TEST_CASE(IslandInTheMiddle) x0->GetOutputSlot(0).Connect(m4->GetInputSlot(0)); // All selected 'M*' layers will be of Activation type - SubGraphSelector::SubGraphs subGraphs = - SubGraphSelector::SelectSubGraphs( + SubgraphViewSelector::Subgraphs subgraphs = + SubgraphViewSelector::SelectSubgraphs( graph, // select the middle layers only [](const Layer & l) @@ -538,44 +541,44 @@ BOOST_AUTO_TEST_CASE(IslandInTheMiddle) }); // expected results to test against - auto largerSubGraph = CreateSubGraphFrom(graph, - CreateInputsFrom({m1, m4}), - CreateOutputsFrom({m3, m4}), - {m1, m4, m2, m3}); - - auto smallerSubGraph = CreateSubGraphFrom(graph, - CreateInputsFrom({m5}), - CreateOutputsFrom({m5}), - {m5}); - - BOOST_TEST(subGraphs.size() == 2); - if (subGraphs.size() == 2) + auto largerSubgraph = CreateSubgraphViewFrom(graph, + CreateInputsFrom({m1, m4}), + CreateOutputsFrom({m3, m4}), + {m1, m4, m2, m3}); + + auto smallerSubgraph = CreateSubgraphViewFrom(graph, + CreateInputsFrom({m5}), + CreateOutputsFrom({m5}), + {m5}); + + BOOST_TEST(subgraphs.size() == 2); + if (subgraphs.size() == 2) { // we need to have valid subgraph pointers here - BOOST_TEST((subGraphs[0] != nullptr)); - BOOST_TEST((subGraphs[1] != nullptr)); + BOOST_TEST((subgraphs[0] != nullptr)); + BOOST_TEST((subgraphs[1] != nullptr)); - if (subGraphs[0].get() != nullptr && subGraphs[1].get() != nullptr) + if (subgraphs[0].get() != nullptr && subgraphs[1].get() != nullptr) { // sort the subgraphs by layer size, so it is simpler to test - std::sort(subGraphs.begin(), subGraphs.end(), - [](SubGraphSelector::SubGraphPtr & lhs, SubGraphSelector::SubGraphPtr & rhs) + std::sort(subgraphs.begin(), subgraphs.end(), + [](SubgraphViewSelector::SubgraphViewPtr & lhs, SubgraphViewSelector::SubgraphViewPtr & rhs) { return (lhs->GetLayers().size() < rhs->GetLayers().size()); } ); // one subgraph needs to be size=1 and the other one is 4 - BOOST_TEST(subGraphs[0]->GetLayers().size() == 1); - BOOST_TEST(subGraphs[1]->GetLayers().size() == 4); + BOOST_TEST(subgraphs[0]->GetLayers().size() == 1); + BOOST_TEST(subgraphs[1]->GetLayers().size() == 4); - CompareSubGraphs(subGraphs[0], smallerSubGraph); - CompareSubGraphs(subGraphs[1], largerSubGraph); + CompareSubgraphViews(subgraphs[0], smallerSubgraph); + CompareSubgraphViews(subgraphs[1], largerSubgraph); } } } -BOOST_AUTO_TEST_CASE(MultipleSimpleSubGraphs) +BOOST_AUTO_TEST_CASE(MultipleSimpleSubgraphs) { // This test case represents the scenario when we have two distinct subgraphs // in a simple linear network. The selected nodes are the M* and the @@ -605,8 +608,8 @@ BOOST_AUTO_TEST_CASE(MultipleSimpleSubGraphs) graph.InsertNewLayer<InputLayer>(m1->GetInputSlot(0), 0, "x1"); // All selected 'M*' layers will be of Activation type - SubGraphSelector::SubGraphs subGraphs = - SubGraphSelector::SelectSubGraphs( + SubgraphViewSelector::Subgraphs subgraphs = + SubgraphViewSelector::SelectSubgraphs( graph, // select the middle layers only [](const Layer & l) @@ -616,38 +619,38 @@ BOOST_AUTO_TEST_CASE(MultipleSimpleSubGraphs) }); // expected results to test against - auto largerSubGraph = CreateSubGraphFrom(graph, - CreateInputsFrom({m1}), - CreateOutputsFrom({m2}), - {m1, m2}); - - auto smallerSubGraph = CreateSubGraphFrom(graph, - CreateInputsFrom({m3}), - CreateOutputsFrom({m3}), - {m3}); - - BOOST_TEST(subGraphs.size() == 2); - if (subGraphs.size() == 2) + auto largerSubgraph = CreateSubgraphViewFrom(graph, + CreateInputsFrom({m1}), + CreateOutputsFrom({m2}), + {m1, m2}); + + auto smallerSubgraph = CreateSubgraphViewFrom(graph, + CreateInputsFrom({m3}), + CreateOutputsFrom({m3}), + {m3}); + + BOOST_TEST(subgraphs.size() == 2); + if (subgraphs.size() == 2) { // we need to have valid subgraph pointers here - BOOST_TEST((subGraphs[0] != nullptr)); - BOOST_TEST((subGraphs[1] != nullptr)); + BOOST_TEST((subgraphs[0] != nullptr)); + BOOST_TEST((subgraphs[1] != nullptr)); - if (subGraphs[0].get() != nullptr && subGraphs[1].get() != nullptr) + if (subgraphs[0].get() != nullptr && subgraphs[1].get() != nullptr) { // sort the subgraphs by layer size, so it is simpler to test - std::sort(subGraphs.begin(), subGraphs.end(), - [](SubGraphSelector::SubGraphPtr & lhs, SubGraphSelector::SubGraphPtr & rhs) + std::sort(subgraphs.begin(), subgraphs.end(), + [](SubgraphViewSelector::SubgraphViewPtr & lhs, SubgraphViewSelector::SubgraphViewPtr & rhs) { return (lhs->GetLayers().size() < rhs->GetLayers().size()); } ); - BOOST_TEST(subGraphs[0]->GetLayers().size() == 1); - BOOST_TEST(subGraphs[1]->GetLayers().size() == 2); + BOOST_TEST(subgraphs[0]->GetLayers().size() == 1); + BOOST_TEST(subgraphs[1]->GetLayers().size() == 2); - CompareSubGraphs(subGraphs[0], smallerSubGraph); - CompareSubGraphs(subGraphs[1], largerSubGraph); + CompareSubgraphViews(subgraphs[0], smallerSubgraph); + CompareSubgraphViews(subgraphs[1], largerSubgraph); } } } @@ -677,8 +680,8 @@ BOOST_AUTO_TEST_CASE(SimpleLinearTest) layerM1->GetOutputSlot(0).Connect(layerM2->GetInputSlot(0)); layerM2->GetOutputSlot(0).Connect(layerX2->GetInputSlot(0)); - SubGraphSelector::SubGraphs subGraphs = - SubGraphSelector::SelectSubGraphs( + SubgraphViewSelector::Subgraphs subgraphs = + SubgraphViewSelector::SelectSubgraphs( graph, // select the activation layers M1 and M2 [](const Layer & l) @@ -687,15 +690,15 @@ BOOST_AUTO_TEST_CASE(SimpleLinearTest) return toSelect; }); - BOOST_CHECK(subGraphs.size() == 1); - if(subGraphs.size() == 1) + BOOST_CHECK(subgraphs.size() == 1); + if(subgraphs.size() == 1) { - auto expected = CreateSubGraphFrom(graph, - CreateInputsFrom({layerM1}), - CreateOutputsFrom({layerM2}), - {layerM1, layerM2}); + auto expected = CreateSubgraphViewFrom(graph, + CreateInputsFrom({layerM1}), + CreateOutputsFrom({layerM2}), + {layerM1, layerM2}); - CompareSubGraphs(subGraphs[0], expected); + CompareSubgraphViews(subgraphs[0], expected); } } @@ -732,8 +735,8 @@ BOOST_AUTO_TEST_CASE(MultiInputSingleOutput) layerM2->GetOutputSlot(0).Connect(layerM3->GetInputSlot(1)); layerM3->GetOutputSlot(0).Connect(layerX3->GetInputSlot(0)); - SubGraphSelector::SubGraphs subGraphs = - SubGraphSelector::SelectSubGraphs( + SubgraphViewSelector::Subgraphs subgraphs = + SubgraphViewSelector::SelectSubgraphs( graph, // select Activation and Addition Layers M1, M2 and M3 [](const Layer & l) @@ -743,15 +746,15 @@ BOOST_AUTO_TEST_CASE(MultiInputSingleOutput) return toSelect; }); - BOOST_CHECK(subGraphs.size() == 1); - if (subGraphs.size() == 1) + BOOST_CHECK(subgraphs.size() == 1); + if (subgraphs.size() == 1) { - auto expected = CreateSubGraphFrom(graph, - CreateInputsFrom({layerM1, layerM2}), - CreateOutputsFrom({layerM3}), - {layerM1, layerM2, layerM3}); + auto expected = CreateSubgraphViewFrom(graph, + CreateInputsFrom({layerM1, layerM2}), + CreateOutputsFrom({layerM3}), + {layerM1, layerM2, layerM3}); - CompareSubGraphs(subGraphs[0], expected); + CompareSubgraphViews(subgraphs[0], expected); } } @@ -789,8 +792,8 @@ BOOST_AUTO_TEST_CASE(SingleInputMultiOutput) layerM2->GetOutputSlot(0).Connect(layerX2->GetInputSlot(0)); layerM3->GetOutputSlot(0).Connect(layerX3->GetInputSlot(0)); - SubGraphSelector::SubGraphs subGraphs = - SubGraphSelector::SelectSubGraphs( + SubgraphViewSelector::Subgraphs subgraphs = + SubgraphViewSelector::SelectSubgraphs( graph, // select Activation and Splitter Layers M1, M2 and M3 [](const Layer & l) @@ -800,15 +803,15 @@ BOOST_AUTO_TEST_CASE(SingleInputMultiOutput) return toSelect; }); - BOOST_CHECK(subGraphs.size() == 1); - if(subGraphs.size() == 1) + BOOST_CHECK(subgraphs.size() == 1); + if(subgraphs.size() == 1) { - auto expected = CreateSubGraphFrom(graph, - CreateInputsFrom({layerM1}), - CreateOutputsFrom({layerM2, layerM3}), - {layerM1, layerM2, layerM3}); + auto expected = CreateSubgraphViewFrom(graph, + CreateInputsFrom({layerM1}), + CreateOutputsFrom({layerM2, layerM3}), + {layerM1, layerM2, layerM3}); - CompareSubGraphs(subGraphs[0], expected); + CompareSubgraphViews(subgraphs[0], expected); } } @@ -853,8 +856,8 @@ BOOST_AUTO_TEST_CASE(MultiInputMultiOutput) m5->GetOutputSlot(0).Connect(x4->GetInputSlot(0)); - SubGraphSelector::SubGraphs subGraphs = - SubGraphSelector::SelectSubGraphs( + SubgraphViewSelector::Subgraphs subgraphs = + SubgraphViewSelector::SelectSubgraphs( graph, // select Activation and Merger Layers M1, M2, M3, M4, M5 [](const Layer & l) @@ -865,15 +868,15 @@ BOOST_AUTO_TEST_CASE(MultiInputMultiOutput) }); - BOOST_CHECK(subGraphs.size() == 1); - if (subGraphs.size() == 1) + BOOST_CHECK(subgraphs.size() == 1); + if (subgraphs.size() == 1) { - auto expected = CreateSubGraphFrom(graph, - CreateInputsFrom({m1, m2}), - CreateOutputsFrom({m4, m5}), - {m1, m2, m3, m4, m5}); + auto expected = CreateSubgraphViewFrom(graph, + CreateInputsFrom({m1, m2}), + CreateOutputsFrom({m4, m5}), + {m1, m2, m3, m4, m5}); - CompareSubGraphs(subGraphs[0], expected); + CompareSubgraphViews(subgraphs[0], expected); } } @@ -881,7 +884,7 @@ BOOST_AUTO_TEST_SUITE_END() BOOST_AUTO_TEST_SUITE(IntegrationTests) -BOOST_AUTO_TEST_CASE(SingleSubGraph) +BOOST_AUTO_TEST_CASE(SingleSubgraph) { // This test case represents the scenario when we have one subgraph // in which two layers have GpuAcc backend assigned @@ -905,8 +908,8 @@ BOOST_AUTO_TEST_CASE(SingleSubGraph) convLayer2->GetOutputSlot(0).Connect(outputLayer->GetInputSlot(0)); // GpuAcc sub graph selector - SubGraphSelector::SubGraphs subGraphs = - SubGraphSelector::SelectSubGraphs( + SubgraphViewSelector::Subgraphs subgraphs = + SubgraphViewSelector::SelectSubgraphs( graph, // select the GpuAcc layers only [](const Layer & l){ @@ -914,39 +917,39 @@ BOOST_AUTO_TEST_CASE(SingleSubGraph) return toSelect; }); - BOOST_TEST(subGraphs.size() == 1); - if(subGraphs.size() == 1) + BOOST_TEST(subgraphs.size() == 1); + if(subgraphs.size() == 1) { - BOOST_TEST((subGraphs[0] != nullptr)); + BOOST_TEST((subgraphs[0] != nullptr)); - if (subGraphs[0].get() != nullptr) + if (subgraphs[0].get() != nullptr) { - unsigned int numInputSlots = boost::numeric_cast<unsigned int>(subGraphs[0]->GetInputSlots().size()); - unsigned int numOutputSlots = boost::numeric_cast<unsigned int>(subGraphs[0]->GetOutputSlots().size()); + unsigned int numInputSlots = boost::numeric_cast<unsigned int>(subgraphs[0]->GetInputSlots().size()); + unsigned int numOutputSlots = boost::numeric_cast<unsigned int>(subgraphs[0]->GetOutputSlots().size()); BOOST_TEST((numInputSlots == 1)); BOOST_TEST((numOutputSlots == 1)); // Save sub-graph connections for comparison after substitution - IOutputSlot* subGraphInputConn1 = subGraphs[0]->GetInputSlot(0)->GetConnection(); - IInputSlot* subGraphOutputConn1 = subGraphs[0]->GetOutputSlot(0)->GetConnection(0); + IOutputSlot* subgraphInputConn1 = subgraphs[0]->GetInputSlot(0)->GetConnection(); + IInputSlot* subgraphOutputConn1 = subgraphs[0]->GetOutputSlot(0)->GetConnection(0); // Construct dummy pre-compiled layer PreCompiledDescriptor preCompiledDescriptor(numInputSlots, numOutputSlots); Layer* const preCompiledLayer = graph.AddLayer<PreCompiledLayer>(preCompiledDescriptor, "pre-compiled"); // Substitute sub-graph with pre-compiled layer - graph.SubstituteSubGraph((std::move(subGraphs[0])), preCompiledLayer); + graph.SubstituteSubgraph((std::move(subgraphs[0])), preCompiledLayer); // Check that connections are correct after substitution - BOOST_CHECK_EQUAL(preCompiledLayer->GetInputSlot(0).GetConnection(), subGraphInputConn1); + BOOST_CHECK_EQUAL(preCompiledLayer->GetInputSlot(0).GetConnection(), subgraphInputConn1); - BOOST_CHECK_EQUAL(preCompiledLayer->GetOutputSlot(0).GetConnection(0), subGraphOutputConn1); + BOOST_CHECK_EQUAL(preCompiledLayer->GetOutputSlot(0).GetConnection(0), subgraphOutputConn1); } } } -BOOST_AUTO_TEST_CASE(MultipleSubGraphs) +BOOST_AUTO_TEST_CASE(MultipleSubgraphs) { // This test case represents the scenario when we have two subgraphs // in which two layers have CpuAcc backend assigned @@ -978,8 +981,8 @@ BOOST_AUTO_TEST_CASE(MultipleSubGraphs) mergerLayer->GetOutputSlot(0).Connect(outputLayer->GetInputSlot(0)); // CpuAcc sub graph selector - SubGraphSelector::SubGraphs subGraphs = - SubGraphSelector::SelectSubGraphs( + SubgraphViewSelector::Subgraphs subgraphs = + SubgraphViewSelector::SelectSubgraphs( graph, // select the CpuAcc layers only [](const Layer & l){ @@ -987,37 +990,37 @@ BOOST_AUTO_TEST_CASE(MultipleSubGraphs) return toSelect; }); - BOOST_TEST(subGraphs.size() == 2); - if(subGraphs.size() == 2) + BOOST_TEST(subgraphs.size() == 2); + if(subgraphs.size() == 2) { - BOOST_TEST((subGraphs[0] != nullptr)); - BOOST_TEST((subGraphs[1] != nullptr)); + BOOST_TEST((subgraphs[0] != nullptr)); + BOOST_TEST((subgraphs[1] != nullptr)); - if (subGraphs[0].get() != nullptr && subGraphs[1].get() != nullptr) + if (subgraphs[0].get() != nullptr && subgraphs[1].get() != nullptr) { - //Sort subGraphs by their inputSlot size. - std::sort(subGraphs.begin(), subGraphs.end(), - [](SubGraphSelector::SubGraphPtr & lhs, SubGraphSelector::SubGraphPtr & rhs) + //Sort subgraphs by their inputSlot size. + std::sort(subgraphs.begin(), subgraphs.end(), + [](SubgraphViewSelector::SubgraphViewPtr & lhs, SubgraphViewSelector::SubgraphViewPtr & rhs) { return (lhs->GetInputSlots().size() < rhs->GetInputSlots().size()); } ); - unsigned int numInputSlots1 = boost::numeric_cast<unsigned int>(subGraphs[0]->GetInputSlots().size()); - unsigned int numOutputSlots1 = boost::numeric_cast<unsigned int>(subGraphs[0]->GetOutputSlots().size()); + unsigned int numInputSlots1 = boost::numeric_cast<unsigned int>(subgraphs[0]->GetInputSlots().size()); + unsigned int numOutputSlots1 = boost::numeric_cast<unsigned int>(subgraphs[0]->GetOutputSlots().size()); - unsigned int numInputSlots2 = boost::numeric_cast<unsigned int>(subGraphs[1]->GetInputSlots().size()); - unsigned int numOutputSlots2 = boost::numeric_cast<unsigned int>(subGraphs[1]->GetOutputSlots().size()); + unsigned int numInputSlots2 = boost::numeric_cast<unsigned int>(subgraphs[1]->GetInputSlots().size()); + unsigned int numOutputSlots2 = boost::numeric_cast<unsigned int>(subgraphs[1]->GetOutputSlots().size()); // Save sub-graph connections for comparison after substitution - IOutputSlot* subGraph1InputConn = subGraphs[0]->GetInputSlot(0)->GetConnection(); - IInputSlot* subGraph1OutputConn1 = subGraphs[0]->GetOutputSlot(0)->GetConnection(0); - IInputSlot* subGraph1OutputConn2 = subGraphs[0]->GetOutputSlot(1)->GetConnection(0); + IOutputSlot* subgraph1InputConn = subgraphs[0]->GetInputSlot(0)->GetConnection(); + IInputSlot* subgraph1OutputConn1 = subgraphs[0]->GetOutputSlot(0)->GetConnection(0); + IInputSlot* subgraph1OutputConn2 = subgraphs[0]->GetOutputSlot(1)->GetConnection(0); // Save sub-graph connections for comparison after substitution - IOutputSlot* subGraph2InputConn1 = subGraphs[1]->GetInputSlot(0)->GetConnection(); - IOutputSlot* subGraph2InputConn2 = subGraphs[1]->GetInputSlot(1)->GetConnection(); - IInputSlot* subGraph2OutputConn = subGraphs[1]->GetOutputSlot(0)->GetConnection(0); + IOutputSlot* subgraph2InputConn1 = subgraphs[1]->GetInputSlot(0)->GetConnection(); + IOutputSlot* subgraph2InputConn2 = subgraphs[1]->GetInputSlot(1)->GetConnection(); + IInputSlot* subgraph2OutputConn = subgraphs[1]->GetOutputSlot(0)->GetConnection(0); PreCompiledDescriptor preCompiledDescriptor1(numInputSlots1, numOutputSlots1); Layer* const preCompiledLayer1 = graph.AddLayer<PreCompiledLayer>(preCompiledDescriptor1, "pre-compiled1"); @@ -1026,17 +1029,17 @@ BOOST_AUTO_TEST_CASE(MultipleSubGraphs) Layer* const preCompiledLayer2 = graph.AddLayer<PreCompiledLayer>(preCompiledDescriptor2, "pre-compiled2"); // Substitute sub-graph with pre-compiled layer - graph.SubstituteSubGraph((std::move(subGraphs[0])), preCompiledLayer1); - graph.SubstituteSubGraph((std::move(subGraphs[1])), preCompiledLayer2); + graph.SubstituteSubgraph((std::move(subgraphs[0])), preCompiledLayer1); + graph.SubstituteSubgraph((std::move(subgraphs[1])), preCompiledLayer2); // Check that connections are correct after substitution - BOOST_CHECK_EQUAL(preCompiledLayer1->GetInputSlot(0).GetConnection(), subGraph1InputConn); - BOOST_CHECK_EQUAL(preCompiledLayer1->GetOutputSlot(0).GetConnection(0), subGraph1OutputConn1); - BOOST_CHECK_EQUAL(preCompiledLayer1->GetOutputSlot(1).GetConnection(0), subGraph1OutputConn2); + BOOST_CHECK_EQUAL(preCompiledLayer1->GetInputSlot(0).GetConnection(), subgraph1InputConn); + BOOST_CHECK_EQUAL(preCompiledLayer1->GetOutputSlot(0).GetConnection(0), subgraph1OutputConn1); + BOOST_CHECK_EQUAL(preCompiledLayer1->GetOutputSlot(1).GetConnection(0), subgraph1OutputConn2); - BOOST_CHECK_EQUAL(preCompiledLayer2->GetInputSlot(0).GetConnection(), subGraph2InputConn1); - BOOST_CHECK_EQUAL(preCompiledLayer2->GetInputSlot(1).GetConnection(), subGraph2InputConn2); - BOOST_CHECK_EQUAL(preCompiledLayer2->GetOutputSlot(0).GetConnection(0), subGraph2OutputConn); + BOOST_CHECK_EQUAL(preCompiledLayer2->GetInputSlot(0).GetConnection(), subgraph2InputConn1); + BOOST_CHECK_EQUAL(preCompiledLayer2->GetInputSlot(1).GetConnection(), subgraph2InputConn2); + BOOST_CHECK_EQUAL(preCompiledLayer2->GetOutputSlot(0).GetConnection(0), subgraph2OutputConn); } } } |