Backend switching (NumPy / JAX)¶
forge3d supports two computation backends that can be switched at runtime:
ENGINE_BACKEND=numpy python my_script.py # default
ENGINE_BACKEND=jax python my_script.py # JAX JIT + vmap
Both backends produce numerically equivalent results (within float64 tolerance).
Why two backends?¶
- NumPy: Simple, debuggable, no JIT overhead for small scenes.
- JAX: JIT compilation +
vmapbatching → 2,000× throughput for RL training.
The JAX backend shines when stepping thousands of environments in parallel:
import jax
import jax.numpy as jnp
from forge3d.sim.jax_batch import batch_reach_reset, batch_reach_step
key = jax.random.PRNGKey(0)
q, tgt, obs = batch_reach_reset(key, n_envs=256)
q, obs, rew, done = batch_reach_step(q, tgt, jnp.zeros((256, 6)))
Backend API¶
backend ¶
Backend abstraction: numpy ↔ jax.
Select via environment variable before process start
ENGINE_BACKEND=numpy (default) ENGINE_BACKEND=jax
Engine code imports names from here
from forge3d.backend import xp, jit, vmap, set_at, new_prng_key, split_key, rand_uniform
xp — numpy or jax.numpy module jit — jax.jit or no-op decorator vmap — jax.vmap or loop-based fallback