From d6021197715a8a1fcb41edc89955506389241bc3 Mon Sep 17 00:00:00 2001 From: Octi Zhang Date: Wed, 30 Sep 2026 20:15:29 -0700 Subject: [PATCH 1/2] Keep the environment runtime out of the RL entry points' imports The import hoist in #8125 moved multi_agent_to_single_agent to the top of isaaclab_rl.entrypoints.common, which imports isaaclab.envs.direct_marl_env and, through the video recorder, moviepy, SciPy, OpenCV and matplotlib before Kit starts. With moviepy installed, OpenBLAS's at-fork handler then crashes Kit's platform-info fork during startup (3/3 runs, against 0/3 before #8125). Import it where the environment is wrapped, after the launch, and keep torch local to the distributed-device path as KitLauncher documents. --- source/isaaclab/changelog.d/fix-pre-kit-env-import.skip | 0 source/isaaclab/isaaclab/app/sim_launcher.py | 4 +++- .../changelog.d/fix-pre-kit-env-import.fixed.rst | 3 +++ source/isaaclab_rl/isaaclab_rl/entrypoints/common.py | 6 +++++- 4 files changed, 11 insertions(+), 2 deletions(-) create mode 100644 source/isaaclab/changelog.d/fix-pre-kit-env-import.skip create mode 100644 source/isaaclab_rl/changelog.d/fix-pre-kit-env-import.fixed.rst diff --git a/source/isaaclab/changelog.d/fix-pre-kit-env-import.skip b/source/isaaclab/changelog.d/fix-pre-kit-env-import.skip new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/source/isaaclab/isaaclab/app/sim_launcher.py b/source/isaaclab/isaaclab/app/sim_launcher.py index e0d47fdd47ed..66a74a399603 100644 --- a/source/isaaclab/isaaclab/app/sim_launcher.py +++ b/source/isaaclab/isaaclab/app/sim_launcher.py @@ -22,7 +22,6 @@ from dataclasses import dataclass, field from typing import Any -import torch from isaaclab_newton.physics import NewtonCfg, VBDSolverCfg from isaaclab_ov.physics import OvPhysxCfg from isaaclab_ov.renderers import OVRTXRendererCfg @@ -489,6 +488,9 @@ def _resolve_distributed_device(args: dict) -> None: if not args.get("distributed", False): return + # torch loads NumPy/OpenBLAS, whose at-fork handlers can crash Kit's platform-info fork during startup + import torch # noqa: PLC0415 + local_rank = int(os.getenv("LOCAL_RANK", "0")) + int(os.getenv("JAX_LOCAL_RANK", "0")) num_visible_gpus = torch.cuda.device_count() # Compare against the local device count (not WORLD_SIZE) so multi-node runs work. diff --git a/source/isaaclab_rl/changelog.d/fix-pre-kit-env-import.fixed.rst b/source/isaaclab_rl/changelog.d/fix-pre-kit-env-import.fixed.rst new file mode 100644 index 000000000000..4357d036e47b --- /dev/null +++ b/source/isaaclab_rl/changelog.d/fix-pre-kit-env-import.fixed.rst @@ -0,0 +1,3 @@ +* Fixed Isaac Sim crashing at startup in OpenBLAS's at-fork handler when ``moviepy`` is installed: the + reinforcement learning entry points imported the environment runtime, and with it the video recorder's + ``moviepy`` and SciPy, before the launch. diff --git a/source/isaaclab_rl/isaaclab_rl/entrypoints/common.py b/source/isaaclab_rl/isaaclab_rl/entrypoints/common.py index a2576b9a5feb..979d890cb1fb 100644 --- a/source/isaaclab_rl/isaaclab_rl/entrypoints/common.py +++ b/source/isaaclab_rl/isaaclab_rl/entrypoints/common.py @@ -29,7 +29,7 @@ from PIL import Image from isaaclab.app import LoadingScreen -from isaaclab.envs import DirectMARLEnvCfg, DirectRLEnvCfg, ManagerBasedRLEnvCfg, multi_agent_to_single_agent +from isaaclab.envs import DirectMARLEnvCfg, DirectRLEnvCfg, ManagerBasedRLEnvCfg from isaaclab.envs.utils.video_recorder_cfg import VideoRecorderCfg from isaaclab.renderers.renderer_cfg import RendererCfg from isaaclab.utils.assets import retrieve_file_path @@ -501,6 +501,10 @@ def create_isaaclab_env( env = WarpFrontend.build_env(env_cfg, task) if convert_marl_to_single_agent and isinstance(env.unwrapped.cfg, DirectMARLEnvCfg): + # imports the environment runtime and its video recorder (moviepy, SciPy), whose OpenBLAS at-fork handlers + # can crash Kit's startup fork, so it must not load before the launch + from isaaclab.envs import multi_agent_to_single_agent # noqa: PLC0415 + env = multi_agent_to_single_agent(env) return env From de3adf81b08b147b6dbae04c8760c8f370ffe48f Mon Sep 17 00:00:00 2001 From: Octi Zhang Date: Wed, 30 Sep 2026 22:21:15 -0700 Subject: [PATCH 2/2] Narrow video imports and remove ineffective Torch deferral --- source/isaaclab/changelog.d/fix-pre-kit-env-import.fixed.rst | 1 + source/isaaclab/changelog.d/fix-pre-kit-env-import.skip | 0 source/isaaclab/isaaclab/app/sim_launcher.py | 4 +--- source/isaaclab/isaaclab/envs/utils/video_recorder.py | 2 +- source/isaaclab_rl/isaaclab_rl/entrypoints/common.py | 5 ++--- source/isaaclab_rl/test/test_entrypoints.py | 1 + 6 files changed, 6 insertions(+), 7 deletions(-) create mode 100644 source/isaaclab/changelog.d/fix-pre-kit-env-import.fixed.rst delete mode 100644 source/isaaclab/changelog.d/fix-pre-kit-env-import.skip diff --git a/source/isaaclab/changelog.d/fix-pre-kit-env-import.fixed.rst b/source/isaaclab/changelog.d/fix-pre-kit-env-import.fixed.rst new file mode 100644 index 000000000000..064a7936f00b --- /dev/null +++ b/source/isaaclab/changelog.d/fix-pre-kit-env-import.fixed.rst @@ -0,0 +1 @@ +* Avoided loading MoviePy's unrelated editing dependencies when importing the video recorder. diff --git a/source/isaaclab/changelog.d/fix-pre-kit-env-import.skip b/source/isaaclab/changelog.d/fix-pre-kit-env-import.skip deleted file mode 100644 index e69de29bb2d1..000000000000 diff --git a/source/isaaclab/isaaclab/app/sim_launcher.py b/source/isaaclab/isaaclab/app/sim_launcher.py index 66a74a399603..e0d47fdd47ed 100644 --- a/source/isaaclab/isaaclab/app/sim_launcher.py +++ b/source/isaaclab/isaaclab/app/sim_launcher.py @@ -22,6 +22,7 @@ from dataclasses import dataclass, field from typing import Any +import torch from isaaclab_newton.physics import NewtonCfg, VBDSolverCfg from isaaclab_ov.physics import OvPhysxCfg from isaaclab_ov.renderers import OVRTXRendererCfg @@ -488,9 +489,6 @@ def _resolve_distributed_device(args: dict) -> None: if not args.get("distributed", False): return - # torch loads NumPy/OpenBLAS, whose at-fork handlers can crash Kit's platform-info fork during startup - import torch # noqa: PLC0415 - local_rank = int(os.getenv("LOCAL_RANK", "0")) + int(os.getenv("JAX_LOCAL_RANK", "0")) num_visible_gpus = torch.cuda.device_count() # Compare against the local device count (not WORLD_SIZE) so multi-node runs work. diff --git a/source/isaaclab/isaaclab/envs/utils/video_recorder.py b/source/isaaclab/isaaclab/envs/utils/video_recorder.py index 5e0520ac0017..7df49c1815b0 100644 --- a/source/isaaclab/isaaclab/envs/utils/video_recorder.py +++ b/source/isaaclab/isaaclab/envs/utils/video_recorder.py @@ -20,7 +20,7 @@ import numpy as np try: - from moviepy.editor import ImageSequenceClip + from moviepy.video.io.ImageSequenceClip import ImageSequenceClip except ImportError: ImageSequenceClip = None # type: ignore[assignment,misc] diff --git a/source/isaaclab_rl/isaaclab_rl/entrypoints/common.py b/source/isaaclab_rl/isaaclab_rl/entrypoints/common.py index 979d890cb1fb..dfc2243225ec 100644 --- a/source/isaaclab_rl/isaaclab_rl/entrypoints/common.py +++ b/source/isaaclab_rl/isaaclab_rl/entrypoints/common.py @@ -501,9 +501,8 @@ def create_isaaclab_env( env = WarpFrontend.build_env(env_cfg, task) if convert_marl_to_single_agent and isinstance(env.unwrapped.cfg, DirectMARLEnvCfg): - # imports the environment runtime and its video recorder (moviepy, SciPy), whose OpenBLAS at-fork handlers - # can crash Kit's startup fork, so it must not load before the launch - from isaaclab.envs import multi_agent_to_single_agent # noqa: PLC0415 + # Import the environment runtime only after simulation launch. + from isaaclab.envs import multi_agent_to_single_agent env = multi_agent_to_single_agent(env) return env diff --git a/source/isaaclab_rl/test/test_entrypoints.py b/source/isaaclab_rl/test/test_entrypoints.py index 3371f4ec6760..7c24021bdb32 100644 --- a/source/isaaclab_rl/test/test_entrypoints.py +++ b/source/isaaclab_rl/test/test_entrypoints.py @@ -31,6 +31,7 @@ [ ("import isaaclab_rl", ["isaaclab_rl.entrypoints", "torch"]), ("import isaaclab_rl.entrypoints.backends", ["torch"]), + ("import isaaclab_rl.entrypoints.common", ["isaaclab.envs.direct_marl_env", "moviepy"]), # the LEAPP runtime must only load once the simulation has launched ("import isaaclab_rl.entrypoints.backends.export_rsl_rl", ["leapp", "isaaclab.utils.leapp"]), ("import isaaclab_rl.rl_games", ["isaaclab_rl.rl_games.rl_games", "rl_games", "torch"]),