GPU Batch Solvers
Experimental: GPU solvers are under active development and need more validation. Use with caution in production systems.
When to read this guide
Use GPU solvers for offline batch throughput (thousands of independent velocity IK solves). Real-time teleop and WBC use the CPU KinematicsSolver with Solver Robustness and Collision Constraints. See the Guides overview for how batch and interactive paths differ.
EmbodiK provides two GPU-optimized velocity IK solvers for massive parallelism via CusADi:
- FI-PeSNS (Fixed-Iteration Penalized eSNS) — primary solver
- PPH-SNS (Parallel Penalized Hierarchical SNS) — alternative formulation
Both compile to CUDA kernels and achieve 100% constraint satisfaction with zero violations.
Comparison
| Solver | Description | Throughput (10K batch) |
|---|---|---|
| FI-PeSNS | Penalty-based eSNS with analytical scaling | ~675,000 solves/sec |
| PPH-SNS | Soft top-k violation selection, limited rank-1 updates | ~632,000 solves/sec |
FI-PeSNS
Fixed-Iteration Penalized eSNS trades exact constraint saturation for simpler, parallelizable penalty-based enforcement.
Key features: - SRINV (Singularity-Robust Inverse) for numerical stability - Analytical feasible task scales without iterative saturation - Penalty gradient nudge toward feasibility each iteration - Fixed iterations (k_max=12) for predictable compute time
from embodik.gpu.casadi_fi_pesns import build_fi_pesns_single_task
fn = build_fi_pesns_single_task(
n_dof=7, task_dim=6, n_constraints=7,
k_max=12, mu0=1e-3, gamma=2.5, eta=0.1,
)
velocity, scales = fn(target, jacobian.flatten(), C, lower, upper)
PPH-SNS
Parallel Penalized Hierarchical SNS is a GPU-native redesign with:
- Soft top-k violation selection using softmax weights
- Limited rank-1 projector updates (1–2 violators per iteration)
- Aggressive penalty ramping (γ=3.0)
- Fixed-depth unrolling for CusADi compilation
from embodik.gpu.casadi_pph_sns import build_pph_sns_single_task
fn = build_pph_sns_single_task(
n_dof=7, task_dim=6, n_constraints=7,
k_max=14, m_max=2, # Outer iterations, max saturations per iteration
)
velocity, scales = fn(target, jacobian.flatten(), C, lower, upper)
Export and Compile
FI-PeSNS
pixi run -e cuda export-casadi
mkdir -p ~/.local/cusadi/src/casadi_functions
cp build/casadi/fn_velocity_solve.casadi ~/.local/cusadi/src/casadi_functions/
cd ~/.local/cusadi && python run_codegen.py --fn=fn_velocity_solve
PPH-SNS
pixi run -e cuda export-pph-sns # Writes to ~/.local/cusadi/src/casadi_functions/
cd ~/.local/cusadi && python run_codegen.py --fn=fn_pph_sns_velocity_solve