Avoid unnecessary copies of ModelProto from being made in the InferenceSession class (#3012)

* Avoid unneccesary copy creations of ModelProto

* Comment nit

* Nuit

* Comment refactoring

* Comment refactoring

* Fix build break

* Fix a few more instances where copies take place
This commit is contained in:
Hariharan Seshadri 2020-02-12 18:54:11 -08:00 committed by GitHub
parent 69bc8ce3c2
commit c9f18756b9
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 22 additions and 19 deletions

View file

@ -96,7 +96,7 @@ Model::Model(std::unique_ptr<ModelProto> model_proto, const IOnnxRuntimeOpSchema
}
if (!model_proto->has_ir_version() || model_proto->ir_version() > ONNX_NAMESPACE::Version::IR_VERSION) {
throw std::invalid_argument("Unknown model file format version.");
throw std::invalid_argument("Unknown model file format version.");
}
model_proto_ = std::move(model_proto);
@ -394,14 +394,14 @@ Status Model::LoadFromBytes(int count, void* p_bytes, /*out*/ ONNX_NAMESPACE::Mo
Status Model::LoadFromBytes(int count, void* p_bytes, /*out*/ std::shared_ptr<Model>& p_model,
const IOnnxRuntimeOpSchemaRegistryList* local_registries, const logging::Logger& logger) {
ModelProto model_proto;
auto model_proto = onnxruntime::make_unique<ModelProto>();
auto status = LoadFromBytes(count, p_bytes, model_proto);
auto status = LoadFromBytes(count, p_bytes, *model_proto);
if (!status.IsOK()) {
return status;
}
p_model = std::make_shared<Model>(model_proto, local_registries, logger);
p_model = std::make_shared<Model>(std::move(model_proto), local_registries, logger);
ORT_RETURN_IF_ERROR(p_model->MainGraph().Resolve(true));
@ -441,11 +441,11 @@ Status Model::Load(int fd, ONNX_NAMESPACE::ModelProto& model_proto) {
Status Model::Load(int fd, std::shared_ptr<Model>& p_model, const IOnnxRuntimeOpSchemaRegistryList* local_registries,
const logging::Logger& logger) {
ModelProto model_proto;
auto model_proto = onnxruntime::make_unique<ModelProto>();
ORT_RETURN_IF_ERROR(Load(fd, model_proto));
ORT_RETURN_IF_ERROR(Load(fd, *model_proto));
p_model = std::make_shared<Model>(model_proto, local_registries, logger);
p_model = std::make_shared<Model>(std::move(model_proto), local_registries, logger);
ORT_RETURN_IF_ERROR(p_model->MainGraph().Resolve(true));

View file

@ -372,9 +372,10 @@ common::Status InferenceSession::Load(std::function<common::Status(std::shared_p
// all steps complete, mark the model as loaded.
is_model_loaded_ = true;
// since model load was successful, we don't need to hang on to the member 'model_proto_' anymore
// (free up the resource if applicable - if the unique_ptr is a nullptr, reset() doesn't do anything)
model_proto_.reset();
// model_proto_ should either - 1) always have been a nullptr if the ModelProto was never parsed in the ctor (or)
// 2) should have become a nullptr by passing on the ownership of the ModelProto resource it was pointing to,
// to the Model instance
ORT_ENFORCE(model_proto_ == nullptr, "Failed to clear up model_proto_ in Inference Session");
telemetry_.event_name_ = event_name;
@ -451,6 +452,7 @@ common::Status InferenceSession::Load(const ModelProto& model_proto) {
AddCustomOpDomains({domain.get()});
}
#endif
// This call will create a copy of model_proto and the constructed model instance will own the copy thereafter
return onnxruntime::Model::Load(model_proto, model, HasLocalSchema() ? &custom_schema_registries_ : nullptr,
*session_logger_);
};
@ -487,21 +489,21 @@ common::Status InferenceSession::Load(std::istream& model_istream) {
}
auto loader = [this, &model_istream](std::shared_ptr<onnxruntime::Model>& model) {
ModelProto model_proto;
auto model_proto = onnxruntime::make_unique<ONNX_NAMESPACE::ModelProto>();
google::protobuf::io::IstreamInputStream zero_copy_input(&model_istream);
const bool result = model_proto.ParseFromZeroCopyStream(&zero_copy_input) && model_istream.eof();
const bool result = model_proto->ParseFromZeroCopyStream(&zero_copy_input) && model_istream.eof();
if (!result) {
return Status(common::ONNXRUNTIME, common::INVALID_PROTOBUF,
"Failed to load model because protobuf parsing failed.");
}
#ifdef ENABLE_LANGUAGE_INTEROP_OPS
LoadInterOp(model_proto, interop_domains_, [&](const char* msg) { LOGS(*session_logger_, WARNING) << msg; });
LoadInterOp(*model_proto, interop_domains_, [&](const char* msg) { LOGS(*session_logger_, WARNING) << msg; });
for (const auto& domain : interop_domains_) {
AddCustomOpDomains({domain.get()});
}
#endif
return onnxruntime::Model::Load(model_proto, model, HasLocalSchema() ? &custom_schema_registries_ : nullptr,
return onnxruntime::Model::Load(std::move(model_proto), model, HasLocalSchema() ? &custom_schema_registries_ : nullptr,
*session_logger_);
};
@ -516,21 +518,21 @@ common::Status InferenceSession::Load(const void* model_data, int model_data_len
}
auto loader = [this, model_data, model_data_len](std::shared_ptr<onnxruntime::Model>& model) {
ModelProto model_proto;
auto model_proto = onnxruntime::make_unique<ONNX_NAMESPACE::ModelProto>();
const bool result = model_proto.ParseFromArray(model_data, model_data_len);
const bool result = model_proto->ParseFromArray(model_data, model_data_len);
if (!result) {
return Status(common::ONNXRUNTIME, common::INVALID_PROTOBUF,
"Failed to load model because protobuf parsing failed.");
}
#ifdef ENABLE_LANGUAGE_INTEROP_OPS
LoadInterOp(model_proto, interop_domains_, [&](const char* msg) { LOGS(*session_logger_, WARNING) << msg; });
LoadInterOp(*model_proto, interop_domains_, [&](const char* msg) { LOGS(*session_logger_, WARNING) << msg; });
for (const auto& domain : interop_domains_) {
AddCustomOpDomains({domain.get()});
}
#endif
return onnxruntime::Model::Load(model_proto, model, HasLocalSchema() ? &custom_schema_registries_ : nullptr,
return onnxruntime::Model::Load(std::move(model_proto), model, HasLocalSchema() ? &custom_schema_registries_ : nullptr,
*session_logger_);
};
@ -551,7 +553,8 @@ common::Status InferenceSession::Load() {
AddCustomOpDomains({domain.get()});
}
#endif
return Model::Load(*this->model_proto_, model, HasLocalSchema() ? &custom_schema_registries_ : nullptr,
// Pass on ownership of the parsed ModelProto to the Model instance (its job here is done by this stage)
return Model::Load(std::move(this->model_proto_), model, HasLocalSchema() ? &custom_schema_registries_ : nullptr,
*session_logger_);
};