Skip to content

[Mac OS] Default --device to cpu on macOS - #8190

Merged
AntoineRichard merged 4 commits into
isaac-sim:developfrom
AntoineRichard:antoiner/feat/macos-cpu-device-default
Oct 5, 2026
Merged

AntoineRichard merged 4 commits into
isaac-sim:developfrom
AntoineRichard:antoiner/feat/macos-cpu-device-default

Conversation

@AntoineRichard

@AntoineRichard AntoineRichard commented Sep 30, 2026 •

Copy link
Copy Markdown
Collaborator

Description

--device defaults to cuda:0. On macOS, which has no CUDA, every command without an explicit --device cpu fails at simulation start (Torch not compiled with CUDA enabled in SimulationContext._init_usd_physics_scene).

The default is now cpu on macOS and stays cuda:0 elsewhere. It checks sys.platform rather than torch.cuda.is_available() because the launcher defers importing torch until after Kit starts (see the comment in _resolve_device_settings). An explicit --device still wins, and device_explicit is untouched, so the XR device logic is unaffected.

launch_simulation logs a warning when it applies this default (No --device given; using 'cpu' because macOS has no CUDA.), so the switch is visible. Passing --device explicitly suppresses it. Hosts that request a CUDA device without having CUDA are handled separately by #8188, which falls back to the CPU with its own warning.

Part of the experimental macOS (Apple silicon, CPU-only) support series.

Type of change

  • New feature (non-breaking change which adds functionality)

Validation

Checklist

  • I have read and understood the contribution guidelines
  • I have run the pre-commit checks with uv run isaaclab --format (all hooks pass except check-git-lfs-pointers, which needs git-lfs installed locally)
  • I have made corresponding changes to the documentation
  • My changes generate no new warnings
  • I have validated the changed behavior with focused coverage and applied the test-audit criteria to any test changes
  • I have added a changelog fragment under source/<pkg>/changelog.d/ for every touched package (do not edit CHANGELOG.rst or bump package versions — CI handles that)
  • I have added my name to the CONTRIBUTORS.md or my name already exists there

@github-actions github-actions Bot added the isaac-lab Related to Isaac Lab team label Sep 30, 2026
@AntoineRichard
AntoineRichard marked this pull request as ready for review September 30, 2026 13:58
@AntoineRichard
AntoineRichard requested a review from a team September 30, 2026 13:58
@AntoineRichard AntoineRichard changed the title Default --device to cpu on macOS [Mac OS] Default --device to cpu on macOS Sep 30, 2026
@greptile-apps

greptile-apps Bot commented Sep 30, 2026 •

Copy link
Copy Markdown
Contributor

RetriggerConfidence Score: 5/5

[Medium risk] Changes the default compute device on macOS.

This PR appears safe to merge as the scoped launcher-default change.

Summary

The PR makes the launcher’s --device default cpu on macOS while retaining cuda:0 elsewhere.

  • Updates argument help and the changelog.
  • Adds a parametrized test for the three platform defaults and the unset explicit-device marker.

Reviews (1) · Last reviewed commit: "Default --device to cpu on macOS"

@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 change correctly makes the --device parser default cpu on macOS while retaining cuda:0 elsewhere, preserves explicit-device tracking, and documents the behavior in CLI help and the package changelog. The new regression test contains one redundant non-Darwin parameter row that should be removed.

  • Design and architecture: The platform-dependent default remains at the existing launcher argument-registration boundary and uses sys.platform, avoiding an early torch import as required by launcher initialization. No new helper, flag, or configuration surface is introduced.
  • API: The --device option retains its type and _StoreAndMarkExplicit action. Explicit values still take precedence, default values remain unmarked as explicit, and the help text now describes both platform defaults.
  • Compatibility and deprecation: Breaking changes: none identified. Linux and Windows retain the existing cuda:0 default, while macOS changes to the usable CPU default. No launcher attribute, environment-variable, or explicit-device contract is removed, and the change has a package changelog fragment.
  • Implementation: The default expression is evaluated when launcher arguments are registered, and its value flows through the existing device-resolution paths without changing device_explicit, XR pinning, or physics-device handling. The implementation is appropriately localized.
  • Style consistency: The comment explains the non-obvious reason for checking sys.platform instead of torch availability, and the updated docstring and help wording match the changed behavior and surrounding launcher style.
  • Test quality: The added parser-boundary test protects the platform-specific default and verifies that a default is not marked explicit. However, the linux and win32 cases exercise the same sys.platform != "darwin" branch with the same expected result, violating the test-audit requirement that parameter rows cover distinct paths. Keep the Darwin case and one representative non-Darwin case.

Minor fixes needed. Posted 1 actionable finding inline.

Automated review; human maintainers own approval decisions.

return launcher


@pytest.mark.parametrize(("platform", "expected"), [("linux", "cuda:0"), ("win32", "cuda:0"), ("darwin", "cpu")])

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.

🔵 Suggestion · Test Quality — Redundant non-Darwin parametrize row

The default is chosen by the single predicate sys.platform == "darwin", so the linux and win32 rows execute the identical else branch and assert the identical value; neither can fail without the other. The test-audit guidance rejects parametrize rows whose axis value selects no distinct code path. Keep darwin plus one representative non-Darwin platform.



@pytest.mark.parametrize(("platform", "expected"), [("linux", "cuda:0"), ("win32", "cuda:0"), ("darwin", "cpu")])
def test_device_defaults_to_cpu_on_macos(platform, expected, monkeypatch):

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

We can drop the test

@hujc7

hujc7 commented Sep 30, 2026

Copy link
Copy Markdown
Collaborator

run-ci

