# gpr_cpp — C++/CUDA счёт-ядро MIMO GPR 3D SAR > Инфраструктура (сборка, NVRTC, PocketFFT, npy) вендорена из репозитория > VNA_AlGo (`gpr_cpp/`, коммит `544dc59`) без python-биндингов > (`GPR_BUILD_PYTHON=OFF`). АЛГОРИТМ с сентября 2026 переписан: это порт > эталонного ноутбука `Multi_antenna_3D_clean_v1.ipynb` (ячейки 0 и 4), а не > старого `gpr_core`/Horns_3D. Паритет с ноутбуком проверяется инструментом > `sar3d_parity` + `python_app/scripts/sar3d_volume_compare.py` по > референсным `*_volume.npz`. Собирается из корневого Makefile radar_system > (цель `$(GPR_CPP_LIB)` вызывает `build_cmake.sh`). ## Что внутри **В C++ (`libgpr_core_cpp`):** сегментированный тайминг кадра по per-trace меткам захвата (`compute_pair_timestamps`), препроцессинг A-сканов (bg-subtract, полная фазовая коррекция движения intra+pair до IFFT, k0-вставка + Ханн + IFFT через PocketFFT, нормировка пар), полнообластная ground-сетка (`build_full_region_grid`), 3D SAR апертурный объём (одно CUDA-ядро на всю апертуру; геометрия в double, A-сканы float32) и финализация (`finish_volume`: |acc/cnt| → маска глубины → нормировка без Y-краёв → гаусс по (Z,X) → нормировка; возвращает объём [0,1] + level). ## Ключевое решение: CUDA без nvcc (NVRTC + Driver API) На целевых машинах (x86+T600, Jetson) нет полного CUDA toolkit — только runtime + **NVRTC** (как у cupy). Поэтому ядро **не компилируется nvcc'ом**: его исходник встроен строкой ([src/kernel_src.hpp](src/kernel_src.hpp)), компилируется в рантайме через NVRTC в **cubin под точную арх устройства** (запрос compute capability → `sm_XY`, без JIT PTX), грузится и запускается через **CUDA Driver API**. Хост-часть собирается обычным g++. Плюс: без toolkit и без привязки к SM — один код для x86 (sm_75) и Jetson (sm_87). ## Сборка ```bash bash build_cmake.sh # авто-детект pip CUDA-путей; собирает всё # артефакты в build/: libgpr_core_cpp.a, _gpr_cpp*.so, standalone_bp ``` Требуется: g++ ≥13, cmake ≥3.24, pybind11 (`pip install pybind11`), pip-пакеты `nvidia-*` (nvrtc+cudart, идут с cupy), системный `libcuda`. rpath на каталог libnvrtc прописан — бинарники/модуль грузятся без `LD_LIBRARY_PATH`. ## Публичный C++ API ([include/gpr/](include/gpr/)) ```cpp #include "gpr/config.hpp" // GeometryConfig/BPConfig/MotionConfig/SARConfig (дефолты = ноутбук) #include "gpr/ascan.hpp" // compute_pair_timestamps, preprocess_snapshot(...) -> AScanSet #include "gpr/sar3d.hpp" // SarEngine::aperture_volume -> VolumeRaw; finish_volume -> FinishedVolume #include "gpr/geometry.hpp" // frame_offsets, frame_weights, build_full_region_grid gpr::SarEngine engine(geom, bp, mot, sar); // компилит ядро под устройство auto raw = engine.aperture_volume(frames, grid); // один запуск ядра на апертуру auto fin = gpr::finish_volume(raw, grid, mot.pitch_deg, bp, sar); // объём [0,1] + level ``` Пример без Python: [examples/standalone_bp.cpp](examples/standalone_bp.cpp) — грузит S21 из `.npy`, строит объём, печатает максимум. ```bash ./build/standalone_bp 0038_id39_ns11361438137486 ``` ## Python-модуль ```python import _gpr_cpp # из gpr_cpp/build eng = _gpr_cpp.SarEngine(_gpr_cpp.GeometryConfig(), _gpr_cpp.BPConfig(), _gpr_cpp.MotionConfig(), _gpr_cpp.SARConfig()) a = _gpr_cpp.preprocess_snapshot(s21, freq, background, mot, geom, bp, True) # -> AScanSet acc, cnt = eng.aperture_volume([(a, dx, dy, dz, w), ...], gx, gy, gz) # numpy ``` ## Паритет с ноутбуком (проверено на x86 T600, датасет 20260922_mine_fast_true) Кадры 0034/0035/0036 против референсных `*_volume.npz` ноутбука (`make sar3d_parity` + `python_app/scripts/sar3d_volume_compare.py`): max|Δ| ≤ 1.6e-6 вне ножевой границы маски глубины, argmax и level совпадают (level rel ≤ 7e-7). Python-эталон той же цепочки: `python_app/scripts/sar3d_reference_check.py`. ## Статус - [x] x86 (T600, sm_75, CUDA 13): собрано, паритет, standalone работает. - [ ] Jetson (Orin NX, sm_87, CUDA 12.6): порт тривиален (NVRTC сам берёт sm_87); собрать `build_cmake.sh` на Jetson с его venv. - Опц.: ветка `impl='cpp'` в `gpr_core/sar3d.py` (адаптер `gpr_cpp_backend.py`), кэш device-A-сканов (сейчас каждый вызов грузит стек на GPU).