-
Notifications
You must be signed in to change notification settings - Fork 3.9k
[Fix] Automatically work around OVPhysX multi-GPU device selection #7142
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
03b0113
583e57d
38a58bf
8af61e7
63aeffc
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,8 @@ | ||
| Added | ||
| ^^^^^ | ||
|
|
||
| * Added automatic single-GPU-per-worker execution to the multi-GPU launchers when the selected presets | ||
| include OVPhysX, which otherwise hangs runs on more than one GPU whenever an RTX renderer shares the | ||
| process. Every worker sees its own GPU as ``cuda:0`` and reports ``LOCAL_RANK=0`` while this is active, | ||
| so use the global rank to name per-rank files. This is applied automatically and needs no flag; it will | ||
| be removed once the pinned OVPhysX version contains the fix. |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -50,6 +50,12 @@ | |
| SKRL_JAX_TORCHRUN_ONLY_ARGS = tuple(name for name in TORCHRUN_ARGS if name not in SKRL_JAX_ARGS) | ||
| """``torchrun`` options that have no skrl JAX equivalent.""" | ||
|
|
||
| PRESET_SELECTOR_PREFIXES = ("presets=", "physics=") | ||
| """Hydra-style tokens that can name a physics backend, forwarded to the worker rather than parsed here.""" | ||
|
|
||
| VIRTUAL_LOCAL_RANK_PRESET = "ovphysx" | ||
| """Preset that needs one visible GPU per worker. See :func:`_use_virtual_local_rank`.""" | ||
|
|
||
| # torchelastic gives its own workers 30 s before it SIGKILLs them, so the graceful window stays | ||
| # above that rather than preempting a shutdown that is already making progress. | ||
| _POLL_INTERVAL_S = 0.2 | ||
|
|
@@ -206,6 +212,9 @@ def build_launch_command(args_cli: argparse.Namespace, worker_args: list[str], c | |
| if not args_cli.log_all_ranks and args_cli.local_ranks_filter is None: | ||
| command.extend(("--local_ranks_filter", "0")) | ||
|
|
||
| if _use_virtual_local_rank(worker_args): | ||
| command.append("--virtual_local_rank") | ||
|
|
||
| return command + _worker_argv(args_cli, worker_args, cfg) | ||
|
|
||
|
|
||
|
|
@@ -229,7 +238,8 @@ def run_multigpu_cli(argv: list[str] | None, cfg: MultiGpuLauncherCfg) -> int: | |
| print(shlex.join(command)) | ||
| return 0 | ||
|
|
||
| print(f"[INFO] Launching distributed workers with: {shlex.join(command)}") | ||
| # Flushed so the launcher preamble precedes the workers' inherited-fd output in a redirected log. | ||
| print(f"[INFO] Launching distributed workers with: {shlex.join(command)}", flush=True) | ||
| return run_launch_command(command) | ||
|
|
||
|
|
||
|
|
@@ -280,6 +290,28 @@ def _is_skrl_jax_launcher(args_cli: argparse.Namespace, worker_args: list[str], | |
| return _forwarded_arg_value(worker_args, "--ml_framework") == "jax" | ||
|
|
||
|
|
||
| def _use_virtual_local_rank(worker_args: list[str]) -> bool: | ||
| """Return whether the presets select OVPhysX, which needs one visible GPU per worker. | ||
|
|
||
| Works around nvbug 6573426 in ovphysx <= 0.5.10; delete with the pin. Matches the physics backend | ||
| only, because ``renderer=rtx`` resolves to OVRTX inside the worker, and matches the raw name, so a | ||
| future ``ovphysx`` alias would bypass it. | ||
| """ | ||
| selected: set[str] = set() | ||
| for arg in worker_args: | ||
| for prefix in PRESET_SELECTOR_PREFIXES: | ||
| if arg.startswith(prefix): | ||
| selected.update(name.strip() for name in arg[len(prefix) :].split(",")) | ||
| if VIRTUAL_LOCAL_RANK_PRESET not in selected: | ||
|
Comment on lines
+304
to
+305
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
When a kitless multi-GPU launch uses |
||
| return False | ||
| print( | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🟡 Warning · Implementation — Info banner breaks dry-run command output
|
||
| "[INFO] Presets select OVPhysX; giving every worker a single GPU as cuda:0 to avoid the " | ||
| "multi-GPU device-selection hang (nvbug 6573426).", | ||
| flush=True, | ||
| ) | ||
| return True | ||
|
|
||
|
|
||
| def _visible_cuda_device_count() -> int | None: | ||
| """Return the number of visible CUDA devices on this node, or ``None`` if undetermined.""" | ||
| visible_devices = os.environ.get("CUDA_VISIBLE_DEVICES") | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.