24 KiB
Szilassi — поиск геометрических реализаций многогранников
Репозиторий содержит CUDA/CPU-систему поиска геометрических реализаций для 59 комбинаторных топологий соседственных 12-гранных многогранников. Для каждой топологии программа подбирает 12 плоскостей, восстанавливает вершины и минимизирует геометрические дефекты.
Проект предназначен для вычислительного исследования и не является доказательством существования или невозможности бездефектной реализации.
Происхождение
Проект основан на исходной кодовой базе CodeParade HackerPoet/NeighborlyPolyhedra. Постановка задачи и исходное исследование представлены в видео CodeParade. Текущая версия существенно расширяет исходную реализацию: добавлены CUDA FP32-поиск, CPU/DD-верификация, продолжаемые checkpoint, многотопологический планировщик, MAP-Elites/CEM, online-MLP, общий Set Transformer ranker и локальный долговременный ML-датасет.
Критерии результата
В логах и файлах результатов используются два целочисленных счётчика:
C(crossings) — самопересечения границы отдельной грани после проекции на плоскость этой грани;I(intersections) — пересечения внутренности грани с рёбрами, которые не инцидентны этой грани. Пересечение продолжений вне отрезка или вне многоугольника не учитывается.
Кандидаты сравниваются лексикографически по кортежу
(C + I, max(C, I), C, energy). Поэтому уменьшение точного количества дефектов
важнее гладких штрафов и эвристических оценок.
Массовый поиск выполняется на GPU в FP32. Отобранные кандидаты пересчитываются на
CPU в double; состояния около цели дополнительно классифицируются реализацией
double-double (WideReal, примерно 31 десятичный знак). Заявленный результат
C/I = 0/0 проходит повторные проверки с несколькими допусками.
Как устроен поиск
- Постоянные CUDA-цепочки сохраняют RNG, температуру, шаг, стагнацию и состояние между короткими пакетами.
- Портфель стратегий включает базовый simulated annealing, replica exchange, адаптивные ходы, population-based transfer и инъекцию состояний из MAP-Elites, CEM и нейросетевой подсказки.
- Планировщик распределяет работу между топологиями с учётом качества, улучшений, неопределённости и давности последнего запуска. Режим проработки худших вариантов меняет приоритет, но сохраняет исследование остальных топологий.
- MAP-Elites поддерживает разнообразие по обусловленности геометрии и локализации дефектов. Диагональный CEM строит новые стартовые состояния по успешным потомкам.
- Небольшой SPSA+Adam этап выполняется на CPU; его результат округляется обратно в FP32 и проверяется заново.
- Нейросеть является только источником предложений. Она не может заменить точную CPU/DD-проверку или отключить базовую долю независимого поиска.
- Общий для 59 топологий Set Transformer ранжирует только управляемую часть injected-пула. Из 64 seed-кандидатов 48 по-прежнему формируются MAP-Elites, CEM и независимым поиском, 4 управляемых seed остаются контрольными без ранжирования, и только 12 выбираются трансформером. Повреждённая, несовместимая или неутверждённая модель автоматически отключается.
Штраф вырождения намеренно мягкий. По умолчанию полностью учитывается худший из
барьеров определителя, короткого ребра, малого угла поворота и чрезмерного размера;
остальные барьеры дают по 5% вклада. Вес штрафа — 0.01.
Поисковый процесс и CUDA stream запускаются с низким приоритетом. Искусственного ограничения загрузки GPU нет; короткие kernels обеспечивают отзывчивую остановку и устойчивость под Windows WDDM.
Структура репозитория
projects/Szilassi— основной CLI-поиск;projects/PolyhedronGui— Windows GUI для штатного CUDA-поиска;projects/VerifyCpp— отдельная проверка OBJ-кандидатов;projects/TransformerTrainingExport— потоковый read-only экспорт размеченных trajectory из immutable.sztdдля обучения;src/NeighborlyCore— геометрия, точные предикаты и общие типы;src/CudaSearch— FP32 CUDA backend и диагностический CPU stub;src/Checkpoint— CRC-защищённые поколения checkpoint;src/SearchArchive— mergeable MAP-Elites delta-файлы;src/OnlineSurrogate— локальная online residual-MLP модель;src/TrainingArchive— локальный долговременный ML-датасет и crash recovery;src/TransformerRanker— нативный FP32 inference общей transformer-модели;tests/TrainingArchiveSelfTest— тест формата, CRC, WAL, восстановления и лимита;tests/TransformerRankerSelfTest— тест features, формата модели, CRC и fallback;tools/train_transformer.py— CUDA/PyTorch-обучение и публикация модели;data— описание топологий и входные модели;results/topologiesиresults/showcases— сохранённые исследовательские модели;results/search— продолжаемое геометрическое состояние поиска;runtime— временные тестовые прогоны, отчёты и локальные файлы;build— централизованный вывод CMake и MSBuild.
Общего solution-файла в репозитории нет. Основной поддерживаемый способ сборки — CMake; проекты Visual Studio можно собирать по отдельности.
Требования
- Windows x64;
- компилятор с поддержкой C++17;
- Visual Studio 18 / 2026 с workload для C++ desktop development;
- CUDA Toolkit 13.3 с интеграцией в Visual Studio для GPU-поиска;
- NVIDIA GPU с поддерживаемой архитектурой. Сборка содержит цели для Ada
sm_89и Blackwellsm_120; - Eigen 3.4.0 уже находится в
external/eigen-3.4.0.
Для самого поиска Python не нужен. Для переобучения трансформера дополнительно
нужны Python 3.12, NumPy и CUDA-сборка PyTorch. Эти зависимости устанавливаются
в локальную .venv и не входят в штатный exe.
Без CUDA проект собирает диагностический stub. Запуск с --cuda в такой сборке
завершается с понятной ошибкой и не переключается на CPU незаметно.
Сборка через CMake
Из корня репозитория:
cmake --preset vs2026-x64
cmake --build --preset vs2026-release
ctest --test-dir build/vs2026 -C Release --output-on-failure
Основные исполняемые файлы появятся в build/vs2026/Release:
neighborly_main.exe— поиск;polyhedron_gui.exe— GUI;verify_cpp.exe— проверка OBJ;training_archive_selftest.exe— regression/self-test локального ML-архива.transformer_training_export.exe— потоковый экспорт trajectory;transformer_ranker_selftest.exe— regression/self-test transformer runtime.
Для сборки без CUDA используется отдельный каталог:
cmake -S . -B build/cpu -G "Visual Studio 18 2026" -A x64 -DSZILASSI_ENABLE_CUDA=OFF
cmake --build build/cpu --config Release
Сборка отдельных проектов Visual Studio
Если CMake не используется, каждый .vcxproj собирается отдельно:
msbuild projects\Szilassi\Szilassi.vcxproj /m /p:Configuration=Release /p:Platform=x64
msbuild projects\PolyhedronGui\PolyhedronGui.vcxproj /m /p:Configuration=Release /p:Platform=x64
msbuild projects\VerifyCpp\VerifyCpp.vcxproj /m /p:Configuration=Release /p:Platform=x64
msbuild projects\TransformerTrainingExport\TransformerTrainingExport.vcxproj /m /p:Configuration=Release /p:Platform=x64
msbuild tests\TrainingArchiveSelfTest\TrainingArchiveSelfTest.vcxproj /m /p:Configuration=Release /p:Platform=x64
msbuild tests\TransformerRankerSelfTest\TransformerRankerSelfTest.vcxproj /m /p:Configuration=Release /p:Platform=x64
Вывод этих проектов находится в build/msbuild/bin/x64/Release.
Штатный запуск через GUI
Запустите polyhedron_gui.exe из CMake-сборки или PolyhedronGui.exe из
MSBuild-сборки. В интерфейсе остаются две управляющие кнопки:
Запустить поиск— продолжает исследование с учётом найденных checkpoint;Остановить поиск— ждёт окончания короткого CUDA-пакета и сохраняет изменённое состояние перед завершением процесса.
Настройки GUI:
- количество GPU-цепочек (
0— автоматический выбор по GPU и occupancy); - число итераций в одном коротком CUDA-пакете;
- длительность запуска;
- включительный диапазон топологий
0..58; - период durable checkpoint;
- обычный режим или приоритет проработки худших топологий.
GUI автоматически создаёт seed нового процесса. Seed и параметры сохраняются в
run.tsv, поэтому запуск можно воспроизвести без поля Seed в интерфейсе.
Запуск через CLI
Пример CUDA-поиска топологий 20–29 в течение восьми часов:
.\build\vs2026\Release\neighborly_main.exe --global-search --cuda `
--topology-from 20 --topology-to 29 --minutes 480 `
--cuda-chains 0 --cuda-iters 64 --checkpoint-seconds 30 `
--seed 30000157
По умолчанию геометрическое состояние находится в results/search. Другой каталог
задаётся через --global-dir. Повторный запуск с тем же каталогом продолжает поиск.
Дополнительные режимы можно посмотреть через --help:
--study <obj>— продолжение оптимизации существующего OBJ;--repair-local <obj>— локальная координатная коррекция;--hunt-local <obj>— сфокусированный поиск около известных дефектов;--batch-hunt <obj>— серия независимых локальных запусков;- запуск без режима — интерактивный legacy solver.
Проверка модели:
.\build\vs2026\Release\verify_cpp.exe --obj path\candidate.obj `
--topology 42 --eps 1e-13 --report runtime\verify.md
Геометрическое состояние и восстановление
Состояние штатного поиска хранится в results/search:
topology_N/resume.planes,resume.obj,resume.meta— удобное текущее представление лучшего результата;runs/<UUID>/topology_N/checkpoints/*.szcp— immutable поколения checkpoint с CRC;runs/<UUID>/topology_N/archive/*.szar— MAP-Elites delta-файлы;runs/<UUID>/run.tsvиmetrics.tsv— seed, конфигурация и телеметрия запуска.
Новые поколения публикуются атомарно после flush. Повреждённое последнее поколение не уничтожает предыдущее валидное. При штатной остановке сохраняются все изменённые топологии, а ошибка durable-записи приводит к безопасному завершению с ошибкой.
leaderboard.tsv, временные файлы и логи являются производными и игнорируются Git;
leaderboard восстанавливается при следующем запуске.
Локальный ML-датасет
Обучающие данные и производные neural-модели являются локальным кэшем и не входят в Git:
results/search/runs/<UUID>/training—.sztdshards и активный WAL;results/search/topology_N/neural— online-модель.szonnи служебные receipts;results/search/neural/transformer— immutable поколения.sztf, активнаяcurrent.sztfи отчёты обучения;- временные варианты этих файлов и marker достижения лимита.
.gitignore исключает каталоги training, neural, все .sztd/.szonn/.sztf и их
временные варианты. Не используйте git add -f для этих путей.
Schema v3 сохраняет пригодные для последующего обучения факты: каждый успешный и
неуспешный CPU-верифицированный кандидат, FP32 chain-best выборку с точным K/N,
CUDA lineage и полный RNG snapshot, начальные и injected предложения, проверенные
rollout, SPSA double-траектории и старый replay в lossless-виде.
WAL имеет CRC и durable commit boundary. После сбоя питания незавершённый хвост отбрасывается, а подтверждённые записи сохраняются. Завершённые shards immutable.
Общий локальный лимит ML-кэша равен ровно 200000000000 байт (200 GB, не GiB).
В расчёт входят существующие neural-файлы, резерв 59 online-моделей, transformer
generation/current и временные файлы атомарной замены. При достижении лимита:
- новые обучающие записи больше не создаются;
- online-обучение замораживается;
- геометрический поиск, CPU/DD-проверка и checkpoint продолжаются;
- программа выводит предупреждение о необходимости пересмотреть формат/политику хранения перед дальнейшим накоплением.
Лимит рассчитан для одного поискового процесса в одном checkout.
Обучение трансформера
Transformer обучается на GPU, но штатный поиск выполняет его маленький FP32
inference на CPU, не отнимая CUDA-ресурсы у геометрических цепочек. Основные labels
берутся только из InjectedTrajectory: SeedProposal без результата считается
неизвестным, а не неудачным исходом.
Тренер сначала фиксирует список завершённых .sztd, проверяет их CRC штатным C++
reader и создаёт временный бинарный snapshot. Активный WAL и shards, появившиеся
после начала обучения, в этот snapshot не входят и попадут в следующее
переобучение. Поэтому накопление архива можно продолжать; временный snapshot после
успеха или ошибки удаляется, если не указан --keep-snapshot.
Первичная настройка локального окружения:
python -m venv .venv
.\.venv\Scripts\python.exe -m pip install numpy
.\.venv\Scripts\python.exe -m pip install torch==2.13.0 `
--index-url https://download.pytorch.org/whl/cu130
Обучение на текущих четырёх независимых seed-run:
.\scripts\TrainTransformer.bat
Скрипт проверяет torch.cuda.is_available() и пропускает Python-окружения с
CPU-only PyTorch. Если CUDA-Python не находится автоматически, его можно указать
без изменения файлов проекта:
$env:SZILASSI_PYTHON = "C:\path\to\python.exe"
.\scripts\TrainTransformer.bat
Train/validation/test делятся целыми run UUID, а не случайными соседними
записями. Модель публикуется только после проверки AP, Brier и top-decile uplift
на отдельных запусках. Затем deployment-ensemble заново обучается на всех четырёх
run и атомарно публикуется как results/search/neural/transformer/current.sztf.
Предыдущие model_<digest>.sztf не переписываются, а идентификатор загруженного
поколения сохраняется в run.tsv и algorithm fingerprint обучающих записей.
При будущем переобучении на всём накопившемся архиве, включая новые run:
.\scripts\TrainTransformer.bat --deployment-all-runs
После публикации достаточно снова нажать Запустить поиск. Сбор .sztd, online-MLP,
MAP-Elites/CEM, CUDA-поиск и CPU/DD-проверка продолжают работать независимо от
наличия transformer-модели.
Работа на нескольких компьютерах
Для параллельного исследования задавайте непересекающиеся диапазоны топологий.
Каждый запуск создаёт отдельный UUID, поэтому .szcp, .szar, манифесты и метрики
объединяются обычным Git merge без отдельного merge-скрипта.
Через Git переносятся только геометрическое состояние и небольшая телеметрия.
Локальный ML-датасет и neural-модели между компьютерами автоматически не
объединяются. Не добавляйте весь results/search принудительно; проверяйте
git status перед коммитом.
Если локальный ML-кэш уже отслеживается Git
Следующая команда удаляет только записи из индекса и сохраняет сами файлы на диске:
git rm -r --cached --ignore-unmatch -- `
":(glob)results/search/**/training/**" `
":(glob)results/search/**/neural/**" `
":(glob)results/search/**/*.sztd" `
":(glob)results/search/**/*.sztd.*" `
":(glob)results/search/**/*.szonn" `
":(glob)results/search/**/*.szonn.*" `
":(glob)results/search/**/*.sztf" `
":(glob)results/search/**/*.sztf.*" `
":(glob)results/search/**/TRAINING_DATA_LIMIT_REACHED_REWRITE_REQUIRED.tsv"
После этого проверьте результат:
git status --short
git ls-files -ci --exclude-standard -- results/search
Затем изменения .gitignore и удаление из индекса можно закоммитить и отправить
обычным способом. git rm --cached не очищает старые commits. Если большие файлы
уже были опубликованы и должны исчезнуть из истории сервера, требуется отдельное
согласованное переписывание истории (git filter-repo и force-push); после него
остальные клоны необходимо пересоздать или синхронизировать вручную.
Тесты
TrainingArchiveSelfTest проверяет byte-exact round-trip schema v3, CRC, corruption
detection, частичные WAL, recovery после сбоя, immutable publication и точную границу
200 GB.
TransformerRankerSelfTest проверяет byte-exact размер модели, единую нормализацию
features, batch inference, CRC, отклонение повреждённой модели и сохранение
последней валидной модели при неудачной загрузке.
Запуск через CTest:
ctest --test-dir build/vs2026 -C Release --output-on-failure
Для проверки отдельного OBJ используется verify_cpp.exe.
Лицензия
Условия использования находятся в LICENSE.