Skip to content

[Multi-GPU] Refactors multi-gpu logic into module, fix ghost process on keyboard interrup - #6975

Merged
kellyguo11 merged 2 commits into
isaac-sim:developfrom
StafaH:mhaiderbhai/multigpu-entrypoint-refactor
Aug 8, 2026
Merged

[Multi-GPU] Refactors multi-gpu logic into module, fix ghost process on keyboard interrup#6975
kellyguo11 merged 2 commits into
isaac-sim:developfrom
StafaH:mhaiderbhai/multigpu-entrypoint-refactor

Conversation

@StafaH

@StafaH StafaH commented Aug 7, 2026

Copy link
Copy Markdown
Contributor

Description

Refactors multi-gpu logic from train_multigpu into isaaclab_rl

Checklist

  • I have read and understood the contribution guidelines
  • I have run the pre-commit checks with ./isaaclab.sh --format
  • I have made corresponding changes to the documentation
  • My changes generate no new warnings
  • I have added tests that prove my fix is effective or that my feature works
  • I have added a changelog fragment under source/<pkg>/changelog.d/ for every touched package (do not edit CHANGELOG.rst or bump extension.toml — CI handles that)
  • I have added my name to the CONTRIBUTORS.md or my name already exists there

@StafaH
StafaH requested a review from a team August 7, 2026 19:52
@github-actions github-actions Bot added the isaac-lab Related to Isaac Lab team label Aug 7, 2026
@greptile-apps

greptile-apps Bot commented Aug 7, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

The PR moves multi-GPU launcher construction into isaaclab_rl, introduces a shared per-rank training worker, and adds process-group supervision intended to prevent workers surviving an interrupt.

  • Replaces the script-local launcher implementation with a package API and thin compatibility shim.
  • Resolves the packaged worker entrypoint for torchrun and skrl JAX launches.
  • Adds POSIX process-group signal forwarding, escalation, cleanup, and shutdown tests.
  • Leaves the non-process-group fallback unable to clean up worker descendants.

Confidence Score: 4/5

The fallback shutdown behavior should be fixed before merging because interrupted distributed runs can still leave worker processes and GPU allocations behind on platforms without process groups.

POSIX shutdown is substantially improved, but the newly retained fallback ends only the direct launcher process and provides no mechanism to terminate or reap its distributed worker descendants.

Files Needing Attention: source/isaaclab_rl/isaaclab_rl/entrypoints/multigpu.py

Important Files Changed

Filename Overview
source/isaaclab_rl/isaaclab_rl/entrypoints/multigpu.py Centralizes command construction and adds robust POSIX group supervision, but its fallback terminates only the immediate launcher and can leave workers alive.
source/isaaclab_rl/isaaclab_rl/entrypoints/train_worker.py Provides a packaged worker entrypoint while preserving Warp configuration ordering and torch elastic traceback recording.
scripts/reinforcement_learning/train_multigpu.py Becomes a thin compatibility shim over the new package-level multi-GPU API.
source/isaaclab_rl/test/test_multigpu_shutdown.py Covers POSIX process groups, interrupt cleanup, forced escalation, and exit codes, but skips the fallback path entirely.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    CLI[train_multigpu CLI] --> Check{os.killpg available?}
    Check -->|Yes| Group[Start launcher in new session]
    Group --> Forward[Forward signal to process group]
    Forward --> Escalate[Escalate and reap descendants]
    Check -->|No| Fallback[Start direct child]
    Fallback --> Terminate[Terminate direct launcher only]
    Terminate --> Orphans[Worker descendants may survive]
Loading

Reviews (1): Last reviewed commit: "Stop multi-GPU Ctrl-C from leaving worke..." | Re-trigger Greptile

Comment on lines +379 to +380
proc.terminate()

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Fallback leaves workers running

When multi-GPU training is interrupted on a platform without os.killpg, this handler terminates only the direct torchrun or skrl launcher and performs no descendant cleanup or escalation, causing worker processes to continue running and retain GPU resources after the CLI exits.

