Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions .github/workflows/publish-weights-cvc.yml
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
name: publish-weights-cvc

# Publish the grl-snam-weights data package (base GRL-SNAM nav coefficients — the
# research tier, NO RF-comm forces) to the PUBLIC `cvc` org on cvcpkg.org, using
# geometry-only research tier) to the PUBLIC `cvc` org on cvcpkg.org, using
# this repo's CVCPKG_TOKEN (the cvc-org publisher) — the same token that ships the
# grl-snam-cpXXX columns. Kept separate from publish-cvcpkg.yml (the interpreter
# matrix) because the weights are a single noarch data package with no py column.
#
# Org packages belong in their own repo's recipes, never in libcvc-deps: this
# recipe lives here, in cvcpkg/recipes/grl-snam-weights. The DBG comm-aware weights
# are the SEPARATE private cvc-dbg-weights on the utdbg org — the research/
# development seam is the org boundary; this workflow only ever targets --org cvc.
# recipe lives here, in cvcpkg/recipes/grl-snam-weights. Weights that a downstream
# application trains with its own extra force terms are published by that project
# to its own org; this workflow only ever targets --org cvc.
#
# workflow_dispatch: dry_run=true (default) packs only; dry_run=false publishes.
on:
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,7 @@ GRL-SNAM (not the other way round) and keep their dataset-specific code and mode
of this general library. Such an extension reuses exactly the pieces shown above — the
differentiable surrogate, the coefficient network, and the `pycvc`/`pycvc_gl` scene
bindings — and versions its own additions in its own repository. This library stays
general; the extensions stay separate and private.
general; the extensions stay separate.

## Repository Structure

Expand Down
7 changes: 5 additions & 2 deletions cvcpkg/recipes/grl-snam-weights/payload/PROVENANCE.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# grl-snam-weights — base GRL-SNAM nav coefficient provenance

Base GRL-SNAM navigation coefficients (no RF-comm forces) for the differentiable
Base GRL-SNAM navigation coefficients (geometry only) for the differentiable
SDF navigator's `CoefMLP` — predicts `(alpha, beta, gamma)`.

- `coef_sdf.cvcnav` — native `CVNV` blob for the C++ `cvc::nav` forward.
Expand All @@ -9,7 +9,7 @@ SDF navigator's `CoefMLP` — predicts `(alpha, beta, gamma)`.
## How it was trained (v1.0.0)

- **Pipeline:** `grl-snam train <nav_sdf.npz>` (self-supervised SDF-coefficient
training — geometry only, NO comm-force term) → `grl_snam.tools.coef_export`
training — geometry only, NO external-force term) → `grl_snam.tools.coef_export`
(checkpoint → `CVNV`).
- **Data:** the `austin_south` navigation SDF (`nav_sdf.npz`, 1024×1024 φ field
over the public Austin geometry).
Expand All @@ -18,5 +18,8 @@ SDF navigator's `CoefMLP` — predicts `(alpha, beta, gamma)`.
- **Character:** an initial, deliberately short proof-of-pipeline run — enough
that the coefficients have moved and the weights are usable, NOT a full
training campaign. Regenerate from a longer run for production accuracy.
- **Metadata:** the checkpoint's `meta` and the `.cvcnav` provenance trailer
name the training SDF as `austin_south/nav_sdf.npz` (scene-relative). Since
revision 2; the weights are the same as in revision 1.

Bump `cvc_revision` in `recipe.yaml` whenever these bytes change.
Binary file modified cvcpkg/recipes/grl-snam-weights/payload/coef_sdf.cvcnav
Binary file not shown.
Binary file modified cvcpkg/recipes/grl-snam-weights/payload/coef_sdf.pt
Binary file not shown.
4 changes: 2 additions & 2 deletions cvcpkg/recipes/grl-snam-weights/recipe.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,15 @@ recipe:
# BUMP cvc_revision on ANY change to the staged bytes (a new checkpoint/blob, or
# an edited PROVENANCE.md that ships under share/) — a same-revision re-push
# silently no-ops against the already-published artifact.
cvc_revision: 1
cvc_revision: 2
kind: data
maintainer: "cvcpkg group"
maintainer_email: "info@cvcpkg.org"
homepage: https://github.com/CVC-Lab/GRL-SNAM
license: MIT
tags: [data, grl-snam, weights, nav]
description: >-
Pretrained base GRL-SNAM navigation coefficients (no RF-comm forces): the
Pretrained base GRL-SNAM navigation coefficients (geometry only): the
self-supervised SDF CoefMLP that predicts (alpha, beta, gamma) for the
differentiable SDF navigator. Ships BOTH the native CVNV blob
(coef_sdf.cvcnav, for the C++ cvc::nav forward) and the torch checkpoint
Expand Down
12 changes: 6 additions & 6 deletions docs/CVCNAV_CPP_PORT_ROADMAP.md
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ Boundary is drawn **exactly at the bilinear sample**. Everything upstream stays

