blob: 23f969d8eebfa5a31d31c851d6e5eaa9daaff279 [file] [log] [blame]
David Beckf98d21a2018-10-26 16:03:03 +01001//
2// Copyright © 2017 Arm Ltd. All rights reserved.
3// SPDX-License-Identifier: MIT
4//
5
Derek Lambertiff05cc52019-04-26 13:05:17 +01006#include "SubgraphView.hpp"
Matteo Martincighadddddb2019-01-24 14:06:23 +00007#include "Graph.hpp"
David Beckf98d21a2018-10-26 16:03:03 +01008
9#include <boost/numeric/conversion/cast.hpp>
10
Matteo Martincighadddddb2019-01-24 14:06:23 +000011#include <utility>
12
David Beckf98d21a2018-10-26 16:03:03 +010013namespace armnn
14{
15
Matteo Martincighadddddb2019-01-24 14:06:23 +000016namespace
David Beckf98d21a2018-10-26 16:03:03 +010017{
Matteo Martincighadddddb2019-01-24 14:06:23 +000018
19template <class C>
20void AssertIfNullsOrDuplicates(const C& container, const std::string& errorMessage)
21{
22 using T = typename C::value_type;
23 std::unordered_set<T> duplicateSet;
24 std::for_each(container.begin(), container.end(), [&duplicateSet, &errorMessage](const T& i)
25 {
26 // Ignore unused for release builds
27 boost::ignore_unused(errorMessage);
28
29 // Check if the item is valid
30 BOOST_ASSERT_MSG(i, errorMessage.c_str());
31
32 // Check if a duplicate has been found
33 BOOST_ASSERT_MSG(duplicateSet.find(i) == duplicateSet.end(), errorMessage.c_str());
34
35 duplicateSet.insert(i);
36 });
David Beckf98d21a2018-10-26 16:03:03 +010037}
38
Matteo Martincighadddddb2019-01-24 14:06:23 +000039} // anonymous namespace
40
Derek Lambertiff05cc52019-04-26 13:05:17 +010041SubgraphView::SubgraphView(Graph& graph)
Matteo Martincighadddddb2019-01-24 14:06:23 +000042 : m_InputSlots{}
43 , m_OutputSlots{}
44 , m_Layers(graph.begin(), graph.end())
45 , m_ParentGraph(&graph)
David Beckf98d21a2018-10-26 16:03:03 +010046{
Derek Lambertiff05cc52019-04-26 13:05:17 +010047 CheckSubgraph();
David Beckf98d21a2018-10-26 16:03:03 +010048}
49
Derek Lambertiff05cc52019-04-26 13:05:17 +010050SubgraphView::SubgraphView(Graph* parentGraph, InputSlots&& inputs, OutputSlots&& outputs, Layers&& layers)
Matteo Martincighadddddb2019-01-24 14:06:23 +000051 : m_InputSlots{inputs}
52 , m_OutputSlots{outputs}
53 , m_Layers{layers}
54 , m_ParentGraph(parentGraph)
55{
Derek Lambertiff05cc52019-04-26 13:05:17 +010056 CheckSubgraph();
Matteo Martincighadddddb2019-01-24 14:06:23 +000057}
58
Derek Lambertiff05cc52019-04-26 13:05:17 +010059SubgraphView::SubgraphView(const SubgraphView& referenceSubgraph,
60 InputSlots&& inputs,
61 OutputSlots&& outputs,
62 Layers&& layers)
Matteo Martincighadddddb2019-01-24 14:06:23 +000063 : m_InputSlots{inputs}
64 , m_OutputSlots{outputs}
65 , m_Layers{layers}
Derek Lambertiff05cc52019-04-26 13:05:17 +010066 , m_ParentGraph(referenceSubgraph.m_ParentGraph)
Matteo Martincighadddddb2019-01-24 14:06:23 +000067{
Derek Lambertiff05cc52019-04-26 13:05:17 +010068 CheckSubgraph();
Matteo Martincighadddddb2019-01-24 14:06:23 +000069}
70
Derek Lambertiff05cc52019-04-26 13:05:17 +010071SubgraphView::SubgraphView(const SubgraphView& subgraph)
72 : m_InputSlots(subgraph.m_InputSlots.begin(), subgraph.m_InputSlots.end())
73 , m_OutputSlots(subgraph.m_OutputSlots.begin(), subgraph.m_OutputSlots.end())
74 , m_Layers(subgraph.m_Layers.begin(), subgraph.m_Layers.end())
75 , m_ParentGraph(subgraph.m_ParentGraph)
Matteo Martincighadddddb2019-01-24 14:06:23 +000076{
Derek Lambertiff05cc52019-04-26 13:05:17 +010077 CheckSubgraph();
Matteo Martincighadddddb2019-01-24 14:06:23 +000078}
79
Derek Lambertiff05cc52019-04-26 13:05:17 +010080SubgraphView::SubgraphView(SubgraphView&& subgraph)
81 : m_InputSlots(std::move(subgraph.m_InputSlots))
82 , m_OutputSlots(std::move(subgraph.m_OutputSlots))
83 , m_Layers(std::move(subgraph.m_Layers))
84 , m_ParentGraph(std::exchange(subgraph.m_ParentGraph, nullptr))
Matteo Martincighadddddb2019-01-24 14:06:23 +000085{
Derek Lambertiff05cc52019-04-26 13:05:17 +010086 CheckSubgraph();
Matteo Martincighadddddb2019-01-24 14:06:23 +000087}
88
Derek Lambertiff05cc52019-04-26 13:05:17 +010089SubgraphView::SubgraphView(const SubgraphView& referenceSubgraph, IConnectableLayer* layer)
Matteo Martincighadddddb2019-01-24 14:06:23 +000090 : m_InputSlots{}
91 , m_OutputSlots{}
92 , m_Layers{boost::polymorphic_downcast<Layer*>(layer)}
Derek Lambertiff05cc52019-04-26 13:05:17 +010093 , m_ParentGraph(referenceSubgraph.m_ParentGraph)
Matteo Martincighadddddb2019-01-24 14:06:23 +000094{
95 unsigned int numInputSlots = layer->GetNumInputSlots();
96 m_InputSlots.resize(numInputSlots);
97 for (unsigned int i = 0; i < numInputSlots; i++)
98 {
99 m_InputSlots.at(i) = boost::polymorphic_downcast<InputSlot*>(&(layer->GetInputSlot(i)));
100 }
101
102 unsigned int numOutputSlots = layer->GetNumOutputSlots();
103 m_OutputSlots.resize(numOutputSlots);
104 for (unsigned int i = 0; i < numOutputSlots; i++)
105 {
106 m_OutputSlots.at(i) = boost::polymorphic_downcast<OutputSlot*>(&(layer->GetOutputSlot(i)));
107 }
108
Derek Lambertiff05cc52019-04-26 13:05:17 +0100109 CheckSubgraph();
Matteo Martincighadddddb2019-01-24 14:06:23 +0000110}
111
Derek Lambertiff05cc52019-04-26 13:05:17 +0100112void SubgraphView::CheckSubgraph()
Matteo Martincighadddddb2019-01-24 14:06:23 +0000113{
114 // Check that the sub-graph has a valid parent graph
115 BOOST_ASSERT_MSG(m_ParentGraph, "Sub-graphs must have a parent graph");
116
117 // Check for invalid or duplicate input slots
118 AssertIfNullsOrDuplicates(m_InputSlots, "Sub-graphs cannot contain null or duplicate input slots");
119
120 // Check for invalid or duplicate output slots
121 AssertIfNullsOrDuplicates(m_OutputSlots, "Sub-graphs cannot contain null or duplicate output slots");
122
123 // Check for invalid or duplicate layers
124 AssertIfNullsOrDuplicates(m_Layers, "Sub-graphs cannot contain null or duplicate layers");
125
126 // Check that all the layers of the sub-graph belong to the parent graph
127 std::for_each(m_Layers.begin(), m_Layers.end(), [&](const Layer* l)
128 {
129 BOOST_ASSERT_MSG(std::find(m_ParentGraph->begin(), m_ParentGraph->end(), l) != m_ParentGraph->end(),
130 "Sub-graph layer is not a member of the parent graph");
131 });
132}
133
Derek Lambertiff05cc52019-04-26 13:05:17 +0100134void SubgraphView::Update(Graph &graph)
Matteo Martincighadddddb2019-01-24 14:06:23 +0000135{
136 m_InputSlots.clear();
137 m_OutputSlots.clear();
138 m_Layers.assign(graph.begin(), graph.end());
139 m_ParentGraph = &graph;
140
Derek Lambertiff05cc52019-04-26 13:05:17 +0100141 CheckSubgraph();
Matteo Martincighadddddb2019-01-24 14:06:23 +0000142}
143
Derek Lambertiff05cc52019-04-26 13:05:17 +0100144const SubgraphView::InputSlots& SubgraphView::GetInputSlots() const
David Beckf98d21a2018-10-26 16:03:03 +0100145{
146 return m_InputSlots;
147}
148
Derek Lambertiff05cc52019-04-26 13:05:17 +0100149const SubgraphView::OutputSlots& SubgraphView::GetOutputSlots() const
David Beckf98d21a2018-10-26 16:03:03 +0100150{
151 return m_OutputSlots;
152}
153
Derek Lambertiff05cc52019-04-26 13:05:17 +0100154const InputSlot* SubgraphView::GetInputSlot(unsigned int index) const
David Beckf98d21a2018-10-26 16:03:03 +0100155{
156 return m_InputSlots.at(index);
157}
158
Derek Lambertiff05cc52019-04-26 13:05:17 +0100159InputSlot* SubgraphView::GetInputSlot(unsigned int index)
David Beckf98d21a2018-10-26 16:03:03 +0100160{
161 return m_InputSlots.at(index);
162}
163
Derek Lambertiff05cc52019-04-26 13:05:17 +0100164const OutputSlot* SubgraphView::GetOutputSlot(unsigned int index) const
David Beckf98d21a2018-10-26 16:03:03 +0100165{
166 return m_OutputSlots.at(index);
167}
168
Derek Lambertiff05cc52019-04-26 13:05:17 +0100169OutputSlot* SubgraphView::GetOutputSlot(unsigned int index)
David Beckf98d21a2018-10-26 16:03:03 +0100170{
171 return m_OutputSlots.at(index);
172}
173
Derek Lambertiff05cc52019-04-26 13:05:17 +0100174unsigned int SubgraphView::GetNumInputSlots() const
David Beckf98d21a2018-10-26 16:03:03 +0100175{
176 return boost::numeric_cast<unsigned int>(m_InputSlots.size());
177}
178
Derek Lambertiff05cc52019-04-26 13:05:17 +0100179unsigned int SubgraphView::GetNumOutputSlots() const
David Beckf98d21a2018-10-26 16:03:03 +0100180{
181 return boost::numeric_cast<unsigned int>(m_OutputSlots.size());
182}
183
Derek Lambertiff05cc52019-04-26 13:05:17 +0100184const SubgraphView::Layers & SubgraphView::GetLayers() const
David Beckf98d21a2018-10-26 16:03:03 +0100185{
186 return m_Layers;
187}
188
Derek Lambertiff05cc52019-04-26 13:05:17 +0100189SubgraphView::Layers::iterator SubgraphView::begin()
Matteo Martincigh49124022019-01-11 13:25:59 +0000190{
191 return m_Layers.begin();
192}
193
Derek Lambertiff05cc52019-04-26 13:05:17 +0100194SubgraphView::Iterator SubgraphView::end()
Matteo Martincigh49124022019-01-11 13:25:59 +0000195{
196 return m_Layers.end();
197}
198
Derek Lambertiff05cc52019-04-26 13:05:17 +0100199SubgraphView::ConstIterator SubgraphView::begin() const
Matteo Martincigh49124022019-01-11 13:25:59 +0000200{
201 return m_Layers.begin();
202}
203
Derek Lambertiff05cc52019-04-26 13:05:17 +0100204SubgraphView::ConstIterator SubgraphView::end() const
Matteo Martincigh49124022019-01-11 13:25:59 +0000205{
206 return m_Layers.end();
207}
208
Derek Lambertiff05cc52019-04-26 13:05:17 +0100209SubgraphView::ConstIterator SubgraphView::cbegin() const
Matteo Martincigh49124022019-01-11 13:25:59 +0000210{
211 return begin();
212}
213
Derek Lambertiff05cc52019-04-26 13:05:17 +0100214SubgraphView::ConstIterator SubgraphView::cend() const
Matteo Martincigh49124022019-01-11 13:25:59 +0000215{
216 return end();
217}
218
David Beckf98d21a2018-10-26 16:03:03 +0100219} // namespace armnn