2 // Copyright © 2017 Arm Ltd. All rights reserved.
3 // SPDX-License-Identifier: MIT
7 #include <armnn/NetworkFwd.hpp>
8 #include <armnn/DescriptorsFwd.hpp>
9 #include <armnn/TensorFwd.hpp>
10 #include <armnn/Optional.hpp>
12 #include <armnn/Types.hpp>
20 /// @brief An input connection slot for a layer.
21 /// The input slot can be connected to an output slot of the preceding layer in the graph.
22 /// Only one connection to the input slot is allowed.
26 virtual const IOutputSlot* GetConnection() const = 0;
27 virtual IOutputSlot* GetConnection() = 0;
30 /// Not user deletable.
34 /// @brief An output connection slot for a layer.
35 /// The output slot may be connected to 1 or more input slots of subsequent layers in the graph.
39 virtual unsigned int GetNumConnections() const = 0;
40 virtual const IInputSlot* GetConnection(unsigned int index) const = 0;
41 virtual IInputSlot* GetConnection(unsigned int index) = 0;
43 virtual void SetTensorInfo(const TensorInfo& tensorInfo) = 0;
44 virtual const TensorInfo& GetTensorInfo() const = 0;
45 virtual bool IsTensorInfoSet() const = 0;
47 virtual int Connect(IInputSlot& destination) = 0;
48 virtual void Disconnect(IInputSlot& slot) = 0;
51 /// Not user deletable.
55 /// @brief Interface for a layer that is connectable to other layers via InputSlots and OutputSlots.
56 class IConnectableLayer
59 virtual const char* GetName() const = 0;
61 virtual unsigned int GetNumInputSlots() const = 0;
62 virtual unsigned int GetNumOutputSlots() const = 0;
64 virtual const IInputSlot& GetInputSlot(unsigned int index) const = 0;
65 virtual IInputSlot& GetInputSlot(unsigned int index) = 0;
67 virtual const IOutputSlot& GetOutputSlot(unsigned int index) const = 0;
68 virtual IOutputSlot& GetOutputSlot(unsigned int index) = 0;
70 virtual std::vector<TensorShape> InferOutputShapes(const std::vector<TensorShape>& inputShapes) const = 0;
72 virtual LayerGuid GetGuid() const = 0;
74 /// Objects are not deletable via the handle
75 ~IConnectableLayer() {}
78 using INetworkPtr = std::unique_ptr<INetwork, void(*)(INetwork* network)>;
80 /// Main network class which provides the interface for building up a neural network.
81 /// This object is subsequently required by the IRuntime::Load() method.
85 static INetwork* CreateRaw();
86 static INetworkPtr Create();
87 static void Destroy(INetwork* network);
89 virtual Status PrintGraph() = 0;
91 /// Adds an input layer to the network.
92 /// @param id - User generated id to uniquely identify a particular input. The same id needs to be specified.
93 /// when passing the inputs to the IRuntime::EnqueueWorkload() function.
94 /// @param name - Optional name for the layer.
95 /// @return - Interface for configuring the layer.
96 virtual IConnectableLayer* AddInputLayer(LayerBindingId id, const char* name = nullptr) = 0;
98 /// Adds a 2D convolution layer to the network.
99 /// @param convolution2dDescriptor - Description of the 2D convolution layer.
100 /// @param weights - Tensor for the weights data.
101 /// @param biases - (Optional) Tensor for the bias data. Must match the output tensor shape.
102 /// @param name - Optional name for the layer.
103 /// @return - Interface for configuring the layer.
104 virtual IConnectableLayer* AddConvolution2dLayer(const Convolution2dDescriptor& convolution2dDescriptor,
105 const ConstTensor& weights,
106 const char* name = nullptr) = 0;
108 virtual IConnectableLayer* AddConvolution2dLayer(const Convolution2dDescriptor& convolution2dDescriptor,
109 const ConstTensor& weights,
110 const ConstTensor& biases,
111 const char* name = nullptr) = 0;
113 /// Adds a 2D depthwise convolution layer to the network.
114 /// @param convolution2dDescriptor - Description of the 2D depthwise convolution layer.
115 /// @param weights - Tensor for the weights data. Expected format: [1, outputChannels, height, width].
116 /// @param biases (Optional) - Tensor for the bias data. Must match the output tensor shape.
117 /// @param name - Optional name for the layer.
118 /// @return - Interface for configuring the layer.
119 virtual IConnectableLayer* AddDepthwiseConvolution2dLayer(
120 const DepthwiseConvolution2dDescriptor& convolution2dDescriptor,
121 const ConstTensor& weights,
122 const char* name = nullptr) = 0;
124 virtual IConnectableLayer* AddDepthwiseConvolution2dLayer(
125 const DepthwiseConvolution2dDescriptor& convolution2dDescriptor,
126 const ConstTensor& weights,
127 const ConstTensor& biases,
128 const char* name = nullptr) = 0;
130 /// Adds a fully connected layer to the network.
131 /// @param fullyConnectedDescriptor - Description of the fully connected layer.
132 /// @param weights - Tensor for the weights data.
133 /// @param biases - (Optional) Tensor for the bias data.
134 /// @param name - Optional name for the layer.
135 /// @return - Interface for configuring the layer.
136 virtual IConnectableLayer* AddFullyConnectedLayer(const FullyConnectedDescriptor& fullyConnectedDescriptor,
137 const ConstTensor& weights,
138 const char* name = nullptr) = 0;
140 virtual IConnectableLayer* AddFullyConnectedLayer(const FullyConnectedDescriptor& fullyConnectedDescriptor,
141 const ConstTensor& weights,
142 const ConstTensor& biases,
143 const char* name = nullptr) = 0;
145 /// Adds a permute layer to the network.
146 /// @param permuteDescriptor - PermuteDescriptor to configure the permute.
147 /// @param name - Optional name for the layer.
148 /// @return - Interface for configuring the layer.
149 virtual IConnectableLayer* AddPermuteLayer(const PermuteDescriptor& permuteDescriptor,
150 const char* name = nullptr) = 0;
152 /// Adds a batch to space ND layer to the network.
153 /// @param batchToSpaceNdDescriptor - Description of the layer.
154 /// @param name - Optional name for the layer.
155 /// @return - Interface for configuring the layer.
156 virtual IConnectableLayer* AddBatchToSpaceNdLayer(const BatchToSpaceNdDescriptor& batchToSpaceNdDescriptor,
157 const char* name = nullptr) = 0;
159 /// Adds a pooling layer to the network.
160 /// @param pooling2dDescriptor - Pooling2dDescriptor to configure the pooling.
161 /// @param name - Optional name for the layer.
162 /// @return - Interface for configuring the layer.
163 virtual IConnectableLayer* AddPooling2dLayer(const Pooling2dDescriptor& pooling2dDescriptor,
164 const char* name = nullptr) = 0;
166 /// Adds an activation layer to the network.
167 /// @param activationDescriptor - ActivationDescriptor to configure the activation.
168 /// @param name - Optional name for the layer.
169 /// @return - Interface for configuring the layer.
170 virtual IConnectableLayer* AddActivationLayer(const ActivationDescriptor& activationDescriptor,
171 const char* name = nullptr) = 0;
173 /// Adds a normalization layer to the network.
174 /// @param normalizationDescriptor - NormalizationDescriptor to configure the normalization.
175 /// @param name - Optional name for the layer.
176 /// @return - Interface for configuring the layer.
177 virtual IConnectableLayer* AddNormalizationLayer(const NormalizationDescriptor& normalizationDescriptor,
178 const char* name = nullptr) = 0;
180 /// Adds a softmax layer to the network.
181 /// @param softmaxDescriptor - SoftmaxDescriptor to configure the softmax.
182 /// @param name - Optional name for the layer.
183 /// @return - Interface for configuring the layer.
184 virtual IConnectableLayer* AddSoftmaxLayer(const SoftmaxDescriptor& softmaxDescriptor,
185 const char* name = nullptr) = 0;
187 /// Adds a splitter layer to the network.
188 /// @param splitterDescriptor - WindowsDescriptor to configure the splitting process.
189 /// Number of Views must be equal to the number of outputs,
190 /// and their order must match - e.g. first view corresponds to
191 /// the first output, second view to the second output, etc....
192 /// @param name - Optional name for the layer.
193 /// @return - Interface for configuring the layer.
194 virtual IConnectableLayer* AddSplitterLayer(const ViewsDescriptor& splitterDescriptor
195 , const char* name = nullptr) = 0;
197 /// Adds a merger layer to the network.
198 /// @param mergerDescriptor - WindowsDescriptor to configure the merging process. Number of Views must be equal to
199 /// the number of inputs, and their order must match - e.g. first view corresponds to
200 /// the first input, second view to the second input, etc....
201 /// @param name - Optional name for the layer.
202 /// @return - Interface for configuring the layer.
203 virtual IConnectableLayer* AddMergerLayer(const OriginsDescriptor& mergerDescriptor,
204 const char* name = nullptr) = 0;
206 /// Adds an addition layer to the network.
207 /// @param name - Optional name for the layer.
208 /// @return - Interface for configuring the layer.
209 virtual IConnectableLayer* AddAdditionLayer(const char* name = nullptr) = 0;
211 /// Adds a multiplication layer to the network.
212 /// @param name - Optional name for the layer.
213 /// @return - Interface for configuring the layer.
214 virtual IConnectableLayer* AddMultiplicationLayer(const char* name = nullptr) = 0;
216 /// Adds a batch normalization layer to the network.
217 /// @param mean - Pre-calculated mean for each channel.
218 /// @param variance - Pre-calculated variance for each channel.
219 /// @param beta - Per-channel additive factor.
220 /// @param gamma - Per-channel multiplicative factor.
221 /// @return - Interface for configuring the layer.
222 /// @param name - Optional name for the layer.
223 virtual IConnectableLayer* AddBatchNormalizationLayer(const BatchNormalizationDescriptor& desc,
224 const ConstTensor& mean,
225 const ConstTensor& variance,
226 const ConstTensor& beta,
227 const ConstTensor& gamma,
228 const char* name = nullptr) = 0;
230 /// Adds a resize bilinear layer to the network.
231 /// @param resizeDesc - Parameters for the resize operation.
232 /// @param name - Optional name for the layer.
233 /// @return - Interface for configuring the layer.
234 virtual IConnectableLayer* AddResizeBilinearLayer(const ResizeBilinearDescriptor& resizeDesc,
235 const char* name = nullptr) = 0;
237 /// Adds an L2 normalization layer to the network.
238 /// Normalization is performed along dimension 1, but requires a 4d input.
239 /// @param desc - Parameters for the L2 normalization operation.
240 /// @param name - Optional name for the layer.
241 /// @return - Interface for configuring the layer.
242 virtual IConnectableLayer* AddL2NormalizationLayer(const L2NormalizationDescriptor& desc,
243 const char* name = nullptr) = 0;
245 /// Adds a layer with no inputs and a single output, which always corresponds to
246 /// the passed in constant tensor.
247 /// @param input - Tensor to be provided as the only output of the layer. The layer will maintain
248 /// its own copy of the tensor data, meaning the memory referenced by @a input can
249 /// be freed or reused after this function is called.
250 /// @param name - Optional name for the layer.
251 /// @return - Interface for configuring the layer.
252 virtual IConnectableLayer* AddConstantLayer(const ConstTensor& input,
253 const char* name = nullptr) = 0;
255 /// Adds a reshape layer to the network.
256 /// @param reshapeDescriptor - Parameters for the reshape operation.
257 /// @param name - Optional name for the layer.
258 /// @return - Interface for configuring the layer.
259 virtual IConnectableLayer* AddReshapeLayer(const ReshapeDescriptor& reshapeDescriptor,
260 const char* name = nullptr) = 0;
262 /// Adds a space to batch layer to the network.
263 /// @param spaceToBatchNdDescriptor - Parameters for the space to batch operation.
264 /// @param name - Optional name for the layer.
265 /// @return - Interface for configuring the layer.
266 virtual IConnectableLayer* AddSpaceToBatchNdLayer(const SpaceToBatchNdDescriptor& spaceToBatchNdDescriptor,
267 const char* name = nullptr) = 0;
269 /// Adds a floor layer to the network.
270 /// @param name - Optional name for the layer.
271 /// @return - Interface for configuring the layer.
272 virtual IConnectableLayer* AddFloorLayer(const char* name = nullptr) = 0;
274 /// Adds an output layer to the network.
275 /// @param id - User generated id to uniquely identify a particular output. The same id needs to be specified
276 /// when passing the outputs to the IRuntime::EnqueueWorkload() function.
277 /// @param name - Optional name for the layer.
278 /// @return - Interface for configuring the layer.
279 virtual IConnectableLayer* AddOutputLayer(LayerBindingId id, const char* name = nullptr) = 0;
281 /// Add a Lstm layer to the network
282 /// @param descriptor Parameters for the Lstm operation
283 /// @param name Optional name for the layer
284 /// @return Interface for configuring the layer.
285 virtual IConnectableLayer* AddLstmLayer(const LstmDescriptor& descriptor,
286 const LstmInputParams& params,
287 const char* name = nullptr) = 0;
289 /// Adds a division layer to the network.
290 /// @param name - Optional name for the layer.
291 /// @return - Interface for configuring the layer.
292 virtual IConnectableLayer* AddDivisionLayer(const char* name = nullptr) = 0;
294 /// Adds a subtraction layer to the network.
295 /// @param name - Optional name for the layer.
296 /// @return - Interface for configuring the layer.
297 virtual IConnectableLayer* AddSubtractionLayer(const char* name = nullptr) = 0;
299 /// Add a Mean layer to the network.
300 /// @param meanDescriptor - Parameters for the mean operation.
301 /// @param name - Optional name for the layer.
302 /// @ return - Interface for configuring the layer.
303 virtual IConnectableLayer* AddMeanLayer(const MeanDescriptor& meanDescriptor, const char* name = nullptr) = 0;
305 /// Adds a fully pad layer to the network.
306 /// @param paddings - n by 2 tensor, where n is the rank of the input tensor,
307 /// such that paddings[i,0] indicates the amount of padding to add in front of dimonsion i, and
308 /// paddings[i,1] indicates the amount of padding to add after the end of dimension i
309 /// @param name - Optional name for the layer.
310 /// @return - Interface for configuring the layer.
311 virtual IConnectableLayer* AddPadLayer(const PadDescriptor& padDescriptor,
312 const char* name = nullptr) = 0;
314 /// Adds a strided slice layer to the network.
315 /// @param StridedSliceDescriptor - Parameters for the strided slice operation.
316 /// @param name - Optional name for the layer.
317 /// @return - Interface for configuring the layer.
318 virtual IConnectableLayer* AddStridedSliceLayer(const StridedSliceDescriptor& stridedSliceDescriptor,
319 const char* name = nullptr) = 0;
325 using IOptimizedNetworkPtr = std::unique_ptr<IOptimizedNetwork, void(*)(IOptimizedNetwork* network)>;
327 class IOptimizedNetwork
330 static void Destroy(IOptimizedNetwork* network);
332 virtual Status PrintGraph() = 0;
333 virtual Status SerializeToDot(std::ostream& stream) const = 0;
337 ~IOptimizedNetwork() {}
340 struct OptimizerOptions
342 OptimizerOptions() : m_ReduceFp32ToFp16(false) {}
344 OptimizerOptions(bool reduceFp32ToFp16)
345 : m_ReduceFp32ToFp16(reduceFp32ToFp16)
349 // Reduce Fp32 data to Fp16 for faster processing
350 bool m_ReduceFp32ToFp16;
353 /// Create an optimized version of the network
354 /// @param network INetwork description of the network to be optimized.
355 /// @param backendPreferences The choice of the backend ordered by user preferences.
356 /// @param deviceSpec DeviceSpec object as queried from the runtime. See IRuntime::GetDeviceSpec()
357 /// @param errMessages if there are failures or warnings a string describing same will be added to the vector
358 /// @param options OptimizerOptions object with optimizer configuration options
359 /// @return An IOptimizedNetworkPtr interface to the optimized network, throws an exception derived from
360 /// armnn::Exception if process fails.
362 IOptimizedNetworkPtr Optimize(const INetwork& network,
363 const std::vector<BackendId>& backendPreferences,
364 const IDeviceSpec& deviceSpec,
365 const OptimizerOptions& options = OptimizerOptions(),
366 Optional<std::vector<std::string>&> errMessages = EmptyOptional());