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);
124 otherLayer->
Reparent(*
this, m_Layers.end());
126 m_AllowExpandedDims = other.m_AllowExpandedDims;
127 m_ShapeInferenceMethod = other.m_ShapeInferenceMethod;
148 template <
typename LayerT,
typename... Args>
153 template <
typename LayerT,
typename... Args>
157 template <
typename LayerT,
typename... Args>
165 template <
typename LayerT>
220 m_Views[notifyOnEvent].emplace_back(observable);
224 m_Views[notifyOnEvent].remove(observable);
230 const std::shared_ptr<IProfiler>&
GetProfiler()
const;
233 template <
typename LayerT>
234 class LayerInGraphBase;
236 template <
typename LayerT>
250 while ((it != m_Layers.begin()) && ((*std::prev(it))->GetType() ==
LayerType::Output))
260 for (
auto& observable : m_Views[event])
262 observable->Update(graphState);
266 std::unordered_set<LayerBindingId> m_InputIds;
267 std::unordered_set<LayerBindingId> m_OutputIds;
268 std::unordered_map<const Layer*, Iterator> m_PosInGraphMap;
275 mutable bool m_LayersInOrder;
277 bool m_AllowExpandedDims;
279 std::map<const GraphEvent, std::list<IGraphObservable*>> m_Views;
282 std::shared_ptr<IProfiler> m_Profiler;
286 void ConstructErrorMessageForUnconnectedInputs(
Layer*
const layer,
287 unsigned int slotIndex);
293 template <
typename LayerT>
294 class Graph::LayerInGraphBase :
public LayerT
297 template <
typename... Args>
298 LayerInGraphBase(
Graph& graph,
Iterator insertBefore, Args&&... args)
299 : LayerT(
std::forward<Args>(args)...),
m_Graph(&graph)
301 Insert(*
m_Graph, insertBefore);
308 void Reparent(
Graph& destGraph,
Iterator insertBefore)
override 310 Insert(destGraph, insertBefore);
319 graph.m_PosInGraphMap.emplace(
this, graph.m_Layers.emplace(insertBefore,
this));
322 void Remove(
Graph& graph)
325 graph.m_Layers.erase(layerIt);
327 const size_t numErased = graph.m_PosInGraphMap.erase(
this);
337 template <
typename LayerT>
338 class Graph::LayerInGraph final :
public LayerInGraphBase<LayerT>
341 template <
typename... Args>
342 LayerInGraph(
Graph& graph, Args&&... args)
343 : LayerInGraphBase<LayerT>(graph,
346 std::forward<Args>(args)...)
349 template <
typename... Args>
350 LayerInGraph(
Graph& graph,
Iterator insertBefore, Args&&... args)
351 : LayerInGraphBase<LayerT>(graph,
353 graph.ForwardToEndOfInputs(graph.RewindToBeginOfOutputs(insertBefore)),
354 std::forward<Args>(args)...)
361 class Graph::LayerInGraph<
InputLayer> final :
public LayerInGraphBase<InputLayer>
364 template <
typename... Args>
369 std::forward<Args>(args)...)
371 const bool isNewId =
m_Graph->m_InputIds.emplace(GetBindingId()).second;
377 template <
typename... Args>
380 : LayerInGraph(graph,
std::forward<Args>(args)...)
385 const size_t numErased =
m_Graph->m_InputIds.erase(GetBindingId());
393 class Graph::LayerInGraph<
OutputLayer> final :
public LayerInGraphBase<OutputLayer>
396 template <
typename... Args>
401 std::forward<Args>(args)...)
403 const bool isNewId =
m_Graph->m_OutputIds.emplace(GetBindingId()).second;
411 const size_t numErased =
m_Graph->m_OutputIds.erase(GetBindingId());
419 auto it = m_PosInGraphMap.find(&layer);
424 template <
typename LayerT,
typename... Args>
427 m_LayersInOrder = m_LayersInOrder &&
429 LayerT*
const layer =
new LayerInGraph<LayerT>(*
this, std::forward<Args>(args)...);
431 layer->SetShapeInferenceMethod(m_ShapeInferenceMethod);
432 layer->SetAllowExpandedDims(m_AllowExpandedDims);
439 template <
typename LayerT,
typename... Args>
444 const Iterator pos = (parentOut !=
nullptr)
447 LayerT*
const layer =
new LayerInGraph<LayerT>(*
this, pos, std::forward<Args>(args)...);
448 insertBefore.
Insert(*layer);
455 template <
typename LayerT,
typename... Args>
461 LayerT*
const layer =
new LayerInGraph<LayerT>(*
this, pos, std::forward<Args>(args)...);
466 insertAfter.
Connect(layer->GetInputSlot(0));
480 template <
typename LayerT>
Graph & operator=(const Graph &other)=delete
Iterator begin()
Returns iterator pointing to the beginning of the list. Lowercase for range-based for loops...
Interface for a layer that is connectable to other layers via InputSlots and OutputSlots.
Status SerializeToDot(std::ostream &stream)
void AttachObservable(IGraphObservable *const observable, GraphEvent notifyOnEvent)
virtual void Reparent(Graph &dest, std::list< Layer *>::const_iterator iterator)=0
LayerT * AddLayer(Args &&... args)
Adds a new layer, of type LayerType, to the graph constructed with the arguments passed.
LayerInGraph(Graph &graph, Args &&... args)
ConstIterator cbegin() const
Returns const iterator pointing to the beginning of the list. Lowercase for range-based for loops...
Layer & GetOwningLayer() const
int Connect(InputSlot &destination)
void EraseLayer(Iterator pos)
Deletes the layer at the specified position.
static LayerType * PtrCast(Layer *const layer)
size_t GetNumOutputs() const
Copyright (c) 2021 ARM Limited and Contributors.
void IgnoreUnused(Ts &&...)
LayerList::const_iterator Iterator
OutputLayersAccessor(const Graph &graph)
ConstIteratorOutputs begin() const
The SubgraphView class represents a subgraph of a Graph.
Iterator GetPosInGraph(Layer &layer)
Gets the position of a layer in the graph.
A layer user-provided data can be bound to (e.g. inputs, outputs).
void ForEachLayer(Func func) const
ConstIterator end() const
Returns const iterator pointing to the end of the list. Lowercase for range-based for loops...
Validate all output shapes.
#define ARMNN_ASSERT(COND)
Iterator::difference_type IteratorDifference
Wrapper class returned by Graph::GetOutputLayers()
void VerifyConstantLayerSetTensorInfo() const
For each ConstantLayer in Graph, ensures TensorInfo is set on all output slots.
void SubstituteSubgraph(SubgraphView &subgraph, IConnectableLayer *substituteLayer)
Substitutes the given sub-graph with either a new layer or a new sub-graph.
const std::shared_ptr< IProfiler > & GetProfiler() const
OutputLayersAccessor GetOutputLayers() const
Returns a wrapper object with begin(), end() methods to iterate over the output layers in a range-bas...
Graph & operator=(Graph &&other)
std::list< Layer * > LayerList
ConstIterator begin() const
Returns const iterator pointing to the beginning of the list. Lowercase for range-based for loops...
ConstIteratorOutputs end() const
Iterator end()
Returns iterator pointing to the end of the list. Lowercase for range-based for loops.
Infer missing output shapes and validate all output shapes.
ConstIterator cend() const
Returns const iterator pointing to the end of the list. Lowercase for range-based for loops...
Graph & TopologicalSort()
Sorts layers in topological order and return this.
InputLayersAccessor GetInputLayers() const
Returns a wrapper object with begin(), end() methods to iterate over the input layers in a range-base...
Graph(bool shapeInferenceMethod=false, bool allowExpandedDims=false)
size_t GetNumLayers() const
LayerT * InsertNewLayer(InputSlot &insertBefore, Args &&... args)
Inserts a new layer between the output slot currently connected to insertBefore and insertBefore itse...
Status AllocateDynamicBuffers()
Allocates memory for all tensors under output tensor handers of each layer.
size_t GetNumInputs() const
ShapeInferenceMethod
The ShapeInferenceMethod modify how the output shapes are treated.
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...
void DetachObservable(IGraphObservable *const observable, GraphEvent notifyOnEvent)
void MoveAllConnections(OutputSlot &destination)
Moves all connections to another OutputSlot.
LayerType
When adding a new layer, adapt also the LastLayer enum value in the enum class LayerType below...