dimforge / dimforge/nexus

Multibody contact/joint solve produces zero impulses on macOS (naga MSL loop miscompile)

Open
#5 2 comments 0 reactions 0 assignees View on GitHub
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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.