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
11 changes: 11 additions & 0 deletions include/onnxruntime/core/session/environment.h
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,17 @@ class Environment {
return execution_devices_;
}

/// Get hardware device incompatibility details for a specific EP.
/// @param ep_name The name of the execution provider to check.
/// @param hw The hardware device to check for incompatibility.
/// @param details Output: Incompatibility details including reasons for incompatibility if any.
/// @returns Status indicating success or failure.
Status GetHardwareDeviceEpIncompatibilityDetails(const std::string& ep_name,
const OrtHardwareDevice* hw,
std::unique_ptr<OrtDeviceEpIncompatibilityDetails>& details) const;

const std::vector<const OrtHardwareDevice*>& GetSortedOrtHardwareDevices() const;

Status CreateSharedAllocator(const OrtEpDevice& ep_device,
OrtDeviceMemoryType mem_type, OrtAllocatorType allocator_type,
const OrtKeyValuePairs* allocator_options, OrtAllocator** allocator);
Expand Down
128 changes: 127 additions & 1 deletion include/onnxruntime/core/session/onnxruntime_c_api.h
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.

// See docs\c_cxx\README.md on generating the Doxygen documentation from this file
Expand Down Expand Up @@ -333,6 +333,7 @@ ORT_RUNTIME_CLASS(ExternalInitializerInfo);
ORT_RUNTIME_CLASS(ExternalResourceImporter); // Capability object for external resource import
ORT_RUNTIME_CLASS(ExternalMemoryHandle); // EP-imported view of shared external allocation
ORT_RUNTIME_CLASS(ExternalSemaphoreHandle); // EP-imported view of shared external semaphore
ORT_RUNTIME_CLASS(DeviceEpIncompatibilityDetails);

#ifdef _MSC_VER
typedef _Return_type_success_(return == 0) OrtStatus* OrtStatusPtr;
Expand Down Expand Up @@ -510,6 +511,16 @@ typedef enum OrtExecutionProviderDevicePolicy {
OrtExecutionProviderDevicePolicy_MIN_OVERALL_POWER,
} OrtExecutionProviderDevicePolicy;

/** \brief Reasons why an execution provider might not be compatible with a device
*/
typedef enum OrtDeviceEpIncompatibilityReason {
OrtDeviceEpIncompatibility_NONE = 0,
OrtDeviceEpIncompatibility_DRIVER_INCOMPATIBLE = 1 << 0,
OrtDeviceEpIncompatibility_DEVICE_INCOMPATIBLE = 1 << 1,
OrtDeviceEpIncompatibility_MISSING_DEPENDENCY = 1 << 2,
OrtDeviceEpIncompatibility_UNKNOWN = 1 << 31
} OrtDeviceEpIncompatibilityReason;

/** \brief Delegate to allow providing custom OrtEpDevice selection logic
*
* This delegate is called by the EP selection code to allow the user to provide custom device selection logic.
Expand Down Expand Up @@ -6784,6 +6795,121 @@ struct OrtApi {
ORT_API2_STATUS(SessionGetEpDeviceForOutputs, _In_ const OrtSession* session,
_Out_writes_(num_outputs) const OrtEpDevice** outputs_ep_devices,
_In_ size_t num_outputs);
/** \brief Get the number of available hardware devices.
*
* Returns the count of hardware devices discovered on the system.
* Use this to allocate an array before calling GetHardwareDevices().
*
* \param[in] env The OrtEnv instance where device discovery results are stored.
* \param[out] num_devices The number of OrtHardwareDevice instances available.
*
* \snippet{doc} snippets.dox OrtStatus Return Value
*
* \since Version 1.24.
*/
ORT_API2_STATUS(GetNumHardwareDevices, _In_ const OrtEnv* env, _Out_ size_t* num_devices);