@isaaclab-review-bot isaaclab-review-bot Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Isaac Lab Review Bot

The launcher refactor centralizes multi-GPU command construction and process supervision in isaaclab_rl.entrypoints, but the single-process training shim no longer sets Warp’s enable_backward flag before importing the entrypoints package, weakening the import-order guarantee the previous implementation explicitly preserved.

  • Design and architecture: Moving launcher logic into the package and retaining the script as a compatibility shim provides a cleaner shared entrypoint. The new worker module is a reasonable per-rank target, but importing it through isaaclab_rl.entrypoints executes the package initializer before the worker can configure Warp.
  • API: The existing multi-GPU CLI behavior is retained through run_train_multigpu_cli, which is exported from both isaaclab_rl.entrypoints and the package-level lazy API. No incompatible CLI change is evident in the supplied patch.
  • Implementation: The process-group supervision, signal escalation, command building, and shutdown regression tests directly address orphaned workers. However, train.py now imports isaaclab_rl.entrypoints.train_worker before the worker sets wp.config.enable_backward = False; Python executes isaaclab_rl.entrypoints.__init__ first, so the flag should remain configured in train.py before that import to preserve the stated ordering guarantee.

Minor fixes needed. Posted 1 actionable finding inline.

Automated review; human maintainers own approval decisions.

Comment thread scripts/reinforcement_learning/train.py Outdated

# Importing the worker sets Warp's ``enable_backward`` before any Warp kernels are defined, which
# has to happen before the training stack is imported.
from isaaclab_rl.entrypoints.train_worker import main

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Warning · Implementation — Warp flag set after entrypoints package import

from isaaclab_rl.entrypoints.train_worker import main first executes isaaclab_rl/entrypoints/__init__.py (importing api, dispatch, multigpu); only afterwards does train_worker's body run wp.config.enable_backward = False. The removed code deliberately set the flag before that exact import, so the ordering guarantee the new comment claims no longer holds on the single-process path. Set the flag in train.py before importing the worker.

StafaH added 2 commits August 7, 2026 13:20
The launcher lived entirely in scripts/reinforcement_learning, which left
it outside the package that already owns the train and play entry points
and made its logic unavailable to anything but that one script.

Move it to isaaclab_rl.entrypoints.multigpu, exposed as
run_train_multigpu_cli, and reduce the script to a shim like train.py and
play.py. The module doubles as the per-rank trainer: the launcher points
torchrun at this file, so its __main__ block is what each rank runs. That
keeps the worker resolvable from the package rather than from a path
relative to the script, which matters for wheel installs.

The list of distributed-capable backends moves to api.MULTI_GPU_BACKENDS
so it sits next to BackendName instead of being restated in the launcher,
and the skrl JAX exclusion list is now derived from the torchrun options
rather than spelled out a second time.
The launcher ran torchrun inside its own process group, so a terminal
Ctrl-C was delivered to torchrun and every worker at the same moment the
launcher forwarded a signal of its own. That second signal landed inside
torchelastic's shutdown handler, which then aborted partway through
reaping the workers it had spawned, leaving them alive and holding GPU
memory.

Start the worker tree in a new session so the terminal signals only the
launcher, forward one signal from that single place, and escalate to
SIGTERM and then SIGKILL. A worker wedged in a native CUDA, NCCL, or
renderer call never returns to Python to observe a signal at all, so the
launcher also sweeps the process group before it returns.
@StafaH
StafaH force-pushed the mhaiderbhai/multigpu-entrypoint-refactor branch from 4e6fad5 to 8f18c2c Compare August 7, 2026 20:35
@kellyguo11
kellyguo11 merged commit 04fb61d into isaac-sim:develop Aug 8, 2026
73 of 75 checks passed
@StafaH
StafaH deleted the mhaiderbhai/multigpu-entrypoint-refactor branch August 18, 2026 05:20
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

isaac-lab Related to Isaac Lab team

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants