Skip to content

Commit 6a5fe32

Browse files
committed
Forward the configured determinism mode to Warp instead of assuming run-to-run
NewtonCfg.deterministic_mode maps to the same warp.DeterministicMode enum the global uses, so a backend asking for gpu_to_gpu was getting the stronger guarantee on its solver kernels and a weaker run_to_run everywhere else. The config strings are the enum members lowercased, so the mode is resolved by name rather than by duplicating Newton's mapping table.
1 parent 8d778f4 commit 6a5fe32

2 files changed

Lines changed: 47 additions & 8 deletions

File tree

source/isaaclab_rl/isaaclab_rl/entrypoints/common.py

Lines changed: 19 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -497,11 +497,11 @@ def apply_env_overrides(args_cli: argparse.Namespace, env_cfg: Any, *, apply_dev
497497
physics_cfg = getattr(getattr(env_cfg, "sim", None), "physics", None)
498498
if physics_cfg is not None:
499499
physics_cfg.deterministic = True
500-
request_warp_determinism()
500+
request_warp_determinism(physics_cfg)
501501

502502

503-
def request_warp_determinism() -> None:
504-
"""Ask Warp for run-to-run deterministic atomics process-wide.
503+
def request_warp_determinism(physics_cfg: Any) -> None:
504+
"""Ask Warp for deterministic atomics process-wide, matching the configured guarantee.
505505
506506
Newton's solvers take a ``deterministic`` argument and apply it as a per-module option, so a
507507
solver-level request already covers the physics kernels. Its sensor and geometry modules take
@@ -512,14 +512,25 @@ def request_warp_determinism() -> None:
512512
then break ties differently and a tiled camera renders a handful of pixels differently from
513513
identical simulation state, which is enough to make an image-observation policy diverge.
514514
515-
Warp reads this at module build time, so it must be set before the first kernel launch;
516-
:func:`apply_env_overrides` runs before the environment is created. An explicit setting is
517-
left alone so a caller can still opt into ``GPU_TO_GPU``.
515+
A backend that names a stronger guarantee gets it here too: the strings accepted by
516+
:attr:`~isaaclab_newton.physics.NewtonCfg.deterministic_mode` are the
517+
``warp.DeterministicMode`` members lowercased, so ``"gpu_to_gpu"`` selects
518+
``GPU_TO_GPU`` rather than being weakened to ``RUN_TO_RUN``. Warp reads the setting at module
519+
build time, so it must land before the first kernel launch; :func:`apply_env_overrides` runs
520+
before the environment is created. A mode already set on ``warp.config`` is left alone.
521+
522+
Args:
523+
physics_cfg: Resolved physics config, or ``None`` when the config tree carries none.
518524
"""
519525
import warp as wp
520526

521-
if wp.config.deterministic == wp.DeterministicMode.NOT_GUARANTEED:
522-
wp.config.deterministic = wp.DeterministicMode.RUN_TO_RUN
527+
if wp.config.deterministic != wp.DeterministicMode.NOT_GUARANTEED:
528+
return
529+
requested = getattr(physics_cfg, "deterministic_mode", None)
530+
mode = getattr(wp.DeterministicMode, requested.upper(), None) if isinstance(requested, str) else None
531+
if mode is None or mode == wp.DeterministicMode.NOT_GUARANTEED:
532+
mode = wp.DeterministicMode.RUN_TO_RUN
533+
wp.config.deterministic = mode
523534

524535

525536
def validate_distributed_device(args_cli: argparse.Namespace) -> None:

source/isaaclab_rl/test/test_entrypoints_common.py

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -434,6 +434,34 @@ def test_apply_env_overrides_requests_warp_determinism(monkeypatch: pytest.Monke
434434
assert wp.config.deterministic == wp.DeterministicMode.RUN_TO_RUN
435435

436436

437+
def test_apply_env_overrides_forwards_a_stronger_configured_mode(monkeypatch: pytest.MonkeyPatch) -> None:
438+
"""A backend asking for ``gpu_to_gpu`` gets it globally, not a weakened ``run_to_run``."""
439+
import warp as wp
440+
441+
monkeypatch.setattr(wp.config, "deterministic", wp.DeterministicMode.NOT_GUARANTEED)
442+
physics = _fake_physics_cfg("NewtonCfg", deterministic_mode="gpu_to_gpu")
443+
env_cfg = SimpleNamespace(sim=SimpleNamespace(physics=physics))
444+
445+
args_cli = argparse.Namespace(num_envs=None, device=None, deterministic=True)
446+
_rl_common.apply_env_overrides(args_cli, env_cfg, apply_device=False)
447+
448+
assert wp.config.deterministic == wp.DeterministicMode.GPU_TO_GPU
449+
450+
451+
def test_apply_env_overrides_upgrades_an_unset_backend_mode(monkeypatch: pytest.MonkeyPatch) -> None:
452+
"""``not_guaranteed`` is the shipped default, so it means "unset", not "opt out"."""
453+
import warp as wp
454+
455+
monkeypatch.setattr(wp.config, "deterministic", wp.DeterministicMode.NOT_GUARANTEED)
456+
physics = _fake_physics_cfg("NewtonCfg", deterministic_mode="not_guaranteed")
457+
env_cfg = SimpleNamespace(sim=SimpleNamespace(physics=physics))
458+
459+
args_cli = argparse.Namespace(num_envs=None, device=None, deterministic=True)
460+
_rl_common.apply_env_overrides(args_cli, env_cfg, apply_device=False)
461+
462+
assert wp.config.deterministic == wp.DeterministicMode.RUN_TO_RUN
463+
464+
437465
def test_apply_env_overrides_keeps_an_explicit_warp_mode(monkeypatch: pytest.MonkeyPatch) -> None:
438466
"""A caller that already chose a stronger guarantee keeps it."""
439467
import warp as wp

0 commit comments

Comments
 (0)