Release 18.08
[platform/upstream/armnn.git] / include / armnn / INetwork.hpp
1 //
2 // Copyright © 2017 Arm Ltd. All rights reserved.
3 // See LICENSE file in the project root for full license information.
4 //
5 #pragma once
6
7 #include "armnn/NetworkFwd.hpp"
8 #include "armnn/DescriptorsFwd.hpp"
9 #include "armnn/TensorFwd.hpp"
10
11 #include "armnn/Types.hpp"
12
13 #include <memory>
14 #include <vector>
15
16 namespace armnn
17 {
18
19 /// @brief An input connection slot for a layer.
20 /// The input slot can be connected to an output slot of the preceding layer in the graph.
21 /// Only one connection to the input slot is allowed.
22 class IInputSlot
23 {
24 public:
25     virtual const IOutputSlot* GetConnection() const = 0;
26     virtual IOutputSlot* GetConnection() = 0;
27
28 protected:
29    /// Not user deletable.
30     ~IInputSlot() {}
31 };
32
33 /// @brief An output connection slot for a layer.
34 /// The output slot may be connected to 1 or more input slots of subsequent layers in the graph.
35 class IOutputSlot
36 {
37 public:
38     virtual unsigned int GetNumConnections() const = 0;
39     virtual const IInputSlot* GetConnection(unsigned int index) const = 0;
40     virtual IInputSlot* GetConnection(unsigned int index) = 0;
41
42     virtual void SetTensorInfo(const TensorInfo& tensorInfo) = 0;
43     virtual const TensorInfo& GetTensorInfo() const = 0;
44     virtual bool IsTensorInfoSet() const = 0;
45
46     virtual int Connect(IInputSlot& destination) = 0;
47     virtual void Disconnect(IInputSlot& slot) = 0;
48
49 protected:
50     /// Not user deletable.
51     ~IOutputSlot() {}
52 };
53
54 /// @brief Interface for a layer that is connectable to other layers via InputSlots and OutputSlots.
55 class IConnectableLayer
56 {
57 public:
58     virtual const char* GetName() const = 0;
59
60     virtual unsigned int GetNumInputSlots() const = 0;
61     virtual unsigned int GetNumOutputSlots() const = 0;
62
63     virtual const IInputSlot& GetInputSlot(unsigned int index) const = 0;
64     virtual IInputSlot& GetInputSlot(unsigned int index) = 0;
65
66     virtual const IOutputSlot& GetOutputSlot(unsigned int index) const = 0;
67     virtual IOutputSlot& GetOutputSlot(unsigned int index) = 0;
68
69     virtual std::vector<TensorShape> InferOutputShapes(const std::vector<TensorShape>& inputShapes) const = 0;
70
71     virtual LayerGuid GetGuid() const = 0;
72 protected:
73       /// Objects are not deletable via the handle
74     ~IConnectableLayer() {}
75 };
76
77 using INetworkPtr = std::unique_ptr<INetwork, void(*)(INetwork* network)>;
78
79 /// Main network class which provides the interface for building up a neural network.
80 /// This object is subsequently required by the IRuntime::Load() method.
81 class INetwork
82 {
83 public:
84     static INetwork* CreateRaw();
85     static INetworkPtr Create();
86     static void Destroy(INetwork* network);
87
88     virtual Status PrintGraph() = 0;
89
90     /// Adds an input layer to the network.
91     /// @param id - User generated id to uniquely identify a particular input. The same id needs to be specified.
92     /// when passing the inputs to the IRuntime::EnqueueWorkload() function.
93     /// @param name - Optional name for the layer.
94     /// @return - Interface for configuring the layer.
95     virtual IConnectableLayer* AddInputLayer(LayerBindingId id, const char* name = nullptr) = 0;
96
97     /// Adds a 2D convolution layer to the network.
98     /// @param convolution2dDescriptor - Description of the 2D convolution layer.
99     /// @param weights - Tensor for the weights data.
100     /// @param biases - (Optional) Tensor for the bias data. Must match the output tensor shape.
101     /// @param name - Optional name for the layer.
102     /// @return - Interface for configuring the layer.
103     virtual IConnectableLayer* AddConvolution2dLayer(const Convolution2dDescriptor& convolution2dDescriptor,
104         const ConstTensor& weights,
105         const char* name = nullptr) = 0;
106
107     virtual IConnectableLayer* AddConvolution2dLayer(const Convolution2dDescriptor& convolution2dDescriptor,
108         const ConstTensor& weights,
109         const ConstTensor& biases,
110         const char* name = nullptr) = 0;
111
112     /// Adds a 2D depthwise convolution layer to the network.
113     /// @param convolution2dDescriptor - Description of the 2D depthwise convolution layer.
114     /// @param weights - Tensor for the weights data. Expected format: [1, outputChannels, height, width].
115     /// @param biases (Optional) - Tensor for the bias data. Must match the output tensor shape.
116     /// @param name - Optional name for the layer.
117     /// @return - Interface for configuring the layer.
118     virtual IConnectableLayer* AddDepthwiseConvolution2dLayer(
119         const DepthwiseConvolution2dDescriptor& convolution2dDescriptor,
120         const ConstTensor& weights,
121         const char* name = nullptr) = 0;
122
123     virtual IConnectableLayer* AddDepthwiseConvolution2dLayer(
124         const DepthwiseConvolution2dDescriptor& convolution2dDescriptor,
125         const ConstTensor& weights,
126         const ConstTensor& biases,
127         const char* name = nullptr) = 0;
128
129     /// Adds a fully connected layer to the network.
130     /// @param fullyConnectedDescriptor - Description of the fully connected layer.
131     /// @param weights - Tensor for the weights data.
132     /// @param biases - (Optional) Tensor for the bias data.
133     /// @param name - Optional name for the layer.
134     /// @return - Interface for configuring the layer.
135     virtual IConnectableLayer* AddFullyConnectedLayer(const FullyConnectedDescriptor& fullyConnectedDescriptor,
136         const ConstTensor& weights,
137         const char* name = nullptr) = 0;
138
139     virtual IConnectableLayer* AddFullyConnectedLayer(const FullyConnectedDescriptor& fullyConnectedDescriptor,
140         const ConstTensor& weights,
141         const ConstTensor& biases,
142         const char* name = nullptr) = 0;
143
144     /// Adds a permute layer to the network.
145     /// @param permuteDescriptor - PermuteDescriptor to configure the permute.
146     /// @param name - Optional name for the layer.
147     /// @return - Interface for configuring the layer.
148     virtual IConnectableLayer* AddPermuteLayer(const PermuteDescriptor& permuteDescriptor,
149                                                const char* name = nullptr) = 0;
150
151     /// Adds a pooling layer to the network.
152     /// @param pooling2dDescriptor - Pooling2dDescriptor to configure the pooling.
153     /// @param name - Optional name for the layer.
154     /// @return - Interface for configuring the layer.
155     virtual IConnectableLayer* AddPooling2dLayer(const Pooling2dDescriptor& pooling2dDescriptor,
156         const char* name = nullptr) = 0;
157
158     /// Adds an activation layer to the network.
159     /// @param activationDescriptor - ActivationDescriptor to configure the activation.
160     /// @param name - Optional name for the layer.
161     /// @return - Interface for configuring the layer.
162     virtual IConnectableLayer* AddActivationLayer(const ActivationDescriptor& activationDescriptor,
163         const char* name = nullptr) = 0;
164
165     /// Adds a normalization layer to the network.
166     /// @param normalizationDescriptor - NormalizationDescriptor to configure the normalization.
167     /// @param name - Optional name for the layer.
168     /// @return - Interface for configuring the layer.
169     virtual IConnectableLayer* AddNormalizationLayer(const NormalizationDescriptor& normalizationDescriptor,
170         const char* name = nullptr) = 0;
171
172     /// Adds a softmax layer to the network.
173     /// @param softmaxDescriptor - SoftmaxDescriptor to configure the softmax.
174     /// @param name - Optional name for the layer.
175     /// @return - Interface for configuring the layer.
176     virtual IConnectableLayer* AddSoftmaxLayer(const SoftmaxDescriptor& softmaxDescriptor,
177         const char* name = nullptr) = 0;
178
179     /// Adds a splitter layer to the network.
180     /// @param splitterDescriptor - WindowsDescriptor to configure the splitting process.
181     ///                             Number of Views must be equal to the number of outputs,
182     ///                             and their order must match - e.g. first view corresponds to
183     ///                             the first output, second view to the second output, etc....
184     /// @param name - Optional name for the layer.
185     /// @return - Interface for configuring the layer.
186     virtual IConnectableLayer* AddSplitterLayer(const ViewsDescriptor& splitterDescriptor
187         , const char* name = nullptr) = 0;
188
189     /// Adds a merger layer to the network.
190     /// @param mergerDescriptor - WindowsDescriptor to configure the merging process. Number of Views must be equal to
191     ///                           the number of inputs, and their order must match - e.g. first view corresponds to
192     ///                           the first input, second view to the second input, etc....
193     /// @param name - Optional name for the layer.
194     /// @return - Interface for configuring the layer.
195     virtual IConnectableLayer* AddMergerLayer(const OriginsDescriptor& mergerDescriptor,
196         const char* name = nullptr) = 0;
197
198     /// Adds an addition layer to the network.
199     /// @param name - Optional name for the layer.
200     /// @return - Interface for configuring the layer.
201     virtual IConnectableLayer* AddAdditionLayer(const char* name = nullptr) = 0;
202
203     /// Adds a multiplication layer to the network.
204     /// @param name - Optional name for the layer.
205     /// @return - Interface for configuring the layer.
206     virtual IConnectableLayer* AddMultiplicationLayer(const char* name = nullptr) = 0;
207
208     /// Adds a batch normalization layer to the network.
209     /// @param mean - Pre-calculated mean for each channel.
210     /// @param variance - Pre-calculated variance for each channel.
211     /// @param beta - Per-channel additive factor.
212     /// @param gamma - Per-channel multiplicative factor.
213     /// @return - Interface for configuring the layer.
214     /// @param name - Optional name for the layer.
215     virtual IConnectableLayer* AddBatchNormalizationLayer(const BatchNormalizationDescriptor& desc,
216         const ConstTensor& mean,
217         const ConstTensor& variance,
218         const ConstTensor& beta,
219         const ConstTensor& gamma,
220         const char* name = nullptr) = 0;
221
222     /// Adds a resize bilinear layer to the network.
223     /// @param resizeDesc - Parameters for the resize operation.
224     /// @param name - Optional name for the layer.
225     /// @return - Interface for configuring the layer.
226     virtual IConnectableLayer* AddResizeBilinearLayer(const ResizeBilinearDescriptor& resizeDesc,
227                                                       const char* name = nullptr) = 0;
228
229     /// Adds an L2 normalization layer to the network.
230     /// Normalization is performed along dimension 1, but requires a 4d input.
231     /// @param name - Optional name for the layer.
232     /// @return - Interface for configuring the layer.
233     virtual IConnectableLayer* AddL2NormalizationLayer(const char* name = nullptr) = 0;
234
235     /// Adds a layer with no inputs and a single output, which always corresponds to
236     /// the passed in constant tensor.
237     /// @param input - Tensor to be provided as the only output of the layer. The layer will maintain
238     ///                its own copy of the tensor data, meaning the memory referenced by @a input can
239     ///                be freed or reused after this function is called.
240     /// @param name - Optional name for the layer.
241     /// @return - Interface for configuring the layer.
242     virtual IConnectableLayer* AddConstantLayer(const ConstTensor& input,
243         const char* name = nullptr) = 0;
244
245     /// Adds a reshape layer to the network.
246     /// @param reshapeDescriptor - Parameters for the reshape operation.
247     /// @param name - Optional name for the layer.
248     /// @return - Interface for configuring the layer.
249     virtual IConnectableLayer* AddReshapeLayer(const ReshapeDescriptor& reshapeDescriptor,
250                                                const char* name = nullptr) = 0;
251
252     /// Adds a floor layer to the network.
253     /// @param name - Optional name for the layer.
254     /// @return - Interface for configuring the layer.
255     virtual IConnectableLayer* AddFloorLayer(const char* name = nullptr) = 0;
256
257     /// Adds an output layer to the network.
258     /// @param id - User generated id to uniquely identify a particular output. The same id needs to be specified
259     /// when passing the outputs to the IRuntime::EnqueueWorkload() function.
260     /// @param name - Optional name for the layer.
261     /// @return - Interface for configuring the layer.
262     virtual IConnectableLayer* AddOutputLayer(LayerBindingId id, const char* name = nullptr) = 0;
263
264     /// Add a Lstm layer to the network
265     /// @param descriptor Parameters for the Lstm operation
266     /// @param name Optional name for the layer
267     /// @return Interface for configuring the layer.
268     virtual IConnectableLayer* AddLstmLayer(const LstmDescriptor& descriptor,
269                                             const LstmInputParams& params,
270                                             const char* name = nullptr) = 0;
271
272 protected:
273     ~INetwork() {}
274 };
275
276 using IOptimizedNetworkPtr = std::unique_ptr<IOptimizedNetwork, void(*)(IOptimizedNetwork* network)>;
277
278 class IOptimizedNetwork
279 {
280 public:
281     static void Destroy(IOptimizedNetwork* network);
282
283     virtual Status PrintGraph() = 0;
284     virtual Status SerializeToDot(std::ostream& stream) const = 0;
285
286
287 protected:
288     ~IOptimizedNetwork() {}
289 };
290
291 struct OptimizerOptions
292 {
293     OptimizerOptions() : m_ReduceFp32ToFp16(false) {}
294
295     OptimizerOptions(bool reduceFp32ToFp16)
296         : m_ReduceFp32ToFp16(reduceFp32ToFp16)
297     {
298     }
299
300     // Reduce Fp32 data to Fp16 for faster processing
301     bool m_ReduceFp32ToFp16;
302 };
303
304 /// Create an optimized version of the network
305 /// @param network INetwork description of the network to be optimized.
306 /// @param backendPreferences The choice of the backend ordered by user preferences.
307 /// @param deviceSpec DeviceSpec object as queried from the runtime. See IRuntime::GetDeviceSpec()
308 /// @param options OptimizerOptions object with optimizer configuration options
309 /// @return An IOptimizedNetworkPtr interface to the optimized network, throws an exception derived from
310 /// armnn::Exception if process fails.
311
312 IOptimizedNetworkPtr Optimize(const INetwork& network,
313                               const std::vector<armnn::Compute>& backendPreferences,
314                               const IDeviceSpec& deviceSpec,
315                               const OptimizerOptions& options = OptimizerOptions());
316 } //namespace armnn