# Szilassi — поиск геометрических реализаций многогранников Репозиторий содержит CUDA/CPU-систему поиска геометрических реализаций для 59 комбинаторных топологий соседственных 12-гранных многогранников. Для каждой топологии программа подбирает 12 плоскостей, восстанавливает вершины и минимизирует геометрические дефекты. Проект предназначен для вычислительного исследования и не является доказательством существования или невозможности бездефектной реализации. ## Происхождение Проект основан на исходной кодовой базе CodeParade [HackerPoet/NeighborlyPolyhedra](https://github.com/HackerPoet/NeighborlyPolyhedra). Постановка задачи и исходное исследование представлены в [видео CodeParade](https://youtu.be/5dd8_N_nKRI). Текущая версия существенно расширяет исходную реализацию: добавлены 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` и Blackwell `sm_120`; - Eigen 3.4.0 уже находится в `external/eigen-3.4.0`. Для самого поиска Python не нужен. Для переобучения трансформера дополнительно нужны Python 3.12, NumPy и CUDA-сборка PyTorch. Эти зависимости устанавливаются в локальную `.venv` и не входят в штатный exe. Без CUDA проект собирает диагностический stub. Запуск с `--cuda` в такой сборке завершается с понятной ошибкой и не переключается на CPU незаметно. ## Сборка через CMake Из корня репозитория: ```powershell 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 используется отдельный каталог: ```powershell 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` собирается отдельно: ```powershell 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 в течение восьми часов: ```powershell .\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; - `--repair-local ` — локальная координатная коррекция; - `--hunt-local ` — сфокусированный поиск около известных дефектов; - `--batch-hunt ` — серия независимых локальных запусков; - запуск без режима — интерактивный legacy solver. Проверка модели: ```powershell .\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//topology_N/checkpoints/*.szcp` — immutable поколения checkpoint с CRC; - `runs//topology_N/archive/*.szar` — MAP-Elites delta-файлы; - `runs//run.tsv` и `metrics.tsv` — seed, конфигурация и телеметрия запуска. Новые поколения публикуются атомарно после flush. Повреждённое последнее поколение не уничтожает предыдущее валидное. При штатной остановке сохраняются все изменённые топологии, а ошибка durable-записи приводит к безопасному завершению с ошибкой. `leaderboard.tsv`, временные файлы и логи являются производными и игнорируются Git; leaderboard восстанавливается при следующем запуске. ## Локальный ML-датасет Обучающие данные и производные neural-модели являются локальным кэшем и **не входят в Git**: - `results/search/runs//training` — `.sztd` shards и активный 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`. Первичная настройка локального окружения: ```powershell 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: ```powershell .\scripts\TrainTransformer.bat ``` Скрипт проверяет `torch.cuda.is_available()` и пропускает Python-окружения с CPU-only PyTorch. Если CUDA-Python не находится автоматически, его можно указать без изменения файлов проекта: ```powershell $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_.sztf` не переписываются, а идентификатор загруженного поколения сохраняется в `run.tsv` и algorithm fingerprint обучающих записей. При будущем переобучении на всём накопившемся архиве, включая новые run: ```powershell .\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 Следующая команда удаляет только записи из индекса и сохраняет сами файлы на диске: ```powershell 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" ``` После этого проверьте результат: ```powershell 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: ```powershell ctest --test-dir build/vs2026 -C Release --output-on-failure ``` Для проверки отдельного OBJ используется `verify_cpp.exe`. ## Лицензия Условия использования находятся в [LICENSE](LICENSE).