/** \brief Get the list of available hardware devices.
*
* Enumerates hardware devices available on the system.
* Populates a user-provided array with pointers to OrtHardwareDevice instances. The caller is responsible
* for allocating the array with sufficient space (use GetNumHardwareDevices() to get the count).
*
* The returned pointers reference internal ORT data structures that are discovered once at process
* startup and remain valid for the lifetime of the OrtEnv. The caller does not need to release these
* pointers, but should not use them after calling ReleaseEnv().
*
* \param[in] env The OrtEnv instance where device discovery results are stored.
* \param[out] devices User-allocated array to receive pointers to OrtHardwareDevice instances.
* The array must have space for at least num_devices elements.
* \param[in] num_devices The size of the user-allocated devices array.
*
* \snippet{doc} snippets.dox OrtStatus Return Value
*
* \since Version 1.24.
*/
ORT_API2_STATUS(GetHardwareDevices, _In_ const OrtEnv* env,
_Out_writes_(num_devices) const OrtHardwareDevice** devices,
_In_ size_t num_devices);

/** \brief Check for known incompatibility issues between hardware device and a specific execution provider.
*
* This function checks for known incompatibility issues between the specified hardware device
* and a specific execution provider.
* If returned incompatibility details have non-zero reasons, it indicates the device is not compatible.
* However, if returned detail have reason == 0, it doesn't guarantee 100% compatibility for all models,
* as models may have specific requirements.
*
* Note: This method should only be called when the OrtEnv has been initialized with execution
* providers (after RegisterExecutionProviderLibrary is called).
*
* \param[in] env The OrtEnv instance with registered execution providers.
* \param[in] ep_name The name of the execution provider to check. Required and cannot be null or empty.
* \param[in] hw The hardware device to check for incompatibility.
* \param[out] details Compatibility details including reasons for incompatibility if any.
* Must be freed with OrtApi::ReleaseDeviceEpIncompatibilityDetails.
*
* \snippet{doc} snippets.dox OrtStatus Return Value
*
* \since Version 1.24.
*/
ORT_API2_STATUS(GetHardwareDeviceEpIncompatibilityDetails, _In_ const OrtEnv* env,
_In_ const char* ep_name,
_In_ const OrtHardwareDevice* hw,
_Outptr_ OrtDeviceEpIncompatibilityDetails** details);

/// \name OrtDeviceEpIncompatibilityDetails
/// Accessor functions for device incompatibility details
/// @{

/** \brief Get the incompatibility reasons bitmask from OrtDeviceEpIncompatibilityDetails.
*
* \param[in] details The OrtDeviceEpIncompatibilityDetails instance to query.
* \param[out] reasons_bitmask Pointer to store the bitmask of incompatibility reasons.
*
* \snippet{doc} snippets.dox OrtStatus Return Value
*
* \since Version 1.24.
*/
ORT_API2_STATUS(DeviceEpIncompatibilityDetails_GetReasonsBitmask,
_In_ const OrtDeviceEpIncompatibilityDetails* details,
_Out_ uint32_t* reasons_bitmask);

/** \brief Get the notes from OrtDeviceEpIncompatibilityDetails.
*
* \param[in] details The OrtDeviceEpIncompatibilityDetails instance to query.
* \param[out] notes Pointer to the notes string. May be nullptr if no notes are available.
* The returned string is owned by the details object and should not be freed.
*
* \snippet{doc} snippets.dox OrtStatus Return Value
*
* \since Version 1.24.
*/
ORT_API2_STATUS(DeviceEpIncompatibilityDetails_GetNotes,
_In_ const OrtDeviceEpIncompatibilityDetails* details,
_Outptr_result_maybenull_ const char** notes);

/** \brief Get the execution provider error code from OrtDeviceEpIncompatibilityDetails.
*
* This allows Independent Hardware Vendors (IHVs) to define their own error codes
* to provide additional details about device incompatibility.
*
* \param[in] details The OrtDeviceEpIncompatibilityDetails instance to query.
* \param[out] error_code Pointer to store the EP-specific error code. A value of 0 indicates no error code was set.
*
* \snippet{doc} snippets.dox OrtStatus Return Value
*
* \since Version 1.24.
*/
ORT_API2_STATUS(DeviceEpIncompatibilityDetails_GetErrorCode,
_In_ const OrtDeviceEpIncompatibilityDetails* details,
_Out_ int32_t* error_code);

