Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
b3664f8
[CUDA] Support SwiGlu in MoE and qMoE (#25530)
tianleiwu Jul 28, 2025
a8e1186
[CUDA] BF16 MoE and qMoE (#25572)
tianleiwu Jul 31, 2025
a9f74a0
Add CUDA implementation of GatherBlockQuantized operator (#25575)
xiaomsft Aug 1, 2025
d83904b
Add support for QMoE in CPU (#25558)
apsonawane Aug 2, 2025
8654241
Update MoE and qMoE spec (#25619)
tianleiwu Aug 2, 2025
6ca2047
[CPU] Improve QMoE kernel (#25822)
apsonawane Aug 26, 2025
dd32daf
Fix MoE CPP tests (#25877)
apsonawane Aug 28, 2025
581b8e7
Add custom ops library_path to EP metadata (#25830)
psakhamoori Aug 29, 2025
a9308a1
[Fix] illegal memory access in GetInputIndices with optional inputs (…
mingyueliuh Aug 29, 2025
6c7f150
[TRT RTX EP] Add sync method (#25898)
gedoensmax Sep 2, 2025
535fcc6
[TRT RTX EP] Memory map the engine buffer (#25909)
gedoensmax Sep 3, 2025
1f4e581
[TRT RTX EP] Add support for RTX runtime caches (#25917)
gedoensmax Sep 3, 2025
9732a3e
Compile API: disable optimizations by default (#25474)
adrianlizarraga Sep 3, 2025
df25f45
[CXX] Introduce C++ API for new C entry points (#25897)
yuslepukhin Sep 3, 2025
8f587b1
Migrate model tests to ONNX Model ZOO only (#25888)
kobby-kobbs Sep 3, 2025
ab71f1e
Remove std::string::data() non-const usage from public headers (#25943)
yuslepukhin Sep 4, 2025
2d36f04
Compile API: output model and initializer stream write functions (#25…
adrianlizarraga Sep 4, 2025
c5096d9
[TRT RTX EP] Fixing the stream parameter in CopyTensors API and passi…
praneshgo Sep 4, 2025
5ee309e
[MLAS] Add 8-bit weights ARM64 Gemm implementation (#25110)
hariharans29 Sep 4, 2025
157df9c
[NV TensorRT RTX] Handle unsupported data types (#25953)
ishwar-raut1 Sep 4, 2025
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
Prev Previous commit
Next Next commit
Add custom ops library_path to EP metadata (#25830)
## Summary
Adds EP metadata library path support to enable custom ops DLL
registration with proper path resolution.

## Changes
- Added `library_path` metadata key to EP metadata infrastructure
- Pass resolved library path directly to `EpLibraryProviderBridge`
constructor
- Simplified implementation per reviewer feedback (removed virtual
method complexity)
- Added `#include <utility>` for std::move compliance

## Purpose
Enables downstream applications (like onnxruntime-genai) to resolve
relative custom ops library paths using EP metadata, improving DLL
registration reliability.

## Files Modified
- `plugin_ep/ep_factory_provider_bridge.h`
- `plugin_ep/ep_library.h` 
- `plugin_ep/ep_library_plugin.h`
- `plugin_ep/ep_library_provider_bridge.cc`
- `plugin_ep/ep_library_provider_bridge.h`
- `utils.cc`
  • Loading branch information
psakhamoori authored and tianleiwu committed Sep 4, 2025
commit 581b8e747bebc4f446006ce254acea98c661b9ad
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,7 @@ static const char* const kOrtEpDevice_EpMetadataKey_Version = "version";
// Prefix for execution provider compatibility information stored in model metadata.
// Used when generating EP context models to store compatibility strings for each EP.
// Full key format: "ep_compatibility_info.<EP_TYPE>"
static const char* const kOrtModelMetadata_EpCompatibilityInfoPrefix = "ep_compatibility_info.";
static const char* const kOrtModelMetadata_EpCompatibilityInfoPrefix = "ep_compatibility_info.";

// Key for the execution provider library path (for dynamically loaded EPs)
static const char* const kOrtEpDevice_EpMetadataKey_LibraryPath = "library_path";
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
#include "core/session/plugin_ep/ep_factory_provider_bridge.h"

#include "core/providers/shared_library/provider_host_api.h"
#include "core/session/plugin_ep/ep_library_plugin.h"
#include "core/session/onnxruntime_ep_device_ep_metadata_keys.h"

namespace onnxruntime {
OrtStatus* ProviderBridgeEpFactory::GetSupportedDevices(EpFactoryInternal& ep_factory,
Expand All @@ -20,6 +22,11 @@ OrtStatus* ProviderBridgeEpFactory::GetSupportedDevices(EpFactoryInternal& ep_fa
auto* ep_device = ep_devices[i];
if (ep_device) {
ep_device->ep_factory = &ep_factory;

// Add library path to EP metadata if available
if (library_path_.has_value()) {
ep_device->ep_metadata.Add(kOrtEpDevice_EpMetadataKey_LibraryPath, library_path_->string());
}
}
}

Expand Down
15 changes: 11 additions & 4 deletions onnxruntime/core/session/plugin_ep/ep_factory_provider_bridge.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,10 @@

#pragma once

#include <filesystem>
#include <optional>
#include <utility>

#include "core/framework/error_code_helper.h"
#include "core/session/abi_devices.h"
#include "core/session/abi_session_options_impl.h"
Expand All @@ -12,12 +16,14 @@
namespace onnxruntime {
class ProviderBridgeEpFactory : public EpFactoryInternalImpl {
public:
ProviderBridgeEpFactory(OrtEpFactory& ep_factory, ProviderLibrary& provider_library)
ProviderBridgeEpFactory(OrtEpFactory& ep_factory, ProviderLibrary& provider_library,
std::optional<std::filesystem::path> library_path = std::nullopt)
: EpFactoryInternalImpl(ep_factory.GetName(&ep_factory),
ep_factory.GetVendor(&ep_factory),
ep_factory.GetVendorId(&ep_factory)),
ep_factory_{ep_factory},
provider_library_{provider_library} {
provider_library_{provider_library},
library_path_{std::move(library_path)} {
}

private:
Expand Down Expand Up @@ -59,8 +65,9 @@ class ProviderBridgeEpFactory : public EpFactoryInternalImpl {
return ep_factory_.CreateSyncStreamForDevice(&ep_factory_, device, stream_options, stream);
}

OrtEpFactory& ep_factory_; // OrtEpFactory from the provider bridge EP
ProviderLibrary& provider_library_; // ProviderLibrary from the provider bridge EP
OrtEpFactory& ep_factory_;
ProviderLibrary& provider_library_;
std::optional<std::filesystem::path> library_path_;
};

} // namespace onnxruntime
1 change: 1 addition & 0 deletions onnxruntime/core/session/plugin_ep/ep_library.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ class EpLibrary {
virtual Status Load() { return Status::OK(); }
virtual const std::vector<OrtEpFactory*>& GetFactories() = 0; // valid after Load()
virtual Status Unload() { return Status::OK(); }

virtual ~EpLibrary() = default;

ORT_DISALLOW_COPY_AND_ASSIGNMENT(EpLibrary);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
#include "core/session/plugin_ep/ep_library_provider_bridge.h"

#include "core/session/plugin_ep/ep_factory_provider_bridge.h"
#include "core/session/plugin_ep/ep_library_plugin.h"

namespace onnxruntime {
Status EpLibraryProviderBridge::Load() {
Expand All @@ -26,8 +27,9 @@ Status EpLibraryProviderBridge::Load() {
// to do this we need to capture `factory` and plug it in to is_supported_fn and create_fn.
// we also need to update any returned OrtEpDevice instances to swap the wrapper EpFactoryInternal in so that we can
// call Provider::CreateIExecutionProvider in EpFactoryInternal::CreateIExecutionProvider.

for (const auto& factory : ep_library_plugin_->GetFactories()) {
auto factory_impl = std::make_unique<ProviderBridgeEpFactory>(*factory, *provider_library_);
auto factory_impl = std::make_unique<ProviderBridgeEpFactory>(*factory, *provider_library_, library_path_);
auto internal_factory = std::make_unique<EpFactoryInternal>(std::move(factory_impl));

factory_ptrs_.push_back(internal_factory.get());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,11 @@ namespace onnxruntime {
class EpLibraryProviderBridge : public EpLibrary {
public:
EpLibraryProviderBridge(std::unique_ptr<ProviderLibrary> provider_library,
std::unique_ptr<EpLibrary> ep_library_plugin)
std::unique_ptr<EpLibrary> ep_library_plugin,
std::optional<std::filesystem::path> library_path = std::nullopt)
: provider_library_{std::move(provider_library)},
ep_library_plugin_{std::move(ep_library_plugin)} {
ep_library_plugin_{std::move(ep_library_plugin)},
library_path_{std::move(library_path)} {
}

const char* RegistrationName() const override {
Expand Down Expand Up @@ -53,6 +55,9 @@ class EpLibraryProviderBridge : public EpLibrary {
// implement EpFactoryInternal::CreateIExecutionProvider by calling Provider::CreateIExecutionProvider.
std::unique_ptr<EpLibrary> ep_library_plugin_;

// Library path for EP metadata
std::optional<std::filesystem::path> library_path_;

std::vector<std::unique_ptr<EpFactoryInternal>> factories_;
std::vector<OrtEpFactory*> factory_ptrs_; // for convenience
std::vector<EpFactoryInternal*> internal_factory_ptrs_; // for convenience
Expand Down
5 changes: 3 additions & 2 deletions onnxruntime/core/session/utils.cc
Original file line number Diff line number Diff line change
Expand Up @@ -421,13 +421,14 @@ Status LoadPluginOrProviderBridge(const std::string& registration_name,
<< (is_provider_bridge ? " as a provider bridge" : " as a plugin");

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

if (is_provider_bridge) {
// wrap the EpLibraryPlugin with EpLibraryProviderBridge to add to directly create an IExecutionProvider
auto ep_library_provider_bridge = std::make_unique<EpLibraryProviderBridge>(std::move(provider_library),
std::move(ep_library_plugin));
std::move(ep_library_plugin),
resolved_library_path);
ORT_RETURN_IF_ERROR(ep_library_provider_bridge->Load());
internal_factories = ep_library_provider_bridge->GetInternalFactories();
ep_library = std::move(ep_library_provider_bridge);
Expand Down