Кампания на пять равных долей: контейнер сразу считает свою часть

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>
This commit is contained in:
2026-10-01 20:15:40 +03:00
co-authored by Claude Opus 5.5
parent 3e81ed130c
commit 1d495e3e89
12 changed files with 582 additions and 130 deletions
@@ -0,0 +1,77 @@
# Кампания, разделённая на ПЯТЬ равных по времени долей — по одной на машину.
#
# Рассчитан на чужой ПК с видеокартой под Windows (Docker Desktop) или WSL2. Файл
# САМОДОСТАТОЧЕН: тянет готовый образ из реестра, исходники не нужны. На машину переносятся
# два файла — этот и shard.bat — и запускается одна команда:
#
# shard.bat 3 # Windows, двойной клик не годится: нужен номер
# docker compose -f docker-compose.shards.yml up -d shard3 # то же вручную, из любой оболочки
# docker compose -f docker-compose.shards.yml logs -f shard3 # смотреть ход
#
# Контейнер стартует и сразу считает: сам проверяет, видна ли карта, сверяет её с CPU-эталоном
# (parity.py, ~2 мин) и идёт по своей доле. Если что-то не так — останавливается с объяснением.
#
# Что ДОЛЖНО стоять на машине (в контейнер это положить нельзя):
# * драйвер видеокарты под Windows — Vulkan внутри контейнера транслируется в D3D12 (dzn);
# * Docker Desktop с бэкендом WSL2 (по умолчанию так и есть) либо Docker внутри WSL2.
#
# Доли посчитаны так, чтобы на ОДИНАКОВЫХ картах закончиться одновременно (≈24 ч каждая при
# 1200 MLUPS, с поправкой на размер сетки — см. bench/gen_scenarios.py). На разных картах
# закончатся в разное время. Результаты — в ./out рядом с этим файлом; собрать их с пяти
# машин = скопировать все out/ в одну папку (каталоги прогонов не пересекаются, у каждой доли
# своя сводка summary_shardN.csv).
#
# Перезапуск безопасен: --resume пропускает всё, у чего уже есть summary.json.
name: kbc2d
x-kbc2d: &kbc2d
image: notbigghost/kbc2d:1.3.0
# Если образа нет ни локально, ни в реестре — `docker compose -f docker-compose.shards.yml
# build` соберёт его из каталога с этим файлом (нужны исходники).
build:
context: .
args:
VERSION: "1.3.0"
pull_policy: missing
devices:
# сама видеокарта (WDDM); есть в любом WSL2, в том числе внутри Docker Desktop
- /dev/dxg:/dev/dxg
volumes:
- ./out:/work/bench/out
# libd3d12.so и libdxcore.so, которые нужны dzn; каталог наполняет сам WSL
- /usr/lib/wsl:/usr/lib/wsl:ro
# Доля задаётся переменной KBC2D_SHARD у каждого сервиса. Команда указана явно только затем,
# чтобы не унаследовать от образа CMD --dry-run.
command: ["--resume"]
# on-failure, а НЕ unless-stopped: доля завершается штатно с кодом 0, и «перезапускать
# всегда» гоняло бы контейнер по кругу. Падение (OOM, сбой драйвера) будет подхвачено.
restart: on-failure:5
stop_grace_period: 30s
logging:
driver: json-file
options:
max-size: "50m"
max-file: "5"
services:
shard1:
<<: *kbc2d
container_name: kbc2d-shard1
environment: { KBC2D_SHARD: "1" }
shard2:
<<: *kbc2d
container_name: kbc2d-shard2
environment: { KBC2D_SHARD: "2" }
shard3:
<<: *kbc2d
container_name: kbc2d-shard3
environment: { KBC2D_SHARD: "3" }
shard4:
<<: *kbc2d
container_name: kbc2d-shard4
environment: { KBC2D_SHARD: "4" }
shard5:
<<: *kbc2d
container_name: kbc2d-shard5
environment: { KBC2D_SHARD: "5" }