ArmNN
 21.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 text file on disk
38  armnn::INetworkPtr CreateNetworkFromTextFile(const char* graphFile);
39 
40  /// Create the network directly from protobuf text in a string. Useful for debugging/testing
41  armnn::INetworkPtr CreateNetworkFromString(const std::string& protoText);
42 
43  /// Retrieve binding info (layer id and tensor info) for the network input identified by the given layer name
44  BindingPointInfo GetNetworkInputBindingInfo(const std::string& name) const;
45 
46  /// Retrieve binding info (layer id and tensor info) for the network output identified by the given layer name
47  BindingPointInfo GetNetworkOutputBindingInfo(const std::string& name) const;
48 
49 public:
50 
52  ~OnnxParserImpl() = default;
53 
54  static ModelPtr LoadModelFromBinaryFile(const char * fileName);
55  static ModelPtr LoadModelFromTextFile(const char * fileName);
56  static ModelPtr LoadModelFromString(const std::string& inputString);
57 
58  /// Retrieve inputs names
59  static std::vector<std::string> GetInputs(ModelPtr& model);
60 
61  /// Retrieve outputs names
62  static std::vector<std::string> GetOutputs(ModelPtr& model);
63 
64  /// Retrieve version in X.Y.Z form
65  static const std::string GetVersion();
66 
67 private:
68 
69  /// Parses a ModelProto loaded into memory from one of the other CreateNetwork*
70  armnn::INetworkPtr CreateNetworkFromModel(onnx::ModelProto& model);
71 
72  /// Parse every node and make the connection between the resulting tensors
73  void LoadGraph();
74 
75  void SetupInfo(const google::protobuf::RepeatedPtrField<onnx::ValueInfoProto >* list);
76 
77  std::vector<armnn::TensorInfo> ComputeOutputInfo(std::vector<std::string> outNames,
78  const armnn::IConnectableLayer* layer,
79  std::vector<armnn::TensorShape> inputShapes);
80 
81  void DetectFullyConnected();
82 
83  template <typename Location>
84  void GetInputAndParam(const onnx::NodeProto& node,
85  std::string* inputName,
86  std::string* constName,
87  const Location& location);
88 
89  template <typename Location>
90  void To1DTensor(const std::string &name, const Location& location);
91 
92  //Broadcast Preparation functions
93  std::pair<std::string, std::string> AddPrepareBroadcast(const std::string& input0, const std::string& input1);
94  void PrependForBroadcast(const std::string& outputName, const std::string& input0, const std::string& input1);
95 
96  void AddConvLayerWithDepthwiseConv(const onnx::NodeProto& node, const armnn::Convolution2dDescriptor& convDesc);
97  void AddFullyConnected(const onnx::NodeProto& matmulNode, const onnx::NodeProto* addNode = nullptr);
98  void AddPoolingLayer(const onnx::NodeProto& nodeProto, armnn::Pooling2dDescriptor& desc);
99 
100  void CreateConstantLayer(const std::string& tensorName, const std::string& layerName);
101  void CreateReshapeLayer(const std::string& inputName,
102  const std::string& outputName,
103  const std::string& layerName);
104 
105  void ParseActivation(const onnx::NodeProto& nodeProto, const armnn::ActivationFunction func);
106  void ParseClip(const onnx::NodeProto& nodeProto);
107  void ParseSigmoid(const onnx::NodeProto& nodeProto);
108  void ParseTanh(const onnx::NodeProto& nodeProto);
109  void ParseRelu(const onnx::NodeProto& nodeProto);
110  void ParseLeakyRelu(const onnx::NodeProto& nodeProto);
111 
112  void ParseAdd(const onnx::NodeProto& nodeProto);
113  void ParseAveragePool(const onnx::NodeProto& nodeProto);
114  void ParseBatchNormalization(const onnx::NodeProto& node);
115  void ParseConstant(const onnx::NodeProto& nodeProto);
116  void ParseConv(const onnx::NodeProto& nodeProto);
117  void ParseFlatten(const onnx::NodeProto& node);
118  void ParseGlobalAveragePool(const onnx::NodeProto& node);
119  void ParseMaxPool(const onnx::NodeProto& nodeProto);
120  void ParseReshape(const onnx::NodeProto& nodeProto);
121 
122  void RegisterInputSlots(armnn::IConnectableLayer* layer, const std::vector<std::string>& tensorIndexes);
123  void RegisterOutputSlots(armnn::IConnectableLayer* layer, const std::vector<std::string>& tensorIndexes);
124 
125  void SetupInputLayers();
126  void SetupOutputLayers();
127 
128  void ResetParser();
129  void Cleanup();
130 
131  std::pair<armnn::ConstTensor, std::unique_ptr<float[]>> CreateConstTensor(const std::string name);
132 
133  template <typename TypeList, typename Location>
134  void ValidateInputs(const onnx::NodeProto& node,
135  TypeList validInputs,
136  const Location& location);
137 
138  /// The network we're building. Gets cleared after it is passed to the user
139  armnn::INetworkPtr m_Network;
140 
141  /// Ptr to the graph we're building the network from
142  GraphPtr m_Graph;
143 
144  /// Map of the information for every tensor
145  struct OnnxTensor
146  {
147  std::unique_ptr<armnn::TensorInfo> m_info;
148  std::unique_ptr<const onnx::TensorProto> m_tensor;
150 
151  OnnxTensor() : m_info(nullptr), m_tensor(nullptr), m_dtype(onnx::TensorProto::FLOAT) { }
152  bool isConstant() { return m_tensor != nullptr; }
153  };
154 
155  std::unordered_map<std::string, OnnxTensor> m_TensorsInfo;
156 
157  /// map of onnx operation names to parsing member functions
158  static const std::map<std::string, OperationParsingFunction> m_ParserFunctions;
159 
160  /// A mapping of an output slot to each of the input slots it should be connected to
161  /// The outputSlot is from the layer that creates this tensor as one of its ouputs
162  /// The inputSlots are from the layers that use this tensor as one of their inputs
163  struct TensorSlots
164  {
165  armnn::IOutputSlot* outputSlot;
166  std::vector<armnn::IInputSlot*> inputSlots;
167 
168  TensorSlots() : outputSlot(nullptr) { }
169  };
170  /// Map of the tensor names to their connections for the connections of the layers of the graph
171  std::unordered_map<std::string, TensorSlots> m_TensorConnections;
172 
173  /// Map of the tensor names to their node and index in graph.node()
174  std::unordered_map<std::string, std::pair<const onnx::NodeProto*, int>> m_OutputsMap;
175 
176  /// Number of times a specific node (identified by his index number) was used as input
177  /// and list of the nodes it was fused with
178  struct UsageSummary
179  {
180  std::vector<size_t> fusedWithNodes;
181  size_t inputForNodes;
182 
183  UsageSummary() : fusedWithNodes({}), inputForNodes(0) { }
184 
185  };
186 
187  std::vector<UsageSummary> m_OutputsFusedAndUsed;
188 
189 };
190 }
Interface for a layer that is connectable to other layers via InputSlots and OutputSlots.
Definition: INetwork.hpp:62
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:32
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:38
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:173
armnn::BindingPointInfo BindingPointInfo
Definition: IOnnxParser.hpp:17
A Pooling2dDescriptor for the Pooling2dLayer.
ActivationFunction
Definition: Types.hpp:56