ArmNN
 22.05.01
Layer.hpp
Go to the documentation of this file.
1 //
2 // Copyright © 2017 Arm Ltd and Contributors. All rights reserved.
3 // SPDX-License-Identifier: MIT
4 //
5 #pragma once
6 
7 #include "LayerFwd.hpp"
8 
10 #include <OutputHandler.hpp>
14 #include "InternalTypes.hpp"
16 #include "DllExport.hpp"
17 
18 #include <armnn/Types.hpp>
19 #include <armnn/Tensor.hpp>
20 #include <armnn/INetwork.hpp>
24 
25 #include <algorithm>
26 #include <functional>
27 #include <iostream>
28 #include <list>
29 #include <memory>
30 #include <string>
31 #include <vector>
33 
34 namespace armnn
35 {
36 
37 class IWorkload;
38 class IWorkloadFactory;
39 class Layer;
40 class Graph;
41 
42 class InputSlot final : public IInputSlot
43 {
44 public:
45  explicit InputSlot(Layer& owner, unsigned int slotIndex)
46  : m_OwningLayer(owner)
47  , m_Connection(nullptr)
48  , m_SlotIndex(slotIndex)
49  {}
50 
51  ~InputSlot();
52 
53  Layer& GetOwningLayer() const { return m_OwningLayer; }
54  unsigned int GetSlotIndex() const { return m_SlotIndex; }
55 
56  const OutputSlot* GetConnectedOutputSlot() const { return m_Connection; }
57  OutputSlot* GetConnectedOutputSlot() { return m_Connection; }
58 
59  const IConnectableLayer& GetOwningIConnectableLayer() const override;
60 
61  /// Links the slot to an output slot or breaks an existing link if passing nullptr.
62  void SetConnection(OutputSlot* source)
63  {
64  if (m_Connection != nullptr && source != nullptr)
65  {
66  throw InvalidArgumentException("Tried to connect an output slot to an input slot, "
67  "but the latter already has a connection");
68  }
69  m_Connection = source;
70  }
71 
72  // Inserts single-output existing layer at this point in the graph.
73  void Insert(Layer& layer);
74 
75  // IInputSlot
76 
77  const IOutputSlot* GetConnection() const override;
78  IOutputSlot* GetConnection() override;
79 
80 private:
81  Layer& m_OwningLayer;
82  OutputSlot* m_Connection;
83  const unsigned int m_SlotIndex;
84 };
85 
86 class OutputSlot final : public IOutputSlot
87 {
88 public:
89  explicit OutputSlot(Layer& owner, OutputHandler& outputHandler)
90  : m_OwningLayer(owner)
91  , m_OutputHandler(outputHandler)
92  , m_TensorHandleFactoryId(ITensorHandleFactory::LegacyFactoryId)
93  {}
94 
95  OutputSlot(const OutputSlot&) = delete;
96  OutputSlot& operator=(const OutputSlot&) = delete;
97  OutputSlot& operator=(OutputSlot&&) = delete;
98 
99  OutputSlot(OutputSlot&&) = default;
100 
102  {
103  try
104  {
105  // Coverity fix: DisconnectAll() may throw uncaught exceptions.
106  DisconnectAll();
107  }
108  catch (const std::exception& e)
109  {
110  // Coverity fix: BOOST_LOG_TRIVIAL (typically used to report errors) may throw an
111  // exception of type std::length_error.
112  // Using stderr instead in this context as there is no point in nesting try-catch blocks here.
113  std::cerr << "WARNING: An error has occurred when disconnecting all output slots: "
114  << e.what() << std::endl;
115  }
116  }
117 
118  Layer& GetOwningLayer() const { return m_OwningLayer; }
119 
120  const IConnectableLayer& GetOwningIConnectableLayer() const override;
121 
122  LayerGuid GetOwningLayerGuid() const override;
123 
124  const OutputHandler& GetOutputHandler() const { return m_OutputHandler; }
125  OutputHandler& GetOutputHandler() { return m_OutputHandler; }
126 
127  int Connect(InputSlot& destination);
128  void Disconnect(InputSlot& slot);
129 
130  const std::vector<InputSlot*>& GetConnections() const { return m_Connections; }
131  const std::vector<EdgeStrategy>& GetEdgeStrategies() const { return m_EdgeStrategies; }
132 
133  bool ValidateTensorShape(const TensorShape& shape) const;
134 
135  // Disconnect all conections.
136  void DisconnectAll();
137 
138  /// Moves all connections to another OutputSlot.
139  void MoveAllConnections(OutputSlot& destination);
140 
141  // IOutputSlot
142 
143  unsigned int GetNumConnections() const override { return armnn::numeric_cast<unsigned int>(m_Connections.size()); }
144  const InputSlot* GetConnection(unsigned int index) const override;
145  InputSlot* GetConnection(unsigned int index) override;
146 
147  void SetTensorInfo(const TensorInfo& tensorInfo) override;
148  const TensorInfo& GetTensorInfo() const override;
149  bool IsTensorInfoSet() const override;
150 
151  int Connect(IInputSlot& destination) override
152  {
153  return Connect(*PolymorphicDowncast<InputSlot*>(&destination));
154  }
155 
156  void Disconnect(IInputSlot& slot) override
157  {
158  return Disconnect(*PolymorphicDowncast<InputSlot*>(&slot));
159  }
160 
161  unsigned int CalculateIndexOnOwner() const override;
162 
163  bool operator==(const OutputSlot& other) const;
164 
165  void SetTensorHandleFactory(const ITensorHandleFactory::FactoryId& id);
166  ITensorHandleFactory::FactoryId GetTensorHandleFactoryId() const;
167 
168  void SetEdgeStrategy(unsigned int connectionIndex, EdgeStrategy strategy);
169  EdgeStrategy GetEdgeStrategyForConnection(unsigned int connectionIdx) const;
170 
171 private:
172  void ValidateConnectionIndex(unsigned int index) const;
173 
174  Layer& m_OwningLayer;
175  OutputHandler& m_OutputHandler;
176  std::vector<InputSlot*> m_Connections;
177 
178  ITensorHandleFactory::FactoryId m_TensorHandleFactoryId;
179  std::vector<EdgeStrategy> m_EdgeStrategies;
180 };
181 
182 // InputSlot inlines that need OutputSlot declaration.
183 
185 {
186  if (m_Connection != nullptr)
187  {
188  try
189  {
190  // Coverity fix: Disconnect() may throw uncaught exceptions.
191  m_Connection->Disconnect(*this);
192  }
193  catch (const std::exception& e)
194  {
195  // Coverity fix: BOOST_LOG_TRIVIAL (typically used to report errors) may throw an
196  // exception of type std::length_error.
197  // Using stderr instead in this context as there is no point in nesting try-catch blocks here.
198  std::cerr << "WARNING: An error has occurred when disconnecting an input slot: "
199  << e.what() << std::endl;
200  }
201  }
202 }
203 
206 
207 
208 class ScopedTensorHandle;
209 
210 // Base layer class
211 
212 using LayerPriority = unsigned int;
213 using AdditionalInfoObjectPtr = std::shared_ptr<void>;
214 
215 class Layer : public IConnectableLayer
216 {
217 public:
218  /// @param name - Optional name for the layer (may be nullptr).
219  Layer(unsigned int numInputSlots, unsigned int numOutputSlots, LayerType type, const char* name);
220  Layer(unsigned int numInputSlots, unsigned int numOutputSlots, LayerType type, DataLayout layout, const char* name);
221 
222  void ExecuteStrategy(IStrategy& strategy) const override;
223 
224 
225  const std::string& GetNameStr() const
226  {
227  return m_LayerName;
228  }
229 
230  const OutputHandler& GetOutputHandler(unsigned int i = 0) const
231  {
232  return m_OutputHandlers[i];
233  }
234 
235  OutputHandler& GetOutputHandler(unsigned int i = 0)
236  {
237  return const_cast<OutputHandler&>(const_cast<const Layer*>(this)->GetOutputHandler(i));
238  }
239 
240  ShapeInferenceMethod GetShapeInferenceMethod() const { return m_ShapeInferenceMethod; };
241  bool GetAllowExpandedDims() const { return m_AllowExpandedDims; };
242 
243  const std::vector<InputSlot>& GetInputSlots() const { return m_InputSlots; }
244  const std::vector<OutputSlot>& GetOutputSlots() const { return m_OutputSlots; }
245 
246  // Allows non-const access to input slots, but don't expose vector (vector size is fixed at layer construction).
247  std::vector<InputSlot>::iterator BeginInputSlots() { return m_InputSlots.begin(); }
248  std::vector<InputSlot>::iterator EndInputSlots() { return m_InputSlots.end(); }
249 
250  // Allows non-const access to output slots, but don't expose vector (vector size is fixed at layer construction).
251  std::vector<OutputSlot>::iterator BeginOutputSlots() { return m_OutputSlots.begin(); }
252  std::vector<OutputSlot>::iterator EndOutputSlots() { return m_OutputSlots.end(); }
253 
254  // Checks whether the outputs of this layer don't have any connection.
256  {
257  unsigned int numConnections = 0;
258 
259  for (auto&& output : GetOutputSlots())
260  {
261  numConnections += output.GetNumConnections();
262  }
263 
264  return (GetNumOutputSlots() > 0) && (numConnections == 0);
265  }
266 
267  // Used for sorting.
268  void ResetPriority() const;
269  LayerPriority GetPriority() const;
270 
271  LayerType GetType() const override { return m_Type; }
272 
273  DataType GetDataType() const;
274 
275  const BackendId& GetBackendId() const { return m_BackendId; }
276  void SetBackendId(const BackendId& id) { m_BackendId = id; }
277 
278  // Virtuals
279 
280  virtual std::unique_ptr<IWorkload> CreateWorkload(const IWorkloadFactory& factory) const = 0;
281 
282  virtual void CreateTensorHandles(const TensorHandleFactoryRegistry& registry,
283  const IWorkloadFactory& factory,
284  const bool IsMemoryManaged = true);
285 
286  /// Creates a dynamically-allocated copy of this layer.
287  /// @param graph - The Graph into which this Layer is being cloned.
288  virtual Layer* Clone(Graph& graph) const = 0;
289 
290  void VerifyLayerConnections(unsigned int expectedConnections, const CheckLocation& location) const;
291 
292  virtual void ValidateTensorShapesFromInputs() = 0;
293 
294  std::vector<TensorShape> InferOutputShapes(const std::vector<TensorShape>& inputShapes) const override;
295 
296  /// Helper to serialize the layer parameters to string.
297  /// (currently used in DotSerializer and company).
298  virtual void SerializeLayerParameters(ParameterStringifyFunction& fn) const;
299 
300  // Free up the constant source data
301  virtual void ReleaseConstantData();
302 
303  template<typename Op>
305  {
306  for (auto constant : GetConstantTensorsByRef())
307  {
308  if (constant.get())
309  {
310  op(constant);
311  }
312  }
313  };
314 
315  // IConnectableLayer
316 
317  const char* GetName() const override { return m_LayerName.c_str(); }
318 
319  unsigned int GetNumInputSlots() const override { return static_cast<unsigned int>(m_InputSlots.size()); }
320  unsigned int GetNumOutputSlots() const override { return static_cast<unsigned int>(m_OutputSlots.size()); }
321 
322  const InputSlot& GetInputSlot(unsigned int index) const override { return m_InputSlots.at(index); }
323  InputSlot& GetInputSlot(unsigned int index) override { return m_InputSlots.at(index); }
324  const OutputSlot& GetOutputSlot(unsigned int index = 0) const override { return m_OutputSlots.at(index); }
325  OutputSlot& GetOutputSlot(unsigned int index = 0) override { return m_OutputSlots.at(index); }
326 
327  void SetGuid(LayerGuid guid) { m_Guid = guid; }
328  LayerGuid GetGuid() const final { return m_Guid; }
329 
330  void AddRelatedLayerName(const std::string layerName) { m_RelatedLayerNames.emplace_back(layerName); }
331 
332  const std::list<std::string>& GetRelatedLayerNames() { return m_RelatedLayerNames; }
333 
334  virtual void Reparent(Graph& dest, std::list<Layer*>::const_iterator iterator) = 0;
335 
337  {
338  m_BackendHint = backend;
339  }
340  Optional<BackendId> GetBackendHint() const { return m_BackendHint; }
341 
343  {
344  m_ShapeInferenceMethod = shapeInferenceMethod;
345  }
346 
347  void SetAllowExpandedDims(bool allowExpandedDims)
348  {
349  m_AllowExpandedDims = allowExpandedDims;
350  }
351 
352  template<typename T>
353  std::shared_ptr<T> GetAdditionalInformation() const
354  {
355  return std::static_pointer_cast<T>(m_AdditionalInfoObject);
356  }
357 
359  {
360  m_AdditionalInfoObject = additionalInfo;
361  }
362 
363  virtual const BaseDescriptor& GetParameters() const override { return m_NullDescriptor; }
364 
365 protected:
366  // Graph needs access to the virtual destructor.
367  friend class Graph;
368  virtual ~Layer() = default;
369 
370  template <typename QueueDescriptor>
372  {
373  WorkloadDataCollector dataCollector(descriptor.m_Inputs, info.m_InputTensorInfos);
374  CollectWorkloadInputs(dataCollector);
375  }
376 
377  template <typename QueueDescriptor>
379  {
380  WorkloadDataCollector dataCollector(descriptor.m_Outputs, info.m_OutputTensorInfos);
381  CollectWorkloadOutputs(dataCollector);
382  }
383 
384  void ValidateAndCopyShape(const TensorShape& outputShape,
385  const TensorShape& inferredShape,
386  const ShapeInferenceMethod shapeInferenceMethod,
387  const std::string& layerName,
388  const unsigned int outputSlotIndex = 0);
389 
390  void VerifyShapeInferenceType(const TensorShape& outputShape, ShapeInferenceMethod shapeInferenceMethod);
391 
392  /// Helper function to reduce duplication in *Layer::CreateWorkload.
393  template <typename QueueDescriptor>
395  {
397  CollectQueueDescriptorInputs(descriptor, info);
398  CollectQueueDescriptorOutputs(descriptor, info);
399  return info;
400  }
401 
402  template <typename LayerType, typename ... Params>
403  LayerType* CloneBase(Graph& graph, Params&& ... params) const;
404 
405  // Retrieve the Handles to the constants
406  // Marking this as override and having this here keeps IConnectable abstract with only pure virtual function
407  virtual ConstantTensors GetConstantTensorsByRef() override {return ConstantTensors(); };
408 
409  // "Blob"
411 
412  // Utility method to set a pointer in the queueDescriptor to the "blob" location in the layer
413  void SetAdditionalInfo(QueueDescriptor& descriptor) const;
414 
415 private:
416  void CollectWorkloadInputs(WorkloadDataCollector& dataCollector) const;
417  void CollectWorkloadOutputs(WorkloadDataCollector& dataCollector) const;
418 
419 protected:
420  std::vector<OutputHandler> m_OutputHandlers;
422 
423 private:
424  const std::string m_LayerName;
425 
426  std::vector<InputSlot> m_InputSlots;
427  std::vector<OutputSlot> m_OutputSlots;
428 
429  const LayerType m_Type;
430  BackendId m_BackendId;
431  Optional<BackendId> m_BackendHint;
432 
433  /// Used for sorting.
434  mutable LayerPriority m_Priority = 0;
435  mutable bool m_Visiting = false;
436 
437  bool m_AllowExpandedDims = false;
438 
439  LayerGuid m_Guid;
440 
441  std::list<std::string> m_RelatedLayerNames;
442 
443  /// returned by layers which have no parameters associated with them.
444  /// has to be a member as it is returned as a const reference
445  /// declared static so that there is only ever one of them in memory
446  ARMNN_DLLEXPORT static NullDescriptor m_NullDescriptor;
447 };
448 
449 // A layer user-provided data can be bound to (e.g. inputs, outputs).
450 class BindableLayer : public Layer
451 {
452 public:
453  BindableLayer(unsigned int numInputSlots,
454  unsigned int numOutputSlots,
455  LayerType type,
456  const char* name,
457  LayerBindingId id)
458  : Layer(numInputSlots, numOutputSlots, type, name)
459  , m_Id(id)
460  {
461  }
462 
463  LayerBindingId GetBindingId() const { return m_Id; };
464 
465  void ExecuteStrategy(IStrategy& strategy) const override
466  {
467  strategy.ExecuteStrategy(this, BaseDescriptor(), {}, GetName(), GetBindingId());
468  }
469 
470 protected:
471  ~BindableLayer() = default;
472 
473 private:
474  LayerBindingId m_Id;
475 };
476 
477 }
std::vector< InputSlot >::iterator EndInputSlots()
Definition: Layer.hpp:248
void CollectQueueDescriptorInputs(QueueDescriptor &descriptor, WorkloadInfo &info) const
Definition: Layer.hpp:371
const std::vector< InputSlot * > & GetConnections() const
Definition: Layer.hpp:130
void Insert(Layer &layer)
Definition: Layer.cpp:48
Interface for a layer that is connectable to other layers via InputSlots and OutputSlots.
Definition: INetwork.hpp:66
DataLayout
Definition: Types.hpp:62
unsigned int GetNumInputSlots() const override
Returns the number of connectable input slots.
Definition: Layer.hpp:319
std::unique_ptr< armnn::IWorkload > CreateWorkload(const armnn::IWorkloadFactory &workloadFactory, const armnn::WorkloadInfo &info, const DescriptorType &descriptor)
Optional< BackendId > GetBackendHint() const
Definition: Layer.hpp:340
void AddRelatedLayerName(const std::string layerName)
Definition: Layer.hpp:330
void BackendSelectionHint(Optional< BackendId > backend) final
Provide a hint for the optimizer as to which backend to prefer for this layer.
Definition: Layer.hpp:336
void SetAllowExpandedDims(bool allowExpandedDims)
Definition: Layer.hpp:347
void SetShapeInferenceMethod(ShapeInferenceMethod shapeInferenceMethod)
Definition: Layer.hpp:342
const std::vector< EdgeStrategy > & GetEdgeStrategies() const
Definition: Layer.hpp:131
LayerBindingId GetBindingId() const
Definition: Layer.hpp:463
void OperateOnConstantTensors(Op op)
Definition: Layer.hpp:304
void ExecuteStrategy(IStrategy &strategy) const override
Apply a visitor to this layer.
Definition: Layer.hpp:465
OutputSlot & GetOutputSlot(unsigned int index=0) override
Get the output slot handle by slot index.
Definition: Layer.hpp:325
Layer & GetOwningLayer() const
Definition: Layer.hpp:118
virtual void ExecuteStrategy(const armnn::IConnectableLayer *layer, const armnn::BaseDescriptor &descriptor, const std::vector< armnn::ConstTensor > &constants, const char *name, const armnn::LayerBindingId id=0)=0
ShapeInferenceMethod GetShapeInferenceMethod() const
Definition: Layer.hpp:240
unsigned int LayerPriority
Definition: Layer.hpp:212
void Disconnect(IInputSlot &slot) override
Definition: Layer.hpp:156
int Connect(IInputSlot &destination) override
Definition: Layer.hpp:151
Copyright (c) 2021 ARM Limited and Contributors.
void SetBackendId(const BackendId &id)
Definition: Layer.hpp:276
const std::vector< InputSlot > & GetInputSlots() const
Definition: Layer.hpp:243
const IOutputSlot * GetConnection() const override
Definition: Layer.hpp:204
bool IsOutputUnconnected()
Definition: Layer.hpp:255
unsigned int GetNumOutputSlots() const override
Returns the number of connectable output slots.
Definition: Layer.hpp:320
int LayerBindingId
Type of identifiers for bindable layers (inputs, outputs).
Definition: Types.hpp:290
Base class for all descriptors.
Definition: Descriptors.hpp:22
std::vector< InputSlot >::iterator BeginInputSlots()
Definition: Layer.hpp:247
const IConnectableLayer & GetOwningIConnectableLayer() const override
Definition: Layer.cpp:546
std::shared_ptr< void > AdditionalInfoObjectPtr
Definition: Layer.hpp:213
unsigned int GetNumConnections() const override
Definition: Layer.hpp:143
const InputSlot & GetInputSlot(unsigned int index) const override
Get a const input slot handle by slot index.
Definition: Layer.hpp:322
std::vector< TensorInfo > m_InputTensorInfos
#define ARMNN_DLLEXPORT
Definition: DllExport.hpp:17
bool operator==(const armnn::DataLayout &dataLayout, const DataLayoutIndexed &indexed)
Equality methods.
Null Descriptor used as a return value from the IConnectableLayer GetParameters method by layers whic...
Definition: Descriptors.hpp:30
std::vector< std::reference_wrapper< std::shared_ptr< ConstTensorHandle > >> ConstantTensors
Definition: INetwork.hpp:124
DataType
Definition: Types.hpp:48
void SetGuid(LayerGuid guid)
Definition: Layer.hpp:327
AdditionalInfoObjectPtr m_AdditionalInfoObject
Definition: Layer.hpp:407
WorkloadInfo PrepInfoAndDesc(QueueDescriptor &descriptor) const
Helper function to reduce duplication in *LayerCreateWorkload.
Definition: Layer.hpp:394
An output connection slot for a layer.
Definition: INetwork.hpp:40
InputSlot(Layer &owner, unsigned int slotIndex)
Definition: Layer.hpp:45
unsigned int GetSlotIndex() const
Definition: Layer.hpp:54
const std::string & GetNameStr() const
Definition: Layer.hpp:225
LayerType GetType() const override
Returns the armnn::LayerType of this layer.
Definition: Layer.hpp:271
const OutputSlot * GetConnectedOutputSlot() const
Definition: Layer.hpp:56
std::vector< TensorInfo > m_OutputTensorInfos
InputSlot & GetInputSlot(unsigned int index) override
Get the input slot handle by slot index.
Definition: Layer.hpp:323
Layer & GetOwningLayer() const
Definition: Layer.hpp:53
OutputSlot * GetConnectedOutputSlot()
Definition: Layer.hpp:57
const BackendId & GetBackendId() const
Definition: Layer.hpp:275
std::vector< OutputHandler > m_OutputHandlers
Definition: Layer.hpp:420
const std::vector< OutputSlot > & GetOutputSlots() const
Definition: Layer.hpp:244
BindableLayer(unsigned int numInputSlots, unsigned int numOutputSlots, LayerType type, const char *name, LayerBindingId id)
Definition: Layer.hpp:453
void SetAdditionalInfoForObject(const AdditionalInfoObjectPtr &additionalInfo)
Definition: Layer.hpp:358
const std::list< std::string > & GetRelatedLayerNames()
Definition: Layer.hpp:332
arm::pipe::ProfilingGuid LayerGuid
Define LayerGuid type.
Definition: Types.hpp:26
std::vector< OutputSlot >::iterator BeginOutputSlots()
Definition: Layer.hpp:251
std::vector< ITensorHandle * > m_Outputs
void CollectQueueDescriptorOutputs(QueueDescriptor &descriptor, WorkloadInfo &info) const
Definition: Layer.hpp:378
void SetConnection(OutputSlot *source)
Links the slot to an output slot or breaks an existing link if passing nullptr.
Definition: Layer.hpp:62
const OutputHandler & GetOutputHandler(unsigned int i=0) const
Definition: Layer.hpp:230
virtual const BaseDescriptor & GetParameters() const override
If the layer has a descriptor return it.
Definition: Layer.hpp:363
bool GetAllowExpandedDims() const
Definition: Layer.hpp:241
std::vector< OutputSlot >::iterator EndOutputSlots()
Definition: Layer.hpp:252
std::enable_if_t< std::is_unsigned< Source >::value &&std::is_unsigned< Dest >::value, Dest > numeric_cast(Source source)
Definition: NumericCast.hpp:35
const OutputSlot & GetOutputSlot(unsigned int index=0) const override
Get the const output slot handle by slot index.
Definition: Layer.hpp:324
OutputHandler & GetOutputHandler()
Definition: Layer.hpp:125
OutputSlot(Layer &owner, OutputHandler &outputHandler)
Definition: Layer.hpp:89
const OutputHandler & GetOutputHandler() const
Definition: Layer.hpp:124
Contains information about TensorInfos of a layer.
const char * GetName() const override
Returns the name of the layer.
Definition: Layer.hpp:317
void Connect(armnn::IConnectableLayer *from, armnn::IConnectableLayer *to, const armnn::TensorInfo &tensorInfo, unsigned int fromIndex, unsigned int toIndex)
Definition: TestUtils.cpp:14
std::vector< ITensorHandle * > m_Inputs
std::function< void(const std::string &name, const std::string &value)> ParameterStringifyFunction
const TensorInfo & GetTensorInfo(const ITensorHandle *tensorHandle)
float32 helpers
ShapeInferenceMethod
The ShapeInferenceMethod modify how the output shapes are treated.
Definition: Types.hpp:221
An input connection slot for a layer.
Definition: INetwork.hpp:26
ShapeInferenceMethod m_ShapeInferenceMethod
Definition: Layer.hpp:421
OutputHandler & GetOutputHandler(unsigned int i=0)
Definition: Layer.hpp:235
std::shared_ptr< T > GetAdditionalInformation() const
Definition: Layer.hpp:353
LayerType
When adding a new layer, adapt also the LastLayer enum value in the enum class LayerType below...
Definition: Types.hpp:467
LayerGuid GetGuid() const final
Returns the unique id of the layer.
Definition: Layer.hpp:328