Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
99 changes: 96 additions & 3 deletions csharp/src/Microsoft.ML.OnnxRuntime/NativeMethods.shared.cs
Original file line number Diff line number Diff line change
Expand Up @@ -353,6 +353,7 @@ public struct OrtApi

public IntPtr SessionOptionsAppendExecutionProvider_V2;
public IntPtr SessionOptionsSetEpSelectionPolicy;
public IntPtr SessionOptionsSetEpSelectionPolicyDelegate;

public IntPtr HardwareDevice_Type;
public IntPtr HardwareDevice_VendorId;
Expand Down Expand Up @@ -692,6 +693,11 @@ static NativeMethods()
(DSessionOptionsSetEpSelectionPolicy)Marshal.GetDelegateForFunctionPointer(
api_.SessionOptionsSetEpSelectionPolicy,
typeof(DSessionOptionsSetEpSelectionPolicy));

OrtSessionOptionsSetEpSelectionPolicyDelegate =
(DSessionOptionsSetEpSelectionPolicyDelegate)Marshal.GetDelegateForFunctionPointer(
api_.SessionOptionsSetEpSelectionPolicyDelegate,
typeof(DSessionOptionsSetEpSelectionPolicyDelegate));
}

internal class NativeLib
Expand Down Expand Up @@ -2278,28 +2284,49 @@ out IntPtr lora_adapter
#region Auto EP API related
//
// OrtKeyValuePairs

/// <summary>
/// Create an OrtKeyValuePairs instance.
/// </summary>
[UnmanagedFunctionPointer(CallingConvention.Winapi)]
public delegate void DOrtCreateKeyValuePairs(out IntPtr /* OrtKeyValuePairs** */ kvps);

/// <summary>
/// Add/replace a key-value pair in the OrtKeyValuePairs instance.
/// </summary>
[UnmanagedFunctionPointer(CallingConvention.Winapi)]
public delegate void DOrtAddKeyValuePair(IntPtr /* OrtKeyValuePairs* */ kvps,
byte[] /* const char* */ key,
byte[] /* const char* */ value);

/// <summary>
/// Get the value for the provided key.
/// </summary>
/// <returns>Value. Returns IntPtr.Zero if key was not found.</returns>
[UnmanagedFunctionPointer(CallingConvention.Winapi)]
public delegate IntPtr /* const char* */ DOrtGetKeyValue(IntPtr /* const OrtKeyValuePairs* */ kvps,
byte[] /* const char* */ key);

/// <summary>
/// Get all the key-value pairs in the OrtKeyValuePairs instance.
/// </summary>
[UnmanagedFunctionPointer(CallingConvention.Winapi)]
public delegate void DOrtGetKeyValuePairs(IntPtr /* const OrtKeyValuePairs* */ kvps,
out IntPtr /* const char* const** */ keys,
out IntPtr /* const char* const** */ values,
out UIntPtr /* size_t* */ numEntries);

/// <summary>
/// Remove a key-value pair from the OrtKeyValuePairs instance.
/// Ignores keys that are not present.
/// </summary>
[UnmanagedFunctionPointer(CallingConvention.Winapi)]
public delegate void DOrtRemoveKeyValuePair(IntPtr /* OrtKeyValuePairs* */ kvps,
byte[] /* const char* */ key);

/// <summary>
/// Release the OrtKeyValuePairs instance.
/// </summary>
[UnmanagedFunctionPointer(CallingConvention.Winapi)]
public delegate void DOrtReleaseKeyValuePairs(IntPtr /* OrtKeyValuePairs* */ kvps);

