Skip to content

Commit ad5b97b

Browse files
'LoadPluginOrProviderBridge' should load the library_path as absolute (#24587)
### Description `LoadPluginOrProviderBridge` is called when attempting to load a Plugin. It uses the passed `library_path` to attempt to load the Plugin as a `Provider` - using `ProviderLibrary` - to see if it can be treated as a 'ProviderBridge'. `ProviderLibrary` attempts to load the Provider by prefixing the path to the onnxruntime.dll. Plugins needn't be redistributed with OnnxRuntime, so the path to the Plugin _may_ be an absolute path, and if so `ProviderLibrary` fails. At the same time - however - `LoadPluginOrProviderBridge` needs to support OnnxRuntime-relative paths: As 'Providers' are migrated to 'Plugins', existing Providers should be usable as Plugins. To accommodate both scenarios, this PR: 1. Adds support to `ProviderLibrary` to be created with an absolute path. 2. Validates the path passed to `LoadPluginOrProviderBridge`; 1. if it is absolute, the same absolute path is passed to `ProviderLibrary` and `EpLibraryPlugin`. 2. if the path is not absolute, it is converted to an absolute path by prefixing the OnnxRuntime location, and the same path is passed to `ProviderLibrary` and `EpLibraryPlugin`. ### Motivation and Context This PR enables `LoadPluginOrProviderBridge` to be called with an absolute path to the Plugin, allowing it to be used as a 'ProviderBridge', or with an OnnxRuntime-relative path to the Plugin. --------- Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
1 parent a2f8255 commit ad5b97b

File tree

4 files changed

+34
-10
lines changed

4 files changed

+34
-10
lines changed

onnxruntime/core/session/ep_library_plugin.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,9 @@ namespace onnxruntime {
1616
/// </summary>
1717
class EpLibraryPlugin : public EpLibrary {
1818
public:
19-
EpLibraryPlugin(const std::string& registration_name, const ORTCHAR_T* library_path)
19+
EpLibraryPlugin(const std::string& registration_name, std::filesystem::path library_path)
2020
: registration_name_{registration_name},
21-
library_path_{library_path} {
21+
library_path_{std::move(library_path)} {
2222
}
2323

2424
const char* RegistrationName() const override {

onnxruntime/core/session/provider_bridge_library.h

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,13 @@
99
namespace onnxruntime {
1010
struct Provider;
1111

12+
enum class ProviderLibraryPathType {
13+
Default,
14+
Absolute,
15+
};
16+
1217
struct ProviderLibrary {
13-
ProviderLibrary(const ORTCHAR_T* filename, bool unload = true);
18+
ProviderLibrary(const ORTCHAR_T* filename, bool unload = true, ProviderLibraryPathType pathType = ProviderLibraryPathType::Default);
1419
~ProviderLibrary();
1520

1621
Status Load();
@@ -19,8 +24,9 @@ struct ProviderLibrary {
1924

2025
private:
2126
std::mutex mutex_;
22-
const ORTCHAR_T* filename_;
27+
const ORTCHAR_T* const filename_;
2328
bool unload_;
29+
const bool absolute_;
2430
bool initialized_{};
2531
Provider* provider_{};
2632
void* handle_{};

onnxruntime/core/session/provider_bridge_ort.cc

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1727,8 +1727,8 @@ bool InitProvidersSharedLibrary() try {
17271727
return false;
17281728
}
17291729

1730-
ProviderLibrary::ProviderLibrary(const ORTCHAR_T* filename, bool unload)
1731-
: filename_{filename}, unload_{unload} {
1730+
ProviderLibrary::ProviderLibrary(const ORTCHAR_T* filename, bool unload, ProviderLibraryPathType pathType)
1731+
: filename_{filename}, unload_{unload}, absolute_{pathType == ProviderLibraryPathType::Absolute} {
17321732
}
17331733

17341734
ProviderLibrary::~ProviderLibrary() {
@@ -1744,8 +1744,16 @@ Status ProviderLibrary::Load() {
17441744
std::lock_guard<std::mutex> lock{mutex_};
17451745
s_library_shared.Ensure();
17461746

1747-
auto full_path = Env::Default().GetRuntimePath() + filename_;
1748-
ORT_RETURN_IF_ERROR(Env::Default().LoadDynamicLibrary(full_path, false, &handle_));
1747+
if (absolute_) {
1748+
// If filename_ is not absolute it should not be loaded.
1749+
if (!std::filesystem::path{filename_}.is_absolute()) {
1750+
return ORT_MAKE_STATUS(ONNXRUNTIME, FAIL, "An absolute path must be specified.");
1751+
}
1752+
ORT_RETURN_IF_ERROR(Env::Default().LoadDynamicLibrary(filename_, false, &handle_));
1753+
} else {
1754+
auto full_path = Env::Default().GetRuntimePath() + filename_;
1755+
ORT_RETURN_IF_ERROR(Env::Default().LoadDynamicLibrary(full_path, false, &handle_));
1756+
}
17491757

17501758
Provider* (*PGetProvider)();
17511759
ORT_RETURN_IF_ERROR(Env::Default().GetSymbolFromLibrary(handle_, "GetProvider", (void**)&PGetProvider));

onnxruntime/core/session/utils.cc

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -240,15 +240,25 @@ Status LoadPluginOrProviderBridge(const std::string& registration_name,
240240
const ORTCHAR_T* library_path,
241241
std::unique_ptr<EpLibrary>& ep_library,
242242
std::vector<EpFactoryInternal*>& internal_factories) {
243+
// If the `library_path` is absolute, use it as-is. Otherwise follow the precedent of ProviderLibrary::Load and make
244+
// it absolute by combining it with the OnnxRuntime location.
245+
std::filesystem::path resolved_library_path{library_path};
246+
247+
if (!resolved_library_path.is_absolute()) {
248+
resolved_library_path = Env::Default().GetRuntimePath() / std::move(resolved_library_path);
249+
}
250+
243251
// if it's a provider bridge library we need to create ProviderLibrary first to ensure the dependencies are loaded
244252
// like the onnxruntime_provider_shared library.
245-
auto provider_library = std::make_unique<ProviderLibrary>(library_path);
253+
auto provider_library = std::make_unique<ProviderLibrary>(resolved_library_path.native().c_str(),
254+
true,
255+
ProviderLibraryPathType::Absolute);
246256
bool is_provider_bridge = provider_library->Load() == Status::OK(); // library has GetProvider
247257
LOGS_DEFAULT(INFO) << "Loading EP library: " << library_path
248258
<< (is_provider_bridge ? " as a provider bridge" : " as a plugin");
249259

250260
// create EpLibraryPlugin to ensure CreateEpFactories and ReleaseEpFactory are available
251-
auto ep_library_plugin = std::make_unique<EpLibraryPlugin>(registration_name, library_path);
261+
auto ep_library_plugin = std::make_unique<EpLibraryPlugin>(registration_name, std::move(resolved_library_path));
252262
ORT_RETURN_IF_ERROR(ep_library_plugin->Load());
253263

254264
if (is_provider_bridge) {

0 commit comments

Comments
 (0)