21 #include <unordered_map>
22 #include <unordered_set>
33 template <
typename LayerType>
36 return PolymorphicDowncast<LayerType*>(layer);
39 template <
typename Func>
42 for (
auto it = m_Layers.begin(); it != m_Layers.end(); )
44 auto next = std::next(it);
67 return {
m_Graph.m_Layers.begin(), &(PtrCast<const InputLayer>) };
73 &(PtrCast<const InputLayer>) };
87 &(PtrCast<const OutputLayer>) };
92 return {
m_Graph.m_Layers.end(), &(PtrCast<const OutputLayer>) };
98 Graph(
bool shapeInferenceMethod =
false,
bool allowExpandedDims =
false)
99 : m_LayersInOrder(true)
100 , m_AllowExpandedDims(allowExpandedDims)
112 *
this = std::move(other);
117 m_InputIds = std::move(other.m_InputIds);
118 m_OutputIds = std::move(other.m_OutputIds);
119 m_LayersInOrder = std::move(other.m_LayersInOrder);
120 m_Views = std::move(other.m_Views);
121 m_Profiler = std::move(other.m_Profiler);
122 m_AllowExpandedDims = other.m_AllowExpandedDims;
123 m_ShapeInferenceMethod = other.m_ShapeInferenceMethod;
124 other.ForEachLayer([
this](
Layer* otherLayer)
126 otherLayer->
Reparent(*
this, m_Layers.end());
129 if (!other.m_PosInGraphMap.empty())
134 if (!other.m_Layers.empty())
155 template <
typename LayerT,
typename... Args>
160 template <
typename LayerT,
typename... Args>
164 template <
typename LayerT,
typename... Args>
172 template <
typename LayerT>
227 m_Views[notifyOnEvent].emplace_back(observable);
231 m_Views[notifyOnEvent].remove(observable);
237 const std::shared_ptr<IProfiler>&
GetProfiler()
const;
242 template <
typename LayerT>
243 class LayerInGraphBase;
245 template <
typename LayerT>
258 while ((it != m_Layers.end()) &&
268 while ((it != m_Layers.begin()) && ((*std::prev(it))->GetType() ==
LayerType::Output))
275 void NotifyObservables(
GraphEvent event, Layer* graphState)
278 for (
auto& observable : m_Views[event])
280 observable->Update(graphState);
284 std::unordered_set<LayerBindingId> m_InputIds;
285 std::unordered_set<LayerBindingId> m_OutputIds;
286 std::unordered_map<const Layer*, Iterator> m_PosInGraphMap;
293 mutable bool m_LayersInOrder;
295 bool m_AllowExpandedDims;
297 std::map<const GraphEvent, std::list<IGraphObservable*>> m_Views;
300 std::shared_ptr<IProfiler> m_Profiler;
304 void ConstructErrorMessageForUnconnectedInputs(Layer*
const layer,
305 unsigned int slotIndex);
311 template <
typename LayerT>
312 class Graph::LayerInGraphBase :
public LayerT
315 template <
typename... Args>
316 LayerInGraphBase(
Graph& graph,
Iterator insertBefore, Args&&... args)
317 : LayerT(
std::forward<Args>(args)...), m_Graph(&graph)
319 Insert(*m_Graph, insertBefore);
326 void Reparent(
Graph& destGraph,
Iterator insertBefore)
override
328 Insert(destGraph, insertBefore);
331 m_Graph = &destGraph;
337 graph.m_PosInGraphMap.emplace(
this, graph.m_Layers.emplace(insertBefore,
this));
340 void Remove(
Graph& graph)
342 auto layerIt = graph.GetPosInGraph(*
this);
343 graph.m_Layers.erase(layerIt);
345 const size_t numErased = graph.m_PosInGraphMap.erase(
this);
357 template <
typename LayerT>
358 class Graph::LayerInGraph final :
public LayerInGraphBase<LayerT>
361 template <
typename... Args>
362 LayerInGraph(
Graph& graph, Args&&... args)
363 : LayerInGraphBase<LayerT>(graph,
366 std::forward<Args>(args)...)
369 template <
typename... Args>
370 LayerInGraph(
Graph& graph,
Iterator insertBefore, Args&&... args)
371 : LayerInGraphBase<LayerT>(graph,
373 graph.ForwardToEndOfInputsAndConstants(graph.RewindToBeginOfOutputs(insertBefore)),
374 std::forward<Args>(args)...)
380 class Graph::LayerInGraph<
ConstantLayer> final :
public LayerInGraphBase<ConstantLayer>
383 template <
typename... Args>
388 std::forward<Args>(args)...)
390 template <
typename... Args>
393 : LayerInGraph(graph,
std::forward<Args>(args)...)
401 class Graph::LayerInGraph<
InputLayer> final :
public LayerInGraphBase<InputLayer>
404 template <
typename... Args>
409 std::forward<Args>(args)...)
411 const bool isNewId = m_Graph->m_InputIds.emplace(GetBindingId()).second;
417 template <
typename... Args>
420 : LayerInGraph(graph,
std::forward<Args>(args)...)
425 const size_t numErased = m_Graph->m_InputIds.erase(GetBindingId());
432 class Graph::LayerInGraph<
OutputLayer> final :
public LayerInGraphBase<OutputLayer>
435 template <
typename... Args>
440 std::forward<Args>(args)...)
442 const bool isNewId = m_Graph->m_OutputIds.emplace(GetBindingId()).second;
450 const size_t numErased = m_Graph->m_OutputIds.erase(GetBindingId());
457 auto it = m_PosInGraphMap.find(&layer);
458 if (it == m_PosInGraphMap.end())
465 template <
typename LayerT,
typename... Args>
468 m_LayersInOrder = m_LayersInOrder &&
470 LayerT*
const layer =
new LayerInGraph<LayerT>(*
this, std::forward<Args>(args)...);
472 layer->SetShapeInferenceMethod(m_ShapeInferenceMethod);
473 layer->SetAllowExpandedDims(m_AllowExpandedDims);
480 template <
typename LayerT,
typename... Args>
485 const Iterator pos = (parentOut !=
nullptr)
488 LayerT*
const layer =
new LayerInGraph<LayerT>(*
this, pos, std::forward<Args>(args)...);
489 insertBefore.
Insert(*layer);
496 template <
typename LayerT,
typename... Args>
502 LayerT*
const layer =
new LayerInGraph<LayerT>(*
this, pos, std::forward<Args>(args)...);
504 if (layer->GetNumInputSlots() != 1)
510 insertAfter.
Connect(layer->GetInputSlot(0));
524 template <
typename LayerT>
A layer that the constant data can be bound to.
Base class for all ArmNN exceptions so that users can filter to just those.
LayerInGraph(Graph &graph, Iterator, Args &&... args)
LayerInGraph(Graph &graph, Args &&... args)
LayerInGraph(Graph &graph, Args &&... args)
ConstIterator cend() const
Returns const iterator pointing to the end of the list. Lowercase for range-based for loops.
Graph & operator=(Graph &&other)
friend class SubgraphView
Status SerializeToDot(std::ostream &stream)
Iterator begin()
Returns iterator pointing to the beginning of the list. Lowercase for range-based for loops.
void DetachObservable(IGraphObservable *const observable, GraphEvent notifyOnEvent)
LayerT * InsertNewLayer(InputSlot &insertBefore, Args &&... args)
Inserts a new layer between the output slot currently connected to insertBefore and insertBefore itse...
void AttachObservable(IGraphObservable *const observable, GraphEvent notifyOnEvent)
Iterator::difference_type IteratorDifference
Status AllocateDynamicBuffers()
Allocates memory for all tensors under output tensor handers of each layer.
Status Print(bool extended=false) const
size_t GetNumOutputs() const
ConstIterator end() const
Returns const iterator pointing to the end of the list. Lowercase for range-based for loops.
void VerifyConstantLayerSetTensorInfo() const
For each ConstantLayer in Graph, ensures TensorInfo is set on all output slots.
LayerT * AddLayer(Args &&... args)
Adds a new layer, of type LayerType, to the graph constructed with the arguments passed.
const std::shared_ptr< IProfiler > & GetProfiler() const
size_t GetNumInputs() const
InputLayersAccessor GetInputLayers() const
Returns a wrapper object with begin(), end() methods to iterate over the input layers in a range-base...
void EraseLayer(Iterator pos)
Deletes the layer at the specified position.
ConstIterator cbegin() const
Returns const iterator pointing to the beginning of the list. Lowercase for range-based for loops.
Graph & operator=(const Graph &other)=delete
Graph & TopologicalSort()
Sorts layers in topological order and return this.
OutputLayersAccessor GetOutputLayers() const
Returns a wrapper object with begin(), end() methods to iterate over the output layers in a range-bas...
Graph(bool shapeInferenceMethod=false, bool allowExpandedDims=false)
std::list< Layer * > LayerList
void SubstituteSubgraph(SubgraphView &subgraph, IConnectableLayer *substituteLayer)
Substitutes the given sub-graph with either a new layer or a new sub-graph.
Iterator end()
Returns iterator pointing to the end of the list. Lowercase for range-based for loops.
static LayerType * PtrCast(Layer *const layer)
void SetLayersOutOfOrder()
Iterator GetPosInGraph(Layer &layer)
Gets the position of a layer in the graph.
LayerList::const_iterator Iterator
void AddCompatibilityLayers(std::map< BackendId, std::unique_ptr< class IBackendInternal >> &backends, TensorHandleFactoryRegistry ®istry)
Modifies the graph in-place, removing edges connecting layers using different compute devices,...
ConstIterator begin() const
Returns const iterator pointing to the beginning of the list. Lowercase for range-based for loops.
void ForEachLayer(Func func) const
size_t GetNumLayers() const
Interface for a layer that is connectable to other layers via InputSlots and OutputSlots.
virtual void Reparent(Graph &dest, std::list< Layer * >::const_iterator iterator)=0
A layer user-provided data can be bound to (e.g. inputs, outputs).
void MoveAllConnections(OutputSlot &destination)
Moves all connections to another OutputSlot.
Layer & GetOwningLayer() const
int Connect(InputSlot &destination)
The SubgraphView class represents a subgraph of a Graph.
Copyright (c) 2021 ARM Limited and Contributors.
void IgnoreUnused(Ts &&...)
LayerType
When adding a new layer, adapt also the LastLayer enum value in the enum class LayerType below.
ShapeInferenceMethod
The ShapeInferenceMethod modify how the output shapes are treated.
@ InferAndValidate
Infer missing output shapes and validate all output shapes.
@ ValidateOnly
Validate all output shapes.
Wrapper class returned by Graph::GetOutputLayers()
ConstIteratorOutputs begin() const
ConstIteratorOutputs end() const
OutputLayersAccessor(const Graph &graph)