ac7faab279fcd39cbc6205ec266565cb2f294ff6
[platform/upstream/armnn.git] / include / armnn / INetwork.hpp
1 //
2 // Copyright © 2017 Arm Ltd. All rights reserved.
3 // SPDX-License-Identifier: MIT
4 //
5 #pragma once
6
7 #include <armnn/NetworkFwd.hpp>
8 #include <armnn/DescriptorsFwd.hpp>
9 #include <armnn/TensorFwd.hpp>
10 #include <armnn/Optional.hpp>
11
12 #include <armnn/Types.hpp>
13
14 #include <memory>
15 #include <vector>
16
17 namespace armnn
18 {
19
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.
23 class IInputSlot
24 {
25 public:
26     virtual const IOutputSlot* GetConnection() const = 0;
27     virtual IOutputSlot* GetConnection() = 0;
28
29 protected:
30    /// Not user deletable.
31     ~IInputSlot() {}
32 };
33
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.
36 class IOutputSlot
37 {
38 public:
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;
42
43     virtual void SetTensorInfo(const TensorInfo& tensorInfo) = 0;
44     virtual const TensorInfo& GetTensorInfo() const = 0;
45     virtual bool IsTensorInfoSet() const = 0;
46
47     virtual int Connect(IInputSlot& destination) = 0;
48     virtual void Disconnect(IInputSlot& slot) = 0;
49
50 protected:
51     /// Not user deletable.
52     ~IOutputSlot() {}
53 };
54
55 /// @brief Interface for a layer that is connectable to other layers via InputSlots and OutputSlots.
56 class IConnectableLayer
57 {
58 public:
59     virtual const char* GetName() const = 0;
60
61     virtual unsigned int GetNumInputSlots() const = 0;
62     virtual unsigned int GetNumOutputSlots() const = 0;
63
64     virtual const IInputSlot& GetInputSlot(unsigned int index) const = 0;
65     virtual IInputSlot& GetInputSlot(unsigned int index) = 0;
66
67     virtual const IOutputSlot& GetOutputSlot(unsigned int index) const = 0;
68     virtual IOutputSlot& GetOutputSlot(unsigned int index) = 0;
69
70     virtual std::vector<TensorShape> InferOutputShapes(const std::vector<TensorShape>& inputShapes) const = 0;
71
72     virtual LayerGuid GetGuid() const = 0;
73 protected:
74       /// Objects are not deletable via the handle
75     ~IConnectableLayer() {}
76 };
77
78 using INetworkPtr = std::unique_ptr<INetwork, void(*)(INetwork* network)>;
79
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.
82 class INetwork
83 {
84 public:
85     static INetwork* CreateRaw();
86     static INetworkPtr Create();
87     static void Destroy(INetwork* network);
88
89     virtual Status PrintGraph() = 0;
90
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;
97
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;
107
108     virtual IConnectableLayer* AddConvolution2dLayer(const Convolution2dDescriptor& convolution2dDescriptor,
109         const ConstTensor& weights,
110         const ConstTensor& biases,
111         const char* name = nullptr) = 0;
112
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;
123
124     virtual IConnectableLayer* AddDepthwiseConvolution2dLayer(
125         const DepthwiseConvolution2dDescriptor& convolution2dDescriptor,
126         const ConstTensor& weights,
127         const ConstTensor& biases,
128         const char* name = nullptr) = 0;
129
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;
139
140     virtual IConnectableLayer* AddFullyConnectedLayer(const FullyConnectedDescriptor& fullyConnectedDescriptor,
141         const ConstTensor& weights,
142         const ConstTensor& biases,
143         const char* name = nullptr) = 0;
144
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;
151
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;
158
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;
165
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;
172
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;
179
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;
186
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;
196
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;
205
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;
210
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;
215
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;
229
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;
236
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;
244
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;
254
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;
261
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;
268
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;
273
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;
280
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;
288
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;
293
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;
298
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;
304
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;
313
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;
320
321 protected:
322     ~INetwork() {}
323 };
324
325 using IOptimizedNetworkPtr = std::unique_ptr<IOptimizedNetwork, void(*)(IOptimizedNetwork* network)>;
326
327 class IOptimizedNetwork
328 {
329 public:
330     static void Destroy(IOptimizedNetwork* network);
331
332     virtual Status PrintGraph() = 0;
333     virtual Status SerializeToDot(std::ostream& stream) const = 0;
334
335
336 protected:
337     ~IOptimizedNetwork() {}
338 };
339
340 struct OptimizerOptions
341 {
342     OptimizerOptions() : m_ReduceFp32ToFp16(false) {}
343
344     OptimizerOptions(bool reduceFp32ToFp16)
345         : m_ReduceFp32ToFp16(reduceFp32ToFp16)
346     {
347     }
348
349     // Reduce Fp32 data to Fp16 for faster processing
350     bool m_ReduceFp32ToFp16;
351 };
352
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.
361
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());
367 } //namespace armnn