Unable to fetch GPU information in WSL windows
I have an application which heavily really on hardware, The piece of code perfectly run fine on windows and macos, but when I try to run the application on WSL Windows the GPU information is empty.
Example:
package main
import (
"fmt"
"github.com/jaypipes/ghw"
)
func main() {
gpu, err := ghw.GPU()
if err != nil {
fmt.Printf("Error getting GPU info: %v", err)
}
fmt.Printf("%v\n", gpu)
for _, card := range gpu.GraphicsCards {
fmt.Printf(" %v\n", card)
}
}
Output when I run it inside wsl:
Output in normal windows:
Hi @Chetan177 hope you are doing well! You have run into the classic "Windows Subsystem for Linux isn't actually Linux and isn't Windows" problem. :)
This is why I often refer to WSL as "World's Shoddiest Linux" (though I often use a different spelling of "Shoddiest" ;)
I'm not sure there's much I will be able to do to "fix" this problem, since it really has to do with various expected Linux sysfs mounts not existing in WSL, and there's really not much I can do about that. I'm all open to any ideas you might have, though!
@Chetan177 @jaypipes thx. I made some attempts. Although they failed, I still hope that the GPU-PV technology can be successfully applied. This might require the joint efforts of developers from all sectors. This is also one of the few functions that can be virtualized at a very low cost on consumer-level NVIDIA graphics cards.
mian.go
package main
import (
"fmt"
"github.com/jaypipes/ghw"
)
func main() {
gpu, err: = ghw.GPU()
if err != nil {
fmt.Printf("Error getting GPU info: %v", err)
}
fmt.Printf("%v\n", gpu)
for _, card: = range gpu.GraphicsCards {
fmt.Printf(" %v\n", card)
}
fmt.Printf("=====\n")
accel, err: = ghw.Accelerator()
if err != nil {
fmt.Printf("Error getting processing accelerator info: %v", err)
}
fmt.Printf("%v\n", accel)
for _, device: = range accel.Devices {
fmt.Printf(" %v\n", device)
}
}
output:
root@fnasfnas1:/tmp/test# go run main.go
gpu (0 graphics cards)
=====
processing accelerators (1 device)
device @d8f8:00:00.0 -> driver: 'dxgkrnl' class: 'Display controller' vendor: 'Microsoft Corporation' product: 'Basic Render Driver'
system info:
root@fnasfnas1:/tmp/test# lspci -v
d8f8:00:00.0 3D controller: Microsoft Corporation Basic Render Driver
Physical Slot: 1349682479
Flags: bus master, fast devsel, latency 0, NUMA node 0
Capabilities: [40] Null
Kernel driver in use: dxgkrnl
Kernel modules: dxgkrnl
root@fnasfnas1:/tmp/test# lspci -vn
d8f8:00:00.0 0302: 1414:008e
Physical Slot: 1349682479
Flags: bus master, fast devsel, latency 0, NUMA node 0
Capabilities: [40] Null
Kernel driver in use: dxgkrnl
Kernel modules: dxgkrnl
root@fnasfnas1:/tmp/test# lsmod | grep dxg
dxgkrnl 225280 0
hv_vmbus 176128 9 hv_balloon,hv_utils,hv_netvsc,hid_hyperv,dxgkrnl,hv_storvsc,hyperv_keyboard,pci_hyperv,hyperv_fb
root@fnasfnas1:/tmp/test# lsmod | grep vgem
vgem 12288 0
drm_shmem_helper 36864 1 vgem
drm 757760 4 drm_kms_helper,drm_shmem_helper,vgem
root@fnasfnas1:/tmp/test# ll /dev/dri/
by-path/ card0 renderD128
root@fnasfnas1:/tmp/test# ll /dev/dri/
total 0
drwxr-xr-x 3 root root 100 Aug 12 00:00 .
drwxr-xr-x 20 root root 3480 Aug 12 00:00 ..
drwxr-xr-x 2 root root 80 Aug 12 00:00 by-path
crw-rw---- 1 root video 226, 0 Aug 12 00:00 card0
crw-rw---- 1 root render 226, 128 Aug 12 00:00 renderD128
root@fnasfnas1:/tmp/test# ll /dev/dri/card0
crw-rw---- 1 root video 226, 0 Aug 12 00:00 /dev/dri/card0
root@fnasfnas1:/tmp/test# ll /sys/class/drm/
total 0
drwxr-xr-x 2 root root 0 Aug 12 00:00 .
drwxr-xr-x 53 root root 0 Aug 12 00:00 ..
lrwxrwxrwx 1 root root 0 Aug 12 00:00 card0 -> ../../devices/platform/vgem/drm/card0
lrwxrwxrwx 1 root root 0 Aug 12 00:00 renderD128 -> ../../devices/platform/vgem/drm/renderD128
-r--r--r-- 1 root root 4096 Aug 12 00:01 version
root@fnasfnas1:~# glxinfo -B
name of display: localhost:10.0
display: localhost:10 screen: 0
direct rendering: Yes
Extended renderer info (GLX_MESA_query_renderer):
Vendor: Microsoft Corporation (0xffffffff)
Device: D3D12 (NVIDIA GeForce RTX 3060) (0xffffffff)
Version: 22.3.6
Accelerated: yes
Video memory: 44776MB
Unified memory: no
Preferred profile: core (0x1)
Max core profile version: 4.2
Max compat profile version: 4.2
Max GLES1 profile version: 1.1
Max GLES[23] profile version: 3.1
OpenGL vendor string: Microsoft Corporation
OpenGL renderer string: D3D12 (NVIDIA GeForce RTX 3060)
OpenGL core profile version string: 4.2 (Core Profile) Mesa 22.3.6
OpenGL core profile shading language version string: 4.20
OpenGL core profile context flags: (none)
OpenGL core profile profile mask: core profile
OpenGL version string: 4.2 (Compatibility Profile) Mesa 22.3.6
OpenGL shading language version string: 4.20
OpenGL context flags: (none)
OpenGL profile mask: compatibility profile
OpenGL ES profile version string: OpenGL ES 3.1 Mesa 22.3.6
OpenGL ES profile shading language version string: OpenGL ES GLSL ES 3.10
root@fnasfnas1:~# nvi
nvidia-ngx-updater nvidia-smi
root@fnasfnas1:~# nvidia-smi
Tue Aug 12 01:12:25 2025
+-----------------------------------------------------------------------------------------+
| NVIDIA-SMI 575.64.04 Driver Version: 577.00 CUDA Version: 12.9 |
|-----------------------------------------+------------------------+----------------------+
| GPU Name Persistence-M | Bus-Id Disp.A | Volatile Uncorr. ECC |
| Fan Temp Perf Pwr:Usage/Cap | Memory-Usage | GPU-Util Compute M. |
| | | MIG M. |
|=========================================+========================+======================|
| 0 NVIDIA GeForce RTX 3060 On | 00000000:01:00.0 On | N/A |
| 0% 51C P0 35W / 170W | 5243MiB / 12288MiB | 7% Default |
| | | N/A |
+-----------------------------------------+------------------------+----------------------+
+-----------------------------------------------------------------------------------------+
| Processes: |
| GPU GI CI PID Type Process name GPU Memory |
| ID ID Usage |
|=========================================================================================|
| No running processes found |
+-----------------------------------------------------------------------------------------+
Obviously, in Debian 12, hyper-v integrated GPU-PV can access the graphics card. However, this is merely a bridging operation. There are no NVIDIA PCIe devices linked to Debian.
And in WSL, the GPU device registered using /vgem - Virtual GPU Graphics Memory Manager is being used, so we may not be able to obtain pciAddress.
The actual address corresponding to the vgem card0 is /sys/devices/platform/vgem/drm/card0.
regex101: https://regex101.com/r/zgfOA8/1
https://github.com/jaypipes/ghw/blob/d0f46e2c7af550135bdbcc33fc40aa9d70628094/pkg/gpu/gpu_linux.go#L98
Architecture:
https://devblogs.microsoft.com/directx/directx-heart-linux/
So I'm wondering if we have the capability to integrate the virtual graphics card created by the vgem driver. A possible structure for a Graphics Card might look like this
type GraphicsCard struct {
Address string `json:"address"` // d8f8:00:00.0
Index int `json:"index"` // 0
DeviceInfo *pci.Device `json:"pci"` // from pci.New(context.WithContext(i.ctx))
Node *topology.Node `json:"node,omitempty"` // nil
}