gen_scenarios.py раскладывает 115 прогонов по пяти долям (LPT, поправка на размер сетки по замерам dzn) — по ≈24 ч каждая; поле shard в scenarios.json. run_campaign.sh/.ps1 получили --shard. Новая точка входа образа entrypoint.sh: при KBC2D_SHARD сама выбирает путь к карте (dzn или NVIDIA), проверяет vulkaninfo и parity.py и запускает долю. Для чужих ПК под Windows/WSL2 — docker-compose.shards.yml и shard.bat. Образ notbigghost/kbc2d:1.3.0. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
67 lines
4.6 KiB
Bash
67 lines
4.6 KiB
Bash
#!/usr/bin/env bash
|
||
# Точка входа образа.
|
||
#
|
||
# Без KBC2D_SHARD — ровно прежнее поведение: аргументы уходят в run_campaign.sh, а по
|
||
# умолчанию (CMD --dry-run) печатается смета. Профили check в compose-файлах работают как раньше.
|
||
#
|
||
# С KBC2D_SHARD=K контейнер — одна из долей кампании, и считать он начинает сам, без ручной
|
||
# цепочки vulkan → parity → plan. Перед стартом три шага, каждый обрывает запуск с понятным
|
||
# сообщением, а не даёт кампании уйти считать впустую:
|
||
# 1. путь к карте: /dev/dxg есть — значит WSL2 или Docker Desktop, и работает dzn;
|
||
# нет — настоящий Linux, Vulkan-ICD подкладывает NVIDIA Container Toolkit;
|
||
# 2. vulkaninfo должен увидеть хотя бы один НЕпрограммный адаптер;
|
||
# 3. parity.py — сверка GPU с CPU-f64 на двух эталонах (~2 мин). Один раз на каталог out:
|
||
# после успеха кладётся маркер, и перезапуск контейнера её не повторяет.
|
||
|
||
set -u
|
||
cd "$(dirname "$0")"
|
||
|
||
[ -n "${KBC2D_SHARD:-}" ] || exec ./run_campaign.sh "$@"
|
||
|
||
K="$KBC2D_SHARD"
|
||
OUT="${KBC2D_OUT:-out}"
|
||
mkdir -p "$OUT"
|
||
say() { echo "[доля $K] $*"; }
|
||
die() { echo; echo "[доля $K] ОСТАНОВЛЕНО: $*" >&2; exit 3; }
|
||
|
||
# ── 1. путь к карте ──────────────────────────────────────────────────────────
|
||
if [ -e /dev/dxg ]; then
|
||
say "найден /dev/dxg — WSL2 / Docker Desktop, Vulkan через dzn (Vulkan → D3D12)"
|
||
[ -d /usr/lib/wsl/lib ] || die "нет /usr/lib/wsl/lib: смонтируйте /usr/lib/wsl:/usr/lib/wsl:ro
|
||
(в docker-compose.shards.yml это уже прописано)"
|
||
export LD_LIBRARY_PATH="${LD_LIBRARY_PATH:-/usr/lib/wsl/lib}"
|
||
# dzn сообщает conformanceVersion 0.0.0.0, и без согласия wgpu его прячет. Согласие
|
||
# оправдано только потому, что шаг 3 ниже проверяет числа.
|
||
export WGPU_ALLOW_UNDERLYING_NONCOMPLIANT_ADAPTER="${WGPU_ALLOW_UNDERLYING_NONCOMPLIANT_ADAPTER:-1}"
|
||
else
|
||
say "/dev/dxg нет — нативный Linux, Vulkan-драйвер NVIDIA от Container Toolkit"
|
||
fi
|
||
|
||
# ── 2. видна ли карта ────────────────────────────────────────────────────────
|
||
info=$(vulkaninfo --summary 2>&1)
|
||
gpus=$(printf '%s\n' "$info" | grep -E 'deviceType *=' | grep -vc 'PHYSICAL_DEVICE_TYPE_CPU')
|
||
if [ "$gpus" -lt 1 ]; then
|
||
printf '%s\n' "$info" | tail -20 >&2
|
||
die "Vulkan не видит ни одной видеокарты. Что проверить на хосте:
|
||
* Windows / WSL2: драйвер видеокарты под Windows установлен и свежий; Docker Desktop
|
||
работает на бэкенде WSL2; контейнеру проброшены /dev/dxg и /usr/lib/wsl.
|
||
* Linux: установлен nvidia-container-toolkit, контейнер запущен с GPU, и в
|
||
NVIDIA_DRIVER_CAPABILITIES есть graphics (сейчас: ${NVIDIA_DRIVER_CAPABILITIES:-не задано})."
|
||
fi
|
||
printf '%s\n' "$info" | grep -E 'deviceName *=|driverName *=|deviceType *=' | sed 's/^ */ /'
|
||
|
||
# ── 3. считает ли карта правильно ────────────────────────────────────────────
|
||
mark="$OUT/parity_shard$K.ok"
|
||
if [ -f "$mark" ]; then
|
||
say "сверка GPU с CPU уже пройдена ранее ($mark)"
|
||
else
|
||
say "сверка GPU с CPU-эталоном (parity.py, около двух минут)…"
|
||
python3 parity.py || die "GPU расходится с CPU-эталоном — результаты этой машины нечем
|
||
защищать. Вывод сверки выше. Повторить: удалить контейнер и поднять заново."
|
||
date -Is > "$mark"
|
||
fi
|
||
|
||
# ── кампания ─────────────────────────────────────────────────────────────────
|
||
say "старт: run_campaign.sh --resume --shard $K"
|
||
exec ./run_campaign.sh --resume --shard "$K" "$@"
|