Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions cmake/onnxruntime_providers_openvino.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
onnxruntime_add_include_to_target(onnxruntime_providers_openvino onnxruntime_common onnx)
install(FILES ${PROJECT_SOURCE_DIR}/../include/onnxruntime/core/providers/openvino/openvino_provider_factory.h
DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/onnxruntime/)
set_target_properties(onnxruntime_providers_openvino PROPERTIES CXX_STANDARD 20)
set_target_properties(onnxruntime_providers_openvino PROPERTIES LINKER_LANGUAGE CXX)
set_target_properties(onnxruntime_providers_openvino PROPERTIES FOLDER "ONNXRuntime")
if(NOT MSVC)
Expand Down
14 changes: 14 additions & 0 deletions include/onnxruntime/core/graph/graph.h
Original file line number Diff line number Diff line change
Expand Up @@ -571,6 +571,13 @@ class Node {
gsl::span<NodeArg* const> output_args,
const NodeAttributes* attributes,
std::string_view domain);
void Init(std::string_view name,
std::string_view op_type,
std::string_view description,
gsl::span<NodeArg* const> input_args,
gsl::span<NodeArg* const> output_args,
NodeAttributes&& attributes,
std::string_view domain);
#endif

#if !defined(ORT_MINIMAL_BUILD) || defined(ORT_EXTENDED_MINIMAL_BUILD)
Expand Down Expand Up @@ -952,6 +959,13 @@ class Graph { // NOLINT(clang-analyzer-optin.performance.Padding): preserve exi
const NodeAttributes* attributes = nullptr,
const std::string& domain = kOnnxDomain);

