-
Couldn't load subscription status.
- Fork 3.5k
[Plugin EP] Allow EP to provide additional virtual devices #26234
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
… metadata entry to indicate who created the device instance
| * \note New additional devices created by this EP factory are not provided to other EP factories. Only this | ||
| * EP factory receives the new additional hardware devices via OrtEpFactory::GetSupportedDevices(). | ||
| * Any OrtEpDevice instances that this EP factory creates with an additional hardware device are visible to | ||
| * applications that call OrtApi::GetEpDevices(). |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we need this complexity?
Alternatively, if we're only going to show the OrtEpDevice to the EP that created it, can the EP create it inside of GetSupportedDevices?
e.g. inside GetSupportedDevices
- EP determines a virtual device is required
- EP creates OrtHardwareDevice.
- EP uses that to create OrtEpDevice.
EP could register the OrtHardwareDevice with ORT so we can release it when the EP is unregistered, or EP could own it if we provided a ReleaseHardwareDevice function. Only place the OrtHardwareDevice shows up is indirectly in the OrtEpDevice.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think that helps with complexity, but it lacks a signal for the EP to know it should create a virtual device.
GetAdditionalHardwareDevices is better, but that doesn't have a signal for device type (e.g. create a GPU or NPU or both).
Or do we expect it creates all possible virtual devices by default?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Or do we expect it creates all possible virtual devices by default?
Yeah, that was my original idea. The EP library knows
- The platform/arch the Ep library was built for (e.g., win x64).
- The set of actual
OrtHardwareDeviceinstances that ORT found. - The set of virtual devices that the EP library wants to expose to the application for that specific platform/arch.
So, based on the above, the EP library would create all possible/necessary virtual devices. The EP library also knows the correct provider options to associate with each virtual device.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As per our offline discussion, this PR now allows app to signal the EP (via ".virtual" suffix to EP registration name) that virtual devices are allowed.
| cpu_device.vendor_id = cpuid_info.GetCPUVendorId(); | ||
| cpu_device.device_id = 0; | ||
| cpu_device.type = OrtHardwareDeviceType_CPU; | ||
| cpu_device.metadata.Add(kOrtHardwareDevice_MetadataKey_DiscoveredBy, "ONNX Runtime"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we need this as well as IsVirtual? Wary of having too much stuff in metadata, and possibly the IsVirtual implies it was not discovered by ORT unless there's some other feature that will rely on an explicit 'discovered by' value.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
My thought is that:
DiscoveredBytells the application who discovered the device. May be useful if the app only wants stuff discovered by ORT.IsVirtualis "1" if it does not correspond to actual hardware. It's the negation ofIsHardwareused by dxcore api. This is a separate concept fromDiscoveredBy. This would be useful for off-target compilation, for example.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If we only show the virtual device to the EP that created it, is there value in DiscoveredBy?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The application, which can see all OrtEpDevices via GetEpDevices, would be able to see who created the hw device.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I removed DiscoveredBy and retained IsVirtual.
|
How does an EP know what sort of device it should create? e.g. an arm64 vs x64 virtual device. Would it create a generic virtual device so we have an OrtEpDevice for it, that gets explicitly selected using SessionOptionsAppendExecutionProvider_V2, and the EP options that can be provided there are used to specify things like the target architecture etc. if this is a cross compiling scenario? |
…ODO: dont make the EP parse the suffix
| } | ||
|
|
||
| Status SetEpFactoryEnvironmentOptions(OrtEpFactory& factory, std::string_view lib_registration_name) { | ||
| if (factory.SetEnvironmentOptions == nullptr) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
needs version check as well. could be random bits if the EP was built with ORT 1.23
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks!
Description
Adds APIs to allow a plugin EP to create a virtual
OrtHardwareDevicethat can be used for model cross-compilation. For example, this allows an EP to create a compiled model for NPU on a device that does not have an NPU.Application code
An application must explicitly allow registered plugin EPs to create virtual devices. This is currently done by using a registration name that ends in the
".virtual"suffix. Ex:Plugin EP code
This PR introduces a new optional C API function in the
OrtEpFactorystruct calledSetEnvironmentOptionsthat allows ORT to pass options (as key/value pairs) to an EP factory. Currently, the only key supported is"allow_virtual_devices", which indicates to the EP factory that creating virtual devices is allowed.When the application registers a plugin EP library, ORT creates the library's EP factories and checks if they implement the
SetEnvironmentOptionsAPI function. If so, ORT callsep_factory.SetEnvironmentOptionswith"allow_virtual_devices"set to"1"if the EP registration name set by the application ends in the".virtual"suffix (or"0"otherwise).Here's an example implementation of
OrtEpFactory::SetEnvironmentOptionstaken from a test plugin EP that supports a virtual GPU:An EP factory can create a virtual hardware device within
OrtEpFactory::GetSupportedDevicesby using a new API function calledCreateHardwareDevice. The EP factory is expected to own the hardware device instance, which should be released when the factory is destroyed viaReleaseHardwareDevice.The test plugin EP shows an implementation of
OrtEpFactory::GetSupportedDevicesthat creates a virtual GPU device.Motivation and Context