blob: dc2b9e9e81b8ee5f220511dec7bead9feb9f18d2 [file] [log] [blame]
#pragma once
#include <cstdint>
#include <string>
#include <unordered_map>
#include <vector>
#include "onnx/onnx_pb.h"
#include "caffe2/core/common.h"
#include "caffe2/core/operator.h"
#include "caffe2/core/workspace.h"
#include "caffe2/onnx/onnxifi_init.h"
#include "caffe2/proto/caffe2_pb.h"
namespace caffe2 {
namespace onnx {
class OnnxExporter;
}
struct OnnxifiTransformerOptions {
// Run shape inference
bool infer_shapes{false};
// Dump onnx model for debugging
bool debug{false};
// Pass serialized onnx model if true, otherwise pass serialized c2 model
bool use_onnx{true};
};
class CAFFE2_API OnnxifiTransformer final {
public:
explicit OnnxifiTransformer(const OnnxifiTransformerOptions& opts);
~OnnxifiTransformer();
void Transform(
Workspace* ws,
NetDef* pred_net,
const std::vector<std::string>& external_inputs,
const std::unordered_map<std::string, TensorShape>& shape_hints,
const std::unordered_set<int>& blacklisted_ops);
const std::unordered_map<std::string, std::string>& input_mapping() const {
return input_mapping_;
}
const std::unordered_map<std::string, std::string>& reverse_input_mapping()
const {
return reverse_input_mapping_;
}
private:
// Since we create new tensors during the conversion process, we actually need
// into inject them into the original workspace
caffe2::NetDef SubnetToOnnxifiOpViaOnnx(
const caffe2::NetDef& net,
const std::unordered_set<std::string>& weights_in_ws,
Workspace* ws,
onnx::OnnxExporter* exporter,
std::unordered_map<std::string, TensorShape>* shape_hints);
// Convert a cutoff subgraph net to an Onnxifi op
caffe2::NetDef SubnetToOnnxifiOpViaC2(
const caffe2::NetDef& net,
const std::unordered_set<std::string>& weights_in_ws,
const std::unordered_map<std::string, TensorShape>& shape_hints);
// We already have all the ops and external inputs and outputs!
OperatorDef BuildOnnxifiOp(
const std::string& onnx_model_str,
const std::unordered_map<std::string, TensorShape>& output_size_hints,
const std::unordered_set<std::string>& initialization_list,
const caffe2::NetDef& net);
CaffeMap<std::string, TensorShape> SsaRewriteAndMapNames(
Workspace* ws,
NetDef* pred_net,
const std::unordered_map<std::string, TensorShape>& input_shape_hints);
// Transform by passing C2 proto to backend
NetDef TransformViaC2(
NetDef* pred_net,
const std::unordered_set<std::string>& weights,
const std::unordered_set<int>& blacklisted_ops,
const std::unordered_map<std::string, TensorShape>& shape_hints);
// Transform by passing ONNX proto to backend
NetDef TransformViaOnnx(
Workspace* ws,
NetDef* pred_net,
const std::unordered_set<std::string>& weights,
const std::unordered_set<int>& blacklisted_ops,
std::unordered_map<std::string, TensorShape>* shape_hints);
// Options
OnnxifiTransformerOptions opts_;
// Pointer to loaded onnxifi library
onnxifi_library* lib_{nullptr};
// Number of backends
size_t num_backends_{0};
// backend idx
int idx_{0};
// Backned IDs
std::vector<onnxBackendID> backend_ids_;
// Input mapping of input name -> original input name
std::unordered_map<std::string, std::string> input_mapping_;
// Input mapping of orignal input name -> input name
std::unordered_map<std::string, std::string> reverse_input_mapping_;
};
} // namespace caffe2