Skip to content

Commit 204163d

Browse files
[OVEP] Fix for precision accuracy
1 parent 60ee27a commit 204163d

File tree

4 files changed

+113
-59
lines changed

4 files changed

+113
-59
lines changed

onnxruntime/core/providers/openvino/backends/basic_backend.cc

+1-3
Original file line numberDiff line numberDiff line change
@@ -164,10 +164,8 @@ void BasicBackend::PopulateConfigValue(ov::AnyMap& device_config) {
164164
if (session_context_.precision.find("FP32") != std::string::npos) {
165165
device_config.emplace(ov::hint::inference_precision("f32"));
166166
}
167-
if (session_context_.precision.find("ACCURACY") != std::string::npos &&
168-
session_context_.device_type.find("GPU") != std::string::npos) {
167+
if (session_context_.precision.find("ACCURACY") != std::string::npos) {
169168
if (session_context_.OpenVINO_Version.at(0) >= 2024) {
170-
device_config.emplace(ov::hint::inference_precision(ov::element::dynamic));
171169
device_config.emplace(ov::hint::execution_mode(ov::hint::ExecutionMode::ACCURACY));
172170
} else {
173171
if (!subgraph_context_.model_precision.empty())
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
#include <algorithm>
2+
#include "core/providers/openvino/openvino_parser_utils.h"
3+
#include "core/providers/shared_library/provider_api.h"
4+
5+
namespace onnxruntime {
6+
namespace openvino_ep {
7+
8+
std::string OpenVINOParserUtils::ParsePrecision(const ProviderOptions& provider_options,
9+
std::string& device_type,
10+
const std::string& option_name) {
11+
using DeviceName = std::string;
12+
using DefaultValue = std::string;
13+
using ValidValues = std::list<std::string>;
14+
using foo = std::pair<DefaultValue, ValidValues>;
15+
using ParserHelper = std::map<DeviceName, foo>;
16+
17+
ParserHelper helper = {
18+
{"GPU", {"FP16", {"FP16", "FP32", "ACCURACY"}}},
19+
{"NPU", {"FP16", {"FP16", "ACCURACY"}}},
20+
{"CPU", {"FP32", {"FP32", "ACCURACY"}}},
21+
};
22+
23+
std::set<std::string> deprecated_device_types = {
24+
"CPU_FP32", "GPU_FP32", "GPU.0_FP32", "GPU.1_FP32", "GPU_FP16",
25+
"GPU.0_FP16", "GPU.1_FP16"};
26+
27+
bool is_composite = device_type.find(':') != std::string::npos; // FOR devices AUTO:,HETERO:,MULTI:
28+
29+
if (provider_options.contains(option_name)) {
30+
const auto& precision = provider_options.at(option_name);
31+
32+
if (is_composite) {
33+
std::set<std::string> allowed_precisions = {"FP16", "FP32", "ACCURACY"};
34+
if (allowed_precisions.contains(precision)) {
35+
return precision;
36+
} else {
37+
ORT_THROW("[ERROR] [OpenVINO] Unsupported inference precision is selected. ",
38+
precision, ".\n");
39+
}
40+
} else {
41+
if (helper.contains(device_type)) {
42+
auto const& valid_values = helper[device_type].second;
43+
44+
if (precision == "ACCURACY") {
45+
return valid_values.back(); // Return highest supported precision
46+
} else {
47+
if (std::find(valid_values.begin(), valid_values.end(), precision) != valid_values.end()) {
48+
return precision; // Return precision selected if valid
49+
} else {
50+
auto value_iter = valid_values.begin();
51+
std::string valid_values_joined = *value_iter;
52+
// Append 2nd and up, if only one then ++value_iter is same as end()
53+
for (++value_iter; value_iter != valid_values.end(); ++value_iter) {
54+
valid_values_joined += ", " + *value_iter;
55+
}
56+
57+
ORT_THROW("[ERROR] [OpenVINO] Unsupported inference precision is selected. ",
58+
device_type, " only supports", valid_values_joined, ".\n");
59+
}
60+
}
61+
} else if (deprecated_device_types.contains(device_type)) {
62+
LOGS_DEFAULT(WARNING)
63+
<< "[OpenVINO] Selected 'device_type' " + device_type + " is deprecated. \n"
64+
<< "Update the 'device_type' to specified types 'CPU', 'GPU', 'GPU.0', "
65+
<< "'GPU.1', 'NPU' or from HETERO/MULTI/AUTO options and set 'precision' separately. \n";
66+
auto delimit = device_type.find("_");
67+
device_type = device_type.substr(0, delimit);
68+
return device_type.substr(delimit + 1);
69+
} else {
70+
ORT_THROW("[ERROR] [OpenVINO] Unsupported device type provided: ",
71+
device_type, "\n");
72+
}
73+
}
74+
} else {
75+
if (device_type.find("NPU") != std::string::npos || device_type.find("GPU") != std::string::npos) {
76+
return "FP16";
77+
} else if (device_type.find("CPU") != std::string::npos) {
78+
return "FP32";
79+
} else {
80+
ORT_THROW("[ERROR] [OpenVINO] Unsupported device is selected", device_type, "\n");
81+
}
82+
}
83+
}
84+
85+
} // namespace openvino_ep
86+
} // namespace onnxruntime
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
#pragma once
2+
3+
#include <list>
4+
#include <map>
5+
#include <set>
6+
#include <string>
7+
#include <utility>
8+
9+
#include "core/framework/provider_options.h"
10+
11+
namespace onnxruntime {
12+
namespace openvino_ep {
13+
14+
class OpenVINOParserUtils {
15+
public:
16+
static std::string ParsePrecision(const ProviderOptions& provider_options,
17+
std::string& device_type,
18+
const std::string& option_name);
19+
};
20+
21+
} // namespace openvino_ep
22+
} // namespace onnxruntime

onnxruntime/core/providers/openvino/openvino_provider_factory.cc

+4-56
Original file line numberDiff line numberDiff line change
@@ -11,11 +11,12 @@
1111
#include "core/providers/openvino/backend_utils.h"
1212
#include "core/session/onnxruntime_session_options_config_keys.h"
1313
#include "nlohmann/json.hpp"
14+
#include "core/providers/openvino/openvino_parser_utils.h"
1415

1516
namespace onnxruntime {
1617
namespace openvino_ep {
1718
void ParseConfigOptions(ProviderInfo& pi) {
18-
if(pi.config_options==NULL)
19+
if (pi.config_options == NULL)
1920
return;
2021

2122
pi.so_disable_cpu_ep_fallback = pi.config_options->GetConfigOrDefault(kOrtSessionOptionsDisableCPUEPFallback, "0") == "1";
@@ -29,7 +30,6 @@ void ParseConfigOptions(ProviderInfo& pi) {
2930
map["NPU_COMPILATION_MODE_PARAMS"] = "enable-wd-blockarg-input=true compute-layers-with-higher-precision=Sqrt,Power,ReduceSum";
3031
pi.load_config["NPU"] = std::move(map);
3132
}
32-
3333
}
3434

3535
void* ParseUint64(const ProviderOptions& provider_options, std::string option_name) {
@@ -115,58 +115,6 @@ std::string ParseDeviceType(std::shared_ptr<OVCore> ov_core, const ProviderOptio
115115
}
116116
}
117117

118-
// Depends on ProviderOptions.
119-
std::string ParsePrecision(const ProviderOptions& provider_options, std::string& device_type, const std::string& option_name) {
120-
using DeviceName = std::string;
121-
using DefaultValue = std::string;
122-
using ValidValues = std::list<std::string>;
123-
using foo = std::pair<DefaultValue, ValidValues>;
124-
using ParserHelper = std::map<DeviceName, foo>;
125-
ParserHelper helper = {
126-
{"GPU", {"FP16", {"FP16", "FP32"}}},
127-
{"NPU", {"FP16", {"FP16"}}},
128-
{"CPU", {"FP32", {"FP32"}}},
129-
};
130-
131-
std::set<std::string> deprecated_device_types = {"CPU_FP32", "GPU_FP32",
132-
"GPU.0_FP32", "GPU.1_FP32", "GPU_FP16",
133-
"GPU.0_FP16", "GPU.1_FP16"};
134-
135-
if (provider_options.contains(option_name)) {
136-
// Start by checking if the device_type is a normal valid one
137-
if (helper.contains(device_type)) {
138-
auto const& valid_values = helper[device_type].second;
139-
const auto& precision = provider_options.at(option_name);
140-
if (precision == "ACCURACY") {
141-
return valid_values.back(); // Return highest supported precision
142-
} else {
143-
if (std::find(valid_values.begin(), valid_values.end(), precision) != valid_values.end()) {
144-
return precision; // Return precision selected if valid
145-
} else {
146-
auto value_iter = valid_values.begin();
147-
std::string valid_values_joined = *value_iter;
148-
// Append 2nd and up, if only one then ++value_iter is same as end()
149-
for (++value_iter; value_iter != valid_values.end(); ++value_iter) {
150-
valid_values_joined += ", " + *value_iter;
151-
}
152-
153-
ORT_THROW("[ERROR] [OpenVINO] Unsupported inference precision is selected. ", device_type, " only supports", valid_values_joined, ".\n");
154-
}
155-
}
156-
} else if (deprecated_device_types.contains(device_type)) {
157-
LOGS_DEFAULT(WARNING) << "[OpenVINO] Selected 'device_type' " + device_type + " is deprecated. \n"
158-
<< "Update the 'device_type' to specified types 'CPU', 'GPU', 'GPU.0', "
159-
<< "'GPU.1', 'NPU' or from"
160-
<< " HETERO/MULTI/AUTO options and set 'precision' separately. \n";
161-
auto delimit = device_type.find("_");
162-
device_type = device_type.substr(0, delimit);
163-
return device_type.substr(delimit + 1);
164-
}
165-
}
166-
// Return default
167-
return helper[device_type].first;
168-
}
169-
170118
void ParseProviderOptions([[maybe_unused]] ProviderInfo& result, [[maybe_unused]] const ProviderOptions& config_options) {}
171119

172120
struct OpenVINOProviderFactory : IExecutionProviderFactory {
@@ -204,7 +152,7 @@ struct OpenVINO_Provider : Provider {
204152
const ProviderOptions* provider_options_ptr = reinterpret_cast<ProviderOptions*>(pointers_array[0]);
205153
const ConfigOptions* config_options = reinterpret_cast<ConfigOptions*>(pointers_array[1]);
206154

207-
if(provider_options_ptr == NULL) {
155+
if (provider_options_ptr == NULL) {
208156
LOGS_DEFAULT(ERROR) << "[OpenVINO EP] Passed NULL ProviderOptions to CreateExecutionProviderFactory()";
209157
return nullptr;
210158
}
@@ -234,7 +182,7 @@ struct OpenVINO_Provider : Provider {
234182
pi.cache_dir = provider_options.at("cache_dir");
235183
}
236184

237-
pi.precision = ParsePrecision(provider_options, pi.device_type, "precision");
185+
pi.precision = OpenVINOParserUtils::ParsePrecision(provider_options, pi.device_type, "precision");
238186

239187
if (provider_options.contains("load_config")) {
240188
auto parse_config = [&](const std::string& config_str) -> std::map<std::string, ov::AnyMap> {

0 commit comments

Comments
 (0)