@isaaclab-bot isaaclab-bot Bot added ci:run-docker Trigger the on-demand Docker and GPU CI workflow and removed ci:run-docker Trigger the on-demand Docker and GPU CI workflow labels Sep 30, 2026
@AntoineRichard

Copy link
Copy Markdown
Collaborator Author

run-ci

@isaaclab-bot isaaclab-bot Bot added ci:run-docker Trigger the on-demand Docker and GPU CI workflow and removed ci:run-docker Trigger the on-demand Docker and GPU CI workflow labels Oct 2, 2026
@AntoineRichard
AntoineRichard enabled auto-merge (squash) October 2, 2026 08:52
@AntoineRichard
AntoineRichard merged commit 13a958a into isaac-sim:develop Oct 5, 2026
58 checks passed
AntoineRichard added a commit that referenced this pull request Oct 9, 2026
…t CUDA (#8188)

# Description

Hosts without CUDA, such as macOS, could not train with RSL-RL even with
`--device cpu`. The agent configuration's device (`cuda:0` by default)
was used to build the policy, so the run failed with `AssertionError:
Torch not compiled with CUDA enabled`.

This PR uses the device `launch_simulation` already resolves (since
#8125), and sets it in each RL library's shared agent-config setup:

- **Clear error without CUDA.** `_resolve_device` in
`isaaclab.app.sim_launcher` raises `RuntimeError: Device 'cuda:0'
requires CUDA, which is not available; pass --device cpu.` when the
resolved device is a CUDA device and CUDA is unavailable. Before, the
run failed later inside PyTorch. On macOS, #8190
defaults `--device` to `cpu`.
- **The agent runs on the resolved device, set in one shared setup per
library.** Each library's config setup takes the device
(`args_cli.device`, which `launch_simulation` resolves) as an explicit
argument. Every workflow calls it after launch, before the agent is
built or its config is saved. This is unconditional, not only for
`--distributed`:
- **RSL-RL:** the existing `update_rsl_rl_cfg(agent_cfg, args_cli)` sets
`agent_cfg.device = args_cli.device`, for train, play, and benchmark
train. Export and benchmark play, whose CLIs don't define the RSL-RL
training arguments, set the device directly.
- **RL-Games:** the new `update_rl_games_cfg(agent_cfg, args_cli)`
mirrors `update_rsl_rl_cfg`: it sets `device` / `device_name` and the
seed for train, play, export, and both benchmarks. RL-Games export gains
`--seed`, matching RSL-RL export, so every RL-Games workflow can call
it.
- **Stable-Baselines3:** the new `update_sb3_cfg(agent_cfg, args_cli)`
mirrors `update_rsl_rl_cfg`: it sets the device and seed for train,
play, and both benchmarks. Both `PPO.load()` calls pass
`device=agent_cfg["device"]`, so checkpoint loading follows the same
setup.

skrl and TorchRL already used the simulation's device. The saved agent
config records the device actually used, which addresses the bot
findings.

Closes #8193.

Part of the experimental macOS (Apple silicon, CPU-only) support series.

## Type of change

- Bug fix (non-breaking change which fixes an issue)
- Breaking change (existing functionality will not work without user
modification)

**Breaking:** outside distributed runs, the RSL-RL, RL-Games and SB3 CLI
workflows used to ignore `--device` for the agent:

| Command | Before | After |
|---|---|---|
| `--device cpu` | Simulation on CPU, agent on `cuda:0` | Both on the
CPU |
| `--device cuda:1` | Simulation on GPU 1, agent on GPU 0 (see
#2148) | Both on GPU 1 |

The agent configuration's `device` is now overwritten by these
workflows. The wrappers still support running the simulation and the
agent on different devices for custom scripts;
`source/isaaclab_tasks/test/core/test_rl_device_separation.py` covers
that and is unaffected. `isaaclab_rl` gets a `.major` fragment.

## Validation

On macOS arm64, CPU-only:

| Run | Result |
|---|---|
| RSL-RL train, `--device cpu` | Trains |
| SB3 train, `--device cpu` | Trains (`Using cpu device`) |
| RL-Games train, `--device cpu` (512 envs) | Completes 2 epochs |
| RSL-RL train, `--device cuda:0` | Stops with `RuntimeError: Device
'cuda:0' requires CUDA, which is not available; pass --device cpu.` |

`source/isaaclab_rl/test/test_entrypoints.py`,
`test_entrypoints_common.py`, and
`source/isaaclab/test/app/test_launch_simulation_require_kit.py`: 83
passed. The one failure is
`test_skrl_training_parser_leaves_algorithm_implicit`, which needs
`skrl`, not installed locally.
`test_run_summary_reports_the_launch_resolved_visualizers_and_device`
now launches on `cpu`: it only used `cuda:0` as a label and still checks
the device resolved after launch.

## Checklist

- [x] I have read and understood the [contribution
guidelines](https://isaac-sim.github.io/IsaacLab/main/source/refs/contributing.html)
- [x] I have run the [`pre-commit` checks](https://pre-commit.com/) with
`uv run isaaclab --format` (all hooks pass except
`check-git-lfs-pointers`, which needs git-lfs installed locally)
- [ ] I have made corresponding changes to the documentation
- [x] My changes generate no new warnings
- [ ] I have validated the changed behavior with focused coverage and
applied the [test-audit
criteria](https://github.com/isaac-sim/IsaacLab/blob/develop/skills/developer/test-audit/SKILL.md)
to any test changes
- [x] I have added a changelog fragment under
`source/<pkg>/changelog.d/` for every touched package (do **not** edit
`CHANGELOG.rst` or bump package versions — CI handles that)
- [x] I have added my name to the `CONTRIBUTORS.md` or my name already
exists there
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.

4 participants