ArmNN
 25.11
Loading...
Searching...
No Matches
SubgraphView.cpp
Go to the documentation of this file.
1//
2// Copyright © 2017, 2019-2024 Arm Ltd and Contributors. All rights reserved.
3// SPDX-License-Identifier: MIT
4//
5
7
8#include <Graph.hpp>
9
13
14#include <fmt/format.h>
15#include <utility>
16
17namespace armnn
18{
19
20namespace
21{
22
23template <class C>
24void AssertIfNullsOrDuplicates(const C& container, const std::string& errorMessage)
25{
26 using T = typename C::value_type;
27 std::unordered_set<T> duplicateSet;
28 std::for_each(container.begin(), container.end(), [&duplicateSet, &errorMessage](const T& i)
29 {
30 // Check if the item is valid
31 if (!i)
32 {
33 throw armnn::GraphValidationException(errorMessage.c_str());
34 }
35
36 // Check if a duplicate has been found
37 if (duplicateSet.find(i) != duplicateSet.end())
38 {
39 throw armnn::GraphValidationException(errorMessage.c_str());
40 }
41
42 duplicateSet.insert(i);
43 });
44}
45
46} // anonymous namespace
47
49 : enable_shared_from_this()
50 , m_InputSlots{}
51 , m_OutputSlots{}
52 , m_Layers(graph.begin(), graph.end())
53 , m_IConnectableLayers(graph.begin(), graph.end())
54{
55 ArrangeBySortOrder();
56 CheckSubgraph();
57}
58
59/// IConnectable Duplication to maintain backwards compatibility
60SubgraphView::SubgraphView(InputSlots&& inputs, OutputSlots&& outputs, Layers&& layers)
61 : enable_shared_from_this()
62 , m_InputSlots{InputSlots{inputs.begin(), inputs.end()}}
63 , m_IInputSlots{IInputSlots{inputs.begin(), inputs.end()}}
64 , m_OutputSlots{OutputSlots{outputs.begin(), outputs.end()}}
65 , m_IOutputSlots{IOutputSlots{outputs.begin(), outputs.end()}}
66 , m_Layers(layers)
67 , m_IConnectableLayers(IConnectableLayers{layers.begin(), layers.end()})
68{
69 ArrangeBySortOrder();
70 CheckSubgraph();
71}
72
73/// IConnectable Duplication to maintain backwards compatibility
77 : enable_shared_from_this()
78 , m_IInputSlots{inputs}
79 , m_IOutputSlots{outputs}
80 , m_IConnectableLayers(IConnectableLayers{layers.begin(), layers.end()})
81{
82 // Cast from IConnectableLayer to Layer for backward compatibility
83 auto f = [](IConnectableLayer* value)
84 {
85 return PolymorphicDowncast<Layer*>(value);
86 };
87 std::transform(layers.begin(), layers.end(), std::back_inserter(m_Layers), f);
88
89 m_InputSlots.resize(inputs.size());
90 m_IInputSlots.resize(inputs.size());
91 for (unsigned int i = 0; i < inputs.size(); i++)
92 {
93 m_InputSlots.at(i) = PolymorphicDowncast<InputSlot*>(inputs[i]);
94 m_IInputSlots.at(i) = inputs[i];
95 }
96
97 m_OutputSlots.resize(outputs.size());
98 m_IOutputSlots.resize(outputs.size());
99 for (unsigned int i = 0; i < outputs.size(); i++)
100 {
101 m_OutputSlots.at(i) = PolymorphicDowncast<OutputSlot*>(outputs[i]);
102 m_IOutputSlots.at(i) = outputs[i];
103 }
104
105 ArrangeBySortOrder();
106 CheckSubgraph();
107}
108
109/// IConnectable Duplication to maintain backwards compatibility
113 std::shared_ptr<SubgraphViewWorkingCopy> ptr)
114 : enable_shared_from_this()
115 , m_IInputSlots{inputs}
116 , m_IOutputSlots{outputs}
117 , m_IConnectableLayers(IConnectableLayers{layers.begin(), layers.end()})
118 , p_WorkingCopyImpl(std::move(ptr))
119{
120 // Cast from IConnectableLayer to Layer for backward compatibility
121 auto f = [](IConnectableLayer* value)
122 {
123 return PolymorphicDowncast<Layer*>(value);
124 };
125 std::transform(layers.begin(), layers.end(), std::back_inserter(m_Layers), f);
126
127 m_InputSlots.resize(inputs.size());
128 m_IInputSlots.resize(inputs.size());
129 for (unsigned int i = 0; i < inputs.size(); i++)
130 {
131 m_InputSlots.at(i) = PolymorphicDowncast<InputSlot*>(inputs[i]);
132 m_IInputSlots.at(i) = inputs[i];
133 }
134
135 m_OutputSlots.resize(outputs.size());
136 m_IOutputSlots.resize(outputs.size());
137 for (unsigned int i = 0; i < outputs.size(); i++)
138 {
139 m_OutputSlots.at(i) = PolymorphicDowncast<OutputSlot*>(outputs[i]);
140 m_IOutputSlots.at(i) = outputs[i];
141 }
142
143 ArrangeBySortOrder();
144 CheckSubgraph();
145}
146
148 : enable_shared_from_this()
149 , m_InputSlots(subgraph.m_InputSlots.begin(), subgraph.m_InputSlots.end())
150 , m_IInputSlots(subgraph.m_IInputSlots.begin(), subgraph.m_IInputSlots.end())
151 , m_OutputSlots(subgraph.m_OutputSlots.begin(), subgraph.m_OutputSlots.end())
152 , m_IOutputSlots(subgraph.m_IOutputSlots.begin(), subgraph.m_IOutputSlots.end())
153 , m_Layers(subgraph.m_Layers.begin(), subgraph.m_Layers.end())
154 , m_IConnectableLayers(IConnectableLayers{subgraph.m_IConnectableLayers.begin(),
155 subgraph.m_IConnectableLayers.end()})
156{
157 ArrangeBySortOrder();
158 CheckSubgraph();
159}
160
162 : enable_shared_from_this()
163 , m_InputSlots(std::move(subgraph.m_InputSlots))
164 , m_IInputSlots(std::move(subgraph.m_IInputSlots))
165 , m_OutputSlots(std::move(subgraph.m_OutputSlots))
166 , m_IOutputSlots(std::move(subgraph.m_IOutputSlots))
167 , m_Layers(std::move(subgraph.m_Layers))
168 , m_IConnectableLayers(std::move(subgraph.m_IConnectableLayers))
169{
170 ArrangeBySortOrder();
171 CheckSubgraph();
172}
173
175 : enable_shared_from_this()
176 , m_Layers{PolymorphicDowncast<Layer*>(layer)}
177 , m_IConnectableLayers{layer}
178{
179 unsigned int numInputSlots = layer->GetNumInputSlots();
180 m_InputSlots.resize(numInputSlots);
181 m_IInputSlots.resize(numInputSlots);
182 for (unsigned int i = 0; i < numInputSlots; i++)
183 {
184 m_InputSlots.at(i) = PolymorphicDowncast<InputSlot*>(&(layer->GetInputSlot(i)));
185 m_IInputSlots.at(i) = &(layer->GetInputSlot(i));
186 }
187
188 unsigned int numOutputSlots = layer->GetNumOutputSlots();
189 m_OutputSlots.resize(numOutputSlots);
190 m_IOutputSlots.resize(numOutputSlots);
191 for (unsigned int i = 0; i < numOutputSlots; i++)
192 {
193 m_OutputSlots.at(i) = PolymorphicDowncast<OutputSlot*>(&(layer->GetOutputSlot(i)));
194 m_IOutputSlots.at(i) = &(layer->GetOutputSlot(i));
195 }
196
197 CheckSubgraph();
198}
199
201{
202 m_InputSlots = std::move(other.m_InputSlots);
203 m_IInputSlots = std::move(other.m_IInputSlots);
204 m_OutputSlots = std::move(other.m_OutputSlots);
205 m_IOutputSlots = std::move(other.m_IOutputSlots);
206 m_Layers = std::move(other.m_Layers);
207 m_IConnectableLayers = std::move(other.m_IConnectableLayers);
208
209 CheckSubgraph();
210
211 return *this;
212}
213
214void SubgraphView::CheckSubgraph()
215{
216 // Check for invalid or duplicate input slots
217 AssertIfNullsOrDuplicates(m_InputSlots, "Sub-graphs cannot contain null or duplicate input slots");
218
219 // Check for invalid or duplicate output slots
220 AssertIfNullsOrDuplicates(m_OutputSlots, "Sub-graphs cannot contain null or duplicate output slots");
221
222 // Check for invalid or duplicate layers
223 AssertIfNullsOrDuplicates(m_Layers, "Sub-graphs cannot contain null or duplicate layers");
224
225 // Check for invalid or duplicate input slots
226 AssertIfNullsOrDuplicates(m_IInputSlots, "Sub-graphs cannot contain null or duplicate IInputSlots");
227
228 // Check for invalid or duplicate output slots
229 AssertIfNullsOrDuplicates(m_IOutputSlots, "Sub-graphs cannot contain null or duplicate IOutputSlots");
230
231 // Check for invalid or duplicate layers
232 AssertIfNullsOrDuplicates(m_IConnectableLayers,
233 "Sub-graphs cannot contain null or duplicate IConnectableLayers");
234}
235
237{
238 return m_IInputSlots;
239}
240
242{
243 return m_IOutputSlots;
244}
245
246const IInputSlot* SubgraphView::GetIInputSlot(unsigned int index) const
247{
248 return m_IInputSlots.at(index);
249}
250
252{
253 return m_IInputSlots.at(index);
254}
255
256const IOutputSlot* SubgraphView::GetIOutputSlot(unsigned int index) const
257{
258 return m_IOutputSlots.at(index);
259}
260
262{
263 return m_OutputSlots.at(index);
264}
265
267{
268 return m_IOutputSlots.at(index);
269}
270
272{
273 return armnn::numeric_cast<unsigned int>(m_IInputSlots.size());
274}
275
277{
278 return armnn::numeric_cast<unsigned int>(m_IOutputSlots.size());
279}
280
282{
283 return m_IConnectableLayers;
284}
285
287{
288 return m_IConnectableLayers.begin();
289}
290
292{
293 return m_IConnectableLayers.end();
294}
295
296// IConnectable Duplication to maintain backwards compatibility
297SubgraphView::IConnectableLayerIterator SubgraphView::beginIConnectable()
298{
299 return m_IConnectableLayers.begin();
300}
301
302SubgraphView::IConnectableLayerIterator SubgraphView::endIConnectable()
303{
304 return m_IConnectableLayers.end();
305}
306
308{
309 return m_IConnectableLayers.begin();
310}
311
313{
314 return m_IConnectableLayers.end();
315}
316
317// IConnectable Duplication to maintain backwards compatibility
318SubgraphView::ConstIConnectableIterator SubgraphView::beginIConnectable() const
319{
320 return m_IConnectableLayers.begin();
321}
322
323SubgraphView::ConstIConnectableIterator SubgraphView::endIConnectable() const
324{
325 return m_IConnectableLayers.end();
326}
327
332
337
338// IConnectable Duplication to maintain backwards compatibility
339SubgraphView::ConstIConnectableIterator SubgraphView::cbeginIConnectable() const
340{
341 return begin();
342}
343
344SubgraphView::ConstIConnectableIterator SubgraphView::cendIConnectable() const
345{
346 return end();
347}
348
350{
351 m_InputSlots.clear();
352 m_OutputSlots.clear();
353 m_Layers.clear();
354
355 m_IInputSlots.clear();
356 m_IOutputSlots.clear();
357 m_IConnectableLayers.clear();
358}
359
360void SubgraphView::ArrangeBySortOrder()
361{
362 using LayerList = std::list<Layer*>;
363 auto compareLayerPriority = [](const LayerList::value_type& layerA, const LayerList::value_type& layerB)
364 {
365 return layerA->GetPriority() < layerB->GetPriority();
366 };
367
368 m_Layers.sort(compareLayerPriority);
369
370 using IConnectableLayersList = std::list<IConnectableLayer*>;
371 auto compareIConnectableLayerPriority = [](const IConnectableLayersList::value_type& layerA,
372 const IConnectableLayersList::value_type& layerB)
373 {
374 return PolymorphicDowncast<Layer*>(layerA)->GetPriority() <
375 PolymorphicDowncast<Layer*>(layerB)->GetPriority();
376 };
377
378 m_IConnectableLayers.sort(compareIConnectableLayerPriority);
379}
380
381struct SubgraphView::SubgraphViewWorkingCopy
382{
383public:
384
385 SubgraphViewWorkingCopy() = default;
386 SubgraphViewWorkingCopy(Graph graph, std::shared_ptr<const SubgraphView> originalSubgraphView)
387 : m_Graph(graph)
388 , m_OriginalSubgraphView(originalSubgraphView)
389 {};
390
391 Graph m_Graph;
392 std::shared_ptr<const SubgraphView> m_OriginalSubgraphView;
393
394};
395
397{
398 if (p_WorkingCopyImpl)
399 {
400 throw Exception("The SubgraphView calling GetWorkingCopy() is already a working copy. This function "
401 "should be called on original SubgraphView obtained from OptimizeSubgraphView()");
402 }
403
404 // Create a cut down SubgraphView with underlying graph containing only the relevant layers.
405 // It needs its own underlying layers so that they can be replaced safely.
406 auto ptr = std::make_shared<SubgraphViewWorkingCopy>(Graph(), shared_from_this());
407
408 std::unordered_map<const IConnectableLayer*, IConnectableLayer*> originalToClonedLayerMap;
409 std::list<armnn::IConnectableLayer*> originalSubgraphLayers = GetIConnectableLayers();
410
411 for (auto&& originalLayer : originalSubgraphLayers)
412 {
413 Layer* const layer = PolymorphicDowncast<const Layer*>(originalLayer)->Clone(ptr->m_Graph);
414 originalToClonedLayerMap.emplace(originalLayer, layer);
415 }
416
417 SubgraphView::IInputSlots workingCopyInputs;
418 // Add IInputSlots to workingCopy
419 for (auto originalSubgraphInputSlot : GetIInputSlots())
420 {
421 const IConnectableLayer& originalSubgraphLayer =
422 PolymorphicDowncast<InputSlot*>(originalSubgraphInputSlot)->GetOwningLayer();
423
424 auto* clonedLayer = originalToClonedLayerMap[&originalSubgraphLayer];
425
426 workingCopyInputs.push_back(&clonedLayer->GetInputSlot(originalSubgraphInputSlot->GetSlotIndex()));
427 }
428
429 for (auto originalSubgraphLayer : originalSubgraphLayers)
430 {
431 IConnectableLayer* const clonedLayer = originalToClonedLayerMap[originalSubgraphLayer];
432
433 // OutputLayers have no OutputSlots to be connected
434 if (clonedLayer->GetType() != LayerType::Output)
435 {
436 // connect all cloned layers as per original subgraph
437 for (unsigned int i = 0; i < clonedLayer->GetNumOutputSlots(); i++)
438 {
439 auto& originalOutputSlot = originalSubgraphLayer->GetOutputSlot(i);
440 auto& clonedOutputSlot = clonedLayer->GetOutputSlot(i);
441 for (unsigned int j = 0; j < originalOutputSlot.GetNumConnections(); j++)
442 {
443 // nextLayer is the layer with IInputSlot connected to IOutputSlot we are working on
444 const IConnectableLayer& nextLayerOnOriginalSubgraph =
445 originalOutputSlot.GetConnection(j)->GetOwningIConnectableLayer();
446
447 // Check the layer is in our map and so has a clonedLayer
448 if (originalToClonedLayerMap.find(&nextLayerOnOriginalSubgraph) != originalToClonedLayerMap.end())
449 {
450 auto* nextLayerOnClonedSubgraph = originalToClonedLayerMap[&nextLayerOnOriginalSubgraph];
451
453 &originalOutputSlot)->GetConnection(j)->GetSlotIndex();
454
455 IInputSlot& inputSlot = nextLayerOnClonedSubgraph->GetInputSlot(index);
456
457 // Then make the connection
458 clonedOutputSlot.Connect(inputSlot);
459 }
460 }
461 // Copy the tensorInfo to the clonedOutputSlot
462 clonedOutputSlot.SetTensorInfo(originalOutputSlot.GetTensorInfo());
463 }
464 }
465 }
466
467 SubgraphView::IOutputSlots workingCopyOutputs;
468
469 // Add IOutputSlots to workingCopy
470 for (auto outputSlot : GetIOutputSlots())
471 {
472 auto outputSlotIndex = outputSlot->CalculateIndexOnOwner();
473 const IConnectableLayer& originalSubgraphLayer = outputSlot->GetOwningIConnectableLayer();
474
475 // OutputLayers have no OutputSlots to be connected
476 if (originalSubgraphLayer.GetType() != LayerType::Output)
477 {
478 IConnectableLayer* clonedLayer = originalToClonedLayerMap[&originalSubgraphLayer];
479
480 // Add the OutputSlot of clonedLayer to WorkingCopy OutputSlots
481 workingCopyOutputs.push_back(&clonedLayer->GetOutputSlot(outputSlotIndex));
482 }
483 }
484
485 SubgraphView::IConnectableLayers workingCopyLayers;
486 for (auto& pair : originalToClonedLayerMap)
487 {
488 workingCopyLayers.push_back(pair.second);
489 }
490
491 return {std::move(workingCopyLayers),
492 std::move(workingCopyInputs),
493 std::move(workingCopyOutputs),
494 ptr};
495}
496
498{
499 ARMNN_THROW_INVALIDARG_MSG_IF_FALSE(substituteLayer, "substituteLayer should not be null");
500
501 SubgraphView substituteSubgraph(substituteLayer);
502
503 SubstituteSubgraph(subgraph, substituteSubgraph);
504}
505
506void SubgraphView::UpdateSubgraphViewSlotPointers(SubgraphView& patternSubgraph,
507 const SubgraphView& substituteSubgraph)
508{
509 std::vector<IInputSlot*>::iterator inputSlotPosition;
510 // search for and erase any InputSlots that appear in the WorkingCopy that match those in the PatternSubgraph
511 for (unsigned long idx = 0; idx < patternSubgraph.GetIInputSlots().size(); idx++)
512 {
513 IInputSlot *slot = patternSubgraph.GetIInputSlots()[idx];
514 inputSlotPosition = std::find(m_IInputSlots.begin(), m_IInputSlots.end(), slot);
515 if (inputSlotPosition != m_IInputSlots.end())
516 {
517 m_IInputSlots.erase(inputSlotPosition);
518
519 // while here, with correct position, add in replacement InputSlot from the substituteSubgraph
520 m_IInputSlots.insert(inputSlotPosition, substituteSubgraph.GetIInputSlots()[idx]);
521 }
522 }
523
524 std::vector<IOutputSlot*>::iterator outputSlotPosition;
525 // search for and erase any OutputSlots that appear in the WorkingCopy that match those in the PatternSubgraph
526 for (unsigned long idx = 0; idx < patternSubgraph.GetIOutputSlots().size(); idx++)
527 {
528 IOutputSlot *slot = patternSubgraph.GetIOutputSlots()[idx];
529 outputSlotPosition = std::find(m_IOutputSlots.begin(), m_IOutputSlots.end(), slot);
530 if (outputSlotPosition != m_IOutputSlots.end())
531 {
532 m_IOutputSlots.erase(outputSlotPosition);
533
534 // while here, with correct position, add in replacement OutputSlot from the substituteSubgraph
535 m_IOutputSlots.insert(outputSlotPosition, substituteSubgraph.GetIOutputSlots()[idx]);
536 }
537 }
538}
539
540void SubgraphView::SubstituteSubgraph(SubgraphView& patternSubgraph, const SubgraphView& substituteSubgraph)
541{
542 if (!p_WorkingCopyImpl)
543 {
544 throw NullPointerException("The SubgraphView calling SubstituteSubgraphView is not a working copy. "
545 "Call this function on SubgraphView returned from SubgraphView::GetWorkingCopy()");
546 }
547
548 auto numPatternInputs = patternSubgraph.GetIInputSlots().size();
549 auto numSubInputs = substituteSubgraph.GetIInputSlots().size();
550 if (numPatternInputs != numSubInputs)
551 {
553 fmt::format("Number of InputSlots on substitute SubgraphView ({}) must equal the number of"
554 " InputSlots on pattern SubgraphView ({})",
555 numSubInputs,
556 numPatternInputs));
557 }
558
559 auto numPatternOutputs = patternSubgraph.GetIOutputSlots().size();
560 auto numSubOutputs = substituteSubgraph.GetIOutputSlots().size();
561 if (numPatternOutputs != numSubOutputs)
562 {
564 fmt::format("Number of OutputSlots on substitute SubgraphView ({}) must equal the number of"
565 " OutputSlots on pattern SubgraphView ({})",
566 numSubOutputs,
567 numPatternOutputs));
568 }
569
570 // Add substitute layer to the Main graph i.e. graph in p_WorkingCopyImpl
571 auto workingCopyGraph = &p_WorkingCopyImpl->m_Graph;
572 substituteSubgraph.ForEachIConnectableLayer([workingCopyGraph](IConnectableLayer* iConnectableLayer)
573 {
574 // Search WorkingCopy Graph for substituteLayer and add if missing
575 if (std::find(std::begin(workingCopyGraph->m_Layers),
576 std::end(workingCopyGraph->m_Layers),
577 iConnectableLayer) ==
578 std::end(workingCopyGraph->m_Layers))
579 {
580 auto layer = PolymorphicDowncast<Layer*>(iConnectableLayer);
581
582 layer->Reparent(*workingCopyGraph,
583 (workingCopyGraph->m_Layers).end());
584
585 workingCopyGraph->m_LayersInOrder = false;
586 }
587 });
588
589 // Replace the old connections with connections to new layer
590 workingCopyGraph->ReplaceSubgraphConnections(patternSubgraph, substituteSubgraph);
591
592 // Update input/outputSlot pointers
593 UpdateSubgraphViewSlotPointers(patternSubgraph, substituteSubgraph);
594
595 // Delete the old layers.
596 workingCopyGraph->EraseSubgraphLayers(patternSubgraph);
597
598 // Sort
599 workingCopyGraph->TopologicalSort();
600
601 // Update SubgraphView layer pointers to match those of the internal WorkingCopy layer pointers
602 m_IConnectableLayers = IConnectableLayers{ workingCopyGraph->m_Layers.begin(),
603 workingCopyGraph->m_Layers.end() };
604}
605
607{
608 if (!p_WorkingCopyImpl)
609 {
610 throw NullPointerException("The SubgraphView calling GetOriginalInputSlots is not a working copy. "
611 "Call this function on SubgraphView returned from SubgraphView::GetWorkingCopy()");
612 }
613 if (!p_WorkingCopyImpl->m_OriginalSubgraphView)
614 {
615 throw NullPointerException("The working copy SubgraphView pointer to its original SubgraphView is null.");
616 }
617 return p_WorkingCopyImpl->m_OriginalSubgraphView->GetIInputSlots();
618}
620{
621 if (!p_WorkingCopyImpl)
622 {
623 throw NullPointerException("The SubgraphView calling GetOriginalOutputSlots is not a working copy. "
624 "Call this function on SubgraphView returned from SubgraphView::GetWorkingCopy()");
625 }
626 if (!p_WorkingCopyImpl->m_OriginalSubgraphView)
627 {
628 throw NullPointerException("The working copy SubgraphView pointer to its original SubgraphView is null.");
629 }
630 return p_WorkingCopyImpl->m_OriginalSubgraphView->GetIOutputSlots();
631}
632
633
634} // namespace armnn
#define ARMNN_THROW_INVALIDARG_MSG_IF_FALSE(_cond, _str)
Base class for all ArmNN exceptions so that users can filter to just those.
Interface for a layer that is connectable to other layers via InputSlots and OutputSlots.
Definition INetwork.hpp:81
virtual const IInputSlot & GetInputSlot(unsigned int index) const =0
Get a const input slot handle by slot index.
virtual const IOutputSlot & GetOutputSlot(unsigned int index) const =0
Get the const output slot handle by slot index.
virtual unsigned int GetNumInputSlots() const =0
Returns the number of connectable input slots.
virtual unsigned int GetNumOutputSlots() const =0
Returns the number of connectable output slots.
virtual LayerType GetType() const =0
Returns the armnn::LayerType of this layer.
An input connection slot for a layer.
Definition INetwork.hpp:26
An output connection slot for a layer.
Definition INetwork.hpp:54
virtual void SetTensorInfo(const TensorInfo &tensorInfo)=0
virtual Layer * Clone(Graph &graph) const =0
Creates a dynamically-allocated copy of this layer.
The SubgraphView class represents a subgraph of a Graph.
OutputSlot * GetOutputSlot(unsigned int index)
const IOutputSlots & GetOriginalOutputSlots() const
IConnectableLayers::iterator IConnectableLayerIterator
IConnectableLayers::const_iterator ConstIConnectableIterator
IConnectableLayerIterator begin()
OutputSlots && outputs
std::vector< IOutputSlot * > IOutputSlots
SubgraphView(Graph &graph)
Constructs a sub-graph from the entire given graph.
ConstIConnectableIterator cend() const
std::vector< IInputSlot * > IInputSlots
unsigned int GetNumOutputSlots() const
SubgraphView GetWorkingCopy() const
This method returns a copy of the original SubgraphView provided by OptimizeSubgraphView with a separ...
OutputSlots Layers && layers
unsigned int GetNumInputSlots() const
ConstIConnectableIterator cbegin() const
const IInputSlot * GetIInputSlot(unsigned int index) const
const IConnectableLayers & GetIConnectableLayers() const
void ForEachIConnectableLayer(Func func) const
const IOutputSlot * GetIOutputSlot(unsigned int index) const
const IInputSlots & GetOriginalInputSlots() const
These methods should be called on a working copy subgraph created from GetWorkingCopy.
SubgraphView & operator=(SubgraphView &&other)
Move-assignment operator.
std::list< IConnectableLayer * > IConnectableLayers
const IInputSlots & GetIInputSlots() const
const IOutputSlots & GetIOutputSlots() const
void SubstituteSubgraph(SubgraphView &, IConnectableLayer *)
These methods should be called on a working copy subgraph created from GetWorkingCopy.
IConnectableLayerIterator end()
Copyright (c) 2021 ARM Limited and Contributors.
std::enable_if_t< std::is_unsigned< Source >::value &&std::is_unsigned< Dest >::value, Dest > numeric_cast(Source source)
DestType PolymorphicDowncast(SourceType *value)
Polymorphic downcast for build in pointers only.