Skip to content

Multi-unit robot.so build, per-unit object cache, faster receipts, 0.5.1 prep - #29

Merged
plancherb1 merged 20 commits into
mainfrom
claude/multi-tu-build
Oct 11, 2026
Merged

plancherb1 merged 20 commits into
mainfrom
claude/multi-tu-build

Conversation

@plancherb1

Copy link
Copy Markdown
Member

Multi-unit robot.so build, per-unit object cache, cache GC, compile-on-first-use notice

Why. A full-g1 bindings build was one 48-minute, 8 GB nvcc translation unit; iiwa14 took 10 minutes. Everything a user does for the first time paid that.

What changed

  • Build is multi-TU. wrapper_template.cu stays one fenced file (// [[unit: <family>]] … // [[unit: end]], surface-tagged jax/torch blocks); grid_rbd._units splits it into wrapper_core.cu + one unit per algorithm family (abi_specs.FAMILIES / FAMILY_OF). _compile._build_units compiles them -c in a bounded pool (GRID_RBD_BUILD_JOBS, default min(8, cores, MemAvailable/3 GB), heavy families first) and host-links with -Xfatbin -compress-all (size ≈ the old monolith). Shared declarations live in bindings/grid_rbd/wrapper_common.cuh (package data, in both cache keys). One build path; no -rdc.
  • Core address-takes no kernel. Context creation registers attributes through generated per-family grid_rbd_family_<f>_init_attrs, which call new library-safe init_grid_kernel_attr_<algo>_checked / _mjx_checked twins emitted by kernel_attrs.py. This is an additive change to every generated grid.cuh (byte gate: 0 lines removed). The kernel-ceiling table and the torch op registration are per family too; the core's single TORCH_LIBRARY delegates to grid_rbd_torch_def_/impl_<f>.
  • Bindings builds no longer compile the bench-only _single_timing twins or the never-launched overloads (NOT_LAUNCHED_BY_BINDINGS): ~3x on its own.
  • Hand-written torch impls moved from an anonymous namespace to static; the wrapper no longer references the aggregate init_grid_checked.
  • Per-unit object cache (<cache_dir>/objects/<unit>-<key>.o): each unit's object is keyed by exactly its compile inputs; only the core unit carries the torch op-namespace key, so a wrapper edit rebuilds only the touched units and family objects are shared across store entries. Kept forever by default; GRID_RBD_OBJECT_CACHE_DAYS=N opts in to pruning.
  • Cache GC: python -m grid_rbd.gc_cache (dry run; --execute) removes store entries no manifest name binds, dangling bykey pointers, dead staging dirs.
  • Compile-on-first-use notice: a one-line WARNING (visible with no logging setup; GRID_RBD_QUIET=1 silences) says what is being compiled and roughly how long; get_robot(name, urdf_path=...) compiles and registers on a miss.
  • Opt-in GRID_RBD_SPLIT_COMPILE=N on the heavy unit(s) (default integrator_gradient), folded into the content key. Off by default: nvcc --split-compile changes register allocation. A/B on g1 (integrator_gradient unit 362 s → 120 s): every integrator / integrator_gradient / forward_dynamics output bitwise identical, kernel time within 1.3 % (noise). Kept opt-in.
  • Receipt launcher: caps units per compile job at 4 (a humanoid at 8 units peaks ~15 GB; the scheduler's ru_maxrss ledger only sees the largest unit).
  • algorithm_list closure fixes found on the way: forward_dynamics_parameter_gradient needs forward_dynamics; integrator_gradient/integrator_with_gradient need integrator (closure test now also matches _finish/_device helpers).

Measured (RTX 5090 / 24-core host)

build before after
iiwa14 fixed, full 618 s ~100 s
go2 floating, full 755 s ~160 s
g1 floating pin-only, full 53 min / 8.1 GB 6 min 6 s / ~14 GB build RAM (8 units)
wrapper comment edit, iiwa14 re-register full rebuild 22 s (12/14 units cached)

Gates: CPU suite (896), iiwa14 + go2 python_wrappers modules one per process (all green), byte gate for the closure fixes (8/8 identical), and ONE fresh full receipt under the RELEASE policy at 9c9d960 (evidence commit 75307e5: 44 shards, 1541 tests, 0 failures, 0 carried) — the whole run took 2 h 31 min on the dev box (the previous release receipt took ~12 h).

Docs: CHANGELOG, Fast Robot Setup (multi-unit note + re-measured table), python_wrappers cache tree + object cache + GC + first-use notice, bindings README build knobs, CLAUDE.md conventions, guide §7.z43/§7.z44, docs/compile_time_arc_2026-10.md.

Receipt infrastructure (same branch; every future receipt is faster)

  • CUDA test runners register only what they launch (flagship + second-order, integrator, plant, centroidal runners: init_grid_streams + per-algorithm init_grid_kernel_attr_<algo>_checked twins instead of init_grid<T>()'s aggregate, which address-took — compiled — every kernel in the header). Measured uncontended: h1_2 fixed second-order cell 3021 s / 15 GB → 81 s / 2.1 GB; g1 floating integrator SHARED 2253 s → 635 s. Referee test/test_runner_registration.py. Generated headers untouched (header caches hit); runner executables re-key.
  • Compile scheduler measures the process tree (/usr/bin/time's ru_maxrss saw only the largest child → ~4x under-prediction for multi-unit builds); ledger schema 2 with wall time; legacy ledger dropped. Heaviest job per consumer launches first. Two GPU shards side by side in the launcher.
  • Split driver soundness: never carry from a receipt recorded dirty (the merge tool would launder it); --resume re-runs dirty-recorded shards; repo root on sys.path (no-op resume crashed on the stdlib test package).
  • Reproducible sdist/wheel in CI (SOURCE_DATE_EPOCH, deterministic sdist repack).

0.5.1 prep

pyproject.toml 0.5.0 → 0.5.1 (+ README / SECURITY / Sphinx conf), CHANGELOG 0.5.1 section. Release receipt: evidence commit 75307e5 (see above); test/run_validation.py --finalize verified it under test/gpu-proof-policy-release.yaml.

🤖 Generated with Claude Code

… the _finish helpers; closure test net covers _finish/_device
…e, no _single_timing twins) for the bindings' per-family registration
…es the all-kernel aggregate in context create; family tables in abi_specs
…ily units (wrapper_common.cuh, per-family registration/ceiling/torch fragments), parallel unit compile + host link
…gistration per family via grid_rbd_torch_def_/impl_<f>, namespace key core-only; multi-TU docs + CHANGELOG
…e notice (GRID_RBD_QUIET), get_robot(urdf_path=) registers on a miss
…lt integrator_gradient), folded into the content key
…z44 incl. byte-clean receipt lesson, design note)
… shards on resume, repo root on sys.path at import
… first per consumer, two GPU shards side by side
…ked twins); h1_2 second-order cell 3021 s -> 81 s
@plancherb1
plancherb1 merged commit cc46dca into main Oct 11, 2026
7 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant