Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
141 commits
Select commit Hold shift + click to select a range
ce4db9c
Reset only masked environments in Newton and OVPhysX assets
hujc7 Sep 30, 2026
116e021
Forward the reset mask to every Warp scene entity
hujc7 Sep 30, 2026
88b1ba2
Write collection masks and reset ray-caster drift without host sync
hujc7 Sep 30, 2026
16ee932
Read history_order as a group setting in the Warp observation manager
hujc7 Sep 30, 2026
7949cb9
Write fixed tendon masks on Newton articulations without host sync
hujc7 Sep 30, 2026
12bd5a9
Make masked native-actuator and ray-caster resets capturable
hujc7 Sep 30, 2026
eb458ca
Write Newton tendon targets every step so captured commands apply
hujc7 Sep 30, 2026
b358e1a
Capture Warp frontend stages without an eager warm-up
hujc7 Sep 30, 2026
d0b411a
Reset Warp manager-based environments by mask
hujc7 Sep 30, 2026
d528675
Make stateful Warp event terms classes
hujc7 Sep 30, 2026
80cacc6
Test event capture through the recorded reset stage
hujc7 Sep 30, 2026
ca4eefb
Decide Warp stage capture per term
hujc7 Sep 30, 2026
eb61420
Drop the removed fixed-tendon mask conversion from the sync gate
hujc7 Sep 30, 2026
bf58395
Decide Warp term capturability from each term's parameters
hujc7 Sep 30, 2026
ab709eb
Let physics own decimation in the Warp environments
hujc7 Sep 30, 2026
3ac3db4
Store terminal observations in the Warp environments
hujc7 Sep 30, 2026
e6fcbba
Return copies of the logged values from the Warp environments
hujc7 Sep 30, 2026
a1743b7
Return copies of the reset log from the base Warp environment
hujc7 Sep 30, 2026
1e520d6
Run command terms through the Warp command manager
hujc7 Sep 30, 2026
1454ebd
Add a Warp height_scan twin for the rough velocity tasks
hujc7 Sep 30, 2026
a26abb3
Keep external Warp terms on the Warp frontend
hujc7 Sep 30, 2026
565740d
Run base_height_l2 eagerly when it reads a height scanner
hujc7 Sep 30, 2026
9443fe0
Record Warp stages again when a term configuration changes
hujc7 Sep 30, 2026
1252efc
Document the Warp capture contract and rough task support
hujc7 Sep 30, 2026
cb24464
Record Warp observation stages again when a term configuration changes
hujc7 Sep 30, 2026
3f906eb
Record Warp stages again only when a term configuration changes
hujc7 Sep 30, 2026
12a3b4a
Merge remote-tracking branch 'upstream/develop' into jichuanh/warp-sc…
hujc7 Oct 1, 2026
adfd1ad
Merge branch 'jichuanh/warp-scene-mask-native' into jichuanh/warp-fro…
hujc7 Oct 1, 2026
5727c6d
Merge branch 'jichuanh/warp-frontend-cleanup' into jichuanh/warp-fron…
hujc7 Oct 1, 2026
29b25ec
Merge remote-tracking branch 'upstream/develop' into jichuanh/warp-sc…
hujc7 Oct 1, 2026
2bb8e9e
Resolve adapter reset ids through preallocated masks
hujc7 Oct 1, 2026
edc61c8
Reset Isaac Lab actuator models from the environment mask
hujc7 Oct 1, 2026
e89284a
Reset surface grippers by index in the Warp scene
hujc7 Oct 1, 2026
8b2a161
Drop float from the fixed-tendon position limit type
hujc7 Oct 1, 2026
4fb4e01
Rename the fixed-tendon mask helper and move it beside its setters
hujc7 Oct 1, 2026
3c5e2de
Reuse the shared masked-copy kernel for tendon and link-pose writes
hujc7 Oct 1, 2026
ea94e20
Rename the collection body-mask resolver to _resolve_body_mask
hujc7 Oct 1, 2026
3f26cfa
Pass masks explicitly to actuator models, native actuators and delay …
hujc7 Oct 1, 2026
75de1d9
Forward env_mask through PhysX asset resets
hujc7 Oct 1, 2026
6ac6061
Share one per-environment Warp RNG state through WarpRng
hujc7 Oct 1, 2026
7966bba
Merge remote-tracking branch 'upstream/develop' into jichuanh/warp-sc…
hujc7 Oct 1, 2026
69c13a6
Point the Warp migration guide at WarpRng.state
hujc7 Oct 1, 2026
f846372
Allocate the scratch body mask in the Newton collection test helper
hujc7 Oct 1, 2026
11e36c4
Reset Multirotor thrusters and test actuator stubs from the environme…
hujc7 Oct 1, 2026
9328d98
Defer annotations in the seed module so the docs import it with Warp …
hujc7 Oct 1, 2026
e86c3c4
Merge remote-tracking branch 'upstream/develop' into jichuanh/warp-sc…
hujc7 Oct 1, 2026
e06ab39
Merge branch 'jichuanh/warp-scene-mask-native' into jichuanh/warp-fro…
hujc7 Oct 2, 2026
ee9e8ad
Record Warp stages per call and step the Warp environments like stable
hujc7 Oct 2, 2026
5ad9281
Merge remote-tracking branch 'upstream/develop' into jichuanh/warp-fr…
hujc7 Oct 2, 2026
4ed7151
Merge branch 'jichuanh/warp-frontend-cleanup' into jichuanh/warp-fron…
hujc7 Oct 4, 2026
bd5a5a0
Record Warp stages again only when a set term configuration changes
hujc7 Oct 4, 2026
76fb382
Document the Warp capture contract with the per-call capture names
hujc7 Oct 4, 2026
e35945b
Merge remote-tracking branch 'upstream/develop' into jichuanh/warp-sc…
hujc7 Oct 4, 2026
0c8af1d
Merge branch 'jichuanh/warp-scene-mask-native' into jichuanh/warp-fro…
hujc7 Oct 4, 2026
ab9a5c4
Merge branch 'jichuanh/warp-frontend-cleanup' into jichuanh/warp-fron…
hujc7 Oct 4, 2026
e9535c6
Merge remote-tracking branch 'upstream/main' into jichuanh/warp-scene…
hujc7 Oct 20, 2026
326f33a
Merge branch 'jichuanh/warp-scene-mask-native' into jichuanh/warp-fro…
hujc7 Oct 20, 2026
0fb7300
Reach the physics backend through the simulation's backend manager in…
hujc7 Oct 20, 2026
59a1eb8
Merge branch 'jichuanh/warp-frontend-cleanup' into jichuanh/warp-fron…
hujc7 Oct 20, 2026
f6d31ca
Drop the history_order changelog entry that main already ships
hujc7 Oct 20, 2026
eb283d9
Merge branch 'jichuanh/warp-scene-mask-native' into jichuanh/warp-fro…
hujc7 Oct 20, 2026
54b8186
Merge branch 'jichuanh/warp-frontend-cleanup' into jichuanh/warp-fron…
hujc7 Oct 20, 2026
dbb3b12
Merge remote-tracking branch 'upstream/main' into jichuanh/warp-scene…
hujc7 Oct 22, 2026
2030fe3
Move the shared WarpRng state out of this pull request
hujc7 Oct 22, 2026
3ddcf7e
Share one per-environment Warp RNG state through WarpRng
hujc7 Oct 22, 2026
5f1321c
Merge branch 'jichuanh/warp-rng-shared' into jichuanh/warp-frontend-c…
hujc7 Oct 22, 2026
34e3af1
Merge commit '5f1321c61bea825ef67181d7472d952ffeb89337' into jichuanh…
hujc7 Oct 22, 2026
5676dd1
Add resolve_ids next to resolve_1d_mask as the shared id and mask hel…
hujc7 Oct 26, 2026
97e5662
Resolve sensor, camera and wrench composer selections through the sha…
hujc7 Oct 26, 2026
92590d0
Fix the deformable mask writers that raised on any env mask
hujc7 Oct 26, 2026
f044c92
Resolve Newton selections through the shared helpers and write its ma…
hujc7 Oct 26, 2026
7b48c38
Resolve OVPhysX selections through the shared helpers
hujc7 Oct 26, 2026
3d3661f
Resolve PhysX selections through the shared helpers
hujc7 Oct 26, 2026
b455d35
Merge jichuanh/id-mask (#8821) into jichuanh/warp-scene-mask-native
hujc7 Oct 26, 2026
a9f7c50
Merge remote-tracking branch 'upstream/main' into jichuanh/warp-scene…
hujc7 Oct 26, 2026
3846f49
Merge branch 'jichuanh/warp-scene-mask-native' into jichuanh/warp-rng…
hujc7 Oct 26, 2026
009c820
Merge branch 'jichuanh/warp-rng-shared' into jichuanh/warp-frontend-c…
hujc7 Oct 26, 2026
778e20f
Merge branch 'jichuanh/warp-frontend-cleanup' into jichuanh/warp-fron…
hujc7 Oct 26, 2026
6c31123
Write Newton tendon targets behind the host flag again
hujc7 Oct 26, 2026
fd7c803
Merge branch 'jichuanh/warp-frontend-cleanup' into jichuanh/warp-fron…
hujc7 Oct 26, 2026
121ed8a
Merge branch 'jichuanh/warp-rng-shared' into jichuanh/warp-frontend-c…
hujc7 Oct 26, 2026
fdd4f5e
Merge branch 'jichuanh/warp-scene-mask-native' into jichuanh/warp-rng…
hujc7 Oct 26, 2026
44021e5
Reset only the masked environments from the stable scene
hujc7 Oct 26, 2026
43bb968
Merge remote-tracking branch 'upstream/main' into jichuanh/id-mask
hujc7 Oct 26, 2026
93daa9b
Merge branch 'jichuanh/id-mask' into jichuanh/warp-scene-mask-native
hujc7 Oct 26, 2026
c2d540b
Check the Warp command and external-term contracts without env builds
hujc7 Oct 27, 2026
e390289
Trim duplicate id-resolution and mask-writer tests
hujc7 Oct 27, 2026
1d17a83
Trim redundant builds and layout checks from the capture tests
hujc7 Oct 27, 2026
2048c62
Trim redundant setup from the masked-reset tests
hujc7 Oct 27, 2026
6318c47
Drop unused WarpRng setup from the parity tests
hujc7 Oct 27, 2026
9eec506
Merge the Part 4 head first so the newest commit shows this part's ow…
hujc7 Oct 27, 2026
e74ad95
Raise a clear error on a masked ray-caster reset without WarpRng state
hujc7 Oct 27, 2026
0402115
Merge branch 'jichuanh/id-mask' into jichuanh/warp-scene-mask-native
hujc7 Oct 27, 2026
3202c70
Merge branch 'jichuanh/warp-scene-mask-native' into jichuanh/warp-rng…
hujc7 Oct 27, 2026
1d89726
Merge branch 'jichuanh/warp-rng-shared' into jichuanh/warp-frontend-c…
hujc7 Oct 27, 2026
dde787b
Merge branch 'jichuanh/warp-frontend-cleanup' into jichuanh/warp-fron…
hujc7 Oct 27, 2026
38721ea
Resample masked ray-caster drift from the device mask
hujc7 Oct 27, 2026
0e9e57d
Pass the reset mask to actuator models only when one is given
hujc7 Oct 27, 2026
59f9cf5
Accept env_mask in the multirotor reset
hujc7 Oct 27, 2026
d8d4911
Match the base reset selector type in the actuator overrides
hujc7 Oct 27, 2026
13ec11c
Accept every id form main accepted in resolve_1d_mask
hujc7 Oct 27, 2026
784b0a2
Refresh the solver on every replay of the Newton tendon mask writer
hujc7 Oct 27, 2026
6a4f173
Tidy the mask writers, their docs and the selection tests
hujc7 Oct 27, 2026
bc9a8bb
Reject Newton masks whose length differs from the asset dimension
hujc7 Oct 27, 2026
981e3a4
Accept strided torch limits in the Newton tendon position limit mask …
hujc7 Oct 27, 2026
cff8f86
Run the tendon replay test before the module's shared scene opens
hujc7 Oct 27, 2026
bbb5104
Revert "Reject Newton masks whose length differs from the asset dimen…
hujc7 Oct 27, 2026
029ee47
Resolve the Newton collection writer masks inline again
hujc7 Oct 27, 2026
551e508
Launch the rewritten Newton mask writers over the mask lengths
hujc7 Oct 27, 2026
86ce1c9
Write the rewritten Newton mask writers through a core masked write
hujc7 Oct 27, 2026
0b464e2
Merge branch 'jichuanh/id-mask' into jichuanh/warp-scene-mask-native
hujc7 Oct 27, 2026
0038bae
Merge branch 'jichuanh/warp-scene-mask-native' into jichuanh/warp-rng…
hujc7 Oct 27, 2026
ef1d994
Merge branch 'jichuanh/warp-frontend-cleanup' into jichuanh/warp-fron…
hujc7 Oct 27, 2026
6a9e461
Merge branch 'jichuanh/warp-rng-shared' into jichuanh/warp-frontend-c…
hujc7 Oct 27, 2026
82587c8
Raise the modifiers deprecation warning at the caller of the Warp obs…
hujc7 Oct 28, 2026
b37d231
Merge upstream main 6ef40d19a6f into jichuanh/id-mask
hujc7 Oct 28, 2026
e1c666f
Merge jichuanh/id-mask (upstream main 6ef40d19a6f) into jichuanh/warp…
hujc7 Oct 28, 2026
798cfaa
Merge jichuanh/warp-scene-mask-native (upstream main 6ef40d19a6f) int…
hujc7 Oct 28, 2026
a76c341
Merge jichuanh/warp-rng-shared (upstream main 6ef40d19a6f) into jichu…
hujc7 Oct 28, 2026
d61c753
Merge jichuanh/warp-frontend-cleanup (upstream main 6ef40d19a6f) into…
hujc7 Oct 28, 2026
ccfe282
Import the root-to-body velocity helpers from the shared Warp math
hujc7 Oct 28, 2026
dc2aba6
Align resolve_ids and write_2d_with_mask with the shared memory helpers
hujc7 Oct 29, 2026
1bbc0f4
Merge branch 'jichuanh/id-mask' into jichuanh/warp-scene-mask-native-…
hujc7 Oct 29, 2026
401505e
Merge branch 'jichuanh/warp-scene-mask-native-push' into jichuanh/war…
hujc7 Oct 29, 2026
8262b83
Merge branch 'jichuanh/warp-rng-shared' into jichuanh/warp-frontend-c…
hujc7 Oct 29, 2026
8223de7
Merge branch 'jichuanh/warp-frontend-cleanup-push' into jichuanh/warp…
hujc7 Oct 29, 2026
92a413e
Write strided vector components through scalar views instead of copyi…
hujc7 Oct 29, 2026
2efdac5
Merge branch 'jichuanh/id-mask' into jichuanh/warp-scene-mask-native-…
hujc7 Oct 29, 2026
c4932c4
Merge branch 'jichuanh/warp-scene-mask-native-push' into jichuanh/war…
hujc7 Oct 29, 2026
e57cd10
Merge branch 'jichuanh/warp-rng-shared' into jichuanh/warp-frontend-c…
hujc7 Oct 29, 2026
1c23be3
Merge branch 'jichuanh/warp-frontend-cleanup-push' into jichuanh/warp…
hujc7 Oct 29, 2026
efee1b9
Update camera poses on reset through the resolved mask
hujc7 Oct 29, 2026
6ea8b42
Merge branch 'jichuanh/id-mask' into jichuanh/warp-scene-mask-native-…
hujc7 Oct 29, 2026
b0b808f
Merge branch 'jichuanh/warp-scene-mask-native-push' into jichuanh/war…
hujc7 Oct 29, 2026
fe3cee2
Merge branch 'jichuanh/warp-rng-shared' into jichuanh/warp-frontend-c…
hujc7 Oct 29, 2026
3b4b211
Merge branch 'jichuanh/warp-frontend-cleanup-push' into jichuanh/warp…
hujc7 Oct 29, 2026
b7d5295
Merge remote-tracking branch 'upstream/main' into jichuanh/id-mask
hujc7 Oct 29, 2026
e0e6e22
Merge branch 'jichuanh/id-mask' into jichuanh/warp-scene-mask-native-…
hujc7 Oct 29, 2026
03dfb44
Merge branch 'jichuanh/warp-scene-mask-native-push' into jichuanh/war…
hujc7 Oct 29, 2026
a39ce7a
Merge branch 'jichuanh/warp-rng-shared' into jichuanh/warp-frontend-c…
hujc7 Oct 29, 2026
4a1ba1b
Merge branch 'jichuanh/warp-frontend-cleanup-push' into jichuanh/warp…
hujc7 Oct 29, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -14,16 +14,12 @@ The following classes are part of the public :mod:`isaaclab_experimental.envs` A
:nosignatures:

DirectRLEnvWarp
InteractiveSceneWarp
ManagerBasedEnvWarp
ManagerBasedRLEnvWarp

.. autoclass:: DirectRLEnvWarp
:show-inheritance:

.. autoclass:: InteractiveSceneWarp
:show-inheritance:

.. autoclass:: ManagerBasedEnvWarp
:show-inheritance:

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,15 +13,13 @@ The following classes are part of the public :mod:`isaaclab_experimental.utils`
.. autosummary::
:nosignatures:

ManagerCallMode
ManagerCallSwitch
WarpGraphCache
CapturedStage
captured
eager

.. autoclass:: ManagerCallMode
.. autoclass:: CapturedStage
:show-inheritance:

.. autoclass:: ManagerCallSwitch
:show-inheritance:
.. autofunction:: captured

.. autoclass:: WarpGraphCache
:show-inheritance:
.. autofunction:: eager
154 changes: 132 additions & 22 deletions docs/source/concepts/warp_environments.rst
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,10 @@ Warp Environments
The warp environment infrastructure lives in ``isaaclab_experimental`` and
``isaaclab_tasks_experimental``. It's an experimental feature.

Experimental Warp environments compute observations, rewards, resets, and actions
in Warp kernels. CUDA graph capture reduces Python overhead during execution.
Experimental Warp environments compute MDP terms (observations, rewards, terminations, events, commands,
and actions) in Warp kernels and record the capturable terms of each manager stage into CUDA graphs, which
reduces Python overhead during execution. Scene writes, actuator models, the stable curriculum and recorder
managers, and terms marked non-capturable still run eagerly.

Here, **stable** means the default Torch environments in ``isaaclab`` and
``isaaclab_tasks``. Pass ``--frontend warp`` to use their experimental Warp counterparts.
Expand Down Expand Up @@ -94,19 +96,28 @@ MDP term for its warp twin). Select the Newton solver explicitly with
- ``Isaac-Velocity-Flat-G1``
- ``Isaac-Velocity-Flat-H1``
- ``Isaac-Velocity-Flat-UnitreeGo2``
- ``Isaac-Velocity-Rough-AnymalD``
- ``Isaac-Velocity-Rough-Cassie``
- ``Isaac-Velocity-Rough-G1``
- ``Isaac-Velocity-Rough-H1``
- ``Isaac-Velocity-Rough-UnitreeGo2``

