2 // Copyright © 2017 Arm Ltd. All rights reserved.
3 // SPDX-License-Identifier: MIT
7 #include <armnn/Deprecated.hpp>
8 #include <armnn/DescriptorsFwd.hpp>
9 #include <armnn/ILayerVisitor.hpp>
10 #include <armnn/NetworkFwd.hpp>
11 #include <armnn/Optional.hpp>
12 #include <armnn/TensorFwd.hpp>
13 #include <armnn/Types.hpp>
14 #include <armnn/Deprecated.hpp>
21 /// @brief An input connection slot for a layer.
22 /// The input slot can be connected to an output slot of the preceding layer in the graph.
23 /// Only one connection to the input slot is allowed.
27 virtual const IOutputSlot* GetConnection() const = 0;
28 virtual IOutputSlot* GetConnection() = 0;
31 /// Not user deletable.
35 /// @brief An output connection slot for a layer.
36 /// The output slot may be connected to 1 or more input slots of subsequent layers in the graph.
40 virtual unsigned int GetNumConnections() const = 0;
41 virtual const IInputSlot* GetConnection(unsigned int index) const = 0;
42 virtual IInputSlot* GetConnection(unsigned int index) = 0;
44 virtual void SetTensorInfo(const TensorInfo& tensorInfo) = 0;
45 virtual const TensorInfo& GetTensorInfo() const = 0;
46 virtual bool IsTensorInfoSet() const = 0;
48 virtual int Connect(IInputSlot& destination) = 0;
49 virtual void Disconnect(IInputSlot& slot) = 0;
51 virtual unsigned int CalculateIndexOnOwner() const = 0;
53 virtual LayerGuid GetOwningLayerGuid() const = 0;
56 /// Not user deletable.
60 /// @brief Interface for a layer that is connectable to other layers via InputSlots and OutputSlots.
61 class IConnectableLayer
64 virtual const char* GetName() const = 0;
66 virtual unsigned int GetNumInputSlots() const = 0;
67 virtual unsigned int GetNumOutputSlots() const = 0;
69 virtual const IInputSlot& GetInputSlot(unsigned int index) const = 0;
70 virtual IInputSlot& GetInputSlot(unsigned int index) = 0;
72 virtual const IOutputSlot& GetOutputSlot(unsigned int index) const = 0;
73 virtual IOutputSlot& GetOutputSlot(unsigned int index) = 0;
75 virtual std::vector<TensorShape> InferOutputShapes(const std::vector<TensorShape>& inputShapes) const = 0;
77 virtual LayerGuid GetGuid() const = 0;
79 virtual void Accept(ILayerVisitor& visitor) const = 0;
81 /// Objects are not deletable via the handle
82 ~IConnectableLayer() {}
85 using INetworkPtr = std::unique_ptr<INetwork, void(*)(INetwork* network)>;
87 /// Main network class which provides the interface for building up a neural network.
88 /// This object is subsequently required by the IRuntime::Load() method.
92 static INetwork* CreateRaw();
93 static INetworkPtr Create();
94 static void Destroy(INetwork* network);
96 virtual Status PrintGraph() = 0;
98 /// Adds an input layer to the network.
99 /// @param id - User generated id to uniquely identify a particular input. The same id needs to be specified.
100 /// when passing the inputs to the IRuntime::EnqueueWorkload() function.
101 /// @param name - Optional name for the layer.
102 /// @return - Interface for configuring the layer.
103 virtual IConnectableLayer* AddInputLayer(LayerBindingId id, const char* name = nullptr) = 0;
105 /// Adds a concatenation layer to the network.
106 /// @param concatDescriptor - ConcatDescriptor (synonym for OriginsDescriptor) to configure the concatenation
107 /// process. Number of Views must be equal to the number of inputs, and their order
108 /// must match - e.g. first view corresponds to the first input, second view to the
109 /// second input, etc....
110 /// @param name - Optional name for the layer.
111 /// @return - Interface for configuring the layer.
112 virtual IConnectableLayer* AddConcatLayer(const ConcatDescriptor& concatDescriptor,
113 const char* name = nullptr) = 0;
115 /// Adds a 2D convolution layer to the network.
116 /// @param convolution2dDescriptor - Description of the 2D convolution layer.
117 /// @param weights - Tensor for the weights data.
118 /// @param biases - Optional tensor for the bias data. If specified, must match the output tensor shape.
119 /// @param name - Optional name for the layer.
120 /// @return - Interface for configuring the layer.
121 virtual IConnectableLayer* AddConvolution2dLayer(const Convolution2dDescriptor& convolution2dDescriptor,
122 const ConstTensor& weights,
123 const Optional<ConstTensor>& biases,
124 const char* name = nullptr) = 0;
126 ARMNN_DEPRECATED_MSG("This AddConvolution2dLayer overload is deprecated")
127 virtual IConnectableLayer* AddConvolution2dLayer(const Convolution2dDescriptor& convolution2dDescriptor,
128 const ConstTensor& weights,
129 const char* name = nullptr) = 0;
131 ARMNN_DEPRECATED_MSG("This AddConvolution2dLayer overload is deprecated")
132 virtual IConnectableLayer* AddConvolution2dLayer(const Convolution2dDescriptor& convolution2dDescriptor,
133 const ConstTensor& weights,
134 const ConstTensor& biases,
135 const char* name = nullptr) = 0;
137 /// Adds a 2D depthwise convolution layer to the network.
138 /// @param convolution2dDescriptor - Description of the 2D depthwise convolution layer.
139 /// @param weights - Tensor for the weights. Expected format: [channelMultiplier, inputChannels, height, width].
140 /// @param biases Optional tensor for the bias data. If specified, must match the output tensor shape.
141 /// @param name - Optional name for the layer.
142 /// @return - Interface for configuring the layer.
143 virtual IConnectableLayer* AddDepthwiseConvolution2dLayer(
144 const DepthwiseConvolution2dDescriptor& convolution2dDescriptor,
145 const ConstTensor& weights,
146 const Optional<ConstTensor>& biases,
147 const char* name = nullptr) = 0;
149 ARMNN_DEPRECATED_MSG("This AddDepthwiseConvolution2dLayer overload is deprecated")
150 virtual IConnectableLayer* AddDepthwiseConvolution2dLayer(
151 const DepthwiseConvolution2dDescriptor& convolution2dDescriptor,
152 const ConstTensor& weights,
153 const char* name = nullptr) = 0;
155 ARMNN_DEPRECATED_MSG("This AddDepthwiseConvolution2dLayer overload is deprecated")
156 virtual IConnectableLayer* AddDepthwiseConvolution2dLayer(
157 const DepthwiseConvolution2dDescriptor& convolution2dDescriptor,
158 const ConstTensor& weights,
159 const ConstTensor& biases,
160 const char* name = nullptr) = 0;
162 /// Adds a Dequantize layer to the network.
163 /// @return - Interface for configuring the layer.
164 virtual IConnectableLayer* AddDequantizeLayer(const char* name = nullptr) = 0;
166 /// Adds a Detection PostProcess layer to the network.
167 /// @param descriptor - Description of the Detection PostProcess layer.
168 /// @param anchors - Tensor for anchors.
169 /// @param name - Optional name for the layer.
170 /// @return - Interface for configuring the layer.
171 virtual IConnectableLayer* AddDetectionPostProcessLayer(
172 const DetectionPostProcessDescriptor& descriptor,
173 const ConstTensor& anchors,
174 const char* name = nullptr) = 0;
176 /// Adds a fully connected layer to the network.
177 /// @param fullyConnectedDescriptor - Description of the fully connected layer.
178 /// @param weights - Tensor for the weights data.
179 /// @param biases - Optional tensor for the bias data.
180 /// @param name - Optional name for the layer.
181 /// @return - Interface for configuring the layer.
182 virtual IConnectableLayer* AddFullyConnectedLayer(const FullyConnectedDescriptor& fullyConnectedDescriptor,
183 const ConstTensor& weights,
184 const Optional<ConstTensor>& biases,
185 const char* name = nullptr) = 0;
187 ARMNN_DEPRECATED_MSG("This AddFullyConnectedLayer overload is deprecated")
188 virtual IConnectableLayer* AddFullyConnectedLayer(const FullyConnectedDescriptor& fullyConnectedDescriptor,
189 const ConstTensor& weights,
190 const char* name = nullptr) = 0;
192 ARMNN_DEPRECATED_MSG("This AddFullyConnectedLayer overload is deprecated")
193 virtual IConnectableLayer* AddFullyConnectedLayer(const FullyConnectedDescriptor& fullyConnectedDescriptor,
194 const ConstTensor& weights,
195 const ConstTensor& biases,
196 const char* name = nullptr) = 0;
198 /// Adds a permute layer to the network.
199 /// @param permuteDescriptor - PermuteDescriptor to configure the permute.
200 /// @param name - Optional name for the layer.
201 /// @return - Interface for configuring the layer.
202 virtual IConnectableLayer* AddPermuteLayer(const PermuteDescriptor& permuteDescriptor,
203 const char* name = nullptr) = 0;
205 /// Adds a batch to space ND layer to the network.
206 /// @param batchToSpaceNdDescriptor - Description of the layer.
207 /// @param name - Optional name for the layer.
208 /// @return - Interface for configuring the layer.
209 virtual IConnectableLayer* AddBatchToSpaceNdLayer(const BatchToSpaceNdDescriptor& batchToSpaceNdDescriptor,
210 const char* name = nullptr) = 0;
212 /// Adds a pooling layer to the network.
213 /// @param pooling2dDescriptor - Pooling2dDescriptor to configure the pooling.
214 /// @param name - Optional name for the layer.
215 /// @return - Interface for configuring the layer.
216 virtual IConnectableLayer* AddPooling2dLayer(const Pooling2dDescriptor& pooling2dDescriptor,
217 const char* name = nullptr) = 0;
219 /// Adds an activation layer to the network.
220 /// @param activationDescriptor - ActivationDescriptor to configure the activation.
221 /// @param name - Optional name for the layer.
222 /// @return - Interface for configuring the layer.
223 virtual IConnectableLayer* AddActivationLayer(const ActivationDescriptor& activationDescriptor,
224 const char* name = nullptr) = 0;
226 /// Adds a normalization layer to the network.
227 /// @param normalizationDescriptor - NormalizationDescriptor to configure the normalization.
228 /// @param name - Optional name for the layer.
229 /// @return - Interface for configuring the layer.
230 virtual IConnectableLayer* AddNormalizationLayer(const NormalizationDescriptor& normalizationDescriptor,
231 const char* name = nullptr) = 0;
233 /// Adds a softmax layer to the network.
234 /// If the data type is QAsymm8, then the output quantization parameters
235 /// must have a scale of 1/256 and an offset of 0
236 /// @param softmaxDescriptor - SoftmaxDescriptor to configure the softmax.
237 /// @param name - Optional name for the layer.
238 /// @return - Interface for configuring the layer.
239 virtual IConnectableLayer* AddSoftmaxLayer(const SoftmaxDescriptor& softmaxDescriptor,
240 const char* name = nullptr) = 0;
242 /// Adds a splitter layer to the network.
243 /// @param splitterDescriptor - ViewsDescriptor to configure the splitting process.
244 /// Number of Views must be equal to the number of outputs,
245 /// and their order must match - e.g. first view corresponds to
246 /// the first output, second view to the second output, etc....
247 /// @param name - Optional name for the layer.
248 /// @return - Interface for configuring the layer.
249 virtual IConnectableLayer* AddSplitterLayer(const ViewsDescriptor& splitterDescriptor
250 , const char* name = nullptr) = 0;
252 /// Adds a merge layer to the network.
253 /// @param name - Optional name for the layer.
254 /// @return - Interface for configuring the layer.
255 virtual IConnectableLayer* AddMergeLayer(const char* name = nullptr) = 0;
257 /// Adds a concat layer to the network.
258 /// @param mergerDescriptor - MergerDescriptor (synonym for OriginsDescriptor) to configure the concatenation
259 /// process. Number of Views must be equal to the number of inputs, and their order
260 /// must match - e.g. first view corresponds to the first input, second view to the
261 /// second input, etc....
262 /// @param name - Optional name for the layer.
263 /// @return - Interface for configuring the layer.
264 ARMNN_DEPRECATED_MSG("Use AddConcatLayer instead")
265 virtual IConnectableLayer* AddMergerLayer(const MergerDescriptor& mergerDescriptor,
266 const char* name = nullptr) = 0;
268 /// Add absolute layer to the network.
269 /// @param name - Optional name for the layer.
270 /// @ return - Interface for configuring the layer.
271 virtual IConnectableLayer* AddAbsLayer(const char* name = nullptr) = 0;
273 /// Adds an addition layer to the network.
274 /// @param name - Optional name for the layer.
275 /// @return - Interface for configuring the layer.
276 virtual IConnectableLayer* AddAdditionLayer(const char* name = nullptr) = 0;
278 /// Adds a multiplication layer to the network.
279 /// @param name - Optional name for the layer.
280 /// @return - Interface for configuring the layer.
281 virtual IConnectableLayer* AddMultiplicationLayer(const char* name = nullptr) = 0;
283 /// Adds a batch normalization layer to the network.
284 /// @param mean - Pre-calculated mean for each channel.
285 /// @param variance - Pre-calculated variance for each channel.
286 /// @param beta - Per-channel additive factor.
287 /// @param gamma - Per-channel multiplicative factor.
288 /// @return - Interface for configuring the layer.
289 /// @param name - Optional name for the layer.
290 virtual IConnectableLayer* AddBatchNormalizationLayer(const BatchNormalizationDescriptor& desc,
291 const ConstTensor& mean,
292 const ConstTensor& variance,
293 const ConstTensor& beta,
294 const ConstTensor& gamma,
295 const char* name = nullptr) = 0;
297 /// Adds a resize bilinear layer to the network.
298 /// @param resizeDesc - Parameters for the resize operation.
299 /// @param name - Optional name for the layer.
300 /// @return - Interface for configuring the layer.
301 ARMNN_DEPRECATED_MSG("Use AddResizeLayer instead")
302 virtual IConnectableLayer* AddResizeBilinearLayer(const ResizeBilinearDescriptor& resizeDesc,
303 const char* name = nullptr) = 0;
305 /// Adds a resize layer to the network.
306 /// @param resizeDescriptor - Parameters for the resize operation.
307 /// @param name - Optional name for the layer.
308 /// @return - Interface for configuring the layer.
309 virtual IConnectableLayer* AddResizeLayer(const ResizeDescriptor& resizeDescriptor,
310 const char* name = nullptr) = 0;
312 /// Adds an L2 normalization layer to the network.
313 /// Normalization is performed along dimension 1, but requires a 4d input.
314 /// @param desc - Parameters for the L2 normalization operation.
315 /// @param name - Optional name for the layer.
316 /// @return - Interface for configuring the layer.
317 virtual IConnectableLayer* AddL2NormalizationLayer(const L2NormalizationDescriptor& desc,
318 const char* name = nullptr) = 0;
320 /// Adds a layer with no inputs and a single output, which always corresponds to
321 /// the passed in constant tensor.
322 /// @param input - Tensor to be provided as the only output of the layer. The layer will maintain
323 /// its own copy of the tensor data, meaning the memory referenced by @a input can
324 /// be freed or reused after this function is called.
325 /// @param name - Optional name for the layer.
326 /// @return - Interface for configuring the layer.
327 virtual IConnectableLayer* AddConstantLayer(const ConstTensor& input,
328 const char* name = nullptr) = 0;
330 /// Adds a reshape layer to the network.
331 /// @param reshapeDescriptor - Parameters for the reshape operation.
332 /// @param name - Optional name for the layer.
333 /// @return - Interface for configuring the layer.
334 virtual IConnectableLayer* AddReshapeLayer(const ReshapeDescriptor& reshapeDescriptor,
335 const char* name = nullptr) = 0;
337 /// Adds a space to batch layer to the network.
338 /// @param spaceToBatchNdDescriptor - Parameters for the space to batch operation.
339 /// @param name - Optional name for the layer.
340 /// @return - Interface for configuring the layer.
341 virtual IConnectableLayer* AddSpaceToBatchNdLayer(const SpaceToBatchNdDescriptor& spaceToBatchNdDescriptor,
342 const char* name = nullptr) = 0;
344 /// Adds a space to depth layer to the network.
345 /// @param spaceToDepthDescriptor - Parameters for the space to depth operation.
346 /// @param name - Optional name for the layer.
347 /// @return - Interface for configuring the layer.
348 virtual IConnectableLayer* AddSpaceToDepthLayer(const SpaceToDepthDescriptor& spaceToDepthDescriptor,
349 const char* name = nullptr) = 0;
351 /// Adds a floor layer to the network.
352 /// @param name - Optional name for the layer.
353 /// @return - Interface for configuring the layer.
354 virtual IConnectableLayer* AddFloorLayer(const char* name = nullptr) = 0;
356 /// Adds an output layer to the network.
357 /// @param id - User generated id to uniquely identify a particular output. The same id needs to be specified
358 /// when passing the outputs to the IRuntime::EnqueueWorkload() function.
359 /// @param name - Optional name for the layer.
360 /// @return - Interface for configuring the layer.
361 virtual IConnectableLayer* AddOutputLayer(LayerBindingId id, const char* name = nullptr) = 0;
363 /// Add a Lstm layer to the network
364 /// @param descriptor - Parameters for the Lstm operation
365 /// @param params - Weights and biases for the LSTM cell
366 /// @param name - Optional name for the layer
367 /// @return - Interface for configuring the layer.
368 virtual IConnectableLayer* AddLstmLayer(const LstmDescriptor& descriptor,
369 const LstmInputParams& params,
370 const char* name = nullptr) = 0;
372 /// Adds a division layer to the network.
373 /// @param name - Optional name for the layer.
374 /// @return - Interface for configuring the layer.
375 virtual IConnectableLayer* AddDivisionLayer(const char* name = nullptr) = 0;
377 /// Adds a subtraction layer to the network.
378 /// @param name - Optional name for the layer.
379 /// @return - Interface for configuring the layer.
380 virtual IConnectableLayer* AddSubtractionLayer(const char* name = nullptr) = 0;
382 /// Add a Maximum layer to the network.
383 /// @param name - Optional name for the layer.
384 /// @ return - Interface for configuring the layer.
385 virtual IConnectableLayer* AddMaximumLayer(const char* name = nullptr) = 0;
387 /// Add a Mean layer to the network.
388 /// @param meanDescriptor - Parameters for the mean operation.
389 /// @param name - Optional name for the layer.
390 /// @ return - Interface for configuring the layer.
391 virtual IConnectableLayer* AddMeanLayer(const MeanDescriptor& meanDescriptor, const char* name = nullptr) = 0;
393 /// Adds a fully pad layer to the network.
394 /// @param paddings - n by 2 tensor, where n is the rank of the input tensor,
395 /// such that paddings[i,0] indicates the amount of padding to add in front of dimonsion i, and
396 /// paddings[i,1] indicates the amount of padding to add after the end of dimension i
397 /// @param name - Optional name for the layer.
398 /// @return - Interface for configuring the layer.
399 virtual IConnectableLayer* AddPadLayer(const PadDescriptor& padDescriptor,
400 const char* name = nullptr) = 0;
402 /// Add a quantize layer to the network
403 ///@param name - Optional name for the layer.
404 /// @return - Interface for configuring the layer.
405 virtual IConnectableLayer* AddQuantizeLayer(const char* name = nullptr) = 0;
407 /// Adds a strided slice layer to the network.
408 /// @param StridedSliceDescriptor - Parameters for the strided slice operation.
409 /// @param name - Optional name for the layer.
410 /// @return - Interface for configuring the layer.
411 virtual IConnectableLayer* AddStridedSliceLayer(const StridedSliceDescriptor& stridedSliceDescriptor,
412 const char* name = nullptr) = 0;
414 /// Add a Minimum layer to the network.
415 /// @param name - Optional name for the layer.
416 /// @ return - Interface for configuring the layer.
417 virtual IConnectableLayer* AddMinimumLayer(const char* name = nullptr) = 0;
419 /// Add a Greater layer to the network.
420 /// @param name - Optional name for the layer.
421 /// @ return - Interface for configuring the layer.
422 virtual IConnectableLayer* AddGreaterLayer(const char* name = nullptr) = 0;
424 /// Add a Equal layer to the network.
425 /// @param name - Optional name for the layer.
426 /// @ return - Interface for configuring the layer.
427 virtual IConnectableLayer* AddEqualLayer(const char* name = nullptr) = 0;
429 /// Add Reciprocal of square root layer to the network.
430 /// @param name - Optional name for the layer.
431 /// @ return - Interface for configuring the layer.
432 virtual IConnectableLayer* AddRsqrtLayer(const char* name = nullptr) = 0;
434 /// Add Gather layer to the network.
435 /// @param name - Optional name for the layer.
436 /// @ return - Interface for configuring the layer.
437 virtual IConnectableLayer* AddGatherLayer(const char* name = nullptr) = 0;
439 /// Adds a switch layer to the network.
440 /// @param name - Optional name for the layer.
441 /// @return - Interface for configuring the layer.
442 virtual IConnectableLayer* AddSwitchLayer(const char* name = nullptr) = 0;
444 /// Adds a PReLU layer to the network.
445 /// @param name - Optional name for the layer.
446 /// @return - Interface for configuring the layer.
447 virtual IConnectableLayer* AddPreluLayer(const char* name = nullptr) = 0;
449 /// Adds a 2D transpose convolution layer to the network.
450 /// @param descriptor - Description of the 2D transpose convolution layer.
451 /// @param weights - Tensor for the weights data.
452 /// @param biases - Optional tensor for the bias data.
453 /// @param name - Optional name for the layer.
454 /// @return - Interface for configuring the layer.
455 virtual IConnectableLayer* AddTransposeConvolution2dLayer(const TransposeConvolution2dDescriptor& descriptor,
456 const ConstTensor& weights,
457 const Optional<ConstTensor>& biases,
458 const char* name = nullptr) = 0;
460 /// Adds a stack layer to the network.
461 /// @param descriptor - Description of the stack layer.
462 /// @param name - Optional name for the layer.
463 /// @return - Interface for configuring the layer.
464 virtual IConnectableLayer* AddStackLayer(const StackDescriptor& descriptor,
465 const char* name = nullptr) = 0;
467 /// Add a QuantizedLstm layer to the network
468 /// @param params - The weights and biases for the Quantized LSTM cell
469 /// @param name - Optional name for the layer
470 /// @return - Interface for configuring the layer.
471 virtual IConnectableLayer* AddQuantizedLstmLayer(const QuantizedLstmInputParams& params,
472 const char* name = nullptr) = 0;
474 virtual void Accept(ILayerVisitor& visitor) const = 0;
480 using IOptimizedNetworkPtr = std::unique_ptr<IOptimizedNetwork, void(*)(IOptimizedNetwork* network)>;
482 class IOptimizedNetwork
485 static void Destroy(IOptimizedNetwork* network);
487 virtual Status PrintGraph() = 0;
488 virtual Status SerializeToDot(std::ostream& stream) const = 0;
492 ~IOptimizedNetwork() {}
495 struct OptimizerOptions
498 : m_ReduceFp32ToFp16(false)
502 OptimizerOptions(bool reduceFp32ToFp16, bool debug)
503 : m_ReduceFp32ToFp16(reduceFp32ToFp16)
507 // Reduce Fp32 data to Fp16 for faster processing
508 bool m_ReduceFp32ToFp16;
510 // Add debug data for easier troubleshooting
514 /// Create an optimized version of the network
515 /// @param network INetwork description of the network to be optimized.
516 /// @param backendPreferences The choice of the backend ordered by user preferences.
517 /// @param deviceSpec DeviceSpec object as queried from the runtime. See IRuntime::GetDeviceSpec()
518 /// @param errMessages if there are failures or warnings a string describing same will be added to the vector
519 /// @param options OptimizerOptions object with optimizer configuration options
520 /// @return An IOptimizedNetworkPtr interface to the optimized network, throws an exception derived from
521 /// armnn::Exception if process fails.
523 IOptimizedNetworkPtr Optimize(const INetwork& network,
524 const std::vector<BackendId>& backendPreferences,
525 const IDeviceSpec& deviceSpec,
526 const OptimizerOptions& options = OptimizerOptions(),
527 Optional<std::vector<std::string>&> errMessages = EmptyOptional());