Skip to content

Commit 3816a5b

Browse files
Fix linesearch skip causing solver divergence in float32 (#1162)
The linesearch early-exit check (`|derivative| < gtol`) was unreliable in float32 because gtol (~1e-10) falls below float32 precision (~1e-7). This caused rare solver divergence (hitting 100 iteration limit), bottlenecking batched simulation by ~15%. Two fixes: - Clamp gtol to 1e-6 minimum (matching tolerance clamp in io.py) - Require cost improvement for the early exit, preventing acceptance of Newton steps that overshoot past the minimum
1 parent fc91589 commit 3816a5b

File tree

1 file changed

+3
-3
lines changed

1 file changed

+3
-3
lines changed

mujoco_warp/_src/solver.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1031,7 +1031,7 @@ def kernel(
10311031
snorm = wp.sqrt(ctx_search_dot_in[worldid])
10321032
meaninertia = stat_meaninertia[worldid % stat_meaninertia.shape[0]]
10331033
scale = meaninertia * wp.float(nv)
1034-
gtol = tolerance * ls_tolerance * snorm * scale
1034+
gtol = wp.max(tolerance * ls_tolerance * snorm * scale, 1e-6)
10351035

10361036
# p0 via parallel reduction
10371037
local_p0 = wp.vec3(0.0)
@@ -1164,8 +1164,8 @@ def kernel(
11641164
lo_in_sum = wp.tile_reduce(wp.add, lo_in_tile)
11651165
lo_in = _eval_pt(ctx_quad_gauss, lo_alpha_in) + lo_in_sum[0]
11661166

1167-
# check for initial convergence: if |derivative| < gtol, accept Newton step immediately
1168-
initial_converged = wp.abs(lo_in[1]) < gtol
1167+
# accept Newton step if derivative is small and cost improved
1168+
initial_converged = wp.abs(lo_in[1]) < gtol and lo_in[0] < p0[0]
11691169

11701170
# main iterative loop - skip if already converged
11711171
if not initial_converged:

0 commit comments

Comments
 (0)