/** \brief Release an OrtDeviceEpIncompatibilityDetails instance.
*
* \since Version 1.24.
*/
ORT_CLASS_RELEASE(DeviceEpIncompatibilityDetails);

/// @}
};
Expand Down
45 changes: 45 additions & 0 deletions include/onnxruntime/core/session/onnxruntime_ep_c_api.h
Original file line number Diff line number Diff line change
Expand Up @@ -1308,6 +1308,27 @@ struct OrtEpApi {
*/
ORT_API2_STATUS(KernelInfo_GetEp, _In_ const OrtKernelInfo* info, _Outptr_ const OrtEp** ep);

/** \brief Set the details of an OrtDeviceEpIncompatibilityDetails instance.
*
* Used by execution provider factories to set incompatibility details in their
* GetHardwareDeviceIncompatibilityDetails implementation. ORT creates and initializes the object
* before passing it to the EP, so calling this function is optional. The EP uses this function
* to set incompatibility information when the device is not compatible.
*
* \param[in,out] details The OrtDeviceEpIncompatibilityDetails instance to update.
* \param[in] reasons_bitmask Bitmask of OrtDeviceEpIncompatibilityReason values. (0 = no incompatibility).
* \param[in] error_code Optional EP-specific error code (0 = no error).
* \param[in] notes Optional human-readable notes. Can be null.
*
* \snippet{doc} snippets.dox OrtStatus Return Value
*
* \since Version 1.24.
*/
ORT_API2_STATUS(DeviceEpIncompatibilityDetails_SetDetails, _Inout_ OrtDeviceEpIncompatibilityDetails* details,
_In_ uint32_t reasons_bitmask,
_In_ int32_t error_code,
_In_opt_z_ const char* notes);

/** \brief Creates an OrtKernelImpl instance for an If operator.
*
* Control flow operators require access to ORT session internals to orchestrate subgraph operations.
Expand Down Expand Up @@ -1990,6 +2011,30 @@ struct OrtEpFactory {
*/
ORT_API2_STATUS(SetEnvironmentOptions, _In_ OrtEpFactory* this_ptr, _In_ const OrtKeyValuePairs* options);

/** \brief Check for known incompatibility reasons between a hardware device and this execution provider.
*
* This function allows an execution provider to check if a specific hardware device is compatible
* with the execution provider. The EP can set specific incompatibility reasons via the
* OrtDeviceEpIncompatibilityDetails parameter using OrtEpApi::DeviceEpIncompatibilityDetails_SetDetails.
*
* \param[in] this_ptr The OrtEpFactory instance.
* \param[in] hw The hardware device to check for incompatibility.
* \param[in,out] details Pre-allocated incompatibility details object created and initialized by ORT.
* The EP can use OrtEpApi::DeviceEpIncompatibilityDetails_SetDetails to set
* incompatibility information. If the device is compatible, the EP can
* leave the object unchanged (it defaults to no incompatibility).
*
* \note Implementation of this function is optional.
* If not implemented, ORT will assume the device is compatible with this EP.
*
* \snippet{doc} snippets.dox OrtStatus Return Value
*
* \since Version 1.24.
*/
ORT_API2_STATUS(GetHardwareDeviceIncompatibilityDetails, _In_ OrtEpFactory* this_ptr,
_In_ const OrtHardwareDevice* hw,
_Inout_ OrtDeviceEpIncompatibilityDetails* details);

/** \brief Create an OrtExternalResourceImporterImpl for external resource import.
*
* This is used to create an external resource importer that enables zero-copy import of
Expand Down
6 changes: 6 additions & 0 deletions onnxruntime/core/session/abi_devices.h
Original file line number Diff line number Diff line change
Expand Up @@ -75,3 +75,9 @@ struct OrtEpDevice {
// get/create methods to be as flexible as possible. this helper converts to a non-const factory instance.
OrtEpFactory* GetMutableFactory() const { return ep_factory; }
};

struct OrtDeviceEpIncompatibilityDetails {
uint32_t reasons_bitmask{0}; // Bitmask of OrtDeviceEpIncompatibilityReason values
int32_t error_code{0}; // EP-specific error code (0 = no error)
std::string notes; // Additional human-readable notes
};
Loading
Loading