Валидационная кампания на 115 прогонов и Docker-образ для сервера
bench/ — список сценариев (порождается gen_scenarios.py, а не правится руками), драйверы под Linux и Windows, предполётная проверка и описание. Девять групп: эталоны первоисточников, цилиндр против литературы, модели стенки и субсеточность, профили крыла, сложная и множественная геометрия, границы домена, старт и время жизни, внутренние инварианты, сверхмелкие сетки до 4096×2048. Стоимость планируется в обновлениях узлов — единственной переносимой между машинами мере; в часы драйвер переводит её по фактическим MLUPS, которые замеряет на месте (--calibrate). Итого 3.76e14 обновлений, ≈90 часов на 4070 Ti. Гифки пишутся на всю длительность прогона в реальном времени, 10 кадр/с. Число кадров этим задано жёстко, поэтому размер регулируется только кадром: замерено 0.103 байта на пиксель после LZW, отсюда бюджет кадры×пиксели с нижней границей по ширине. Итог 4.4 ГБ, самый тяжёлый файл 226 МБ. preflight.py гоняет каждый сценарий на два шага. Окупился сразу: поймал, что вся группа сверхмелких сеток падала на пределе GPU, а девять прогонов группы F передавали --body-x дважды. Оба отказа проявились бы только на сервере, часов через двадцать после старта кампании. Docker: двухстадийная сборка, в образе libvulkan1 и vulkan-tools. NVIDIA Container Toolkit подкладывает Vulkan-ICD только при graphics в NVIDIA_DRIVER_CAPABILITIES — без него wgpu не увидит карту, поэтому capabilities прописаны в образе, а vulkaninfo лежит внутрь для проверки. ENTRYPOINT — драйвер кампании, CMD по умолчанию --dry-run, чтобы случайный docker run не запустил сточасовую задачу. Проверено локально: образ собирается, смоук проходит с монтированием результатов на хост, физика совпадает с хостовой до последней цифры, --backend gpu без карты отказывает явно. GPU-путь в контейнере проверяется только на машине с картой. В README поправлено разделение вкладов в продольную акустику: измерением 2×2 показано, что 74.9% → 1.1% даёт ОДНОРОДНЫЙ СТАРТ, причём при полностью выключенной губке, а губка снимает лишь остаток (1.12% → 0.83% при утроении длины). При старте из покоя губка не помогает совсем — у стоячей четвертьволновой моды там узел давления, где вязкость её не трогает. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,113 @@
|
||||
# Валидационная кампания
|
||||
|
||||
115 прогонов, ≈90 часов на RTX 4070 Ti. Проверяет решатель по трём независимым линиям:
|
||||
эталонам из статей авторов метода, литературе по обтеканию тел и внутренним инвариантам самой
|
||||
схемы. Каждый прогон кладёт логи, ряды, машиночитаемую сводку и гифку в собственную папку.
|
||||
|
||||
## Быстрый старт на сервере
|
||||
|
||||
```sh
|
||||
docker build -t kbc2d docs/theory/2d_solver
|
||||
docker run --rm --gpus all --entrypoint python3 kbc2d preflight.py # сценарии стартуют
|
||||
docker run --rm --gpus all kbc2d --calibrate # GPU виден
|
||||
docker run -d --gpus all -v "$PWD/out:/work/bench/out" --name kbc2d kbc2d --resume
|
||||
docker logs -f kbc2d
|
||||
```
|
||||
|
||||
Первым делом стоит убедиться, что Vulkan внутри контейнера действительно видит карту:
|
||||
|
||||
```sh
|
||||
docker run --rm --gpus all --entrypoint vulkaninfo kbc2d --summary | head -20
|
||||
```
|
||||
|
||||
Если адаптеров ноль — почти наверняка дело в `NVIDIA_DRIVER_CAPABILITIES`: Container Toolkit
|
||||
подкладывает Vulkan-ICD только при наличии `graphics` в списке. В образе это прописано, но
|
||||
может быть переопределено снаружи.
|
||||
|
||||
## Без Docker
|
||||
|
||||
```sh
|
||||
cargo build --release # из docs/theory/2d_solver
|
||||
cd bench
|
||||
python preflight.py # каждый сценарий стартует на два шага
|
||||
./run_campaign.sh --calibrate # замерить MLUPS этой машины
|
||||
KBC2D_GPU_MLUPS=1400 ./run_campaign.sh --dry-run
|
||||
./run_campaign.sh --resume
|
||||
```
|
||||
|
||||
Под Windows то же самое делает `run_campaign.ps1` (тот же `scenarios.json`); он нужен для
|
||||
локальной отладки обвязки, целевая машина — Linux.
|
||||
|
||||
## Ключи драйвера
|
||||
|
||||
| ключ | что делает |
|
||||
|---|---|
|
||||
| `--dry-run` | печатает смету: что, сколько шагов, сколько часов. Ничего не считает |
|
||||
| `--calibrate` | три коротких прогона, замер фактических MLUPS этой машины |
|
||||
| `--smoke` | три самых дешёвых прогона: проверить обвязку, а не физику |
|
||||
| `--resume` | пропускает прогоны, у которых уже есть `summary.json` |
|
||||
| `--group A,B` | только выбранные группы |
|
||||
| `--only cyl_re150` | по подстроке идентификатора |
|
||||
| `--budget-hours 24` | остановиться, когда время выйдет |
|
||||
|
||||
Прогон, который упал или развалился, помечается в сводке и **не останавливает кампанию**:
|
||||
группы E и G специально ищут предел устойчивости, там развал — ожидаемый результат.
|
||||
|
||||
## Что где лежит
|
||||
|
||||
```
|
||||
out/summary.csv сводная таблица: id, группа, статус, секунды, стоимость
|
||||
out/campaign.log журнал с отметками времени
|
||||
out/<id>/cmd.txt точная команда, которой прогон был запущен
|
||||
out/<id>/log.txt полный вывод
|
||||
out/<id>/report.txt только итоговый отчёт
|
||||
out/<id>/series.csv временные ряды по шагам
|
||||
out/<id>/summary.json ключевые метрики машиночитаемо — с этого удобно начинать разбор
|
||||
out/<id>/*.gif анимация
|
||||
out/<id>/*_case.csv энергия, энстрофия, палинстрофия (эталонные течения)
|
||||
out/<id>/xt_*.csv x–t диаграммы (группа G)
|
||||
```
|
||||
|
||||
## Группы
|
||||
|
||||
| | прогонов | что проверяется |
|
||||
|---|---|---|
|
||||
| **A** | 12 | эталоны первоисточников: Тейлор–Грин (второй порядок сходимости; при фиксированном u₀ — полка O(Ma²)), сдвиговый слой Re=3·10⁴, затухающая турбулентность |
|
||||
| **B** | 16 | цилиндр против литературы: стационар Re=20/40, дорожка Re=100…300, разрешение D=16…128, блокировка Ny/D=6…32 с экстраполяцией к бесконечной среде |
|
||||
| **C** | 20 | модели стенки и субсеточность: hrr / grad / bouzidi / staircase при Re=150 и 2000, плюс сдвиг тела внутри клетки на 0 / ¼ / ½ для всех четырёх |
|
||||
| **D** | 14 | профили крыла: поляра NACA 0012, Re-серия, изгиб 4412, сходимость по хорде |
|
||||
| **E** | 12 | сложная и множественная геометрия: тандем, решётка, перфорация, многоэлементный профиль, сверхтонкая пластина, клин, зазубренная кромка |
|
||||
| **F** | 9 | поле влияния и границы домена: отступы до входа и выхода, вложенный патч |
|
||||
| **G** | 14 | старт, акустика, время жизни: x–t диаграммы, губки, предел по Re, прогон на 10⁷ шагов |
|
||||
| **H** | 9 | инварианты: симметрия, зеркальность, зависимость от числа Маха, расхождение f32 против f64 |
|
||||
| **I** | 9 | сверхмелкие сетки 4096×2048 по всем формам и композиции из трёх тел |
|
||||
|
||||
## Стоимость и время
|
||||
|
||||
Стоимость каждого прогона хранится в **обновлениях узлов** (`nodes_per_step × steps`) — это
|
||||
единственная мера, переносимая между машинами. Часы драйвер получает, поделив её на MLUPS.
|
||||
Оценки по умолчанию исходят из 1200 MLUPS на GPU и 22 на CPU; **`--calibrate` обязателен**,
|
||||
потому что эти числа взяты с другой машины.
|
||||
|
||||
Пересобрать список с другой длительностью:
|
||||
|
||||
```sh
|
||||
python gen_scenarios.py --scale 3 # все прогоны в полтора раза длиннее (≈135 ч)
|
||||
```
|
||||
|
||||
## Что известно заранее
|
||||
|
||||
- **Точность f32.** Замерено на Тейлоре–Грине: GPU совпадает с CPU/f64, пока истинная ошибка
|
||||
выше ~10⁻³, и промахивается в 40 раз, когда она ниже. Поэтому исследования сходимости из
|
||||
группы A идут на CPU — это указано в самих сценариях.
|
||||
- **Развалы ожидаемы** в группе G (предел по Re) и у прогона `A09_shear_n512_lbgk`: LBGK при
|
||||
Re=3·10⁴ обязан развалиться там, где KBC доживает — это и есть проверяемое утверждение.
|
||||
- **Гифки** пишутся на всю длительность прогона, в реальном времени, 10 кадр/с. Число кадров
|
||||
этим задано жёстко (у самого длинного прогона их 16 666), поэтому единственный рычаг —
|
||||
размер кадра. Замерено: 0.103 байта на пиксель после LZW; отсюда бюджет
|
||||
кадры×пиксели ≤ 1.5·10⁹ на гифку, но ширина не опускается ниже 480 пикселей. Итог по
|
||||
кампании: **≈4.4 ГБ**, самый тяжёлый файл 226 МБ.
|
||||
- **Перед запуском** имеет смысл прогнать предполётную проверку: каждый сценарий стартует на
|
||||
два шага, что ловит опечатки в ключах и несовместимые сочетания до того, как кампания уйдёт
|
||||
считать на девяносто часов. Именно она поймала, что вся группа I падала на пределе GPU в
|
||||
65535 рабочих групп на измерение.
|
||||
Reference in New Issue
Block a user