The following contributed tasks also have full twin coverage:

- ``IsaacContrib-Velocity-Flat-AnymalB``
- ``IsaacContrib-Velocity-Flat-AnymalC``
- ``IsaacContrib-Velocity-Flat-UnitreeA1``
- ``IsaacContrib-Velocity-Flat-UnitreeGo1``
- ``IsaacContrib-Velocity-Rough-AnymalB``
- ``IsaacContrib-Velocity-Rough-AnymalC``
- ``IsaacContrib-Velocity-Rough-UnitreeA1``
- ``IsaacContrib-Velocity-Rough-UnitreeGo1``

A missing twin is a hard error listing the affected terms, so a partially
covered task fails at build time rather than silently changing behavior.
Rough-terrain velocity configurations that use ``height_scan`` cannot currently be
adapted: that observation term has no Warp twin. Check the terms used by a task rather
than assuming that every terrain configuration has the same limitation.
The Rough tasks keep the stable terrain curriculum. Their ``height_scan``
observation, and ``base_height_l2`` when it reads the height scanner, read a ray
caster whose refresh is decided on the host, so these terms run eagerly.


Performance Comparison
Expand Down Expand Up @@ -251,6 +262,10 @@ specific to warp envs; for Newton physics features and related guides see
- Some scene-side operations (asset write, actuator models, certain sensor types) still go
through torch. They participate in the step but are not yet captured into the graph; they
set the lower bound on observed step time.
- A term marked ``@WarpCapturable(False)``, or rejected by its parameter predicate, runs eagerly
between the recorded graphs of its stage. Observation, reward, termination, command and action
stages run their eager terms before the recorded ones; event stages keep the configured order, so
an eager event term splits its stage into several graphs.
- Sensors that depend on the Kit RTX renderer (camera-based observations) cannot be combined
with the warp env path — they need Kit, which the warp runtime does not initialise.

Expand Down Expand Up @@ -377,11 +392,12 @@ Project Structure
Warp-specific implementations that diverge from the torch-based managers and env classes live in the ``_experimental`` packages:

- ``isaaclab_experimental`` — warp managers, base env classes, warp MDP terms
- ``isaaclab_tasks_experimental`` — warp task configs and task-specific MDP terms
- ``isaaclab_tasks_experimental`` — task-specific warp MDP terms and direct warp envs

Any new warp implementation that differs from the torch-based managers or env classes belongs in these packages.
Warp task configs reference Newton physics directly (no ``PresetCfg``) since the warp path
is Newton-only.
Task configurations are not duplicated: ``--frontend warp`` builds the environment from the stable task
configuration with Newton physics selected. The experimental packages mirror the stable module tree, and each
stable term is replaced by the same-named warp term of the mirrored ``mdp`` package (its *twin*). A term
without a twin is a build-time error.


Writing Warp MDP Terms
Expand All @@ -390,15 +406,16 @@ Writing Warp MDP Terms
Imports
"""""""

Warp task configs import from the experimental packages:
Warp terms import the warp managers' helpers from the experimental packages:

.. code-block:: python

# Warp
from isaaclab_experimental.managers import ObservationTermCfg, RewardTermCfg, SceneEntityCfg
import isaaclab_experimental.envs.mdp as mdp
from isaaclab_experimental.managers import ManagerTermBase, SceneEntityCfg
from isaaclab_experimental.utils.warp import WarpCapturable

The term config classes have the same interface — only the import path changes.
Term configurations keep the stable config classes (for example
:class:`~isaaclab.managers.RewardTermCfg` and the command configurations in :mod:`isaaclab.envs.mdp`);
the frontend only replaces their ``func`` or ``class_type``.


Common Pattern
Expand Down Expand Up @@ -471,7 +488,10 @@ array. This is resolved via a fallback chain (see

3. **Legacy params**: ``term_dim``, ``out_dim``, or ``obs_dim`` keys in ``term_cfg.params``.

4. **Asset config fallback**: Count of ``asset_cfg.joint_ids`` (or ``joint_ids_wp``) for
4. **Ray-caster fallback**: Number of rays of the sensor in ``sensor_cfg``, for terms that
write one value per ray (e.g. ``height_scan``).

5. **Asset config fallback**: Count of ``asset_cfg.joint_ids`` (or ``joint_ids_wp``) for
joint-level terms.


Expand All @@ -493,7 +513,8 @@ checks the mask to skip non-selected environments:
return
# ... modify state for selected envs only

- RNG uses per-env ``env.rng_state_wp`` (``wp.uint32``) instead of ``torch.rand``
- RNG uses the per-env :attr:`WarpRng.state <isaaclab.utils.seed.WarpRng.state>` (``wp.uint32``) instead of
``torch.rand``
- **Startup/prestartup** events use the torch convention ``(env, env_ids, **params)``
- **Reset/interval** events use the warp convention ``(env, env_mask, **params)``

Expand All @@ -509,15 +530,96 @@ buffers.

.. _warp-env-capture-safety:

Command Terms
"""""""""""""

Command terms subclass :class:`isaaclab_experimental.managers.CommandTerm`. They keep their command and
metrics in persistent ``wp.array`` buffers and resample the environments selected by a mask with
:attr:`WarpRng.state <isaaclab.utils.seed.WarpRng.state>`; the command manager records ``compute`` and
``reset`` like the other managers.
Warp terms read a command with ``env.command_manager.get_command_wp(name)`` on every call instead of
caching it, so a term never holds another environment's buffer.


Capture Safety
""""""""""""""

When writing terms that run inside the captured step loop, keep in mind:
Each manager method decorated with :func:`~isaaclab_experimental.utils.captured` is a stage (for example
``RewardManager.compute``, or the ``_reset`` that ``CommandManager.reset`` calls with the reset mask): its
first call records it into CUDA graphs and later calls replay them. That first call is the recording
itself; there is no eager warm-up. A stage records again when it receives a different array or scalar
argument, and every graph is dropped when the physics backend rebinds its buffers or stops. Only device
work is replayed: Python in a recorded term runs once, while the stage records.

Keeping a term safe to record is the author's contract; a synchronization check catches only
part of it:

- **Allocate in** ``__init__`` — class terms allocate every buffer before their first call and
function terms allocate nothing. A buffer allocated while recording belongs to the graph.
- **Write into persistent buffers** — outputs, metrics and state are ``wp.array`` buffers that are
overwritten in place, never replaced. Values returned for logging, for example from ``reset``,
are persistent views over such buffers.
- **Select environments with** ``env_mask`` — kernels launch over ``num_envs`` and test the mask.
Converting a mask to indices (``nonzero``) or reading device values on the host (``.item()``,
``.cpu()``, ``.numpy()``) synchronizes the device and cannot be recorded. Only the environment
base classes do it, once per step, to decide whether any environment resets.
- **Read asset data when called** — pass sim-bound (Tier 1) buffers such as ``root_link_pose_w``
and ``root_com_vel_w`` to the kernel and compute derived quantities inline. Lazily computed
properties refresh through a host-side timestamp that does not replay, and a view cached across
a rebind points at freed memory.
- **Change settings through the managers** — a scalar read in Python, such as a configuration value
or ``env.common_step_counter``, is frozen into the graph when the stage records. The managers'
``set_term_cfg`` records their stages again when it changes what they read from a term's configuration
(observation terms are named ``"<group>/<term>"``), and the ``modify_reward_weight`` and
``modify_term_cfg`` curricula go through it, so an observation noise curriculum applies to recorded
observations. Setting an unchanged configuration keeps the recorded stages. Reward weights are read on
the device, so a weight change applies without recording again, unless the weight turns zero or nonzero,
which takes the term out of the stage or puts it back. A value that changes every step belongs in a
device buffer that the kernel reads. Writing a term configuration directly, bypassing ``set_term_cfg``,
is not supported while stages are recorded.
- **Mark host-dependent terms** — a term that relies on host-side work, such as a sensor whose
refresh is decided on the host, is decorated with ``@WarpCapturable(False, reason=...)``. Its stage
calls it through :func:`~isaaclab_experimental.utils.eager`, between recorded graphs, on every call,
and it raises if it is ever called while a stage records. When only some configurations need the host,
pass a predicate over the term's parameters, e.g.
``@WarpCapturable(lambda params: params.get("sensor_cfg") is None, reason=...)``. On a class term the
annotation covers its call; decorate its ``reset`` method to keep the reset out of the recording. A
command term's class annotation covers both its ``compute`` and its ``reset``. ``height_scan``,
``base_height_l2`` with a height scanner and the rigid-body randomization events are examples.

Setting :attr:`CapturedStage.enabled <isaaclab_experimental.utils.CapturedStage.enabled>` to ``False``
after the environment is built runs every stage eagerly, and ``ISAACLAB_SYNC_DEBUG=1`` makes a hidden
device-to-host synchronization inside an eager stage raise. Comparing an eager and a captured
rollout of the same seeded task is the end-to-end check.

Terms from Other Packages
"""""""""""""""""""""""""

Terms defined outside the mirrored packages, for example in an external project, have no twins.
The frontend uses them unchanged when they are warp terms: a class term that subclasses
:class:`isaaclab_experimental.managers.ManagerTermBase` (warp action and command terms included),
or a function term that declares its capture behavior with ``@WarpCapturable(True)`` or
``@WarpCapturable(False, reason=...)``. Any other term from such a package is rejected, even when a
built-in warp term has the same name.

.. code-block:: python

import warp as wp

from isaaclab_experimental.utils.warp import WarpCapturable


@wp.kernel
def _upright_kernel(pose: wp.array(dtype=wp.transformf), out: wp.array(dtype=wp.float32)):
i = wp.tid()
up = wp.quat_rotate(wp.transform_get_rotation(pose[i]), wp.vec3f(0.0, 0.0, 1.0))
out[i] = up[2]


- **No ``wp.to_torch``** or torch arithmetic — stay in warp throughout
- **No lazy-evaluated properties** — use sim-bound (Tier 1) data directly; if a derived
quantity is needed, compute it inline in the kernel
- **No dynamic allocation** — all buffers must be pre-allocated in ``__init__``
@WarpCapturable(True)
def upright_bonus(env, out, asset_cfg) -> None:
asset = env.scene[asset_cfg.name]
wp.launch(_upright_kernel, dim=env.num_envs, inputs=[asset.data.root_link_pose_w.warp, out])


Parity Testing
Expand Down Expand Up @@ -564,6 +666,9 @@ This test should always be run, even for terms without a torch counterpart.
torch.testing.assert_close(wp.to_torch(out_captured), wp.to_torch(out_uncaptured))

See ``source/isaaclab_experimental/test/envs/mdp/`` for complete parity test examples.
``test_capture_safety.py`` discovers every warp MDP term: a new capturable term needs a ``CAPTURE_SPECS``
entry there, which records the term, overwrites its inputs in place, replays it, and compares the result
with the stable term on the new data.


.. _warp-env-mdp-terms:
Expand All @@ -577,7 +682,7 @@ Available Warp MDP Terms

* - Category
- Available Terms
* - Observations (11)
* - Observations (12)
- | ``base_pos_z``
| ``base_lin_vel``
| ``base_ang_vel``
Expand All @@ -589,6 +694,7 @@ Available Warp MDP Terms
| ``joint_vel_rel``
| ``last_action``
| ``generated_commands``
| ``height_scan``
* - Rewards (16)
- | ``is_alive``
| ``is_terminated``
Expand Down Expand Up @@ -621,6 +727,10 @@ Available Warp MDP Terms
* - Actions (2)
- | ``JointPositionAction``
| ``JointEffortAction``
* - Commands (3)
- | ``UniformVelocityCommand``
| ``UniformPoseCommand``
| ``NullCommand``

Terms not listed here remain in torch only. When using an env that requires unlisted terms,
those terms must be implemented in warp first.
4 changes: 4 additions & 0 deletions source/isaaclab/changelog.d/jichuanh-id-mask.added.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
* Added :func:`~isaaclab.utils.warp.memory.resolve_ids`, which resolves an index selection given as ids or as a
boolean mask to ids on a device, as :func:`~isaaclab.utils.warp.memory.resolve_1d_mask` does to a mask.
* Added :func:`~isaaclab.utils.warp.memory.write_2d_with_mask`, which writes 2-D data or one scalar into a Warp array
where a row mask and a column mask are both true, launching over the mask lengths.
11 changes: 11 additions & 0 deletions source/isaaclab/changelog.d/jichuanh-id-mask.changed.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
* Changed the env selection helpers of :class:`~isaaclab.utils.wrench_composer.WrenchComposer` and
:class:`~isaaclab.sensors.Camera` to resolve ``env_ids`` and ``env_mask`` through
:func:`~isaaclab.utils.warp.memory.resolve_ids` and :func:`~isaaclab.utils.warp.memory.resolve_1d_mask`.
Any integer sequence and slices with a negative step are accepted, ids on another device are moved to the owner's
device, and a :class:`~isaaclab.utils.warp.ProxyArray` is rejected with a :class:`TypeError`. The
:class:`~isaaclab.sensors.Camera` now rejects floating-point ``env_ids`` with a :class:`TypeError` and
multi-dimensional ``env_ids`` with a :class:`ValueError` instead of casting and flattening them.
* Changed :class:`~isaaclab.utils.wrench_composer.WrenchComposer` to resolve ``body_ids`` through
:func:`~isaaclab.utils.warp.memory.resolve_ids` as well, so slices other than ``slice(None)`` are accepted.
* Changed :func:`~isaaclab.utils.warp.memory.resolve_1d_mask` to make ``scratch_mask`` optional for callers that never
pass ids. Their masks are returned as given. Ids without a ``scratch_mask`` raise a :class:`ValueError`.
4 changes: 4 additions & 0 deletions source/isaaclab/changelog.d/jichuanh-id-mask.fixed.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
* Fixed the ``write_nodal_*_to_sim_mask`` methods of :class:`~isaaclab.assets.BaseDeformableObject`, which the
OVPhysX deformable object inherits, raising a :class:`RuntimeError` whenever ``env_mask`` was given.
* Fixed :meth:`~isaaclab.sensors.Camera.reset` with an ``env_mask`` on another device than the camera: the camera
poses are now updated through the mask resolved on the camera's device, like the timestamps and buffers.
Empty file.
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
* Changed :class:`~isaaclab.envs.mdp.curriculums.modify_term_cfg` to hand the modified term configuration back to
the manager's ``set_term_cfg`` after writing a value, so managers that keep values read from the configuration,
such as the recorded stages of the Warp managers, use the new value.
* Changed :class:`~isaaclab.envs.mdp.curriculums.modify_term_cfg` to hand an observation term back to the
observation manager's ``set_term_cfg`` under its ``"<group>/<term>"`` name.
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
* Added :class:`~isaaclab.utils.seed.WarpRng`, the per-environment Warp random number generator state that
environments and sensors share, one per process. :func:`~isaaclab.utils.seed.configure_seed` reseeds it in place,
and environments call :meth:`~isaaclab.utils.seed.WarpRng.initialize` at construction.
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
* Changed masked :meth:`~isaaclab.sensors.ray_caster.BaseRayCaster.reset` to draw its drift from the shared
:class:`~isaaclab.utils.seed.WarpRng` state instead of random states of its own. It raises a ``RuntimeError``
when that state is not initialized.
Empty file.
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
* Added ``env_mask`` to :meth:`~isaaclab.actuators.ActuatorCollection.reset` and
:meth:`~isaaclab.actuators.ActuatorControl.reset_native_actuators`. Isaac Lab actuator models and backend-native
actuator state reset only the masked environments from the mask itself, without converting it to indices.
* Added ``batch_mask`` to :meth:`~isaaclab.utils.buffers.DelayBuffer.set_time_lag` and
:meth:`~isaaclab.utils.buffers.DelayBuffer.reset`, which select batches on the device without synchronizing the
host. Tensor lags set through a mask are full-sized and are not range-checked.
* Added ``env_mask`` to :meth:`~isaaclab.assets.BaseCableObject.reset`, matching the other scene assets.
* Added ``env_mask`` to :meth:`~isaaclab.scene.InteractiveScene.reset`, which forwards the mask to every asset and
sensor so only the masked environments are reset, without synchronizing the host. Surface grippers still reset by
index.
Loading
Loading