ArmNN
 22.02
OnnxParser.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 #include "google/protobuf/repeated_field.h"
9 #include <unordered_map>
10 
11 #include <onnx/onnx.pb.h>
12 
13 
14 namespace armnn
15 {
16 class TensorInfo;
17 enum class ActivationFunction;
18 }
19 
20 namespace armnnOnnxParser
21 {
22 
23 using ModelPtr = std::unique_ptr<onnx::ModelProto>;
24 
26 {
27 
28 using OperationParsingFunction = void(OnnxParserImpl::*)(const onnx::NodeProto& NodeProto);
29 
30 public:
31 
32  using GraphPtr = std::unique_ptr<onnx::GraphProto>;
33 
34  /// Create the network from a protobuf binary file on disk
35  armnn::INetworkPtr CreateNetworkFromBinaryFile(const char* graphFile);
36 
37  /// Create the network from a protobuf binary file on disk, with inputShapes specified
38  armnn::INetworkPtr CreateNetworkFromBinaryFile(const char* graphFile,
39  const std::map<std::string, armnn::TensorShape>& inputShapes);
40 
41  /// Create the network from a protobuf text file on disk
42  armnn::INetworkPtr CreateNetworkFromTextFile(const char* graphFile);
43 
44  /// Create the network from a protobuf text file on disk, with inputShapes specified
45  armnn::INetworkPtr CreateNetworkFromTextFile(const char* graphFile,
46  const std::map<std::string, armnn::TensorShape>& inputShapes);
47 
48  /// Create the network directly from protobuf text in a string. Useful for debugging/testing
49  armnn::INetworkPtr CreateNetworkFromString(const std::string& protoText);
50 
51  /// Create the network directly from protobuf text in a string, with inputShapes specified.
52  /// Useful for debugging/testing
53  armnn::INetworkPtr CreateNetworkFromString(const std::string& protoText,
54  const std::map<std::string, armnn::TensorShape>& inputShapes);
55 
56  /// Retrieve binding info (layer id and tensor info) for the network input identified by the given layer name
57  BindingPointInfo GetNetworkInputBindingInfo(const std::string& name) const;
58 
59  /// Retrieve binding info (layer id and tensor info) for the network output identified by the given layer name
60  BindingPointInfo GetNetworkOutputBindingInfo(const std::string& name) const;
61 
62 public:
63 
65  ~OnnxParserImpl() = default;
66 
67  static ModelPtr LoadModelFromBinaryFile(const char * fileName);
68  static ModelPtr LoadModelFromTextFile(const char * fileName);
69  static ModelPtr LoadModelFromString(const std::string& inputString);
70 
71  /// Retrieve inputs names
72  static std::vector<std::string> GetInputs(ModelPtr& model);
73 
74  /// Retrieve outputs names
75  static std::vector<std::string> GetOutputs(ModelPtr& model);
76 
77  /// Retrieve version in X.Y.Z form
78  static const std::string GetVersion();
79 
80 private:
81 
82  /// Parses a ModelProto loaded into memory from one of the other CreateNetwork*
83  armnn::INetworkPtr CreateNetworkFromModel(onnx::ModelProto& model);
84 
85  /// Parse every node and make the connection between the resulting tensors
86  void LoadGraph();
87 
88  void SetupInfo(const google::protobuf::RepeatedPtrField<onnx::ValueInfoProto >* list);
89 
90  std::vector<armnn::TensorInfo> ComputeOutputInfo(
91  std::vector<std::string> outNames,
92  const armnn::IConnectableLayer* layer,
93  std::vector<armnn::TensorShape> inputShapes,
94  const onnx::TensorProto::DataType& type = onnx::TensorProto::FLOAT);
95 
96  void DetectFullyConnected();
97 
98  template <typename Location>
99  void GetInputAndParam(const onnx::NodeProto& node,
100  std::string* inputName,
101  std::string* constName,
102  const Location& location);
103 
104  template <typename Location>
105  void To1DTensor(const std::string &name, const Location& location);
106 
107  //Broadcast Preparation functions
108  std::pair<std::string, std::string> AddPrepareBroadcast(const std::string& input0, const std::string& input1);
109  void PrependForBroadcast(const std::string& outputName, const std::string& input0, const std::string& input1);
110 
111  void AddConvLayerWithDepthwiseConv(const onnx::NodeProto& node, const armnn::Convolution2dDescriptor& convDesc);
112  void AddFullyConnected(const onnx::NodeProto& matmulNode, const onnx::NodeProto* addNode = nullptr);
113  void AddPoolingLayer(const onnx::NodeProto& nodeProto, armnn::Pooling2dDescriptor& desc);
114 
115  void CreateConstantLayer(const std::string& tensorName, const std::string& layerName);
116  void CreateInt64ConstantLayer(const std::string& tensorName, const std::string& layerName);
117  void CreateReshapeLayer(const std::string& inputName,
118  const std::string& outputName,
119  const std::string& layerName);
120 
121  void ParseActivation(const onnx::NodeProto& nodeProto, const armnn::ActivationFunction func);
122  void ParseClip(const onnx::NodeProto& nodeProto);
123  void ParseSigmoid(const onnx::NodeProto& nodeProto);
124  void ParseTanh(const onnx::NodeProto& nodeProto);
125  void ParseRelu(const onnx::NodeProto& nodeProto);
126  void ParseLeakyRelu(const onnx::NodeProto& nodeProto);
127 
128  void ParseAdd(const onnx::NodeProto& nodeProto);
129  void ParseAveragePool(const onnx::NodeProto& nodeProto);
130  void ParseBatchNormalization(const onnx::NodeProto& node);
131  void ParseConcat(const onnx::NodeProto& nodeProto);
132  void ParseConstant(const onnx::NodeProto& nodeProto);
133  void ParseConv(const onnx::NodeProto& nodeProto);
134  void ParseFlatten(const onnx::NodeProto& node);
135  void ParseGather(const onnx::NodeProto& node);
136  void ParseGemm(const onnx::NodeProto& node);
137  void ParseGlobalAveragePool(const onnx::NodeProto& node);
138  void ParseMaxPool(const onnx::NodeProto& nodeProto);
139  void ParseShape(const onnx::NodeProto& node);
140  void ParseReshape(const onnx::NodeProto& nodeProto);
141  void ParseUnsqueeze(const onnx::NodeProto& nodeProto);
142 
143  void RegisterInputSlot(armnn::IConnectableLayer* layer,
144  const std::string& tensorId,
145  unsigned int slotIndex);
146  void RegisterInputSlots(armnn::IConnectableLayer* layer, const std::vector<std::string>& tensorIndexes);
147  void RegisterOutputSlots(armnn::IConnectableLayer* layer, const std::vector<std::string>& tensorIndexes);
148 
149  void SetupInputLayers();
150  void SetupOutputLayers();
151 
152  void ResetParser();
153  void Cleanup();
154 
155  std::pair<armnn::ConstTensor, std::unique_ptr<float[]>>
156  CreateConstTensor(const std::string name,
158 
159  std::pair<armnn::ConstTensor, std::unique_ptr<int32_t[]>>
160  CreateInt64ConstTensor(const std::string name,
162 
163  template <typename TypeList, typename Location>
164  void ValidateInputs(const onnx::NodeProto& node,
165  TypeList validInputs,
166  const Location& location);
167 
168  /// The network we're building. Gets cleared after it is passed to the user
169  armnn::INetworkPtr m_Network;
170 
171  /// Ptr to the graph we're building the network from
172  GraphPtr m_Graph;
173 
174  /// Map of the information for every tensor
175  struct OnnxTensor
176  {
177  std::unique_ptr<armnn::TensorInfo> m_info;
178  std::unique_ptr<const onnx::TensorProto> m_tensor;
180 
181  OnnxTensor() : m_info(nullptr), m_tensor(nullptr), m_dtype(onnx::TensorProto::FLOAT) { }
182  bool isConstant() { return m_tensor != nullptr; }
183  };
184 
185  std::unordered_map<std::string, OnnxTensor> m_TensorsInfo;
186 
187  /// map of onnx operation names to parsing member functions
188  static const std::map<std::string, OperationParsingFunction> m_ParserFunctions;
189 
190  /// A mapping of an output slot to each of the input slots it should be connected to
191  /// The outputSlot is from the layer that creates this tensor as one of its ouputs
192  /// The inputSlots are from the layers that use this tensor as one of their inputs
193  struct TensorSlots
194  {
195  armnn::IOutputSlot* outputSlot;
196  std::vector<armnn::IInputSlot*> inputSlots;
197 
198  TensorSlots() : outputSlot(nullptr) { }
199  };
200  /// Map of the tensor names to their connections for the connections of the layers of the graph
201  std::unordered_map<std::string, TensorSlots> m_TensorConnections;
202 
203  /// Map of the tensor names to their node and index in graph.node()
204  std::unordered_map<std::string, std::pair<const onnx::NodeProto*, int>> m_OutputsMap;
205 
206  /// Number of times a specific node (identified by its index number) was used as input
207  /// and list of the nodes it was fused with
208  struct UsageSummary
209  {
210  std::vector<size_t> fusedWithNodes;
211  size_t inputForNodes;
212 
213  UsageSummary() : fusedWithNodes({}), inputForNodes(0) { }
214 
215  };
216 
217  std::vector<UsageSummary> m_OutputsFusedAndUsed;
218 
219  std::map<std::string, armnn::TensorShape> m_InputShapes;
220 
221  std::unordered_map<std::string, armnn::TensorInfo> m_InputInfos;
222 
223  std::unordered_map<std::string, armnn::TensorInfo> m_OutputInfos;
224 
225 };
226 }
Interface for a layer that is connectable to other layers via InputSlots and OutputSlots.
Definition: INetwork.hpp:66
A Convolution2dDescriptor for the Convolution2dLayer.
flatbuffers::Offset< ConstTensor > CreateConstTensor(flatbuffers::FlatBufferBuilder &_fbb, flatbuffers::Offset< armnnSerializer::TensorInfo > info=0, armnnSerializer::ConstTensorData data_type=armnnSerializer::ConstTensorData_NONE, flatbuffers::Offset< void > data=0)
Copyright (c) 2021 ARM Limited and Contributors.
const std::string GetVersion()
Definition: Utils.cpp:77
std::unique_ptr< onnx::GraphProto > GraphPtr
Definition: OnnxParser.hpp:32
std::unique_ptr< onnx::ModelProto > ModelPtr
Definition: OnnxParser.hpp:23
DataType
Definition: Types.hpp:35
flatbuffers::Offset< ReshapeLayer > CreateReshapeLayer(flatbuffers::FlatBufferBuilder &_fbb, flatbuffers::Offset< armnnSerializer::LayerBase > base=0, flatbuffers::Offset< armnnSerializer::ReshapeDescriptor > descriptor=0)
An output connection slot for a layer.
Definition: INetwork.hpp:40
EmptyOptional is used to initialize the Optional class in case we want to have default value for an O...
Definition: Optional.hpp:32
flatbuffers::Offset< ConstantLayer > CreateConstantLayer(flatbuffers::FlatBufferBuilder &_fbb, flatbuffers::Offset< armnnSerializer::LayerBase > base=0, flatbuffers::Offset< armnnSerializer::ConstTensor > input=0)
std::unique_ptr< INetwork, void(*)(INetwork *network)> INetworkPtr
Definition: INetwork.hpp:241
armnn::BindingPointInfo BindingPointInfo
Definition: IOnnxParser.hpp:17
A Pooling2dDescriptor for the Pooling2dLayer.
ActivationFunction
Definition: Types.hpp:73