Multibody contact/joint solve produces zero impulses on macOS (naga MSL loop miscompile)
- Dominant language
- Rust
- Stars
- 115
- Forks
- 6
- Avg merge
- 9h 4m
- Merged PRs (30d)
- 4
Description
On macOS (wgpu/Metal), the rbd multibody solver's contact and PD-joint sweeps have no effect: bodies free-fall through the ground, and more solver iterations make the blow-up worse (gravity integrates per TGS iteration while constraints contribute nothing).
**Root cause is not in nexus** — it's a naga 29 MSL backend bug: the writer renders a loop's `continuing` block at the top of the next `while` iteration and re-evaluates the `break_if` condition there, after the continuing statements have advanced the loop variables the condition reads. rust-gpu `while` loops (conditional backedge computed in the loop body) therefore exit one body-execution early on Metal. In `solve_contact_constraints_par`, the per-lane `while i < ndofs { …; i += LANES }` reductions have exactly one iteration per lane — so they execute **zero** times, J·v evaluates to 0, and every impulse stays 0. CUDA and Vulkan (spirv-passthrough) are unaffected, which makes it look like a nexus solver bug when it isn't.
Fix is upstream: **gfx-rs/wgpu#9815** (fixes the long-open gfx-rs/wgpu#4558). Until it ships in a wgpu release, a vendored-naga `[patch.crates-io]` with the condition-snapshot fix restores correct Metal behavior — verified against a CUDA golden reference of the same SPIR-V (step-0 contact impulse matches to 4 decimals; an RL training run over the engine converges identically on macOS and CUDA after the patch).
Happy to share the diagnosis trail (deterministic-seed intermediate diffing down to an in-kernel lane-liveness probe) or the vendored patch. (Originally filed on the old repo as dimforge/nexus-rustgpu#3 before noticing development moved here.)
Contributor guide
No contributing guide indexed for this repository
Research direction
Start by reading gfx-rs/wgpu#9815 and the earlier gfx-rs/wgpu#4558, then inspect the vendored naga condition-snapshot fix described in the issue. Done means Metal contact and joint impulses are restored, the step-0 impulse matches the CUDA reference to four decimals, and the macOS training run converges like CUDA.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- macos, rust
- Domain
- computer-graphics
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 25/100