Namespace `cvc::nav`, raw-pointer SoA cores, `int num_threads` on every batch, all new TUs compiled under the existing discipline (**no `-ffast-math`, no `-ffp-contract=fast`**, float32 interior to track torch f32). **Name collision to avoid:** `cvc::nav::sdf_field` already exists in `grid_nav.h` (the *built* field). The sampler stack is named **`field_stack`**.

Files (all under `/home/joe/src/cvc/wt-libcvc-nav/`):
Files (all under the libcvc repository root):

```
inc/cvc/nav/detail/parallel.h NEW (extract parallel_for from grid_nav.cpp)
Expand Down Expand Up @@ -270,14 +270,14 @@ arch descriptor (hashed): pack("<IIII", in, out, L, flags) ++ per-layer pack("<I

- **`arch_hash` is the "hidden-size change bumps the version" token.** Any change to in/out/layers/flags/per-layer shape-or-act flips it; the loader self-checks it and grl-snam pins it (`assert torch_arch_hash == native.arch_hash`), so `hidden=128` weights can never be paired with a 64-wide net silently. `format_version` is reserved for byte-layout/semantic changes (loader refuses newer).
- **Loader** (`coef_mlp::build_from_bytes`): validate magic → CRC → format ≤ supported → flags known → endpoints match in/out → layers chain → recompute and match arch_hash → read weights → fold `out_bias_off_ = log(expm1(raw))` in f32 → assert `r.off == body_end`. Throws (never a partial model). Add a static LE-only guard.
- **Exporter** `/home/joe/src/cvc/wt-grl-snam-nav/grl_snam/coef_export.py`: `serialize_coef_mlp(model)->bytes` walks the **live** `nn.Module` (activations discovered from `model.net`, `bias` buffer present), plus `serialize_checkpoint(pt_path)` that rebuilds a `CoefMLP` from a saved state_dict. `write_coef_mlp(model, path)`; CLI `python -m grl_snam.coef_export coef_sdf.pt coef_mlp.cvcnav`. Wire `write_coef_mlp` into `grl_snam/tools/train.py` and `grl_snam/tools/pipeline.py` so every checkpoint ships its deployable twin.
- **Exporter** `grl_snam/coef_export.py` (this repo): `serialize_coef_mlp(model)->bytes` walks the **live** `nn.Module` (activations discovered from `model.net`, `bias` buffer present), plus `serialize_checkpoint(pt_path)` that rebuilds a `CoefMLP` from a saved state_dict. `write_coef_mlp(model, path)`; CLI `python -m grl_snam.coef_export coef_sdf.pt coef_mlp.cvcnav`. Wire `write_coef_mlp` into `grl_snam/tools/train.py` and `grl_snam/tools/pipeline.py` so every checkpoint ships its deployable twin.
- **In-memory path is the parity substrate:** the same `bytes` feed torch (its source) and `pycvc.NavCoefMLP(blob)` — no file round-trip in the tolerance test.

---

## 5. Python-green seam + migration order

**pycvc surface** (append to `/home/joe/src/cvc/wt-libcvc-nav/bindings/pycvc/pycvc_nav.i`, following the existing writable-borrow discipline — validate exact dtype/shape/contig, never coerce-copy an in-place buffer, `Py_BEGIN_ALLOW_THREADS` across compute):
**pycvc surface** (append to libcvc's `bindings/pycvc/pycvc_nav.i`, following the existing writable-borrow discipline — validate exact dtype/shape/contig, never coerce-copy an in-place buffer, `Py_BEGIN_ALLOW_THREADS` across compute):

- Fine-grained (parity + optional acceleration): `nav_sdf_sample(field[M,3,H,W]f32, o[N,2]f32, plane[N]i32|None, mnx..S) -> (phi[N], nrm[N,2])`; `NavCoefMLP(bytes)` / `nav_coef_mlp_load(path)` with `.forward(feat[N,5])->(N,3)`; `nav_drive_step(field, plane|None, <SoA borrowed in place>, mlp, veh scalars, integ, reach_tol, mnx..S, num_threads) -> None`.
- Object surface (pure-C++ twin + full delegation): opaque `nav_sim_world_create(...)`, `_step`, `_snapshot(->dict of fresh numpy)`, `_retarget`, `_add_obstacle`, `_free`.
Expand Down Expand Up @@ -355,15 +355,15 @@ def drive_enabled():
- **FSM source of truth:** port `swarm.py._plan_carrot` (ring-buffer form), **not** `nav.py._plan_carrot` (list-pop form). They compute `moved` against different history references; `swarm.py` is the vectorized reference the tests pin, and its integer state is exact.
- **`allow_reverse`:** `bicycle_rollout`'s own default is `False`, but the deployment path (`SdfNavigator.VEHICLE_DEFAULTS`, inherited by `Swarm.veh`) is `True`. C++ `veh_params` default must be `true` (§2.3), and the golden must exercise the reverse branch.
- **Weight bias:** keep it **raw** in the file (D2), not pre-folded (D5) — `log(expm1)` is a load-time constant folded once in f32, and a raw mirror of the state_dict is auditable. D1's fixed-4742-float blob is rejected in favor of D2's generic+arch_hash layout.
- **CMake gtest wiring:** each new `*_test` needs **all five** `nav_test` entries in `/home/joe/src/cvc/wt-libcvc-nav/src/cvc/tests/CMakeLists.txt` — `add_executable` (L100), the `TEST_TARGETS`/list membership (L168), `target_link_libraries` (L320), `target_compile_features(... cxx_std_17)` (L850), `gtest_discover_tests` (L1014) — or the target is silently omitted (the "four-entry" trap in MEMORY).
- **CMake gtest wiring:** each new `*_test` needs **all five** `nav_test` entries in libcvc's `src/cvc/tests/CMakeLists.txt` — `add_executable` (L100), the `TEST_TARGETS`/list membership (L168), `target_link_libraries` (L320), `target_compile_features(... cxx_std_17)` (L850), `gtest_discover_tests` (L1014) — or the target is silently omitted (the "four-entry" trap in MEMORY).

**Open questions needing a decision (do not block P0–P5):**
- **Deployment belief mode:** does a C++ renderer/game-engine host need clustered/private belief, or is **shared (M=1)** the whole deployment path? Shared is the thousands-of-agents target; if only shared, `map_id` is all-zeros and the M>1 COW/rebuild cost is untested-in-anger. Confirm before P6 sizing.
- **`nsub` at deploy** (`meta.get("nsub",1)`): if always 1, the golden and gtests can pin `nsub=1`; if >1, the multi-substep transcendental accumulation must be in the golden.
- **Whole-drive tolerance/horizon sign-off:** the proposed short-horizon `1e-3` normalized, `<0.5%` flip budget are from the existing `Squad(batched_drive)` 5e-3 tier and need empirical confirmation across all six stories and multiple seeds in P3/P6 — this is the single number that gates P6, and it is the top fidelity risk.
- **Canonical `.cvcnav` home + provenance policy:** where the blessed weights live (libcvc test-data vs pycvc-published vs per-deployment bundle) (kept out of public repos where required); and whether the provenance trailer is required for an audit trail.
- **Canonical `.cvcnav` home + provenance policy:** where the blessed weights live (libcvc test-data vs pycvc-published vs per-deployment bundle); and whether the provenance trailer is required for an audit trail.

Files to create are listed in §2; the two files to edit are `/home/joe/src/cvc/wt-libcvc-nav/src/cvc/CMakeLists.txt` (add headers ~L88, sources ~L171 next to `nav/grid_nav.cpp`) and `/home/joe/src/cvc/wt-libcvc-nav/bindings/pycvc/pycvc_nav.i` (append the marshalling), plus the new grl-snam `coef_export.py`, `nav_native.py` additions, and the parity tests under `/home/joe/src/cvc/wt-grl-snam-nav/tests/`.
Files to create are listed in §2; the two files to edit are libcvc's `src/cvc/CMakeLists.txt` (add headers ~L88, sources ~L171 next to `nav/grid_nav.cpp`) and `bindings/pycvc/pycvc_nav.i` (append the marshalling), plus the new grl-snam `coef_export.py`, `nav_native.py` additions, and the parity tests under this repo's `tests/`.
---

## 10. Decisions on the §9 open questions
Expand Down
6 changes: 3 additions & 3 deletions docs/CVCNAV_CUDA_ASSESSMENT.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,12 @@ I have verified every load-bearing claim against the actual code. Synthesis foll

## Verified ground truth (I read the code, not just the analyses)

- **CMake CUDA wiring** (`wt-libcvc-nav/CMakeLists.txt`): `CVC_ENABLE_CUDA` default ON, auto-disables without nvcc (L5, L25, L80-81); arch list `50 60 70 75 80` set **before** `enable_language(CUDA)` (L45, L75, L78 — the documented sm_52 fix); `+90` when nvcc≥11.8, `+100 120` when ≥12.8 (L63-67) — **local nvcc 12.0 compiles 50/60/70/75/80/90**; `CUDA_RESOLVE_DEVICE_SYMBOLS ON` so device-link emits SASS and **PTX is stripped — the arch list is the entire compat surface** (L54-57, SetupCUDA.cmake L29). `CVC_USING_CUDA` is a PUBLIC define (`src/cvc/CMakeLists.txt` L815); `voxels_kernels.cu` is appended to `SOURCE_FILES` only under `if(CVC_ENABLE_CUDA)` (L611-612) — the exact slot a nav `.cu` drops into.
- **CMake CUDA wiring** (libcvc `CMakeLists.txt`): `CVC_ENABLE_CUDA` default ON, auto-disables without nvcc (L5, L25, L80-81); arch list `50 60 70 75 80` set **before** `enable_language(CUDA)` (L45, L75, L78 — the documented sm_52 fix); `+90` when nvcc≥11.8, `+100 120` when ≥12.8 (L63-67) — **local nvcc 12.0 compiles 50/60/70/75/80/90**; `CUDA_RESOLVE_DEVICE_SYMBOLS ON` so device-link emits SASS and **PTX is stripped — the arch list is the entire compat surface** (L54-57, SetupCUDA.cmake L29). `CVC_USING_CUDA` is a PUBLIC define (`src/cvc/CMakeLists.txt` L815); `voxels_kernels.cu` is appended to `SOURCE_FILES` only under `if(CVC_ENABLE_CUDA)` (L611-612) — the exact slot a nav `.cu` drops into.
- **The `--use_fast_math` bug is REAL** (`CMake/SetupCUDA.cmake` L88-96): it is attached **target-wide** to `cvc` for `$<CONFIG:Release>` × `$<COMPILE_LANGUAGE:CUDA>`, not per-source. Any future nav parity `.cu` compiled into `cvc` in Release inherits `ftz=1`, `prec-div=0`, `prec-sqrt=0`, and fast-intrinsic transcendentals — **silently breaking the float-equivalence contract**. This is a hard prerequisite to fix, confirmed by inspection (A3/A4 flagged it; it checks out).
- **`sense_batch` structure** (`src/cvc/nav/grid_nav.cpp`): `parallel_for(planes.K, …)` (L593) — threads **across planes**, so shared M=1 ⇒ K=1 ⇒ one worker. The per-cell fold is accumulate-then-clamp reading the clamped prior value (L561-569, "Model C: running delta is f32"), i.e. **order-dependent**; the ray-march reads only `truth` (L497-551), i.e. **order-free**. The split the analyses propose is valid against the actual code.
- **PERFORMANCE.md**: batched EDT 0.440 ms/agent vs 9.285 ms single-core = GPU ≈ 21 CPU cores (not a win vs 32); A* GPU 18.4 ms vs CPU 2.84 ms = **6.5× worse**; D2H 0.301 + compute 0.440 = 0.741 ms **loses to 16-core CPU 0.580 ms** ("a GPU EDT with a host consumer never wins at any agent count"); the "~60 agents" crossover is EDT-only/device-resident/private-ish, **not** the shared deployment crossover.
- **Recipe** (`cvcpkg/recipes/libcvc-cuda/recipe.yaml`): `provides:[libcvc]`, `requires_capabilities:[cuda]`, `CVC_ENABLE_CUDA=ON`, linux+windows only (no macOS — no CUDA on Apple), self-hosted CUDA runner, `cvc_revision: 2`. Peers exist: `cvcgl-cuda`, `pycvc-cp311-cuda`, `pycvc-gl-cp311-cuda`. **No new recipe needed.**
- **Roadmap fidelity boundary** (`wt-grl-snam-nav/docs/CVCNAV_CPP_PORT_ROADMAP.md`): drawn **exactly at the bilinear sample** — belief→to_occupancy→EDT→field is **BIT**; sample→MLP→rollout is **FLOAT-EQUIV**. Rule 1: only BIT tiers may be a transparent Python default; torch stays the reference/golden forever. §10.1 ships all three belief modes (shared M=1 / clustered / private M=N); §10.2 deploy `nsub=1`, goldens pinned nsub=1. Flags: `GRL_SNAM_NAV_DRIVE` (drive, default `torch`) separate from `GRL_SNAM_NAV_BACKEND` (bit-kernels, default `native`).
- **Roadmap fidelity boundary** (`docs/CVCNAV_CPP_PORT_ROADMAP.md`): drawn **exactly at the bilinear sample** — belief→to_occupancy→EDT→field is **BIT**; sample→MLP→rollout is **FLOAT-EQUIV**. Rule 1: only BIT tiers may be a transparent Python default; torch stays the reference/golden forever. §10.1 ships all three belief modes (shared M=1 / clustered / private M=N); §10.2 deploy `nsub=1`, goldens pinned nsub=1. Flags: `GRL_SNAM_NAV_DRIVE` (drive, default `torch`) separate from `GRL_SNAM_NAV_BACKEND` (bit-kernels, default `native`).

## (1) Per-component GPU-fit table

Expand Down Expand Up @@ -81,4 +81,4 @@ Speedups are device-resident on sm_80-class; "vs current" = vs today's single-th

**The single decision variable:** after Step 1, does any *named* deployment's real N-at-frame-rate on *its own* hardware exceed the agent-parallel CPU ceiling? The GPU crushes today's *broken* single-threaded sense but only ties-to-modestly-beats a *fixed* CPU sense at N~1k; it pulls decisively ahead only as N outgrows core-count saturation. Measure that number before writing a single `.cu`.

Relevant files: `/home/joe/src/cvc/wt-libcvc-nav/CMake/SetupCUDA.cmake` (L88-96, the fast-math fix), `/home/joe/src/cvc/wt-libcvc-nav/CMakeLists.txt` (L42-78, arch list), `/home/joe/src/cvc/wt-libcvc-nav/src/cvc/CMakeLists.txt` (L611-612, L815, wiring slot), `/home/joe/src/cvc/wt-libcvc-nav/src/cvc/nav/grid_nav.cpp` (L497-601, sense split target), `/home/joe/src/cvc/wt-libcvc-nav/cvcpkg/recipes/libcvc-cuda/recipe.yaml`, `/home/joe/src/cvc/wt-grl-snam-nav/docs/CVCNAV_CPP_PORT_ROADMAP.md` (§1 fidelity boundary, §10 belief modes/nsub), `/home/joe/src/cvc/wt-grl-snam-nav/docs/PERFORMANCE.md` (L59-79, CUDA verdict).
Relevant files: libcvc `CMake/SetupCUDA.cmake` (L88-96, the fast-math fix), `CMakeLists.txt` (L42-78, arch list), `src/cvc/CMakeLists.txt` (L611-612, L815, wiring slot), `src/cvc/nav/grid_nav.cpp` (L497-601, sense split target), `cvcpkg/recipes/libcvc-cuda/recipe.yaml`; this repo's `docs/CVCNAV_CPP_PORT_ROADMAP.md` (§1 fidelity boundary, §10 belief modes/nsub), `docs/PERFORMANCE.md` (L59-79, CUDA verdict).
4 changes: 2 additions & 2 deletions docs/CVCNAV_MATERIAL_PORT_ROADMAP.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,8 @@ and hyperparameter. None of them are in this repo. They resolve as
`$GRL_SNAM_MATERIAL_FORK/full_code/train_material.py` — a checkout of
`github.com/SetasAditya/material-aware-grl-snam`, which
`tests/test_material_fork_xcheck.py:22-24` skips against when the env var is
unset. A clone exists at `/home/joe/src/cvc/material-aware-grl-snam`. Set
`GRL_SNAM_MATERIAL_FORK` to it before touching any parity claim; the bit-identity
unset. Clone it and set
`GRL_SNAM_MATERIAL_FORK` to the clone before touching any parity claim; the bit-identity
cross-check is otherwise silently green.

**Companion C++-side doc:** libcvc `docs/NAV_MATERIAL.md` describes the same
Expand Down
Loading
Loading