LOADING
712 words
4 minutes
HyperVにGPUを割り当てて優勝したかった
2024-01-10

構成#

Host 11
VM.04LTS

GPU ARC A770 16GB

kernelは6.5.0-14-generic

前置き#

WSL2で使用されているGPU-PVという技術をHyperVの仮想マシンで使ってVMでもGPUを使おうというお話らしいです。
ダラダラ書き綴っておいてなんですがXeKMDで遊んでた頃はできたのが現在思い出しながらやってみたもののうまく行かず、
そこまでやる必要もなかったので今後の参考になるようにやったことだけ書き残した形になります。
できたので色々書き直しました。

参考文献#

Hyper-VでGPU(GPU-PV)を利用する方法 (Ubuntu編)
Ubuntu 21.04 VM with GPU acceleration under Hyper-V…?
Windows 11 の Hyper-V マシンに GPU を割り当てる(GPU-PV)
wsl2如何更新linux内核? - 雾魂泉守-曌鵷鶵的回答 - 知乎

GPUアダプタを追加する#

まずはGPUのパスを確認する。

Get-VMHostPartitionableGpu | Format-Table Name

以下のような感じでデバイスのパスが返ってくる。(複数GPUがあると複数返ってくるらしい)

Name
----
\\?\PCI#VEN_8086&DEV_56A0&SUBSYS_10208086&REV_08#6&17410126&0&00080008#{064092b3-625e-43bf-9eb5-dc845897dd59}\GPUPARAV

帰ってきた値を元にコマンドを実行してアダプタを追加する。

Add-VMGpuPartitionAdapter -VMName "VM Name" -InstancePath "Device Path"

この場合だと
Add-VMGpuPartitionAdapter -VMName "server" -InstancePath "\\?\PCI#VEN_8086&DEV_56A0&SUBSYS_10208086&REV_08#6&17410126&0&00080008#{064092b3-625e-43bf-9eb5-dc845897dd59}\GPUPARAV"
となる。

GPUリソースを割り当てたりメモリの設定をしたりでホストでの作業はおしまい。

Set-VMGpuPartitionAdapter -VMName "VM Name" -Passthru
Set-VM -VMName "VM Name" -GuestControlledCacheTypes $true -LowMemoryMappedIoSpace 1GB -HighMemoryMappedIoSpace 32GB

ドライバをインストールする#

WSL2 Kernelからdxgkrnlドライバをぶっこ抜いてインストールする。
dkmsを扱うので事前にインストールすること。

以下のコマンドでgithubからwsl2 kernelをクローンする。

git clone -b linux-msft-wsl-6.1.y --depth=1 https://github.com/microsoft/WSL2-Linux-Kernel
cd WSL2-Linux-Kernel

drivers/hv/dxgkrnl/dxgmodule.cのInterface from dxgglobalの部分の上に以下を追記する。

static inline int uuid_le_cmp(const guid_t u1,const guid_t u2)
{
return memcmp(&u1, &u2,sizeof(guid_t));
}

以下のコマンドでdkms.confを作成する。

sudo su
VERSION=$(git rev-parse --short HEAD)
cp -r drivers/hv/dxgkrnl /usr/src/dxgkrnl-$VERSION
mkdir -p /usr/src/dxgkrnl-$VERSION/inc/{uapi/misc,linux}
cp include/uapi/misc/d3dkmthk.h /usr/src/dxgkrnl-$VERSION/inc/uapi/misc/d3dkmthk.h
cp include/linux/hyperv.h /usr/src/dxgkrnl-$VERSION/inc/linux/hyperv_dxgkrnl.h
sed -i 's/\$(CONFIG_DXGKRNL)/m/' /usr/src/dxgkrnl-$VERSION/Makefile
sed -i 's#linux/hyperv.h#linux/hyperv_dxgkrnl.h#' /usr/src/dxgkrnl-$VERSION/dxgmodule.c
echo "EXTRA_CFLAGS=-I\$(PWD)/inc" >> /usr/src/dxgkrnl-$VERSION/Makefile
cat > /usr/src/dxgkrnl-$VERSION/dkms.conf <<EOF
PACKAGE_NAME="dxgkrnl"
PACKAGE_VERSION="$VERSION"
BUILT_MODULE_NAME="dxgkrnl"
DEST_MODULE_LOCATION="/kernel/drivers/hv/dxgkrnl/"
AUTOINSTALL="yes"
EOF

dkmsを使ってインストール。

dkms add dxgkrnl/$VERSION
dkms build dxgkrnl/$VERSION
dkms install dxgkrnl/$VERSION

ホストからGPUドライバをコピーする#

自分は面倒なのでwsl2から直接ぶっこ抜いたものをホストを経由してゲストに入れてます。

sudo cp -r /usr/lib/wsl/ .

以下のコマンドでコピーしたりロードしたり…

cp -r wsl /usr/lib
echo "/usr/lib/wsl/lib" > /etc/ld.so.conf.d/ld.wsl.conf
ldconfig

再起動したらグラフィックがD3D12になってます。
このタイミングから、hypervの仮想マシン接続のウィンドウからGUIの操作ができなくなります。
自分は事前にRustdeskを導入してそれで操作しています。
事前にopenssh-serverを入れるとかして何かあったときに操作できるようにすると良いでしょう。

あとがき#

WSL2と同じように入れるもん入れたらoneAPIなりcudaなり使える。

HyperVにGPUを割り当てて優勝したかった
/posts/2024-01-10-hyperv-gpupv/
Author
なね
Published at
2024-01-10
License
CC BY-NC-SA 4.0

Some information may be outdated