Caffe2 - C++ API
A deep learning, cross platform ML framework
onnxifi_transformer.h
1 #pragma once
2 
3 #include <cstdint>
4 #include <string>
5 #include <unordered_map>
6 #include <vector>
7 
8 #include "onnx/onnx_pb.h"
9 
10 #include "caffe2/core/operator.h"
11 #include "caffe2/onnx/onnxifi_init.h"
12 #include "caffe2/opt/backend_transformer_base.h"
13 
14 namespace caffe2 {
15 namespace onnx {
16 class OnnxExporter;
17 }
18 
20  explicit OnnxifiTransformerOptions() : bound_shape_spec(0, 0) {}
21 
22  // Dump onnx model for debugging
23  bool debug{false};
24 
25  // Pass serialized onnx model if true, otherwise pass serialized c2 model
26  bool use_onnx{true};
27 
28  // Whether to attach AdjustBatch ops or not. In order to maintain static
29  // shapes to the backend, most of the time, we need to add AdjustBatch ops to
30  // the inputs/outputs of the Onnxifi op. But if backend itself supports max
31  // batch size, we don't need to do it.
32  bool add_adjust_batch_ops{true};
33 
34  // Minimum number of ops to create an onnxifi op. If the subgraph is too
35  // small, it doesn't make sense to lower it to backend.
36  size_t min_ops{1};
37 
38  // Bound shape spec
39  BoundShapeSpec bound_shape_spec;
40 };
41 
42 class CAFFE2_API OnnxifiTransformer final : public BackendTransformerBase {
43  public:
44  explicit OnnxifiTransformer(const OnnxifiTransformerOptions& opts);
45  ~OnnxifiTransformer() override;
46 
47  void transform(
48  Workspace* ws,
49  NetDef* pred_net,
50  const std::vector<std::string>& weight_names,
51  const std::unordered_map<std::string, TensorShape>& shape_hints,
52  const std::unordered_set<int>& blacklisted_ops) override;
53 
54  private:
55  // Since we create new tensors during the conversion process, we actually need
56  // into inject them into the original workspace
57  // Since our onnx exporter uses std::unordered_map<std::string, TensorShape>
58  // as lut, we need to include an extra copy of shape info and maintain them
59  // together
60  caffe2::NetDef SubnetToOnnxifiOpViaOnnx(
61  const caffe2::NetDef& net,
62  const std::unordered_set<std::string>& weights_in_ws,
63  Workspace* ws,
64  onnx::OnnxExporter* exporter,
65  ShapeInfoMap* shape_hints);
66 
67  // Convert a cutoff subgraph net to an Onnxifi op
68  caffe2::NetDef SubnetToOnnxifiOpViaC2(
69  const caffe2::NetDef& net,
70  const std::unordered_set<std::string>& weights_in_ws,
71  const ShapeInfoMap& shape_hints);
72 
73  // We already have all the ops and external inputs and outputs!
74  OperatorDef BuildOnnxifiOp(
75  const std::string& onnx_model_str,
76  const std::unordered_map<std::string, TensorShape>& output_size_hints,
77  const std::unordered_set<std::string>& initialization_list,
78  const std::vector<std::string>& external_inputs,
79  const std::vector<std::string>& external_outputs);
80 
81  // Transform by passing C2 proto to backend
82  NetDef TransformViaC2(
83  NetDef* pred_net,
84  const std::unordered_set<std::string>& weights,
85  const std::unordered_set<int>& blacklisted_ops,
86  const ShapeInfoMap& shape_hints);
87 
88  // Transform by passing ONNX proto to backend
89  NetDef TransformViaOnnx(
90  Workspace* ws,
91  NetDef* pred_net,
92  const std::unordered_set<std::string>& weights,
93  const std::unordered_set<int>& blacklisted_ops,
94  ShapeInfoMap* shape_hints);
95 
96  // Query whether an operator is supported by passing C2 protobuf
97  bool supportOpC2(
98  const caffe2::OperatorDef& op,
99  const ShapeInfoMap& shape_hints,
100  const std::unordered_set<int>& blacklisted_ops,
101  onnxBackendID backend_id) const;
102 
103  // Query whether an operator is supported by passing ONNX protobuf
104  bool supportOpOnnx(
105  const caffe2::OperatorDef& op,
106  onnx::OnnxExporter* exporter,
107  const std::unordered_set<int>& blacklisted_ops,
108  onnxBackendID backend_id) const;
109 
110  // Tie the output of Gather to the scalar weight input of the
111  // SparseLengthsWeighted* op. If the latter is disabled, disable the former
112  // too.
113  void tieGatherAndSparseLengthsWeightedSumOps(
114  const NetDef& net,
115  const ShapeInfoMap& shape_hints,
116  std::unordered_set<int>* blacklisted_ops) const;
117 
118  // Rule based filtering
119  void applyFilteringRules(
120  const NetDef& net,
121  const ShapeInfoMap& shape_hints,
122  std::unordered_set<int>* blacklisted_ops) const;
123 
124  // Determine backend id
125  void getBackendId();
126 
127  // Options
129 
130  // Pointer to loaded onnxifi library
131  onnxifi_library* lib_{nullptr};
132 
133  // Number of backends
134  size_t num_backends_{0};
135 
136  // backend idx
137  int idx_{0};
138 
139  // Number of Onnxifi Ops we build so far
140  int onnxifi_op_id_{0};
141 
142  // Model id
143  std::string model_id_;
144 
145  // Backned IDs
146  std::vector<onnxBackendID> backend_ids_;
147 
148  // A cache for ONNX shape hints
149  std::unordered_map<std::string, TensorShape> shape_hints_onnx_;
150 };
151 } // namespace caffe2
Workspace is a class that holds all the related objects created during runtime: (1) all blobs...
Definition: workspace.h:47
A global dictionary that holds information about what Caffe2 modules have been loaded in the current ...
Definition: blob.h:13