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