ArmNN
 21.02
CaffeParser.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
7 
8 #include "armnn/Types.hpp"
9 #include "armnn/NetworkFwd.hpp"
10 #include "armnn/Tensor.hpp"
11 
12 #include <memory>
13 #include <vector>
14 #include <unordered_map>
15 
16 namespace caffe
17 {
18 class BlobShape;
19 class LayerParameter;
20 class NetParameter;
21 }
22 
23 namespace armnnCaffeParser
24 {
25 
27 {
28 public:
29 
30  // Because we haven't looked at reducing the memory usage when loading from Text/String
31  // have to retain these functions here for the moment.
32  /// Create the network from a protobuf text file on disk
33  armnn::INetworkPtr CreateNetworkFromTextFile(
34  const char* graphFile,
35  const std::map<std::string, armnn::TensorShape>& inputShapes,
36  const std::vector<std::string>& requestedOutputs);
37 
38  /// Create the network from a protobuf binary file on the disk.
39  virtual armnn::INetworkPtr CreateNetworkFromBinaryFile(
40  const char* graphFile,
41  const std::map<std::string, armnn::TensorShape>& inputShapes,
42  const std::vector<std::string>& requestedOutputs) = 0;
43 
44 
45  /// Creates the network directly from protobuf text in a string. Useful for debugging/testing.
46  armnn::INetworkPtr CreateNetworkFromString(
47  const char* protoText,
48  const std::map<std::string, armnn::TensorShape>& inputShapes,
49  const std::vector<std::string>& requestedOutputs);
50 
51  /// Retrieves binding info (layer id and tensor info) for the network input identified by the given layer name.
52  BindingPointInfo GetNetworkInputBindingInfo(const std::string& name) const;
53 
54  /// Retrieves binding info (layer id and tensor info) for the network output identified by the given layer name.
55  BindingPointInfo GetNetworkOutputBindingInfo(const std::string& name) const;
56 
57  /// Retrieve version in X.Y.Z form
58  static const std::string GetVersion();
59 
61  virtual ~CaffeParserImpl() = default;
62 
63 protected:
64  /// Adds an armnn layer to m_Network given a Caffe LayerParameter of the correct type
65  /// and is responsible for recording any newly created IOutputSlots using SetArmnnOutputSlotForCaffeTop().
66  /// @{
67  void ParseInputLayer(const caffe::LayerParameter& layerParam);
68  void ParseConvLayer(const caffe::LayerParameter& layerParam);
69  void ParseDeconvLayer(const caffe::LayerParameter& layerParam);
70  void ParsePoolingLayer(const caffe::LayerParameter& layerParam);
71  void ParseReluLayer(const caffe::LayerParameter& layerParam);
72  void ParseLRNLayer(const caffe::LayerParameter& layerParam);
73  void ParseInnerProductLayer(const caffe::LayerParameter& layerParam);
74  void ParseSoftmaxLayer(const caffe::LayerParameter& layerParam);
75  void ParseEltwiseLayer(const caffe::LayerParameter& layerParam);
76  void ParseConcatLayer(const caffe::LayerParameter& layerParam);
77  void ParseBatchNormLayer(const caffe::LayerParameter& layerParam);
78  void ParseScaleLayer(const caffe::LayerParameter& layerParam);
79  void ParseSplitLayer(const caffe::LayerParameter& layerParam);
80  void ParseDropoutLayer(const caffe::LayerParameter& layerParam);
81  void ParseArgmaxLayer(const caffe::LayerParameter& layerParam);
82  /// @}
83 
84  /// ParseConv may use these helpers depending on the group parameter
85  /// @{
86  void AddConvLayerWithSplits(const caffe::LayerParameter& layerParam,
87  const armnn::Convolution2dDescriptor & desc,
88  unsigned int kernelW,
89  unsigned int kernelH);
90  void AddConvLayerWithDepthwiseConv(const caffe::LayerParameter& layerParam,
91  const armnn::Convolution2dDescriptor & desc,
92  unsigned int kernelW,
93  unsigned int kernelH);
94  void AddDeconvLayerWithSplits(const caffe::LayerParameter& layerParam,
96  unsigned int kernelW,
97  unsigned int kernelH);
98  /// @}
99 
100  /// Converts Caffe's protobuf tensor shape format to ArmNN's
101  armnn::TensorInfo BlobShapeToTensorInfo(const caffe::BlobShape& blobShape) const;
102 
103  void TrackInputBinding(armnn::IConnectableLayer* layer,
105  const armnn::TensorInfo& tensorInfo);
106 
107  static void TrackBindingPoint(armnn::IConnectableLayer* layer, armnn::LayerBindingId id,
108  const armnn::TensorInfo& tensorInfo,
109  const char* bindingPointDesc,
110  std::unordered_map<std::string, BindingPointInfo>& nameToBindingInfo);
111 
112  void TrackOutputBinding(armnn::IConnectableLayer* layer,
114  const armnn::TensorInfo& tensorInfo);
115 
116 
117  void SetArmnnOutputSlotForCaffeTop(const std::string& caffeTopName, armnn::IOutputSlot& armnnOutputSlot);
118 
119  /// Retrieves the Armnn IOutputSlot representing the given Caffe top.
120  /// Throws if it cannot be found (e.g. not parsed yet).
121  armnn::IOutputSlot& GetArmnnOutputSlotForCaffeTop(const std::string& caffeTopName) const;
122 
123  static std::pair<armnn::LayerBindingId, armnn::TensorInfo> GetBindingInfo(
124  const std::string& layerName,
125  const char* bindingPointDesc,
126  const std::unordered_map<std::string, BindingPointInfo>& bindingInfos);
127 
128 
129  void Cleanup();
130 
131  using OperationParsingFunction = void(CaffeParserImpl::*)(const caffe::LayerParameter& layerParam);
132 
133  /// Maps Caffe layer names to parsing member functions.
134  static const std::map<std::string, OperationParsingFunction> ms_CaffeLayerNameToParsingFunctions;
135 
136  /// maps input layer names to their corresponding ids and tensor infos
137  std::unordered_map<std::string, BindingPointInfo> m_NetworkInputsBindingInfo;
138 
139  /// maps output layer names to their corresponding ids and tensor infos
140  std::unordered_map<std::string, BindingPointInfo> m_NetworkOutputsBindingInfo;
141 
143 
144  std::map<std::string, armnn::TensorShape> m_InputShapes;
145 
146  /// As we add armnn layers we store the armnn IOutputSlot which corresponds to the Caffe tops.
147  std::unordered_map<std::string, armnn::IOutputSlot*> m_ArmnnOutputSlotForCaffeTop;
148 
149  std::vector<std::string> m_RequestedOutputs;
150 
151 
152  // Stuff which has gone to base class simply because we haven't done any
153  // memory optimisation on the text/string format. If we move this to a layer
154  // by layer parse as well these can move to the CaffeParser class.
155  std::map<std::string, const caffe::LayerParameter*> m_CaffeLayersByTopName;
156 
157  /// Parses a NetParameter loaded into memory from one of the other CreateNetwork*
158  armnn::INetworkPtr CreateNetworkFromNetParameter(
159  caffe::NetParameter& netParam,
160  const std::map<std::string, armnn::TensorShape>& inputShapes,
161  const std::vector<std::string>& requestedOutputs);
162 
163  /// does the actual conversion from caffe::NetParameter to armnn::INetwork
164  void LoadNetParam(caffe::NetParameter& netParameter);
165 
166  /// Find the Caffe layers listed as inputs (bottoms) for a given layer.
167  std::vector<const caffe::LayerParameter*> GetInputs(const caffe::LayerParameter& layerParam);
168 
169  /// Modifies the Caffe network to replace "in-place" layers (whose top() and bottom() are both the same)
170  /// with regular layers. This simplifies further parsing.
171  void ResolveInPlaceLayers(caffe::NetParameter& netParameter);
172 
173 };
174 
176 {
177 public:
178 
179  /// Create the network from a protobuf binary file on disk
180  virtual armnn::INetworkPtr CreateNetworkFromBinaryFile(
181  const char* graphFile,
182  const std::map<std::string, armnn::TensorShape>& inputShapes,
183  const std::vector<std::string>& requestedOutputs) override;
184 
185 public:
186  CaffeParser();
187 
188 };
189 }
Interface for a layer that is connectable to other layers via InputSlots and OutputSlots.
Definition: INetwork.hpp:62
std::map< std::string, armnn::TensorShape > m_InputShapes
A TransposeConvolution2dDescriptor for the TransposeConvolution2dLayer.
A Convolution2dDescriptor for the Convolution2dLayer.
Caffe networks are loaded from protobuf files (binary or text) using the protobuf library and the gen...
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_NetworkOutputsBindingInfo
maps output layer names to their corresponding ids and tensor infos
An output connection slot for a layer.
Definition: INetwork.hpp:38
static const std::map< std::string, OperationParsingFunction > ms_CaffeLayerNameToParsingFunctions
Maps Caffe layer names to parsing member functions.
std::unordered_map< std::string, BindingPointInfo > m_NetworkInputsBindingInfo
maps input layer names to their corresponding ids and tensor infos
std::pair< armnn::LayerBindingId, armnn::TensorInfo > BindingPointInfo
Definition: Tensor.hpp:261
std::unordered_map< std::string, armnn::IOutputSlot * > m_ArmnnOutputSlotForCaffeTop
As we add armnn layers we store the armnn IOutputSlot which corresponds to the Caffe tops...
std::unique_ptr< INetwork, void(*)(INetwork *network)> INetworkPtr
Definition: INetwork.hpp:173
void(CaffeParserImpl::*)(const caffe::LayerParameter &layerParam) OperationParsingFunction
std::map< std::string, const caffe::LayerParameter * > m_CaffeLayersByTopName