diff --git a/csharp/src/Microsoft.ML.OnnxRuntime/SessionOptions.shared.cs b/csharp/src/Microsoft.ML.OnnxRuntime/SessionOptions.shared.cs
index 04239aa4c5b83..c6e576ca84fb9 100644
--- a/csharp/src/Microsoft.ML.OnnxRuntime/SessionOptions.shared.cs
+++ b/csharp/src/Microsoft.ML.OnnxRuntime/SessionOptions.shared.cs
@@ -430,17 +430,10 @@ public IntPtr Appender(IntPtr handle, IntPtr[] optKeys, IntPtr[] optValues, UInt
///
/// Append QNN, SNPE or XNNPACK execution provider
///
- /// Execution provider to add. 'QNN', 'SNPE' 'XNNPACK' or 'CoreML are currently supported.
+ /// Execution provider to add. 'QNN', 'SNPE' 'XNNPACK', 'CoreML and 'AZURE are currently supported.
/// Optional key/value pairs to specify execution provider options.
public void AppendExecutionProvider(string providerName, Dictionary providerOptions = null)
{
- if (providerName != "SNPE" && providerName != "XNNPACK" && providerName != "QNN" &&
- providerName != "AZURE" && providerName != "CoreML")
- {
- throw new NotSupportedException(
- "Only QNN, SNPE, XNNPACK and AZURE execution providers can be enabled by this method.");
- }
-
if (providerOptions == null)
{
providerOptions = new Dictionary();
diff --git a/onnxruntime/core/session/provider_registration.cc b/onnxruntime/core/session/provider_registration.cc
index 0d9ed0789507e..4ae912b23f80b 100644
--- a/onnxruntime/core/session/provider_registration.cc
+++ b/onnxruntime/core/session/provider_registration.cc
@@ -155,7 +155,11 @@ ORT_API_STATUS_IMPL(OrtApis::SessionOptionsAppendExecutionProvider,
status = create_not_supported_status();
#endif
} else if (strcmp(provider_name, "VitisAI") == 0) {
+#ifdef USE_VITISAI
status = OrtApis::SessionOptionsAppendExecutionProvider_VitisAI(options, provider_options_keys, provider_options_values, num_keys);
+#else
+ status = create_not_supported_status();
+#endif
} else if (strcmp(provider_name, "CoreML") == 0) {
#if defined(USE_COREML)
std::string coreml_flags;
diff --git a/onnxruntime/test/perftest/command_args_parser.cc b/onnxruntime/test/perftest/command_args_parser.cc
index e40544d950ed7..46777eda793e0 100644
--- a/onnxruntime/test/perftest/command_args_parser.cc
+++ b/onnxruntime/test/perftest/command_args_parser.cc
@@ -24,6 +24,7 @@
#include
#include "test_configuration.h"
+#include "strings_helper.h"
namespace onnxruntime {
namespace perftest {
@@ -175,39 +176,6 @@ static bool ParseDimensionOverride(std::basic_string& dim_identifier,
return true;
}
-static bool ParseSessionConfigs(const std::string& configs_string,
- std::unordered_map& session_configs) {
- std::istringstream ss(configs_string);
- std::string token;
-
- while (ss >> token) {
- if (token == "") {
- continue;
- }
-
- std::string_view token_sv(token);
-
- auto pos = token_sv.find("|");
- if (pos == std::string_view::npos || pos == 0 || pos == token_sv.length()) {
- // Error: must use a '|' to separate the key and value for session configuration entries.
- return false;
- }
-
- std::string key(token_sv.substr(0, pos));
- std::string value(token_sv.substr(pos + 1));
-
- auto it = session_configs.find(key);
- if (it != session_configs.end()) {
- // Error: specified duplicate session configuration entry: {key}
- return false;
- }
-
- session_configs.insert(std::make_pair(std::move(key), std::move(value)));
- }
-
- return true;
-}
-
/*static*/ bool CommandLineParser::ParseArguments(PerformanceTestConfig& test_config, int argc, ORTCHAR_T* argv[]) {
int ch;
while ((ch = getopt(argc, argv, ORT_TSTR("m:e:r:t:p:x:y:c:d:o:u:i:f:F:S:T:C:AMPIDZvhsqznlR:"))) != -1) {
diff --git a/onnxruntime/test/perftest/ort_test_session.cc b/onnxruntime/test/perftest/ort_test_session.cc
index 4d2ed47a69991..542a57e57d942 100644
--- a/onnxruntime/test/perftest/ort_test_session.cc
+++ b/onnxruntime/test/perftest/ort_test_session.cc
@@ -17,6 +17,7 @@
#include
#include "providers.h"
#include "TestCase.h"
+#include "strings_helper.h"
#ifdef USE_OPENVINO
#include "nlohmann/json.hpp"
@@ -58,6 +59,7 @@ OnnxRuntimeTestSession::OnnxRuntimeTestSession(Ort::Env& env, std::random_device
Ort::SessionOptions session_options;
provider_name_ = performance_test_config.machine_config.provider_type_name;
+ std::unordered_map provider_options;
if (provider_name_ == onnxruntime::kDnnlExecutionProvider) {
#ifdef USE_DNNL
// Generate provider options
@@ -72,23 +74,13 @@ OnnxRuntimeTestSession::OnnxRuntimeTestSession(Ort::Env& env, std::random_device
std::string ov_string = performance_test_config.run_config.ep_runtime_config_string;
#endif // defined(_MSC_VER)
int num_threads = 0;
- std::istringstream ss(ov_string);
- std::string token;
- while (ss >> token) {
- if (token == "") {
- continue;
- }
- auto pos = token.find("|");
- if (pos == std::string::npos || pos == 0 || pos == token.length()) {
+ if (!ParseSessionConfigs(ov_string, provider_options)) {
ORT_THROW(
- "[ERROR] [OneDNN] Use a '|' to separate the key and value for the "
+ "[ERROR] Use a '|' to separate the key and value for the "
"run-time option you are trying to use.\n");
- }
-
- auto key = token.substr(0, pos);
- auto value = token.substr(pos + 1);
-
- if (key == "num_of_threads") {
+ }
+ for (const auto& provider_option : provider_options) {
+ if (provider_option.first == "num_of_threads") {
std::stringstream sstream(value);
sstream >> num_threads;
if (num_threads < 0) {
@@ -144,22 +136,14 @@ OnnxRuntimeTestSession::OnnxRuntimeTestSession(Ort::Env& env, std::random_device
#else
std::string ov_string = performance_test_config.run_config.ep_runtime_config_string;
#endif
- std::istringstream ss(ov_string);
- std::string token;
- while (ss >> token) {
- if (token == "") {
- continue;
- }
- auto pos = token.find("|");
- if (pos == std::string::npos || pos == 0 || pos == token.length()) {
+ if (!ParseSessionConfigs(ov_string, provider_options)) {
ORT_THROW(
- "[ERROR] [CUDA] Use a '|' to separate the key and value for the run-time option you are trying to use.\n");
- }
-
- buffer.emplace_back(token.substr(0, pos));
- option_keys.push_back(buffer.back().c_str());
- buffer.emplace_back(token.substr(pos + 1));
- option_values.push_back(buffer.back().c_str());
+ "[ERROR] Use a '|' to separate the key and value for the "
+ "run-time option you are trying to use.\n");
+ }
+ for (const auto& provider_option : provider_options) {
+ option_keys.push_back(provider_option->first.c_str());
+ option_values.push_back(provider_option->first.c_str());
}
Ort::Status status(api.UpdateCUDAProviderOptions(cuda_options,
@@ -192,24 +176,15 @@ OnnxRuntimeTestSession::OnnxRuntimeTestSession(Ort::Env& env, std::random_device
#else
std::string ov_string = performance_test_config.run_config.ep_runtime_config_string;
#endif
- std::istringstream ss(ov_string);
- std::string token;
- while (ss >> token) {
- if (token == "") {
- continue;
- }
- auto pos = token.find("|");
- if (pos == std::string::npos || pos == 0 || pos == token.length()) {
+ if (!ParseSessionConfigs(ov_string, provider_options)) {
ORT_THROW(
- "[ERROR] [TensorRT] Use a '|' to separate the key and value for the run-time option you are trying to use.\n");
- }
-
- buffer.emplace_back(token.substr(0, pos));
- option_keys.push_back(buffer.back().c_str());
- buffer.emplace_back(token.substr(pos + 1));
- option_values.push_back(buffer.back().c_str());
+ "[ERROR] Use a '|' to separate the key and value for the "
+ "run-time option you are trying to use.\n");
+ }
+ for (const auto& provider_option : provider_options) {
+ option_keys.push_back(provider_option->first.c_str());
+ option_values.push_back(provider_option->first.c_str());
}
-
Ort::Status status(api.UpdateTensorRTProviderOptions(tensorrt_options,
option_keys.data(), option_values.data(), option_keys.size()));
if (!status.IsOK()) {
@@ -239,22 +214,12 @@ OnnxRuntimeTestSession::OnnxRuntimeTestSession(Ort::Env& env, std::random_device
#else
std::string option_string = performance_test_config.run_config.ep_runtime_config_string;
#endif
- std::istringstream ss(option_string);
- std::string token;
- std::unordered_map qnn_options;
-
- while (ss >> token) {
- if (token == "") {
- continue;
- }
- auto pos = token.find("|");
- if (pos == std::string::npos || pos == 0 || pos == token.length()) {
- ORT_THROW("Use a '|' to separate the key and value for the run-time option you are trying to use.");
- }
-
- std::string key(token.substr(0, pos));
- std::string value(token.substr(pos + 1));
-
+ if (!ParseSessionConfigs(option_string, provider_options)) {
+ ORT_THROW(
+ "[ERROR] Use a '|' to separate the key and value for the "
+ "run-time option you are trying to use.\n");
+ }
+ for (const auto& provider_option : provider_options) {
if (key == "backend_path" || key == "profiling_file_path") {
if (value.empty()) {
ORT_THROW("Please provide the valid file path.");
@@ -317,10 +282,8 @@ OnnxRuntimeTestSession::OnnxRuntimeTestSession(Ort::Env& env, std::random_device
'qnn_saver_path', 'htp_graph_finalization_optimization_mode', 'qnn_context_priority', 'soc_model',
'htp_arch', 'device_id', 'enable_htp_fp16_precision', 'offload_graph_io_quantization'])");
}
-
- qnn_options[key] = value;
}
- session_options.AppendExecutionProvider("QNN", qnn_options);
+ session_options.AppendExecutionProvider("QNN", provider_options);
#else
ORT_THROW("QNN is not supported in this build\n");
#endif
@@ -331,22 +294,12 @@ OnnxRuntimeTestSession::OnnxRuntimeTestSession(Ort::Env& env, std::random_device
#else
std::string option_string = performance_test_config.run_config.ep_runtime_config_string;
#endif
- std::istringstream ss(option_string);
- std::string token;
- std::unordered_map snpe_options;
-
- while (ss >> token) {
- if (token == "") {
- continue;
- }
- auto pos = token.find("|");
- if (pos == std::string::npos || pos == 0 || pos == token.length()) {
- ORT_THROW("Use a '|' to separate the key and value for the run-time option you are trying to use.\n");
- }
-
- std::string key(token.substr(0, pos));
- std::string value(token.substr(pos + 1));
-
+ if (!ParseSessionConfigs(option_string, provider_options)) {
+ ORT_THROW(
+ "[ERROR] Use a '|' to separate the key and value for the "
+ "run-time option you are trying to use.\n");
+ }
+ for (const auto& provider_option : provider_options) {
if (key == "runtime") {
std::set supported_runtime = {"CPU", "GPU_FP32", "GPU", "GPU_FLOAT16", "DSP", "AIP_FIXED_TF"};
if (supported_runtime.find(value) == supported_runtime.end()) {
@@ -368,11 +321,9 @@ select from 'TF8', 'TF16', 'UINT8', 'FLOAT', 'ITENSOR'. \n)");
} else {
ORT_THROW("Wrong key type entered. Choose from options: ['runtime', 'priority', 'buffer_type', 'enable_init_cache'] \n");
}
-
- snpe_options[key] = value;
}
- session_options.AppendExecutionProvider("SNPE", snpe_options);
+ session_options.AppendExecutionProvider("SNPE", provider_options);
#else
ORT_THROW("SNPE is not supported in this build\n");
#endif
@@ -448,34 +399,20 @@ select from 'TF8', 'TF16', 'UINT8', 'FLOAT', 'ITENSOR'. \n)");
#endif
} else if (provider_name_ == onnxruntime::kDmlExecutionProvider) {
#ifdef USE_DML
- std::unordered_map dml_options;
- dml_options["performance_preference"] = "high_performance";
- dml_options["device_filter"] = "gpu";
- dml_options["disable_metacommands"] = "false";
- dml_options["enable_graph_capture"] = "false";
#ifdef _MSC_VER
std::string ov_string = ToUTF8String(performance_test_config.run_config.ep_runtime_config_string);
#else
std::string ov_string = performance_test_config.run_config.ep_runtime_config_string;
#endif
- std::istringstream ss(ov_string);
- std::string token;
- while (ss >> token) {
- if (token == "") {
- continue;
- }
- auto pos = token.find("|");
- if (pos == std::string::npos || pos == 0 || pos == token.length()) {
- ORT_THROW("[ERROR] [DML] Use a '|' to separate the key and value for the run-time option you are trying to use.\n");
- }
-
- auto key = token.substr(0, pos);
- auto value = token.substr(pos + 1);
-
+ if (!ParseSessionConfigs(ov_string, provider_options)) {
+ ORT_THROW(
+ "[ERROR] Use a '|' to separate the key and value for the "
+ "run-time option you are trying to use.\n");
+ }
+ for (const auto& provider_option : provider_options) {
if (key == "device_filter") {
std::set ov_supported_device_types = {"gpu", "npu"};
if (ov_supported_device_types.find(value) != ov_supported_device_types.end()) {
- dml_options[key] = value;
} else {
ORT_THROW(
"[ERROR] [DML] You have selected a wrong configuration value for the key 'device_filter'. "
@@ -484,7 +421,6 @@ select from 'TF8', 'TF16', 'UINT8', 'FLOAT', 'ITENSOR'. \n)");
} else if (key == "performance_preference") {
std::set ov_supported_values = {"default", "high_performance", "minimal_power"};
if (ov_supported_values.find(value) != ov_supported_values.end()) {
- dml_options[key] = value;
} else {
ORT_THROW(
"[ERROR] [DML] You have selected a wrong configuration value for the key 'performance_preference'. "
@@ -493,7 +429,6 @@ select from 'TF8', 'TF16', 'UINT8', 'FLOAT', 'ITENSOR'. \n)");
} else if (key == "disable_metacommands") {
std::set ov_supported_values = {"true", "True", "false", "False"};
if (ov_supported_values.find(value) != ov_supported_values.end()) {
- dml_options[key] = value;
} else {
ORT_THROW(
"[ERROR] [DML] You have selected a wrong value for the key 'disable_metacommands'. "
@@ -502,7 +437,6 @@ select from 'TF8', 'TF16', 'UINT8', 'FLOAT', 'ITENSOR'. \n)");
} else if (key == "enable_graph_capture") {
std::set ov_supported_values = {"true", "True", "false", "False"};
if (ov_supported_values.find(value) != ov_supported_values.end()) {
- dml_options[key] = value;
} else {
ORT_THROW(
"[ERROR] [DML] You have selected a wrong value for the key 'enable_graph_capture'. "
@@ -519,7 +453,19 @@ select from 'TF8', 'TF16', 'UINT8', 'FLOAT', 'ITENSOR'. \n)");
}
}
}
- session_options.AppendExecutionProvider("DML", dml_options);
+ if (provider_options.find("performance_preference") == provider_options.end()) {
+ provider_options["performance_preference"] = "high_performance";
+ }
+ if (provider_options.find("device_filter") == provider_options.end()) {
+ provider_options["device_filter"] = "gpu";
+ }
+ if (provider_options.find("disable_metacommands") == provider_options.end()) {
+ provider_options["disable_metacommands"] = "false";
+ }
+ if (provider_options.find("enable_graph_capture") == provider_options.end()) {
+ provider_options["enable_graph_capture"] = "false";
+ }
+ session_options.AppendExecutionProvider("DML", provider_options);
#else
ORT_THROW("DML is not supported in this build\n");
#endif
@@ -530,21 +476,12 @@ select from 'TF8', 'TF16', 'UINT8', 'FLOAT', 'ITENSOR'. \n)");
#else
std::string ov_string = performance_test_config.run_config.ep_runtime_config_string;
#endif // defined(_MSC_VER)
- std::istringstream ss(ov_string);
- std::string token;
bool enable_fast_math = false;
- while (ss >> token) {
- if (token == "") {
- continue;
- }
- auto pos = token.find("|");
- if (pos == std::string::npos || pos == 0 || pos == token.length()) {
- ORT_THROW("[ERROR] [ACL] Use a '|' to separate the key and value for the run-time option you are trying to use.\n");
- }
-
- auto key = token.substr(0, pos);
- auto value = token.substr(pos + 1);
-
+ if (!ParseSessionConfigs(ov_string, provider_options)) {
+ ORT_THROW("[ERROR] Use a '|' to separate the key and value for the "
+ "run-time option you are trying to use.\n");
+ }
+ for (const auto& provider_option : provider_options) {
if (key == "enable_fast_math") {
std::set ov_supported_values = {"true", "True", "false", "False"};
if (ov_supported_values.find(value) != ov_supported_values.end()) {
@@ -612,24 +549,13 @@ select from 'TF8', 'TF16', 'UINT8', 'FLOAT', 'ITENSOR'. \n)");
#else
std::string option_string = performance_test_config.run_config.ep_runtime_config_string;
#endif
- std::istringstream ss(option_string);
- std::string token;
- std::unordered_map vitisai_session_options;
-
- while (ss >> token) {
- if (token == "") {
- continue;
- }
- auto pos = token.find("|");
- if (pos == std::string::npos || pos == 0 || pos == token.length()) {
- ORT_THROW("[ERROR] [VitisAI] Use a '|' to separate the key and value for the run-time option you are trying to use.\n");
- }
-
- std::string key(token.substr(0, pos));
- std::string value(token.substr(pos + 1));
- vitisai_session_options[key] = value;
+ if (!ParseSessionConfigs(option_string, provider_options)) {
+ ORT_THROW(
+ "[ERROR] Use a '|' to separate the key and value for the "
+ "run-time option you are trying to use.\n");
}
- session_options.AppendExecutionProvider_VitisAI(vitisai_session_options);
+
+ session_options.AppendExecutionProvider_VitisAI(provider_options);
#else
ORT_THROW("VitisAI is not supported in this build\n");
#endif
diff --git a/onnxruntime/test/perftest/strings_helper.cc b/onnxruntime/test/perftest/strings_helper.cc
new file mode 100644
index 0000000000000..e9081310b8549
--- /dev/null
+++ b/onnxruntime/test/perftest/strings_helper.cc
@@ -0,0 +1,47 @@
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Copyright (c) 2023 NVIDIA Corporation.
+// SPDX-FileCopyrightText: Copyright 2024 Arm Limited and/or its affiliates
+// Licensed under the MIT License.
+
+#include
+#include
+
+#include "strings_helper.h"
+
+namespace onnxruntime {
+namespace perftest {
+
+bool ParseSessionConfigs(const std::string& configs_string,
+ std::unordered_map& session_configs) {
+ std::istringstream ss(configs_string);
+ std::string token;
+
+ while (ss >> token) {
+ if (token == "") {
+ continue;
+ }
+
+ std::string_view token_sv(token);
+
+ auto pos = token_sv.find("|");
+ if (pos == std::string_view::npos || pos == 0 || pos == token_sv.length()) {
+ // Error: must use a '|' to separate the key and value for session configuration entries.
+ return false;
+ }
+
+ std::string key(token_sv.substr(0, pos));
+ std::string value(token_sv.substr(pos + 1));
+
+ auto it = session_configs.find(key);
+ if (it != session_configs.end()) {
+ // Error: specified duplicate session configuration entry: {key}
+ return false;
+ }
+
+ session_configs.insert(std::make_pair(std::move(key), std::move(value)));
+ }
+
+ return true;
+}
+} // namespace perftest
+} // namespace onnxruntime
diff --git a/onnxruntime/test/perftest/strings_helper.h b/onnxruntime/test/perftest/strings_helper.h
new file mode 100644
index 0000000000000..24feb90a20a61
--- /dev/null
+++ b/onnxruntime/test/perftest/strings_helper.h
@@ -0,0 +1,14 @@
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Copyright (c) 2023 NVIDIA Corporation.
+// SPDX-FileCopyrightText: Copyright 2024 Arm Limited and/or its affiliates
+// Licensed under the MIT License.
+#include
+#include
+
+namespace onnxruntime {
+namespace perftest {
+
+bool ParseSessionConfigs(const std::string& configs_string,
+ std::unordered_map& session_configs);
+} // namespace perftest
+} // namespace onnxruntime