Node& AddNode(const std::string& name,
const std::string& op_type,
const std::string& description,
gsl::span<NodeArg* const> input_args,
gsl::span<NodeArg* const> output_args,
NodeAttributes&& attributes,
const std::string& domain = kOnnxDomain);
Node& AddNode(const std::string& name,
const std::string& op_type,
const std::string& description,
Expand Down
2 changes: 0 additions & 2 deletions include/onnxruntime/core/session/onnxruntime_c_api.h
Original file line number Diff line number Diff line change
Expand Up @@ -631,7 +631,6 @@ typedef struct OrtMIGraphXProviderOptions {
typedef struct OrtOpenVINOProviderOptions {
#ifdef __cplusplus
OrtOpenVINOProviderOptions() : device_type{},
enable_npu_fast_compile{},
device_id{},
num_of_threads{},
cache_dir{},
Expand All @@ -644,7 +643,6 @@ typedef struct OrtOpenVINOProviderOptions {
* Valid settings are one of: "CPU_FP32", "CPU_FP16", "GPU_FP32", "GPU_FP16"
*/
const char* device_type;
unsigned char enable_npu_fast_compile; ///< 0 = disabled, nonzero = enabled
const char* device_id;
size_t num_of_threads; ///< 0 = Use default number of threads
const char* cache_dir; // path is set to empty by default
Expand Down
65 changes: 65 additions & 0 deletions onnxruntime/core/graph/graph.cc
Original file line number Diff line number Diff line change
Expand Up @@ -915,6 +915,42 @@ void Node::Init(std::string_view name,
}
}
}
void Node::Init(std::string_view name,
std::string_view op_type,
std::string_view description,
gsl::span<NodeArg* const> input_args,
gsl::span<NodeArg* const> output_args,
NodeAttributes&& attributes,
std::string_view domain) {
name_ = name;
op_type_ = op_type;
description_ = description;
definitions_.input_defs.assign(input_args.begin(), input_args.end());
definitions_.output_defs.assign(output_args.begin(), output_args.end());
domain_ = domain;
can_be_saved_ = true;
priority_ = 0;
if (kOnnxDomainAlias == domain_) {
domain_ = kOnnxDomain;
}

// Set each arg count as 1 by default.
// It could be adjusted when resolving the node with its operator
// information.
definitions_.input_arg_count.assign(input_args.size(), 1);

attributes_ = std::move(attributes);

for (auto& name_to_attr : attributes_) {
if (utils::HasGraph(name_to_attr.second)) {
#if !defined(ORT_MINIMAL_BUILD)
CreateSubgraph(name_to_attr.first);
#else
ORT_THROW("Creating node with a subgraph via AddNode is not supported in this build.");
#endif
}
}
}
#endif // !defined(ORT_MINIMAL_BUILD) || defined(ORT_EXTENDED_MINIMAL_BUILD) || defined(ORT_MINIMAL_BUILD_CUSTOM_OPS)

#if !defined(ORT_MINIMAL_BUILD) || defined(ORT_EXTENDED_MINIMAL_BUILD)
Expand Down Expand Up @@ -3923,6 +3959,35 @@ Node& Graph::AddNode(const std::string& name,
return *node;
}

Node& Graph::AddNode(const std::string& name,
const std::string& op_type,
const std::string& description,
gsl::span<NodeArg* const> input_args,
gsl::span<NodeArg* const> output_args,
NodeAttributes&& attributes,
const std::string& domain) {
InlinedVector<NodeArg*> inputs;
InlinedVector<NodeArg*> outputs;
inputs.resize(input_args.size());
outputs.resize(output_args.size());
int i = 0;
for (auto input_arg : input_args) {
inputs[i++] = &GetOrCreateNodeArg(input_arg->Name(), input_arg->TypeAsProto());
}
i = 0;
for (auto output_arg : output_args) {
outputs[i++] = &GetOrCreateNodeArg(output_arg->Name(), output_arg->TypeAsProto());
}

const gsl::not_null<Node*> node = AllocateNode();
node->Init(name, op_type, description, inputs, outputs, std::move(attributes), domain);
if (0 != op_type.compare(kNoOp)) {
GraphProtoSyncNeeded(true);
}

return *node;
}

bool Graph::RemoveNode(NodeIndex p_index) {
auto node = GetNode(p_index);
if (nullptr == node) {
Expand Down
26 changes: 11 additions & 15 deletions onnxruntime/core/providers/openvino/backend_manager.cc
Original file line number Diff line number Diff line change
Expand Up @@ -155,32 +155,28 @@ Status BackendManager::ExportCompiledBlobAsEPCtxNode(const onnxruntime::GraphVie
auto compiled_model = concrete_backend_->GetOVCompiledModel();
std::string graph_name = "";
// Epctx file path from SO is mapped to cache_dir variable for OVEP for readability
if (global_context_.cache_dir != "") {
if (!global_context_.cache_dir.empty()) {
graph_name = global_context_.cache_dir;
} else {
graph_name = global_context_.onnx_model_path_name;
// Remove extension so we can append suffix to form the complete name of output graph
graph_name = [&]() {
size_t dot = graph_name.find_last_of(".");
if (dot == std::string::npos) return graph_name;
return graph_name.substr(0, dot);
}();
graph_name = graph_name + "_ctx.onnx";
size_t dot = global_context_.onnx_model_path_name.find_last_of(".");
graph_name = graph_name.substr(0, dot);
if (dot != std::string::npos) graph_name += "_ctx.onnx";
}

// If embed_mode, then pass on the serialized blob
// If not embed_mode, dump the blob here and only pass on the path to the blob
if (global_context_.ep_context_embed_mode) {
std::ostringstream model_blob_stream;
compiled_model.export_model(model_blob_stream);
model_blob_str = model_blob_stream.str();
ORT_ENFORCE(model_blob_str.size() != 0);
model_blob_str = std::move(model_blob_stream).str();
if (model_blob_str.empty()) {
ORT_THROW("Model blob stream is empty after exporting the compiled model.");
}
} else {
// Remove extension so we can append suffix to form the complete name of output graph
auto blob_name = [&]() {
size_t dot = graph_name.find_last_of(".");
if (dot == std::string::npos) return graph_name;
return graph_name.substr(0, dot);
}();
auto blob_name = graph_name.substr(0, graph_name.find_last_of("."));
std::ofstream blob_file(blob_name + ".blob",
std::ios::out | std::ios::trunc | std::ios::binary);
if (!blob_file) {
Expand All @@ -194,7 +190,7 @@ Status BackendManager::ExportCompiledBlobAsEPCtxNode(const onnxruntime::GraphVie
graph_name,
logger,
global_context_.ep_context_embed_mode,
model_blob_str,
std::move(model_blob_str),
openvino_sdk_version_));

return Status::OK();
Expand Down
27 changes: 16 additions & 11 deletions onnxruntime/core/providers/openvino/backends/basic_backend.cc
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,6 @@ BasicBackend::BasicBackend(const ONNX_NAMESPACE::ModelProto& model_proto,
exe_network_ = global_context_.ie_core.ImportModel(model_stream,
remote_context_,
subgraph_context_.subgraph_name);
ie_cnn_network_ = exe_network_.Get().get_runtime_model();
} else if ((global_context.device_type.find("GPU") != std::string::npos) &&
(global_context_.context != nullptr)) {
LOGS_DEFAULT(INFO) << log_tag << "IO Buffering Enabled";
Expand All @@ -75,7 +74,6 @@ BasicBackend::BasicBackend(const ONNX_NAMESPACE::ModelProto& model_proto,
ie_cnn_network_ = CreateOVModel(model_proto, global_context_, subgraph_context_, const_outputs_map_);
exe_network_ = global_context_.ie_core.CompileModel(
ie_cnn_network_, remote_context_, subgraph_context_.subgraph_name);
ie_cnn_network_ = exe_network_.Get().get_runtime_model();
} else {
ie_cnn_network_ = CreateOVModel(model_proto, global_context_, subgraph_context_, const_outputs_map_);
exe_network_ = global_context_.ie_core.CompileModel(
Expand All @@ -91,7 +89,15 @@ BasicBackend::BasicBackend(const ONNX_NAMESPACE::ModelProto& model_proto,
device_config,
global_context_.ep_context_embed_mode,
subgraph_context_.subgraph_name);
ie_cnn_network_ = exe_network_.Get().get_runtime_model();
// ie_cnn_network_ = exe_network_.Get().get_runtime_model();
} else if (global_context_.export_ep_ctx_blob &&
hw_target.find("NPU") != std::string::npos) {
std::shared_ptr<ov::Model> ov_model;
{
const std::string model = model_proto.SerializeAsString();
ov_model = global_context_.ie_core.Get().read_model(model, ov::Tensor());
}
exe_network_ = OVExeNetwork(global_context_.ie_core.Get().compile_model(ov_model, hw_target, device_config));
} else if ((!subgraph_context_.has_dynamic_input_shape) &&
((hw_target.find("AUTO") == std::string::npos) ||
(global_context_.OpenVINO_Version.at(0) >= 2024 && global_context_.OpenVINO_Version.at(1) > 2))) {
Expand All @@ -102,7 +108,6 @@ BasicBackend::BasicBackend(const ONNX_NAMESPACE::ModelProto& model_proto,
hw_target,
device_config,
subgraph_context_.subgraph_name);
ie_cnn_network_ = exe_network_.Get().get_runtime_model();
} else { // For all other types use ov::Model Type
ie_cnn_network_ = CreateOVModel(model_proto, global_context_, const_outputs_map_);
exe_network_ = global_context_.ie_core.CompileModel(
Expand Down Expand Up @@ -270,14 +275,14 @@ void BasicBackend::StartAsyncInference(Ort::KernelContext& context, OVInferReque
input_tensor_shape[tensor_iter] = *i;
tensor_iter += 1;
}
auto input = ie_cnn_network_->get_parameters().at(input_idx);
auto input = graph_input_info.at(input_idx);
OVTensorPtr tensor_ptr;
// avoid input copies on the CPU device
if (global_context_.device_type.find("CPU") != std::string::npos) {
tensor_ptr = std::make_shared<ov::Tensor>(input->get_element_type(), input_tensor_shape,
tensor_ptr = std::make_shared<ov::Tensor>(input.get_element_type(), input_tensor_shape,
(void*)tensor_data);
} else {
tensor_ptr = std::make_shared<ov::Tensor>(input->get_element_type(), input_tensor_shape);
tensor_ptr = std::make_shared<ov::Tensor>(input.get_element_type(), input_tensor_shape);
FillInputBlob(tensor_ptr, batch_slice_idx, input_name, context, subgraph_context_);
}

Expand Down Expand Up @@ -341,9 +346,9 @@ void BasicBackend::StartRemoteAsyncInference(Ort::KernelContext& context, OVInfe
const void* tensor_data = tensor.GetTensorRawData();
const cl::Buffer* shared_buffer_const = static_cast<const cl::Buffer*>(tensor_data);
// Create an Input Remote Blob
auto input = ie_cnn_network_->get_parameters().at(0);
auto input = graph_input_info.at(0);
auto remote_blob = remote_context_->create_tensor(
input->get_element_type(), input->get_shape(), *shared_buffer_const);
input.get_element_type(), input.get_shape(), *shared_buffer_const);
ov::Tensor tensor_remote = static_cast<ov::Tensor>(remote_blob);
OVTensorPtr tensor_ptr = std::make_shared<ov::Tensor>(tensor_remote);
infer_request->SetTensor(input_name, tensor_ptr);
Expand Down Expand Up @@ -392,9 +397,9 @@ void BasicBackend::StartRemoteAsyncInference(Ort::KernelContext& context, OVInfe
const void* tensor_data = tensor.GetTensorRawData();
const cl::Buffer* shared_buffer_const = static_cast<const cl::Buffer*>(tensor_data);
// Create a shared Blob, set the Infer Request Output Blob
auto output = ie_cnn_network_->get_results().at(0);
auto output = graph_output_info.at(0);
auto remote_tensor =
remote_context_->create_tensor(output->get_element_type(), output->get_shape(), *shared_buffer_const);
remote_context_->create_tensor(output.get_element_type(), output.get_shape(), *shared_buffer_const);
ov::Tensor tensor_t = static_cast<ov::Tensor>(remote_tensor);
OVTensorPtr tensor_ptr = std::make_shared<ov::Tensor>(tensor_t);
try {
Expand Down
1 change: 0 additions & 1 deletion onnxruntime/core/providers/openvino/contexts.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ namespace openvino_ep {
struct GlobalContext {
OVCore ie_core;
bool is_wholly_supported_graph = false;
bool enable_npu_fast_compile = false;
bool enable_opencl_throttling = false;
bool disable_dynamic_shapes = false;
bool ep_context_embed_mode = true;
Expand Down
Loading