Expand Down Expand Up @@ -2370,12 +2397,27 @@ public delegate void DOrtRemoveKeyValuePair(IntPtr /* OrtKeyValuePairs* */ kvps,

//
// Auto Selection EP registration and selection customization

/// <summary>
/// Register an execution provider library.
/// The library must implement CreateEpFactories and ReleaseEpFactory.
/// </summary>
/// <param name="env">Environment to add the EP library to.</param>
/// <param name="registration_name">Name to register the library under.</param>
/// <param name="path">Absolute path to the library.</param>
/// <returns>OrtStatus*</returns>
[UnmanagedFunctionPointer(CallingConvention.Winapi)]
public delegate IntPtr /* OrtStatus* */ DOrtRegisterExecutionProviderLibrary(
IntPtr /* OrtEnv* */ env,
byte[] /* const char* */ registration_name,
byte[] /* const ORTCHAR_T* */ path);

/// <summary>
/// Unregister an execution provider library.
/// </summary>
/// <param name="env">The environment to unregister the library from.</param>
/// <param name="registration_name">The name the library was registered under.</param>
/// <returns>OrtStatus*</returns>
[UnmanagedFunctionPointer(CallingConvention.Winapi)]
public delegate IntPtr /* OrtStatus* */ DOrtUnregisterExecutionProviderLibrary(
IntPtr /* OrtEnv* */ env,
Expand All @@ -2384,6 +2426,11 @@ public delegate void DOrtRemoveKeyValuePair(IntPtr /* OrtKeyValuePairs* */ kvps,
public static DOrtRegisterExecutionProviderLibrary OrtRegisterExecutionProviderLibrary;
public static DOrtUnregisterExecutionProviderLibrary OrtUnregisterExecutionProviderLibrary;

/// <summary>
/// Get the OrtEpDevices that are available.
/// These are all the possible execution provider and device pairs.
/// </summary>
/// <returns>OrtStatus*</returns>
[UnmanagedFunctionPointer(CallingConvention.Winapi)]
public delegate IntPtr /* OrtStatus* */ DOrtGetEpDevices(
IntPtr /* const OrtEnv* */ env,
Expand All @@ -2392,6 +2439,20 @@ public delegate void DOrtRemoveKeyValuePair(IntPtr /* OrtKeyValuePairs* */ kvps,

public static DOrtGetEpDevices OrtGetEpDevices;

/// <summary>
/// Add execution provider devices to the session options.
/// Priority is based on the order of the OrtEpDevice instances. Highest priority first.
/// All OrtEpDevice instances in ep_devices must be for the same execution provider.
/// e.g. selecting OpenVINO for GPU and NPU would have an OrtEpDevice for GPU and NPU.
/// </summary>
/// <param name="sess_options">SessionOptions to add to.</param>
/// <param name="env">Environment that the OrtEpDevice instances came from by calling GetEpDevices</param>
/// <param name="ep_devices">One or more OrtEpDevice instances.</param>
/// <param name="num_ep_devices">Number of OrtEpDevice instances.</param>
/// <param name="ep_option_keys">User overrides for execution provider options. May be IntPtr.Zero.</param>
/// <param name="ep_option_vals">User overrides for execution provider options. May be IntPtr.Zero.</param>
/// <param name="num_ep_options">Number of user overrides for execution provider options.</param>
/// <returns></returns>
[UnmanagedFunctionPointer(CallingConvention.Winapi)]
public delegate IntPtr /* OrtStatus* */ DOrtSessionOptionsAppendExecutionProvider_V2(
IntPtr /* OrtSessionOptions* */ sess_options,
Expand All @@ -2404,6 +2465,18 @@ public delegate void DOrtRemoveKeyValuePair(IntPtr /* OrtKeyValuePairs* */ kvps,

public static DOrtSessionOptionsAppendExecutionProvider_V2 OrtSessionOptionsAppendExecutionProvider_V2;

/// <summary>
/// Delegate to do custom execution provider selection.
/// </summary>
/// <param name="epDevices">Available OrtEpDevices to select from.</param>
/// <param name="numDevices">Number of OrtEpDevices.</param>
/// <param name="modelMetadata">Metadata from the ONNX model.</param>
/// <param name="runtimeMetadata">Runtime metadata. May be IntPtr.Zero.</param>
/// <param name="selected">OrtEpDevices that were selected. Pre-allocated array for delegate to update.</param>
/// <param name="maxSelected">Maximum number of OrtEpDevices that can be selected.</param>
/// <param name="numSelected">Number of OrtEpDevices that were selected.</param>
/// <param name="state">State that was provided in when the delegate was registered.</param>
/// <returns>OrtStatus*</returns>
[UnmanagedFunctionPointer(CallingConvention.Winapi)]
public delegate IntPtr DOrtEpSelectionDelegate(
IntPtr /* OrtEpDevice** */ epDevices,
Expand All @@ -2412,16 +2485,36 @@ public delegate IntPtr DOrtEpSelectionDelegate(
IntPtr /* OrtKeyValuePairs* */ runtimeMetadata,
IntPtr /* OrtEpDevice** */ selected,
uint maxSelected,
out UIntPtr numSelected
out UIntPtr numSelected,
IntPtr /* void* */ state
);

/// <summary>
/// Set the execution provider selection policy.
/// </summary>
/// <param name="session_options">SessionOptions to set the policy for.</param>
/// <param name="policy">Selection policy.</param>
/// <returns>OrtStatus*</returns>
[UnmanagedFunctionPointer(CallingConvention.Winapi)]
public delegate IntPtr /* OrtStatus* */ DSessionOptionsSetEpSelectionPolicy(
IntPtr /* OrtSessionOptions* */ session_options,
int /* OrtExecutionProviderDevicePolicy */ policy,
IntPtr /* DOrtEpSelectionDelegate* */ selection_delegate);
int /* OrtExecutionProviderDevicePolicy */ policy);
public static DSessionOptionsSetEpSelectionPolicy OrtSessionOptionsSetEpSelectionPolicy;

/// <summary>
/// Set the execution provider selection policy delegate.
/// </summary>
/// <param name="session_options">SessionOptions to set the policy for.</param>
/// <param name="selection_delegate">Selection policy delegate.</param>
/// <param name="state">State that is passed through to the selection delegate.</param>
/// <returns>OrtStatus*</returns>
[UnmanagedFunctionPointer(CallingConvention.Winapi)]
public delegate IntPtr /* OrtStatus* */ DSessionOptionsSetEpSelectionPolicyDelegate(
IntPtr /* OrtSessionOptions* */ session_options,
IntPtr /* DOrtEpSelectionDelegate* */ selection_delegate,
IntPtr /* void* */ state);
public static DSessionOptionsSetEpSelectionPolicyDelegate OrtSessionOptionsSetEpSelectionPolicyDelegate;


#endregion
#region Misc API
Expand Down
30 changes: 9 additions & 21 deletions csharp/src/Microsoft.ML.OnnxRuntime/OrtEpDevice.shared.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,18 +10,18 @@ namespace Microsoft.ML.OnnxRuntime
/// Represents the combination of an execution provider and a hardware device
/// that the execution provider can utilize.
/// </summary>
public class OrtEpDevice : SafeHandle
public class OrtEpDevice
{
/// <summary>
/// Construct an OrtEpDevice from an existing native OrtEpDevice instance.
/// </summary>
/// <param name="epDeviceHandle">Native OrtEpDevice handle.</param>
internal OrtEpDevice(IntPtr epDeviceHandle)
: base(epDeviceHandle, ownsHandle: false)
{
_handle = epDeviceHandle;
}

internal IntPtr Handle => handle;
internal IntPtr Handle => _handle;

/// <summary>
/// The name of the execution provider.
Expand All @@ -30,7 +30,7 @@ public string EpName
{
get
{
IntPtr namePtr = NativeMethods.OrtEpDevice_EpName(handle);
IntPtr namePtr = NativeMethods.OrtEpDevice_EpName(_handle);
return NativeOnnxValueHelper.StringFromNativeUtf8(namePtr);
}
}
Expand All @@ -42,7 +42,7 @@ public string EpVendor
{
get
{
IntPtr vendorPtr = NativeMethods.OrtEpDevice_EpVendor(handle);
IntPtr vendorPtr = NativeMethods.OrtEpDevice_EpVendor(_handle);
return NativeOnnxValueHelper.StringFromNativeUtf8(vendorPtr);
}
}
Expand All @@ -54,7 +54,7 @@ public OrtKeyValuePairs EpMetadata
{
get
{
return new OrtKeyValuePairs(NativeMethods.OrtEpDevice_EpMetadata(handle));
return new OrtKeyValuePairs(NativeMethods.OrtEpDevice_EpMetadata(_handle));
}
}

Expand All @@ -65,7 +65,7 @@ public OrtKeyValuePairs EpOptions
{
get
{
return new OrtKeyValuePairs(NativeMethods.OrtEpDevice_EpOptions(handle));
return new OrtKeyValuePairs(NativeMethods.OrtEpDevice_EpOptions(_handle));
}
}

Expand All @@ -76,23 +76,11 @@ public OrtHardwareDevice HardwareDevice
{
get
{
IntPtr devicePtr = NativeMethods.OrtEpDevice_Device(handle);
IntPtr devicePtr = NativeMethods.OrtEpDevice_Device(_handle);
return new OrtHardwareDevice(devicePtr);
}
}

/// <summary>
/// Indicates whether the native handle is invalid.
/// </summary>
public override bool IsInvalid => handle == IntPtr.Zero;

/// <summary>
/// No-op. OrtEpDevice is always read-only as the instance is owned by native ORT.
/// </summary>
/// <returns>True</returns>
protected override bool ReleaseHandle()
{
return true;
}
private readonly IntPtr _handle;
}
}
30 changes: 9 additions & 21 deletions csharp/src/Microsoft.ML.OnnxRuntime/OrtHardwareDevice.shared.cs
Original file line number Diff line number Diff line change
Expand Up @@ -21,16 +21,16 @@ public enum OrtHardwareDeviceType
/// <summary>
/// Represents a hardware device that is available on the current system.
/// </summary>
public class OrtHardwareDevice : SafeHandle
public class OrtHardwareDevice
{

/// <summary>
/// Construct an OrtHardwareDevice for a native OrtHardwareDevice instance.
/// </summary>
/// <param name="deviceHandle">Native OrtHardwareDevice handle.</param>
internal OrtHardwareDevice(IntPtr deviceHandle)
: base(deviceHandle, ownsHandle: false)
internal OrtHardwareDevice(IntPtr deviceHandle)
{
_handle = deviceHandle;
}

/// <summary>
Expand All @@ -40,7 +40,7 @@ public OrtHardwareDeviceType Type
{
get
{
return (OrtHardwareDeviceType)NativeMethods.OrtHardwareDevice_Type(handle);
return (OrtHardwareDeviceType)NativeMethods.OrtHardwareDevice_Type(_handle);
}
}

Expand All @@ -54,7 +54,7 @@ public uint VendorId
{
get
{
return NativeMethods.OrtHardwareDevice_VendorId(handle);
return NativeMethods.OrtHardwareDevice_VendorId(_handle);
}
}

Expand All @@ -65,7 +65,7 @@ public string Vendor
{
get
{
IntPtr vendorPtr = NativeMethods.OrtHardwareDevice_Vendor(handle);
IntPtr vendorPtr = NativeMethods.OrtHardwareDevice_Vendor(_handle);
return NativeOnnxValueHelper.StringFromNativeUtf8(vendorPtr);
}
}
Expand All @@ -82,7 +82,7 @@ public uint DeviceId
{
get
{
return NativeMethods.OrtHardwareDevice_DeviceId(handle);
return NativeMethods.OrtHardwareDevice_DeviceId(_handle);
}
}

Expand All @@ -95,22 +95,10 @@ public OrtKeyValuePairs Metadata
{
get
{
return new OrtKeyValuePairs(NativeMethods.OrtHardwareDevice_Metadata(handle));
return new OrtKeyValuePairs(NativeMethods.OrtHardwareDevice_Metadata(_handle));
}
}

/// <summary>
/// Indicates whether the native handle is invalid.
/// </summary>
public override bool IsInvalid => handle == IntPtr.Zero;

/// <summary>
/// No-op. OrtHardwareDevice is always read-only as the instance is owned by native ORT.
/// </summary>
/// <returns>True</returns>
protected override bool ReleaseHandle()
{
return true;
}
private readonly IntPtr _handle;
}
}
Loading
Loading