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