It's the bottleneck worth attacking
Correspondence search and the normal-equation build dominate per-keyframe cost. Move them to the GPU and the whole frontend keeps pace with the camera.
FlashICP rebuilds the point-cloud ICP frontend — the stage a factor-graph SLAM backend (GTSAM) relies on — in CUDA, one kernel at a time, on the registered cloud from an AUV's stereo camera. Every kernel ships with a CPU baseline and an honest Jetson benchmark; the voxel-grid downsample is in place — a single-pass atomic-hash kernel running 3.0× faster than the CPU on a Jetson AGX Orin.
Large clouds, per-point work, run every keyframe. That is exactly the shape a GPU is built for. FlashICP rebuilds that path in CUDA — partly to learn the core GPU patterns end to end, and partly to produce a result that is genuinely useful and benchmarkable on real data.
Correspondence search and the normal-equation build dominate per-keyframe cost. Move them to the GPU and the whole frontend keeps pace with the camera.
Spatial hashing, parallel reduction, and memory coalescing — implemented
against an actual workload instead of a toy kernel.
Each kernel ships with a CPU baseline and a measured CPU-vs-GPU result on real rosbag data — not a synthetic benchmark, and never a speedup claimed without a baseline behind it. The first sort-based port measured 0.7× — slower than the CPU — and the readout said so; rewriting it as a single-pass atomic hash is what earned the 3.0×.
One ZED-registered cloud goes in; a 6-DoF transform comes out. Each stage is a GPU kernel with its own CPU baseline — voxel-downsample preprocess and GPU correspondence are implemented; build & solve and pose are the roadmap.
Dump a cloud straight from a bag, build CPU-always with CUDA-if-available, then race the two paths.
python3 tools/dump_cloud.py /path/to/bag.db3 --out-dir data --max 2 # -> data/cloud0.bin, data/cloud1.bin # int32 n, then n*(float x, y, z)
cmake -B build -DUSE_CUDA=ON cmake --build build
./build/flashicp bench data/cloud0.bin 0.05 20
The bench CLI times both paths on the same cloud and verifies the GPU result matches the CPU one. The first kernel in place is the voxel-grid downsample.
# loaded 113301 points, leaf=0.050 m, iters=50 CPU voxel downsample: 2.991 ms -> 1358 voxels GPU voxel (sort): 4.683 ms -> 1358 voxels (0.6x vs CPU) check: PASS (matches CPU) GPU voxel (hash): 0.998 ms -> 1358 voxels (3.0x vs CPU) check: PASS (matches CPU)