From ee628fcb6731967780b8440a939b92704551f65f Mon Sep 17 00:00:00 2001 From: Haixuan Xavier Tao Date: Tue, 14 Jul 2026 12:20:55 +0200 Subject: [PATCH 1/2] perf(rbd): skip inactive joint-limit constraint rows emit_limit_constraint always emitted a kind=1 row and computed its O(ndofs) compute_constraint_column LU back-solve, even when the joint sits strictly inside its bounds - where the row has zero positional bias AND both impulse clamps at 0, so it can never apply any impulse. Every PGS sweep then carried #limited-joints dead rows per multibody per substep. Skip emission when !min_enabled && !max_enabled: the slot stays kind=0 (pre-zeroed by the discovery walk), which the PGS sweeps already skip. Constraints are rebuilt from current coords each substep, so a joint reaching its bound re-emits on the next substep exactly as before - result-identical by construction. Measured on a downstream biped-RL training stack (RTX 5090, 2048-8192 parallel envs, joint limits on all joints): the joint-constraint kernel was the top GPU kernel for a 25-joint humanoid (~28% of GPU time - O(joints) rows x O(ndofs) back-solve each, every substep). With the skip: full-body Unitree G1 training throughput +16%, 12-DOF biped +5%, with bit-identical training statistics. Co-Authored-By: Claude Fable 5 Claude-Session: https://claude.ai/code/session_016Dbpu5NhqXK2Xt3YzUbJRM --- .../dynamics/multibody/joint_constraints.rs | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/src_rbd_shaders/dynamics/multibody/joint_constraints.rs b/src_rbd_shaders/dynamics/multibody/joint_constraints.rs index 7bce756..d534f4b 100644 --- a/src_rbd_shaders/dynamics/multibody/joint_constraints.rs +++ b/src_rbd_shaders/dynamics/multibody/joint_constraints.rs @@ -370,6 +370,20 @@ fn emit_limit_constraint( // near-rigid, matching the old hardcoded `1/dt`). let min_enabled = curr_pos < limits[0]; let max_enabled = limits[1] < curr_pos; + // INACTIVE limit (joint strictly inside its bounds): the row would carry + // zero positional bias AND both impulse clamps at 0, so it can never apply + // any impulse — dead weight in every PGS sweep. Skip emission: the slot + // stays `kind = 0` (pre-zeroed by the discovery walk), which the PGS + // sweeps already skip (`if cons.kind == 0 { continue }`). Result-identical, + // and it saves the O(ndofs) `compute_constraint_column` back-solve per + // limit per substep — a robot standing at its home pose has essentially + // every joint inside its limits every substep, so the joint-constraint + // work drops from #limited-joints rows to #violated rows (~0). Constraints + // are rebuilt from current coords each substep, so a joint reaching its + // bound re-emits on the next substep exactly as before. + if !min_enabled && !max_enabled { + return; + } let lo_excess = (limits[0] - curr_pos).max(0.0); let hi_excess = (curr_pos - limits[1]).max(0.0); let rhs_bias = (hi_excess - lo_excess) * erp_inv_dt; From 6478317f720afe2cf0d8d4b74c53129c39458f33 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Crozet?= Date: Thu, 16 Jul 2026 14:11:39 +0200 Subject: [PATCH 2/2] chore: make limits constraint skip comment more concise --- .../dynamics/multibody/joint_constraints.rs | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-) diff --git a/src_rbd_shaders/dynamics/multibody/joint_constraints.rs b/src_rbd_shaders/dynamics/multibody/joint_constraints.rs index d534f4b..29a4511 100644 --- a/src_rbd_shaders/dynamics/multibody/joint_constraints.rs +++ b/src_rbd_shaders/dynamics/multibody/joint_constraints.rs @@ -370,17 +370,7 @@ fn emit_limit_constraint( // near-rigid, matching the old hardcoded `1/dt`). let min_enabled = curr_pos < limits[0]; let max_enabled = limits[1] < curr_pos; - // INACTIVE limit (joint strictly inside its bounds): the row would carry - // zero positional bias AND both impulse clamps at 0, so it can never apply - // any impulse — dead weight in every PGS sweep. Skip emission: the slot - // stays `kind = 0` (pre-zeroed by the discovery walk), which the PGS - // sweeps already skip (`if cons.kind == 0 { continue }`). Result-identical, - // and it saves the O(ndofs) `compute_constraint_column` back-solve per - // limit per substep — a robot standing at its home pose has essentially - // every joint inside its limits every substep, so the joint-constraint - // work drops from #limited-joints rows to #violated rows (~0). Constraints - // are rebuilt from current coords each substep, so a joint reaching its - // bound re-emits on the next substep exactly as before. + // No limit is active, skip the constraint for the current substep. if !min_enabled && !max_enabled { return; }