ArmNN
 21.02
TfParser.hpp
Go to the documentation of this file.
1 //
2 // Copyright © 2017 Arm Ltd. All rights reserved.
3 // SPDX-License-Identifier: MIT
4 //
5 #pragma once
6 
8 
9 #include "armnn/Types.hpp"
10 #include "armnn/Tensor.hpp"
11 #include "armnn/INetwork.hpp"
12 
13 #include <list>
14 #include <map>
15 #include <memory>
16 #include <unordered_map>
17 #include <utility>
18 #include <vector>
19 
20 namespace armnn
21 {
22 class TensorInfo;
23 }
24 
25 namespace tensorflow
26 {
27 class GraphDef;
28 class NodeDef;
29 }
30 
31 namespace armnnTfParser
32 {
33 
34 class ParsedTfOperation;
35 using ParsedTfOperationPtr = std::unique_ptr<ParsedTfOperation>;
36 
37 ///
38 /// WithOutputTensorIndex wraps a value and an index. The purpose of
39 /// this template is to signify that, in Tensorflow, the input name of
40 /// a layer has the convention of 'inputTensorName:#index', where the
41 /// #index can be omitted and it implicitly means the 0 output of
42 /// the referenced layer. By supporting this notation we can handle
43 /// layers with multiple outputs, such as Split.
44 ///
45 template <typename T>
47 {
49  unsigned int m_Index;
50 
51  WithOutputTensorIndex(const T & value, unsigned int index)
52  : m_IndexedValue{value}
53  , m_Index{index} {}
54 
55  WithOutputTensorIndex(T && value, unsigned int index)
56  : m_IndexedValue{value}
57  , m_Index{index} {}
58 };
59 
63 
65 {
66 public:
67  /// Creates the network from a protobuf text file on the disk.
68  armnn::INetworkPtr CreateNetworkFromTextFile(
69  const char* graphFile,
70  const std::map<std::string, armnn::TensorShape>& inputShapes,
71  const std::vector<std::string>& requestedOutputs);
72 
73  /// Creates the network from a protobuf binary file on the disk.
74  armnn::INetworkPtr CreateNetworkFromBinaryFile(
75  const char* graphFile,
76  const std::map<std::string, armnn::TensorShape>& inputShapes,
77  const std::vector<std::string>& requestedOutputs);
78 
79  /// Creates the network directly from protobuf text in a string. Useful for debugging/testing.
80  armnn::INetworkPtr CreateNetworkFromString(
81  const char* protoText,
82  const std::map<std::string, armnn::TensorShape>& inputShapes,
83  const std::vector<std::string>& requestedOutputs);
84 
85  /// Retrieves binding info (layer id and tensor info) for the network input identified by the given layer name.
86  BindingPointInfo GetNetworkInputBindingInfo(const std::string& name) const;
87 
88  /// Retrieves binding info (layer id and tensor info) for the network output identified by the given layer name.
89  BindingPointInfo GetNetworkOutputBindingInfo(const std::string& name) const;
90 
91  /// Retrieve version in X.Y.Z form
92  static const std::string GetVersion();
93 
94  TfParserImpl();
95  ~TfParserImpl() = default;
96 
97  TfParserImpl(const TfParserImpl&) = delete;
98  TfParserImpl& operator=(const TfParserImpl&) = delete;
99 
100  /// Parses a GraphDef loaded into memory from one of the other CreateNetwork*.
101  armnn::INetworkPtr CreateNetworkFromGraphDef(const tensorflow::GraphDef& graphDef,
102  const std::map<std::string, armnn::TensorShape>& inputShapes,
103  const std::vector<std::string>& requestedOutputs);
104 
105  /// Sets up variables and then performs BFS to parse all nodes.
106  void LoadGraphDef(const tensorflow::GraphDef& graphDef);
107 
108  /// Parses a given node, assuming nodes before it in the graph have been done.
109  void LoadNodeDef(const tensorflow::NodeDef& nodeDef, const tensorflow::GraphDef& graphDef);
110 
111  /// Handling identity layers as the input for Conv2D layer.
112  const tensorflow::NodeDef* ResolveIdentityNode(const tensorflow::NodeDef* nodeDef);
113  /// Finds the nodes connected as inputs of the given node in the graph.
114  std::vector<OutputOfConstNodeDef> GetTfInputNodes(const tensorflow::NodeDef& nodeDef) const;
115  /// Finds the IParsedTfOperations for the nodes connected as inputs of the given node in the graph,
116  /// and throws an exception if the number of inputs does not match the expected one.
117  /// This will automatically resolve any identity nodes. The result vector contains the parsed operation
118  /// together with the output tensor index to make the connection unambiguous.
119  std::vector<OutputOfParsedTfOperation> GetInputParsedTfOperationsChecked(const tensorflow::NodeDef& nodeDef,
120  std::size_t expectedNumInputs);
121 
122  ParsedTfOperationPtr ParseConst(const tensorflow::NodeDef& nodeDef, const tensorflow::GraphDef& graphDef);
123 
124  /// Checks if there is a pre-parsed const tensor available with the given name and Type.
125  template<typename Type>
126  bool HasParsedConstTensor(const std::string & nodeName) const;
127  template<typename Type>
128  bool HasParsedConstTensor(ParsedTfOperation* parsedTfOpPtr) const;
129 
130  unsigned int GetConstInputIndex(const std::vector<OutputOfParsedTfOperation>& inputs);
131 
132  ParsedTfOperationPtr ParseAdd(const tensorflow::NodeDef& nodeDef, const tensorflow::GraphDef& graphDef);
133  ParsedTfOperationPtr ParseAddN(const tensorflow::NodeDef& nodeDef, const tensorflow::GraphDef& graphDef);
134  ParsedTfOperationPtr ParseBiasAdd(const tensorflow::NodeDef& nodeDef, const tensorflow::GraphDef& graphDef);
135  ParsedTfOperationPtr ParseConv2D(const tensorflow::NodeDef& nodeDef, const tensorflow::GraphDef& graphDef);
136  ParsedTfOperationPtr ParseDepthwiseConv2D(const tensorflow::NodeDef& nodeDef,
137  const tensorflow::GraphDef& graphDef);
138  ParsedTfOperationPtr ParseExpandDims(const tensorflow::NodeDef& nodeDef, const tensorflow::GraphDef& graphDef);
139  ParsedTfOperationPtr ParseFusedBatchNorm(const tensorflow::NodeDef& nodeDef, const tensorflow::GraphDef& graphDef);
140  ParsedTfOperationPtr ParseConcat(const tensorflow::NodeDef& nodeDef, const tensorflow::GraphDef& graphDef);
141  ParsedTfOperationPtr ParseIdentity(const tensorflow::NodeDef& nodeDef, const tensorflow::GraphDef& graphDef);
142  ParsedTfOperationPtr ParseLrn(const tensorflow::NodeDef& nodeDef, const tensorflow::GraphDef& graphDef);
143  ParsedTfOperationPtr ParseMatMul(const tensorflow::NodeDef& nodeDef, const tensorflow::GraphDef& graphDef);
144  ParsedTfOperationPtr ParseMean(const tensorflow::NodeDef& nodeDef, const tensorflow::GraphDef& graphDef);
145  ParsedTfOperationPtr ParseMul(const tensorflow::NodeDef& nodeDef, const tensorflow::GraphDef& graphDef);
146  ParsedTfOperationPtr ParsePlaceholder(const tensorflow::NodeDef& nodeDef, const tensorflow::GraphDef& graphDef);
147  ParsedTfOperationPtr ParseRealDiv(const tensorflow::NodeDef& nodeDef, const tensorflow::GraphDef& graphDef);
148  ParsedTfOperationPtr ParseRelu(const tensorflow::NodeDef& nodeDef, const tensorflow::GraphDef& graphDef);
149  ParsedTfOperationPtr ParseRelu6(const tensorflow::NodeDef& nodeDef, const tensorflow::GraphDef& graphDef);
150  ParsedTfOperationPtr ParseReshape(const tensorflow::NodeDef& nodeDef, const tensorflow::GraphDef& graphDef);
151  ParsedTfOperationPtr ParseResizeBilinear(const tensorflow::NodeDef& nodeDef, const tensorflow::GraphDef& graphDef);
152  ParsedTfOperationPtr ParseRsqrt(const tensorflow::NodeDef& nodeDef, const tensorflow::GraphDef& graphDef);
153  ParsedTfOperationPtr ParseShape(const tensorflow::NodeDef& nodeDef, const tensorflow::GraphDef& graphDef);
154  ParsedTfOperationPtr ParseSqueeze(const tensorflow::NodeDef& nodeDef, const tensorflow::GraphDef& graphDef);
155  ParsedTfOperationPtr ParseSigmoid(const tensorflow::NodeDef& nodeDef, const tensorflow::GraphDef& graphDef);
156  ParsedTfOperationPtr ParseSoftmax(const tensorflow::NodeDef& nodeDef, const tensorflow::GraphDef& graphDef);
157  ParsedTfOperationPtr ParseSoftplus(const tensorflow::NodeDef& nodeDef, const tensorflow::GraphDef& graphDef);
158  ParsedTfOperationPtr ParseSplit(const tensorflow::NodeDef& nodeDef, const tensorflow::GraphDef& graphDef);
159  ParsedTfOperationPtr ParseStridedSlice(const tensorflow::NodeDef& nodeDef, const tensorflow::GraphDef& graphDef);
160  ParsedTfOperationPtr ParseTanh(const tensorflow::NodeDef& nodeDef, const tensorflow::GraphDef& graphDef);
161  ParsedTfOperationPtr ParseMaxPool(const tensorflow::NodeDef& nodeDef, const tensorflow::GraphDef& graphDef);
162  ParsedTfOperationPtr ParseAvgPool(const tensorflow::NodeDef& nodeDef, const tensorflow::GraphDef& graphDef);
163  ParsedTfOperationPtr ParsePooling2d(const tensorflow::NodeDef& nodeDef,
164  const tensorflow::GraphDef& graphDef,
165  armnn::PoolingAlgorithm pooltype);
166  ParsedTfOperationPtr ParseEqual(const tensorflow::NodeDef& nodeDef, const tensorflow::GraphDef& graphDef);
167  ParsedTfOperationPtr ParseMaximum(const tensorflow::NodeDef& nodeDef, const tensorflow::GraphDef& graphDef);
168  ParsedTfOperationPtr ParseMinimum(const tensorflow::NodeDef& nodeDef, const tensorflow::GraphDef& graphDef);
169  ParsedTfOperationPtr ParseGather(const tensorflow::NodeDef& nodeDef, const tensorflow::GraphDef& graphDef);
170  ParsedTfOperationPtr ParseGreater(const tensorflow::NodeDef& nodeDef, const tensorflow::GraphDef& graphDef);
171  ParsedTfOperationPtr ParsePad(const tensorflow::NodeDef& nodeDef, const tensorflow::GraphDef& graphDef);
172  ParsedTfOperationPtr ParseSub(const tensorflow::NodeDef& nodeDef, const tensorflow::GraphDef& graphDef);
173  ParsedTfOperationPtr ParseStack(const tensorflow::NodeDef& nodeDef, const tensorflow::GraphDef& graphDef);
174  ParsedTfOperationPtr ParseTranspose(const tensorflow::NodeDef& nodeDef, const tensorflow::GraphDef& graphDef);
175  ParsedTfOperationPtr AddActivationLayer(const tensorflow::NodeDef& nodeDef, armnn::ActivationDescriptor& desc);
176  ParsedTfOperationPtr AddAdditionLayer(const tensorflow::NodeDef& nodeDef, bool isBiasAdd = false);
177  ParsedTfOperationPtr AddRealDivLayer(const tensorflow::NodeDef& nodeDef);
178  ParsedTfOperationPtr AddMaximumLayer(const tensorflow::NodeDef& nodeDef);
179 
180  armnn::IConnectableLayer* AddMultiplicationLayer(const tensorflow::NodeDef& nodeDef);
181 
182  armnn::IConnectableLayer* AddFullyConnectedLayer(const tensorflow::NodeDef& matMulNodeDef,
183  const tensorflow::NodeDef* addNodeDef, const char* armnnLayerName);
184 
185  bool IsSupportedLeakyReluPattern(const tensorflow::NodeDef& mulNodeDef,
186  size_t alphaLayerIndex,
187  const OutputOfParsedTfOperation& otherOp,
188  armnn::IOutputSlot** outputOfLeakyRelu,
190 
191  std::pair<armnn::IOutputSlot*, armnn::IOutputSlot*> ProcessElementwiseInputSlots(
192  const tensorflow::NodeDef& nodeDef, const std::string& layerName);
193 
194  ParsedTfOperationPtr ProcessComparisonLayer(
195  armnn::IOutputSlot* input0Slot,
196  armnn::IOutputSlot* input1Slot,
197  armnn::IConnectableLayer* const layer,
198  const tensorflow::NodeDef& nodeDef);
199 
200  ParsedTfOperationPtr ProcessElementwiseLayer(
201  armnn::IOutputSlot* input0Slot,
202  armnn::IOutputSlot* input1Slot,
203  armnn::IConnectableLayer* const layer,
204  const tensorflow::NodeDef& nodeDef);
205 
207  const tensorflow::NodeDef& nodeDef,
208  armnn::IOutputSlot* input0Slot,
209  armnn::IOutputSlot* input1Slot,
210  const std::string& layerName);
211 
213  const tensorflow::NodeDef& nodeDef,
214  const OutputOfParsedTfOperation& opOne,
215  const OutputOfParsedTfOperation& opTwo,
216  unsigned int numberOfAddition);
217 
219  const tensorflow::NodeDef& nodeDef,
220  armnn::IConnectableLayer* layerOne,
221  armnn::IConnectableLayer* layerTwo,
222  unsigned int numberOfAddition,
223  unsigned long numberOfLayersToConnect,
224  bool isOdd);
225 
227  const tensorflow::NodeDef& nodeDef,
228  const OutputOfParsedTfOperation& op,
229  armnn::IConnectableLayer* layer);
230 
231  static std::pair<armnn::LayerBindingId, armnn::TensorInfo> GetBindingInfo(const std::string& layerName,
232  const char* bindingPointDesc,
233  const std::unordered_map<std::string, BindingPointInfo>& nameToBindingInfo);
234 
235  void TrackInputBinding(armnn::IConnectableLayer* layer,
237  const armnn::TensorInfo& tensorInfo);
238 
239  void TrackOutputBinding(armnn::IConnectableLayer* layer,
241  const armnn::TensorInfo& tensorInfo);
242 
243  static void TrackBindingPoint(armnn::IConnectableLayer* layer, armnn::LayerBindingId id,
244  const armnn::TensorInfo& tensorInfo,
245  const char* bindingPointDesc,
246  std::unordered_map<std::string, BindingPointInfo>& nameToBindingInfo);
247 
248  void Cleanup();
249 
250  /// The network we're building. Gets cleared after it is passed to the user.
252 
253  using OperationParsingFunction = ParsedTfOperationPtr(TfParserImpl::*)(const tensorflow::NodeDef& nodeDef,
254  const tensorflow::GraphDef& graphDef);
255 
256  /// Map of TensorFlow operation names to parsing member functions.
257  static const std::map<std::string, OperationParsingFunction> ms_OperationNameToParsingFunctions;
258 
259  static const std::list<std::string> m_ControlInputs;
260 
261  std::map<std::string, armnn::TensorShape> m_InputShapes;
262  std::vector<std::string> m_RequestedOutputs;
263 
264  /// Map of nodes extracted from the GraphDef to speed up parsing.
265  std::unordered_map<std::string, const tensorflow::NodeDef*> m_NodesByName;
266 
267  std::unordered_map<std::string, ParsedTfOperationPtr> m_ParsedTfOperations;
268 
269  /// Maps input layer names to their corresponding ids and tensor info.
270  std::unordered_map<std::string, BindingPointInfo> m_NetworkInputsBindingInfo;
271 
272  /// Maps output layer names to their corresponding ids and tensor info.
273  std::unordered_map<std::string, BindingPointInfo> m_NetworkOutputsBindingInfo;
274 };
275 
276 }
WithOutputTensorIndex(T &&value, unsigned int index)
Definition: TfParser.hpp:55
std::map< std::string, armnn::TensorShape > m_InputShapes
Definition: TfParser.hpp:261
Interface for a layer that is connectable to other layers via InputSlots and OutputSlots.
Definition: INetwork.hpp:62
armnn::BindingPointInfo BindingPointInfo
Definition: ITfParser.hpp:19
WithOutputTensorIndex(const T &value, unsigned int index)
Definition: TfParser.hpp:51
Copyright (c) 2021 ARM Limited and Contributors.
armnn::INetworkPtr m_Network
The network we&#39;re building. Gets cleared after it is passed to the user.
Definition: TfParser.hpp:251
std::unordered_map< std::string, ParsedTfOperationPtr > m_ParsedTfOperations
Definition: TfParser.hpp:267
PoolingAlgorithm
Definition: Types.hpp:104
std::vector< std::string > m_RequestedOutputs
Definition: TfParser.hpp:262
const std::string GetVersion()
Definition: Utils.cpp:77
int LayerBindingId
Type of identifiers for bindable layers (inputs, outputs).
Definition: Types.hpp:210
std::unordered_map< std::string, BindingPointInfo > m_NetworkInputsBindingInfo
Maps input layer names to their corresponding ids and tensor info.
Definition: TfParser.hpp:270
std::unique_ptr< ParsedTfOperation > ParsedTfOperationPtr
Definition: TfParser.hpp:35
flatbuffers::Offset< AdditionLayer > CreateAdditionLayer(flatbuffers::FlatBufferBuilder &_fbb, flatbuffers::Offset< armnnSerializer::LayerBase > base=0)
An output connection slot for a layer.
Definition: INetwork.hpp:38
WithOutputTensorIndex wraps a value and an index.
Definition: TfParser.hpp:46
An ActivationDescriptor for the ActivationLayer.
Definition: Descriptors.hpp:25
static const std::list< std::string > m_ControlInputs
Definition: TfParser.hpp:259
ParsedTfOperationPtr(TfParserImpl::*)(const tensorflow::NodeDef &nodeDef, const tensorflow::GraphDef &graphDef) OperationParsingFunction
Definition: TfParser.hpp:254
std::unordered_map< std::string, const tensorflow::NodeDef * > m_NodesByName
Map of nodes extracted from the GraphDef to speed up parsing.
Definition: TfParser.hpp:265
std::unique_ptr< INetwork, void(*)(INetwork *network)> INetworkPtr
Definition: INetwork.hpp:173
static const std::map< std::string, OperationParsingFunction > ms_OperationNameToParsingFunctions
Map of TensorFlow operation names to parsing member functions.
Definition: TfParser.hpp:257
std::unordered_map< std::string, BindingPointInfo > m_NetworkOutputsBindingInfo
Maps output layer names to their corresponding ids and tensor info.
Definition: TfParser.hpp:273