Запуск в WSL2 через docker compose без NVIDIA-runtime
В WSL2 драйвера Vulkan для Linux у NVIDIA нет: карта отдаётся через /dev/dxg по протоколу WDDM, нативный libGLX_nvidia про него не знает и перечисляет ноль устройств, поэтому Container Toolkit нечего подкладывать внутрь и docker падает с `could not select device driver "nvidia"`. С /dev/dxg умеет говорить dzn (Dozen) — драйвер Mesa, транслирующий Vulkan в D3D12. Он положен в образ, и NVIDIA-runtime для этого пути не нужен вовсе: нужны проброс устройства и монтирование /usr/lib/wsl, где Microsoft держит libd3d12.so. Правка в решателе одна: флаги инстанса wgpu теперь читаются из окружения (InstanceFlags::from_build_config().with_env()). Без этого переменная WGPU_ALLOW_UNDERLYING_NONCOMPLIANT_ADAPTER не действует, а wgpu по умолчанию МОЛЧА прячет адаптеры, не прошедшие тесты соответствия Vulkan, — под это правило попадает dzn, и решатель сообщал, что GPU не найден. Поведение по умолчанию не изменилось: без переменной такие адаптеры по-прежнему скрыты. База образа сменена с debian:bookworm-slim на archlinux:base: в пакетах Mesa у Debian и Ubuntu dzn не собирают (проверено по спискам файлов), в Arch он лежит отдельным пакетом той же версии Mesa, что и на хосте WSL. Новое: * docker-compose.wsl.yml — путь через /dev/dxg, с профилем проверок и с build: на случай, когда доступа к реестру нет; * bench/parity.py — сверка GPU-пути с CPU в f64 на течениях, где расхождение f32 и f64 не нарастает. Соответствие dzn вендором не проверено, значит проверяем сами, а не верим на слово. Замерено на Intel Iris Xe (та же карта, нативный драйвер против dzn): * точность: cd 2.39486 против 2.39486, energy_end 5.74813e-05 против 5.74810e-05 — совпадение до 5-6 значащих цифр; * скорость: плата за трансляцию падает с ростом сетки, 4.2x на 61 тыс. узлов, 1.46x на 461 тыс., 1.30x на 1.84 млн. На 95.1% стоимости кампании сетки крупнее 600 тыс. узлов, поэтому ожидаемое удорожание — около трети, не в разы. В калибровку добавлена сетка 1920x960: оценивать кампанию по 240x120 значит занижать пропускную способность вчетверо. Образ опубликован как notbigghost/kbc2d:1.1.0 (он же latest), проверен вытягиванием из реестра. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -6,7 +6,7 @@
|
||||
|
||||
## Быстрый старт на сервере
|
||||
|
||||
Образ опубликован, собирать ничего не нужно: **`notbigghost/kbc2d:1.0.0`**. Исходники на
|
||||
Образ опубликован, собирать ничего не нужно: **`notbigghost/kbc2d:1.1.0`**. Исходники на
|
||||
сервере тоже не нужны — переносится один файл `docker-compose.server.yml`.
|
||||
|
||||
```sh
|
||||
@@ -40,6 +40,77 @@ KBC2D_GPU_MLUPS=1450 KBC2D_CPU_MLUPS=40 docker compose -f $C --profile check run
|
||||
docker run --rm --gpus all nvidia/cuda:12.4.0-base-ubuntu22.04 nvidia-smi
|
||||
```
|
||||
|
||||
## Запуск в WSL2
|
||||
|
||||
Отдельный путь, потому что в WSL2 **драйвера Vulkan для Linux у NVIDIA не существует**.
|
||||
Карта отдаётся через `/dev/dxg` по протоколу WDDM; нативный `libGLX_nvidia` про него не
|
||||
знает и возвращает ноль устройств — загрузчик его выбрасывает. Отсюда и `could not select
|
||||
device driver "nvidia"`: NVIDIA Container Toolkit тут не поможет, потому что подкладывать
|
||||
внутрь нечего.
|
||||
|
||||
Зато с `/dev/dxg` умеет говорить **dzn** (Dozen) — драйвер Mesa, транслирующий Vulkan в
|
||||
D3D12. Он лежит в образе. NVIDIA-runtime при этом **не нужен вовсе**: достаточно проброса
|
||||
устройства и монтирования `/usr/lib/wsl`, где Microsoft держит `libd3d12.so`.
|
||||
|
||||
```sh
|
||||
C=docker-compose.wsl.yml
|
||||
docker compose -f $C --profile check run --rm vulkan # 1. карта видна?
|
||||
docker compose -f $C --profile check run --rm parity # 2. считает ли она правильно?
|
||||
docker compose -f $C --profile check run --rm calibrate # 3. и с какой скоростью?
|
||||
docker compose -f $C --profile check run --rm preflight # 4. все сценарии стартуют?
|
||||
docker compose -f $C --profile check run --rm plan # 5. смета в часах
|
||||
docker compose -f $C up -d # 6. кампания
|
||||
```
|
||||
|
||||
Если образа нет ни локально, ни в реестре — `docker compose -f $C build`, доступ к Docker
|
||||
Hub не обязателен.
|
||||
|
||||
### Шаг parity обязателен
|
||||
|
||||
dzn сообщает о себе `conformanceVersion = 0.0.0.0`: набор тестов соответствия Vulkan он не
|
||||
проходил. wgpu по этой причине по умолчанию **прячет** такие адаптеры, и решатель сообщает,
|
||||
что GPU не найден. Согласие считать на непроверенном драйвере даётся явно — переменной
|
||||
`WGPU_ALLOW_UNDERLYING_NONCOMPLIANT_ADAPTER=1`, она прописана в `docker-compose.wsl.yml`.
|
||||
|
||||
Раз соответствие не проверено вендором, его проверяем сами. `bench/parity.py` гоняет два
|
||||
коротких эталона на CPU в f64 и на GPU и сверяет числа: вихрь Тейлора–Грина (есть точное
|
||||
решение) и стационарное обтекание цилиндра при Re=20. Течения выбраны намеренно не
|
||||
хаотические — там расхождение f32 и f64 не нарастает, поэтому заметное различие означает
|
||||
проблему драйвера, а не разрядности.
|
||||
|
||||
Замерено на Intel Iris Xe: **dzn совпадает с нативным драйвером той же карты до 5–6
|
||||
значащих цифр** (`energy_end` 3.02277e-07 против 3.02283e-07, `cd` 2.39486 против 2.39486).
|
||||
Точность трансляция не портит. Но это замер на Intel; на своей карте прогоните сами — две
|
||||
минуты.
|
||||
|
||||
### Чего трансляция стоит по скорости
|
||||
|
||||
Плата есть, но она почти вся — накладные расходы на вызов, а не на счёт, и потому падает
|
||||
с ростом сетки. Замерено на Intel Iris Xe, один и тот же решатель:
|
||||
|
||||
| сетка | узлов | нативный Vulkan | dzn в контейнере | плата |
|
||||
|---|---|---|---|---|
|
||||
| 320×192 | 61 тыс. | 188.8 MLUPS | 44.5 MLUPS | **4.2×** |
|
||||
| 960×480 | 461 тыс. | 125.3 MLUPS | 86.0 MLUPS | **1.46×** |
|
||||
| 1920×960 | 1.84 млн | 128.7 MLUPS | 98.7 MLUPS | **1.30×** |
|
||||
|
||||
Каждый шаг решателя — несколько отправок в очередь; на мелкой сетке трансляция вызова
|
||||
стоит дороже самого счёта, на крупной размазывается. Для кампании это решающее
|
||||
обстоятельство, потому что дорогие прогоны в ней как раз крупные:
|
||||
|
||||
| узлов в сетке | прогонов | доля стоимости кампании |
|
||||
|---|---|---|
|
||||
| < 150 тыс. | 18 | 0.0% |
|
||||
| 150–600 тыс. | 47 | 4.9% |
|
||||
| > 600 тыс. | 50 | **95.1%** |
|
||||
|
||||
То есть 95% времени кампания проводит там, где плата 1.3–1.5×, и почти не бывает там, где
|
||||
она четырёхкратна. Ожидаемое удорожание по всей кампании — около трети: 90 часов
|
||||
превращаются примерно в 115–120, а не в 400.
|
||||
|
||||
Проверьте на своей карте: профиль `calibrate` меряет три сетки, и ориентироваться надо на
|
||||
**1920×960** — она представительна для кампании, а 240×120 показывает худший случай.
|
||||
|
||||
## Своя сборка образа
|
||||
|
||||
Если нужен образ из текущего состояния репозитория, а не опубликованный:
|
||||
|
||||
Reference in New Issue
Block a user