Skip to content

Commit 8a2df0c

Browse files
Promote benchmarks to library API (#6564)
# Description Promotes the benchmark framework from `isaaclab.test.benchmark` to the public `isaaclab.benchmark` package. Runtime, startup, training, play, and RL backend workflows become library entrypoints with typed in-process dispatch. The transitional import and script shims were removed from this PR to keep the move reviewable and leave one implementation for each workflow. This is an intentional breaking change: callers must replace `isaaclab.test.benchmark` imports with `isaaclab.benchmark` and use `isaaclab benchmark` instead of the former runtime, startup, training, and play scripts. ## Highlights - Adds typed runtime, startup, training, and play request objects and `run_benchmark` convenience APIs. - Returns workflow-specific result types such as `BenchmarkResult[RuntimeBundle]`. - Adds in-process `isaaclab benchmark` CLI dispatch. - Moves the supported benchmark workflows and RL backend adapters into the package. - Removes the duplicate `isaaclab.test.benchmark` namespace and standalone workflow forwarding scripts. - Restores process-global Torch, SKRL, and RL Games state and closes environments safely across repeated calls. - Rejects schema finalization without an attached typed bundle instead of reporting a nonexistent output. - Carries forward #6474 validation: positive workloads, non-negative warm-up counts, one default train/play warm-up step, and `--measure_sync_step`. - Adds public API documentation, migration guidance, tests, and changelog fragments. ## Dependencies - Direct dependency: #6474. - Satisfied prerequisite: #6553, already merged, provides reusable RL train/play entrypoints. ## Breaking migration - `from isaaclab.test.benchmark ...` becomes `from isaaclab.benchmark ...`. - `scripts/benchmarks/{runtime,startup,training,play}.py` becomes `isaaclab benchmark {runtime,startup,training,play}`. - Per-library train/play scripts become the unified training/play commands with `--rl_library`. - Independent camera, loading, Hydra, and other standalone benchmarks remain unchanged. ## Type of change - New feature - Breaking API migration - Documentation update ## Validation - Focused benchmark API, CLI, parser, adapter, and early-stop suite: 265 passed, 4 simulator smoke cases deselected. - Focused public API and CLI entrypoint suite: 26 passed. - `./isaaclab.sh -f`: all applicable hooks pass. The conflict-marker hook was skipped because current `develop` contains literal `=======` headings in three third-party license files. - `tools/changelog/cli.py check develop`: passed. - Runtime/startup smoke tests now invoke `uv run isaaclab benchmark`; the local clean-`uv` bootstrap exceeded the validation window while downloading the CUDA environment, so CI remains the end-to-end CLI confirmation. ## Checklist - [x] I have read and understood the contribution guidelines - [x] I have run the pre-commit checks - [x] I have made corresponding documentation changes - [x] My changes generate no new warnings - [x] I have added tests for the public API and canonical CLI paths - [x] I have added the required changelog fragments - [x] I have documented the intentional breaking migration - [x] My name already exists in `CONTRIBUTORS.md` --------- Co-authored-by: Mustafa Haiderbhai <mhaiderbhai@nvidia.com>
1 parent 44a522d commit 8a2df0c

100 files changed

Lines changed: 3311 additions & 1666 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

docs/conf.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -259,6 +259,7 @@ def _read_pinned_versions() -> dict:
259259
"h5py",
260260
"hid",
261261
"prettytable",
262+
"psutil",
262263
"tqdm",
263264
"tensordict",
264265
"trimesh",

docs/source/api/index.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ The following modules are available in the ``isaaclab`` extension:
1616
app
1717
actuators
1818
assets
19+
benchmark
1920
cloner
2021
controllers
2122
devices
Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
isaaclab.benchmark
2+
==================
3+
4+
.. automodule:: isaaclab.benchmark
5+
6+
.. rubric:: Request and result classes
7+
8+
.. autosummary::
9+
10+
BenchmarkLauncherConfig
11+
BenchmarkOutputConfig
12+
BenchmarkPlayRequest
13+
BenchmarkResult
14+
BenchmarkRuntimeRequest
15+
BenchmarkStartupRequest
16+
BenchmarkTrainingRequest
17+
18+
.. rubric:: Workflow functions
19+
20+
.. autosummary::
21+
22+
run_benchmark
23+
run_play_benchmark
24+
run_runtime_benchmark
25+
run_startup_benchmark
26+
run_training_benchmark
27+
28+
.. rubric:: Benchmark framework
29+
30+
.. autosummary::
31+
32+
BaseIsaacLabBenchmark
33+
BenchmarkMonitor
34+
MethodBenchmarkDefinition
35+
MethodBenchmarkRunner
36+
MethodBenchmarkRunnerConfig
37+
PlayBundle
38+
RuntimeBundle
39+
StartupBundle
40+
TrainingBundle
41+
42+
43+
.. currentmodule:: isaaclab.benchmark
44+
45+
Request and Result Classes
46+
--------------------------
47+
48+
.. autoclass:: BenchmarkLauncherConfig
49+
:members:
50+
51+
.. autoclass:: BenchmarkOutputConfig
52+
:members:
53+
54+
.. autoclass:: BenchmarkPlayRequest
55+
:members:
56+
57+
.. autoclass:: BenchmarkResult
58+
:members:
59+
60+
.. autoclass:: BenchmarkRuntimeRequest
61+
:members:
62+
63+
.. autoclass:: BenchmarkStartupRequest
64+
:members:
65+
66+
.. autoclass:: BenchmarkTrainingRequest
67+
:members:
68+
69+
Workflow Functions
70+
------------------
71+
72+
.. autofunction:: run_benchmark
73+
74+
.. autofunction:: run_play_benchmark
75+
76+
.. autofunction:: run_runtime_benchmark
77+
78+
.. autofunction:: run_startup_benchmark
79+
80+
.. autofunction:: run_training_benchmark
81+
82+
Benchmark Framework
83+
-------------------
84+
85+
.. autoclass:: BaseIsaacLabBenchmark
86+
:members:
87+
88+
.. autoclass:: BenchmarkMonitor
89+
:members:
90+
91+
.. autoclass:: MethodBenchmarkDefinition
92+
:members:
93+
94+
.. autoclass:: MethodBenchmarkRunner
95+
:members:
96+
97+
.. autoclass:: MethodBenchmarkRunnerConfig
98+
:members:
99+
100+
.. autoclass:: PlayBundle
101+
:members:
102+
103+
.. autoclass:: RuntimeBundle
104+
:members:
105+
106+
.. autoclass:: StartupBundle
107+
:members:
108+
109+
.. autoclass:: TrainingBundle
110+
:members:

docs/source/migration/migrating_to_isaaclab_3-0.rst

Lines changed: 53 additions & 81 deletions
Original file line numberDiff line numberDiff line change
@@ -958,7 +958,7 @@ Here's a complete example showing how to update your code:
958958
959959
960960
Quaternion Format
961-
~~~~~~~~~~~~~~~~~
961+
~~~~~~~~~~~~~~~~~~~
962962

963963
**The quaternion format changed from WXYZ to XYZW.**
964964

@@ -1946,36 +1946,41 @@ directly in your code, update your configuration:
19461946
)
19471947
19481948
1949-
Benchmark Scripts
1950-
~~~~~~~~~~~~~~~~~
1949+
Benchmark Workflows
1950+
~~~~~~~~~~~~~~~~~~~
19511951

