Skip to content

Discover GPUs through D3DKMT on WSL2 - #34007

Open
mingyue (mingyueliuh) wants to merge 1 commit into
microsoft:mainfrom
mingyueliuh:fix/wsl-d3dkmt-device-discovery
Open

mingyue (mingyueliuh) wants to merge 1 commit into
microsoft:mainfrom
mingyueliuh:fix/wsl-d3dkmt-device-discovery

Conversation

@mingyueliuh

@mingyueliuh mingyue (mingyueliuh) commented Nov 9, 2026 •

Copy link
Copy Markdown
Contributor

Description

Linux GPU discovery scans /sys/class/drm/card*/device and falls back to /sys/bus/pci/devices. Under WSL2 the GPU is paravirtualized through /dev/dxg: /sys/class/drm holds no card* entries, and the only device the PCI scan finds is a Microsoft virtual display adapter — vendor 0x1414, device 0x008e, class 0x030200 — standing in for the real hardware.

This adds a third discovery tier that enumerates adapters through the D3DKMT entry points exported by libdxcore.so and reads the vendor/device IDs from KMTQAITYPE_PHYSICALADAPTERDEVICEIDS. When it yields adapters, the Microsoft placeholders that those descriptors replace are dropped from the list.

Implementation notes:

  • The D3DKMT structs are declared locally rather than included from the Windows SDK/WDK, so a Linux build gains no new header or package dependency.
  • The thunks are loaded through Env::LoadDynamicLibrary, not linked, and the whole path is gated on /dev/dxg existing — nothing is loaded off WSL2.
  • D3DKMTEnumAdapters3 is preferred where available because D3DKMTEnumAdapters2 cannot report compute-only adapters; it falls back to EnumAdapters2 when the symbol is absent.
  • The adapter LUID is recorded as metadata, giving Linux the device identifier the Windows path already exposes.

Motivation and Context

DiscoverDevicesForPlatform() reported a GPU whose vendor and device IDs belong to no vendor's runtime. Every execution provider that selects its device by matching against the discovered OrtHardwareDevice list therefore registered zero OrtEpDevices on WSL2, even though the vendor runtime enumerated the GPU and inference worked through the older append_execution_provider path. Autoep selection, OrtEpDevice enumeration, and anything built on top of them were unusable.

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines:
There may be pipelines that require an authorized user to comment /azp run to run.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

The WSL discovery path can leak adapter handles when D3DKMTCloseAdapter is unavailable, and focused tests for enumeration, cleanup, and fallback behavior are missing.

2 open issues
What changed in this PR

Adds WSL2 GPU discovery through dynamically loaded D3DKMT functions, allowing ONNX Runtime to identify real GPU hardware for execution-provider device matching.

Changes:

  • Enumerates adapters through libdxcore.so, preferring EnumAdapters3 and falling back to EnumAdapters2.
  • Replaces Microsoft placeholder devices when WSL discovery returns adapters, preserving vendor/device IDs and LUID metadata.
  • Includes the new discovery implementation in Linux builds.
File Description
onnxruntime/​core/​platform/​linux/​wsl_device_discovery.h Declares WSL GPU descriptors and discovery API.
onnxruntime/​core/​platform/​linux/​wsl_device_discovery.cc Loads D3DKMT functions and queries adapter identifiers.
onnxruntime/​core/​platform/​linux/​device_discovery.cc Integrates WSL adapters and removes replaced placeholders.
cmake/​onnxruntime_common.cmake Adds WSL discovery files to Linux builds.

Review effort: Balanced

}

bool IsAvailable() const {
return query_adapter_info != nullptr && (enum_adapters3 != nullptr || enum_adapters2 != nullptr);

} // namespace

Status GetGpuDevices(std::vector<WslGpuInfo>& gpu_devices_out) {
Linux GPU discovery only sees a Microsoft virtual display adapter under WSL2, so execution providers that match OrtHardwareDevice register no devices. Enumerate adapters through libdxcore.so and replace those placeholders with the real vendor and device IDs.

Co-authored-by: Flora Cui <flora.cui@amd.com>
Signed-off-by: mingyue <mingyue@amd.com>
Co-authored-by: Cursor <cursoragent@cursor.com>

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants