Jump to content

Connect Leeroopedia MCP: Equip your AI agents to search best practices, build plans, verify code, diagnose failures, and look up hyperparameter defaults.

Heuristic:Google deepmind Mujoco Solver Selection Guide

From Leeroopedia
Knowledge Sources
Domains Optimization, Physics_Simulation
Last Updated 2026-02-15 05:00 GMT

Overview

Decision framework for choosing between CG, Newton, and PGS constraint solvers based on model complexity, hardware backend, and stability requirements.

Description

MuJoCo provides three constraint solvers: PGS (Projected Gauss-Seidel), CG (Conjugate Gradient), and Newton. Each solver has different convergence properties, computational costs, and backend compatibility. In MJX (JAX/Warp backends), only CG and Newton are implemented; PGS is not available. The choice of solver significantly affects both simulation speed and physical accuracy.

Usage

Use this heuristic when configuring solver parameters for a new model, optimizing simulation throughput, or debugging contact instability. It applies to both native MuJoCo C API and MJX workloads.

The Insight (Rule of Thumb)

  • Action: Choose CG solver as default for most articulated body simulations.
  • Value: Set `m.opt.solver = mujoco.mjtSolver.mjSOL_CG` with `iterations=1` and `ls_iterations=4` for MJX benchmarks.
  • Trade-off: Newton converges faster per iteration for well-conditioned problems but requires Hessian computation. CG is cheaper per iteration and more robust.
  • PGS: Simplest and most robust but slowest convergence. Only available in native C API, not in MJX.
  • Sparse vs Dense: Use `JacobianType.AUTO` which selects sparse when `nv > 60` (especially on TPU), dense otherwise.

Reasoning

CG solver uses preconditioned conjugate gradient which is well-suited for GPU execution (GEMM-friendly operations). Newton requires explicit Hessian factorization which is more expensive but converges in fewer iterations for stiff constraint systems. PGS is sequential by nature and difficult to parallelize, hence excluded from MJX.

The MJX benchmark defaults use CG with `iterations=1, ls_iterations=4` because:

  1. Single CG iteration with 4 line-search steps provides good cost-accuracy trade-off for typical robotics models.
  2. Higher unroll values help GPU GEMM performance.
  3. CG naturally extends to batched (vmapped) execution without per-instance branching.

The sparse vs dense Jacobian decision threshold at `nv=60` comes from empirical observation that sparse matrix operations become faster than dense GEMM at higher degrees of freedom.

Code Evidence

Solver enumeration and PGS exclusion from `mjx/mujoco/mjx/_src/types.py:214-217`:

class SolverType(enum.IntEnum):
  # unsupported: PGS
  CG = mujoco.mjtSolver.mjSOL_CG
  NEWTON = mujoco.mjtSolver.mjSOL_NEWTON

Solver validation in `mjx/mujoco/mjx/_src/io.py:231-232`:

if o.solver not in set(types.SolverType):
    raise NotImplementedError(f'{mujoco.mjtSolver(o.solver)}')

Benchmark defaults from `mjx/mujoco/mjx/_src/test_util.py:56-58`:

def benchmark(
    m: mujoco.MjModel,
    nstep: int = 1000,
    batch_size: int = 1024,
    unroll_steps: int = 1,
    solver: str = 'newton',
    iterations: int = 1,
    ls_iterations: int = 4,
) -> Tuple[float, float, int]:

Sparse Jacobian auto-selection from `mjx/mujoco/mjx/_src/types.py:193-200`:

class JacobianType(enum.IntEnum):
  """Type of constraint Jacobian.
  Attributes:
    DENSE: dense
    SPARSE: sparse
    AUTO: sparse if nv>60 and device is TPU, dense otherwise
  """

Unsupported solver error from `mjx/mujoco/mjx/_src/solver.py:413-414`:

raise NotImplementedError(f'unsupported solver type: {m.opt.solver}')

Related Pages

Page Connections

Double-click a node to navigate. Hold to expand connections.
Principle
Implementation
Heuristic
Environment