# Кампания, разделённая на ПЯТЬ равных по времени долей — по одной на машину. # # Рассчитан на чужой ПК с видеокартой под 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" }