19521952
Isaac Lab 3.0 consolidates the per-backend environment benchmark entry points and their
1953-
wrapper shell runners into a small set of unified, backend-agnostic scripts. The physics
1953+
wrapper shell runners into library-owned, backend-agnostic workflows. The physics
19541954
backend is now selected at launch time through the ``presets=`` system — the same pattern
19551955
used for environment configurations (see "Multi-Backend Support: PresetCfg Pattern" above)
19561956
— rather than by choosing a backend-specific script.
19571957

19581958
What Changed
19591959
------------
19601960

1961-
The standalone environment benchmark entry-point scripts have been removed and replaced by
1962-
unified scripts:
1961+
The environment benchmark entry points are now exposed through ``isaaclab benchmark`` and
1962+
the typed :mod:`isaaclab.benchmark` Python API:
19631963

1964-
* ``runtime.py`` — steps an environment with random actions (no policy) and emits a
1964+
* ``isaaclab benchmark runtime`` — steps an environment with random actions (no policy) and emits a
19651965
``RuntimeBundle``.
1966-
* ``training.py`` — dispatches a real training run for the RL library selected with
1966+
* ``isaaclab benchmark training`` — dispatches a real training run for the RL library selected with
19671967
``--rl_library`` and emits a ``TrainingBundle``.
1968-
* ``startup.py`` — profiles the five startup phases (``app_launch``, ``python_imports``,
1968+
* ``isaaclab benchmark startup`` — profiles the five startup phases (``app_launch``, ``python_imports``,
19691969
``task_config``, ``env_creation``, ``first_step``) with ``cProfile`` and emits a
19701970
``StartupBundle``.
1971-
* ``play.py`` — **new in 3.0** — loads a trained checkpoint and benchmarks policy inference
1971+
* ``isaaclab benchmark play`` — **new in 3.0** — loads a trained checkpoint and benchmarks policy inference
19721972
for the RL library selected with ``--rl_library``, emitting a ``PlayBundle`` (inference
19731973
throughput plus the policy's reward, episode length, and success rate). It consumes the
1974-
checkpoints produced by ``training.py``; 2.x had no per-backend play benchmark.
1974+
checkpoints produced by the training workflow; 2.x had no per-backend play benchmark.
19751975

19761976
The wrapper shell runners that drove these benchmarks — ``run_non_rl_benchmarks.sh`` and
19771977
``run_training_benchmarks.sh`` — were removed as well; their behavior is now expressed
1978-
directly through script arguments and ``presets=`` tokens.
1978+
directly through command arguments and ``presets=`` tokens.
1979+
1980+
The benchmark framework itself moved from :mod:`isaaclab.test.benchmark` to
1981+
:mod:`isaaclab.benchmark`. The old namespace and the transitional runtime, startup,
1982+
training, and play scripts were removed; update imports and invocations to the public
1983+
module and unified command.
19791984

19801985
.. note::
19811986

@@ -2001,30 +2006,30 @@ Map each old invocation to its replacement:
20012006
* - Isaac Lab 2.x
20022007
- Isaac Lab 3.0
20032008
* - ``benchmark_non_rl.py``
2004-
- ``runtime.py`` (no ``--rl_library`` dispatch)
2009+
- ``isaaclab benchmark runtime`` (no ``--rl_library`` dispatch)
20052010
* - ``benchmark_startup.py``
2006-
- ``startup.py``
2011+
- ``isaaclab benchmark startup``
20072012
* - ``benchmark_rsl_rl.py``
2008-
- ``training.py --rl_library rsl_rl``
2013+
- ``isaaclab benchmark training --rl_library rsl_rl``
20092014
* - ``benchmark_rlgames.py``
2010-
- ``training.py --rl_library rl_games``
2015+
- ``isaaclab benchmark training --rl_library rl_games``
20112016
* - *(newly supported)*
2012-
- ``training.py --rl_library skrl``
2017+
- ``isaaclab benchmark training --rl_library skrl``
20132018
* - *(newly supported)*
2014-
- ``training.py --rl_library sb3``
2019+
- ``isaaclab benchmark training --rl_library sb3``
20152020
* - *(newly supported)*
2016-
- ``play.py --rl_library {rsl_rl,rl_games,skrl,sb3}``
2021+
- ``isaaclab benchmark play --rl_library {rsl_rl,rl_games,skrl,sb3}``
20172022

20182023
SKRL and Stable-Baselines3 had no dedicated benchmark script in 2.x; both are now supported
2019-
through the same ``--rl_library`` dispatch on ``training.py``. ``play.py`` is likewise new in
2020-
3.0: it benchmarks inference of a checkpoint trained by ``training.py`` for any of the four
2024+
through the same ``--rl_library`` dispatch on ``isaaclab benchmark training``. ``isaaclab benchmark play`` is likewise new in
2025+
3.0: it benchmarks inference of a checkpoint trained by the training workflow for any of the four
20212026
RL libraries.
20222027

20232028
Running Benchmarks
20242029
------------------
20252030

20262031
The physics (and rendering) backend is selected with Hydra preset tokens — ``presets=``,
2027-
exactly as for ``train.py``. There is no ``--physics`` or ``--render`` flag; pass
2032+
exactly as for the training workflow. There is no ``--physics`` or ``--render`` flag; pass
20282033
``presets=physx``, ``presets=newton_mjwarp``, etc. to choose the backend.
20292034

20302035
**Before (Isaac Lab 2.x):**
@@ -2061,47 +2066,23 @@ exactly as for ``train.py``. There is no ``--physics`` or ``--render`` flag; pas
20612066
20622067
**After (Isaac Lab 3.0):**
20632068

2064-
.. tab-set::
2065-
2066-
.. tab-item:: uv (Recommended)
2067-
2068-
.. code-block:: bash
2069-
2070-
# Non-RL (random-action) runtime benchmark — PhysX (default)
2071-
uv run python scripts/benchmarks/runtime.py --task Isaac-Cartpole-Direct
2072-
2073-
# Same benchmark on Newton/MJWarp — select the backend via presets=
2074-
uv run python scripts/benchmarks/runtime.py --task Isaac-Cartpole-Direct presets=newton_mjwarp
2075-
2076-
# Training benchmark — choose the RL library with --rl_library
2077-
uv run python scripts/benchmarks/training.py --task Isaac-Cartpole-Direct --rl_library rsl_rl
2078-
uv run python scripts/benchmarks/training.py --task Isaac-Cartpole-Direct --rl_library skrl presets=newton_mjwarp
2079-
2080-
# Play (inference) benchmark — loads a checkpoint produced by training.py
2081-
uv run python scripts/benchmarks/play.py --task Isaac-Cartpole-Direct --rl_library rsl_rl --checkpoint /path/to/model.pt
2082-
2083-
# Startup profiling
2084-
uv run python scripts/benchmarks/startup.py --task Isaac-Cartpole-Direct presets=newton_mjwarp
2085-
2086-
.. tab-item:: isaaclab.sh / isaaclab.bat
2087-
2088-
.. code-block:: bash
2069+
.. code-block:: bash
20892070
2090-
# Non-RL (random-action) runtime benchmark — PhysX (default)
2091-
./isaaclab.sh -p scripts/benchmarks/runtime.py --task Isaac-Cartpole-Direct
2071+
# Non-RL (random-action) runtime benchmark — PhysX (default)
2072+
uv run isaaclab benchmark runtime --task Isaac-Cartpole-Direct
20922073
2093-
# Same benchmark on Newton/MJWarp — select the backend via presets=
2094-
./isaaclab.sh -p scripts/benchmarks/runtime.py --task Isaac-Cartpole-Direct presets=newton_mjwarp
2074+
# Same benchmark on Newton/MJWarp — select the backend via presets=
2075+
uv run isaaclab benchmark runtime --task Isaac-Cartpole-Direct presets=newton_mjwarp
20952076
2096-
# Training benchmark — choose the RL library with --rl_library
2097-
./isaaclab.sh -p scripts/benchmarks/training.py --task Isaac-Cartpole-Direct --rl_library rsl_rl
2098-
./isaaclab.sh -p scripts/benchmarks/training.py --task Isaac-Cartpole-Direct --rl_library skrl presets=newton_mjwarp
2077+
# Training benchmark — choose the RL library with --rl_library
2078+
uv run isaaclab benchmark training --task Isaac-Cartpole-Direct --rl_library rsl_rl
2079+
uv run isaaclab benchmark training --task Isaac-Cartpole-Direct --rl_library skrl presets=newton_mjwarp
20992080
2100-
# Play (inference) benchmark — loads a checkpoint produced by training.py
2101-
./isaaclab.sh -p scripts/benchmarks/play.py --task Isaac-Cartpole-Direct --rl_library rsl_rl --checkpoint /path/to/model.pt
2081+
# Play (inference) benchmark — loads a checkpoint produced by training
2082+
uv run isaaclab benchmark play --task Isaac-Cartpole-Direct --rl_library rsl_rl --checkpoint /path/to/model.pt
21022083
2103-
# Startup profiling
2104-
./isaaclab.sh -p scripts/benchmarks/startup.py --task Isaac-Cartpole-Direct presets=newton_mjwarp
2084+
# Startup profiling
2085+
uv run isaaclab benchmark startup --task Isaac-Cartpole-Direct presets=newton_mjwarp
21052086
21062087
Output Format
21072088
-------------
@@ -2112,46 +2093,37 @@ comma-separated list to emit several formats at once. Supported values are ``sch
21122093
``omniperf``, ``osmo``, ``json``, and ``summary`` (legacy long-form aliases such as
21132094
``OmniPerfKPIFile`` are still accepted).
21142095

2115-
.. tab-set::
2116-
2117-
.. tab-item:: uv (Recommended)
2118-
2119-
.. code-block:: bash
2120-
2121-
# Emit the typed schema bundle and an OmniPerf KPI file in one run
2122-
uv run python scripts/benchmarks/runtime.py --task Isaac-Cartpole-Direct \
2123-
--benchmark_formatter schema,omniperf
2124-
2125-
.. tab-item:: isaaclab.sh / isaaclab.bat
2126-
2127-
.. code-block:: bash
2096+
.. code-block:: bash
21282097
2129-
# Emit the typed schema bundle and an OmniPerf KPI file in one run
2130-
./isaaclab.sh -p scripts/benchmarks/runtime.py --task Isaac-Cartpole-Direct \
2131-
--benchmark_formatter schema,omniperf
2098+
# Emit the typed schema bundle and an OmniPerf KPI file in one run
2099+
uv run isaaclab benchmark runtime --task Isaac-Cartpole-Direct \
2100+
--benchmark_formatter schema,omniperf
21322101
21332102
Migration Steps
21342103
---------------
21352104

21362105
If you have custom benchmark scripts or CI based on Isaac Lab 2.x:
21372106

2138-
1. **Replace the old entry points** — swap ``benchmark_non_rl.py`` for ``runtime.py``,
2139-
``benchmark_startup.py`` for ``startup.py``, and the per-library training scripts for
2140-
``training.py --rl_library <lib>``.
2107+
1. **Replace the old entry points** — swap ``benchmark_non_rl.py`` for ``isaaclab benchmark runtime``,
2108+
``benchmark_startup.py`` for ``isaaclab benchmark startup``, and the per-library training scripts for
2109+
``isaaclab benchmark training --rl_library <lib>``.
2110+
2111+
2. **Update benchmark imports** — replace ``isaaclab.test.benchmark`` with
2112+
``isaaclab.benchmark``. The old namespace is no longer available.
21412113

2142-
2. **Drop the wrapper runners** — ``run_non_rl_benchmarks.sh`` and
2114+
3. **Drop the wrapper runners** — ``run_non_rl_benchmarks.sh`` and
21432115
``run_training_benchmarks.sh`` no longer exist; express their behavior with script
21442116
arguments and ``presets=`` tokens. ``run_physx_benchmarks.sh`` is also gone — invoke the
21452117
PhysX micro-benchmarks under ``source/isaaclab_physx/benchmark/`` directly instead.
21462118

2147-
3. **Select the backend with** ``presets=`` — replace any per-backend script choice with a
2119+
4. **Select the backend with** ``presets=`` — replace any per-backend script choice with a
21482120
``presets=`` (and, if needed, rendering) token on a single unified script. Update custom
21492121
benchmark configs to the ``PresetCfg`` pattern.
21502122

2151-
4. **Pick the output format with** ``--benchmark_formatter`` — default ``schema``; pass a
2123+
5. **Pick the output format with** ``--benchmark_formatter`` — default ``schema``; pass a
21522124
comma-separated list for multiple formats.
21532125

2154-
5. **Test both backends** — verify your benchmarks pass with ``presets=physx`` (default) and
2126+
6. **Test both backends** — verify your benchmarks pass with ``presets=physx`` (default) and
21552127
``presets=newton_mjwarp``.
21562128

21572129
For a complete guide to multi-backend support, see the "Multi-Backend Support: PresetCfg

0 commit comments

Comments
 (0)