#!/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" "$@"