blob: 0d41889e150320cad716f884567f91c30710446b [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
Jan Eilers8eb25602020-03-09 12:13:48 +00009#include <armnn/utility/IgnoreUnused.hpp>
Matthew Sloyan0663d662020-09-14 11:47:26 +010010#include <armnn/utility/NumericCast.hpp>
Jan Eilersbb446e52020-04-02 13:56:54 +010011#include <armnn/utility/PolymorphicDowncast.hpp>
David Beckf98d21a2018-10-26 16:03:03 +010012
Matteo Martincighadddddb2019-01-24 14:06:23 +000013#include <utility>
14
David Beckf98d21a2018-10-26 16:03:03 +010015namespace armnn
16{
17
Matteo Martincighadddddb2019-01-24 14:06:23 +000018namespace
David Beckf98d21a2018-10-26 16:03:03 +010019{
Matteo Martincighadddddb2019-01-24 14:06:23 +000020
21template <class C>
22void AssertIfNullsOrDuplicates(const C& container, const std::string& errorMessage)
23{
24 using T = typename C::value_type;
25 std::unordered_set<T> duplicateSet;
26 std::for_each(container.begin(), container.end(), [&duplicateSet, &errorMessage](const T& i)
27 {
28 // Ignore unused for release builds
Jan Eilers8eb25602020-03-09 12:13:48 +000029 IgnoreUnused(errorMessage);
Matteo Martincighadddddb2019-01-24 14:06:23 +000030
31 // Check if the item is valid
Narumol Prangnawaratac2770a2020-04-01 16:51:23 +010032 ARMNN_ASSERT_MSG(i, errorMessage.c_str());
Matteo Martincighadddddb2019-01-24 14:06:23 +000033
34 // Check if a duplicate has been found
Narumol Prangnawaratac2770a2020-04-01 16:51:23 +010035 ARMNN_ASSERT_MSG(duplicateSet.find(i) == duplicateSet.end(), errorMessage.c_str());
Matteo Martincighadddddb2019-01-24 14:06:23 +000036
37 duplicateSet.insert(i);
38 });
David Beckf98d21a2018-10-26 16:03:03 +010039}
40
Matteo Martincighadddddb2019-01-24 14:06:23 +000041} // anonymous namespace
42
Derek Lambertiff05cc52019-04-26 13:05:17 +010043SubgraphView::SubgraphView(Graph& graph)
Matteo Martincighadddddb2019-01-24 14:06:23 +000044 : m_InputSlots{}
45 , m_OutputSlots{}
46 , m_Layers(graph.begin(), graph.end())
David Beckf98d21a2018-10-26 16:03:03 +010047{
Derek Lamberti161d29c2020-12-07 13:54:12 +000048 ArrangeBySortOrder();
Derek Lambertiff05cc52019-04-26 13:05:17 +010049 CheckSubgraph();
David Beckf98d21a2018-10-26 16:03:03 +010050}
51
Matteo Martincigh602af092019-05-01 10:31:27 +010052SubgraphView::SubgraphView(InputSlots&& inputs, OutputSlots&& outputs, Layers&& layers)
Matteo Martincighadddddb2019-01-24 14:06:23 +000053 : m_InputSlots{inputs}
54 , m_OutputSlots{outputs}
55 , m_Layers{layers}
Matteo Martincighadddddb2019-01-24 14:06:23 +000056{
Derek Lamberti161d29c2020-12-07 13:54:12 +000057 ArrangeBySortOrder();
Derek Lambertiff05cc52019-04-26 13:05:17 +010058 CheckSubgraph();
Matteo Martincighadddddb2019-01-24 14:06:23 +000059}
60
Derek Lambertiff05cc52019-04-26 13:05:17 +010061SubgraphView::SubgraphView(const SubgraphView& subgraph)
62 : m_InputSlots(subgraph.m_InputSlots.begin(), subgraph.m_InputSlots.end())
63 , m_OutputSlots(subgraph.m_OutputSlots.begin(), subgraph.m_OutputSlots.end())
64 , m_Layers(subgraph.m_Layers.begin(), subgraph.m_Layers.end())
Matteo Martincighadddddb2019-01-24 14:06:23 +000065{
Derek Lamberti161d29c2020-12-07 13:54:12 +000066 ArrangeBySortOrder();
Derek Lambertiff05cc52019-04-26 13:05:17 +010067 CheckSubgraph();
Matteo Martincighadddddb2019-01-24 14:06:23 +000068}
69
Derek Lambertiff05cc52019-04-26 13:05:17 +010070SubgraphView::SubgraphView(SubgraphView&& subgraph)
71 : m_InputSlots(std::move(subgraph.m_InputSlots))
72 , m_OutputSlots(std::move(subgraph.m_OutputSlots))
73 , m_Layers(std::move(subgraph.m_Layers))
Matteo Martincighadddddb2019-01-24 14:06:23 +000074{
Derek Lamberti161d29c2020-12-07 13:54:12 +000075 ArrangeBySortOrder();
Derek Lambertiff05cc52019-04-26 13:05:17 +010076 CheckSubgraph();
Matteo Martincighadddddb2019-01-24 14:06:23 +000077}
78
Matteo Martincigh602af092019-05-01 10:31:27 +010079SubgraphView::SubgraphView(IConnectableLayer* layer)
Matteo Martincighadddddb2019-01-24 14:06:23 +000080 : m_InputSlots{}
81 , m_OutputSlots{}
Jan Eilersbb446e52020-04-02 13:56:54 +010082 , m_Layers{PolymorphicDowncast<Layer*>(layer)}
Matteo Martincighadddddb2019-01-24 14:06:23 +000083{
84 unsigned int numInputSlots = layer->GetNumInputSlots();
85 m_InputSlots.resize(numInputSlots);
86 for (unsigned int i = 0; i < numInputSlots; i++)
87 {
Jan Eilersbb446e52020-04-02 13:56:54 +010088 m_InputSlots.at(i) = PolymorphicDowncast<InputSlot*>(&(layer->GetInputSlot(i)));
Matteo Martincighadddddb2019-01-24 14:06:23 +000089 }
90
91 unsigned int numOutputSlots = layer->GetNumOutputSlots();
92 m_OutputSlots.resize(numOutputSlots);
93 for (unsigned int i = 0; i < numOutputSlots; i++)
94 {
Jan Eilersbb446e52020-04-02 13:56:54 +010095 m_OutputSlots.at(i) = PolymorphicDowncast<OutputSlot*>(&(layer->GetOutputSlot(i)));
Matteo Martincighadddddb2019-01-24 14:06:23 +000096 }
97
Derek Lambertiff05cc52019-04-26 13:05:17 +010098 CheckSubgraph();
Matteo Martincighadddddb2019-01-24 14:06:23 +000099}
100
Derek Lambertic2fe5fb2019-05-08 10:23:08 +0100101SubgraphView& SubgraphView::operator=(SubgraphView&& other)
102{
103 m_InputSlots = std::move(other.m_InputSlots);
104 m_OutputSlots = std::move(other.m_OutputSlots);
105 m_Layers = std::move(other.m_Layers);
106
107 CheckSubgraph();
108
109 return *this;
110}
111
Derek Lambertiff05cc52019-04-26 13:05:17 +0100112void SubgraphView::CheckSubgraph()
Matteo Martincighadddddb2019-01-24 14:06:23 +0000113{
Matteo Martincighadddddb2019-01-24 14:06:23 +0000114 // Check for invalid or duplicate input slots
115 AssertIfNullsOrDuplicates(m_InputSlots, "Sub-graphs cannot contain null or duplicate input slots");
116
117 // Check for invalid or duplicate output slots
118 AssertIfNullsOrDuplicates(m_OutputSlots, "Sub-graphs cannot contain null or duplicate output slots");
119
120 // Check for invalid or duplicate layers
121 AssertIfNullsOrDuplicates(m_Layers, "Sub-graphs cannot contain null or duplicate layers");
Matteo Martincighadddddb2019-01-24 14:06:23 +0000122}
123
Derek Lambertiff05cc52019-04-26 13:05:17 +0100124const SubgraphView::InputSlots& SubgraphView::GetInputSlots() const
David Beckf98d21a2018-10-26 16:03:03 +0100125{
126 return m_InputSlots;
127}
128
Derek Lambertiff05cc52019-04-26 13:05:17 +0100129const SubgraphView::OutputSlots& SubgraphView::GetOutputSlots() const
David Beckf98d21a2018-10-26 16:03:03 +0100130{
131 return m_OutputSlots;
132}
133
Derek Lambertiff05cc52019-04-26 13:05:17 +0100134const InputSlot* SubgraphView::GetInputSlot(unsigned int index) const
David Beckf98d21a2018-10-26 16:03:03 +0100135{
136 return m_InputSlots.at(index);
137}
138
Derek Lambertiff05cc52019-04-26 13:05:17 +0100139InputSlot* SubgraphView::GetInputSlot(unsigned int index)
David Beckf98d21a2018-10-26 16:03:03 +0100140{
Matteo Martincigh602af092019-05-01 10:31:27 +0100141 return m_InputSlots.at(index);
David Beckf98d21a2018-10-26 16:03:03 +0100142}
143
Derek Lambertiff05cc52019-04-26 13:05:17 +0100144const OutputSlot* SubgraphView::GetOutputSlot(unsigned int index) const
David Beckf98d21a2018-10-26 16:03:03 +0100145{
146 return m_OutputSlots.at(index);
147}
148
Derek Lambertiff05cc52019-04-26 13:05:17 +0100149OutputSlot* SubgraphView::GetOutputSlot(unsigned int index)
David Beckf98d21a2018-10-26 16:03:03 +0100150{
151 return m_OutputSlots.at(index);
152}
153
Derek Lambertiff05cc52019-04-26 13:05:17 +0100154unsigned int SubgraphView::GetNumInputSlots() const
David Beckf98d21a2018-10-26 16:03:03 +0100155{
Matthew Sloyan0663d662020-09-14 11:47:26 +0100156 return armnn::numeric_cast<unsigned int>(m_InputSlots.size());
David Beckf98d21a2018-10-26 16:03:03 +0100157}
158
Derek Lambertiff05cc52019-04-26 13:05:17 +0100159unsigned int SubgraphView::GetNumOutputSlots() const
David Beckf98d21a2018-10-26 16:03:03 +0100160{
Matthew Sloyan0663d662020-09-14 11:47:26 +0100161 return armnn::numeric_cast<unsigned int>(m_OutputSlots.size());
David Beckf98d21a2018-10-26 16:03:03 +0100162}
163
Matteo Martincigh602af092019-05-01 10:31:27 +0100164const SubgraphView::Layers& SubgraphView::GetLayers() const
David Beckf98d21a2018-10-26 16:03:03 +0100165{
166 return m_Layers;
167}
168
Matteo Martincigh602af092019-05-01 10:31:27 +0100169SubgraphView::Iterator SubgraphView::begin()
Matteo Martincigh49124022019-01-11 13:25:59 +0000170{
171 return m_Layers.begin();
172}
173
Derek Lambertiff05cc52019-04-26 13:05:17 +0100174SubgraphView::Iterator SubgraphView::end()
Matteo Martincigh49124022019-01-11 13:25:59 +0000175{
176 return m_Layers.end();
177}
178
Derek Lambertiff05cc52019-04-26 13:05:17 +0100179SubgraphView::ConstIterator SubgraphView::begin() const
Matteo Martincigh49124022019-01-11 13:25:59 +0000180{
181 return m_Layers.begin();
182}
183
Derek Lambertiff05cc52019-04-26 13:05:17 +0100184SubgraphView::ConstIterator SubgraphView::end() const
Matteo Martincigh49124022019-01-11 13:25:59 +0000185{
186 return m_Layers.end();
187}
188
Derek Lambertiff05cc52019-04-26 13:05:17 +0100189SubgraphView::ConstIterator SubgraphView::cbegin() const
Matteo Martincigh49124022019-01-11 13:25:59 +0000190{
191 return begin();
192}
193
Derek Lambertiff05cc52019-04-26 13:05:17 +0100194SubgraphView::ConstIterator SubgraphView::cend() const
Matteo Martincigh49124022019-01-11 13:25:59 +0000195{
196 return end();
197}
198
Derek Lambertic2fe5fb2019-05-08 10:23:08 +0100199void SubgraphView::Clear()
200{
201 m_InputSlots.clear();
202 m_OutputSlots.clear();
203 m_Layers.clear();
204}
205
Derek Lamberti161d29c2020-12-07 13:54:12 +0000206void SubgraphView::ArrangeBySortOrder()
207{
208 using LayerList = std::list<Layer*>;
209 auto compareLayerPriority = [](const LayerList::value_type& layerA, const LayerList::value_type& layerB)
210 {
211 return layerA->GetPriority() < layerB->GetPriority();
212 };
213
214 m_Layers.sort(compareLayerPriority);
215}
216
David Beckf98d21a2018-10-26 16:03:03 +0100217} // namespace armnn