Skip to content

Commit 03cee3c

Browse files
authored
Uses the configuration to obtain the simulation device (#3636)
# Description This MR fixes the slow-down observed in recent IsaacLab updates. Previously, the simulation device was read through the configuration; later, this was changed to read the device through the simulation manager. On profiling, I observed that the simulation manager function took 0.01 s per call. This is quite a bit of overhead, considering that `env.device` refers to `sim.device` and gets called at multiple locations in the environment. This MR reverts back to the previous solution for obtaining the device. Fixes #3554 ## Type of change - Bug fix (non-breaking change which fixes an issue) ## Screenshots ``` ./isaaclab.sh -p scripts/benchmarks/benchmark_non_rl.py --task Isaac-Velocity-Flat-Anymal-C-v0 --headless --seed 0 --num_frames 2000 ``` The numbers reported here are the average FPS on PC with RTX A6000 GPU and Intel i9-9820X: * **Before**: 94784.43553363248 * **Overriding `sim.device`**: 100484.21244511564 ## 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 `./isaaclab.sh --format` - [x] I have made corresponding changes to the documentation - [x] My changes generate no new warnings - [ ] I have added tests that prove my fix is effective or that my feature works - [x] I have updated the changelog and the corresponding version in the extension's `config/extension.toml` file - [x] I have added my name to the `CONTRIBUTORS.md` or my name already exists there
1 parent 6131a57 commit 03cee3c

File tree

4 files changed

+159
-119
lines changed

4 files changed

+159
-119
lines changed

scripts/benchmarks/benchmark_non_rl.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,7 @@ def main(env_cfg: ManagerBasedRLEnvCfg | DirectRLEnvCfg | DirectMARLEnvCfg, agen
113113
# override configurations with non-hydra CLI arguments
114114
env_cfg.scene.num_envs = args_cli.num_envs if args_cli.num_envs is not None else env_cfg.scene.num_envs
115115
env_cfg.sim.device = args_cli.device if args_cli.device is not None else env_cfg.sim.device
116+
env_cfg.seed = args_cli.seed if args_cli.seed is not None else env_cfg.sim.seed
116117

117118
# process distributed
118119
world_size = 1

source/isaaclab/config/extension.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
[package]
22

33
# Note: Semantic Versioning is used: https://semver.org/
4-
version = "0.46.3"
4+
version = "0.46.4"
55

66
# Description
77
title = "Isaac Lab framework for Robot Learning"

source/isaaclab/docs/CHANGELOG.rst

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,16 @@
11
Changelog
22
---------
33

4+
0.46.4 (2025-10-06)
5+
~~~~~~~~~~~~~~~~~~~
6+
7+
Changed
8+
^^^^^^^
9+
10+
* Fixed :attr:`~isaaclab.sim.simulation_context.SimulationContext.device` to return the device from the configuration.
11+
Previously, it was returning the device from the simulation manager, which was causing a performance overhead.
12+
13+
414
0.46.3 (2025-09-17)
515
~~~~~~~~~~~~~~~~~~~
616

@@ -10,6 +20,7 @@ Added
1020
* Modified setter to support for viscous and dynamic joint friction coefficients in articulation based on IsaacSim 5.0.
1121
* Added randomization of viscous and dynamic joint friction coefficients in event term.
1222

23+
1324
0.46.2 (2025-09-13)
1425
~~~~~~~~~~~~~~~~~~~
1526

source/isaaclab/isaaclab/sim/simulation_context.py

Lines changed: 146 additions & 118 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
import omni.physx
2727
import omni.usd
2828
from isaacsim.core.api.simulation_context import SimulationContext as _SimulationContext
29+
from isaacsim.core.simulation_manager import SimulationManager
2930
from isaacsim.core.utils.carb import get_carb_setting, set_carb_setting
3031
from isaacsim.core.utils.viewports import set_camera_view
3132
from isaacsim.core.version import get_version
@@ -259,6 +260,19 @@ def __init__(self, cfg: SimulationCfg | None = None):
259260
" simulation step size if you run into physics issues."
260261
)
261262

263+
# set simulation device
264+
# note: Although Isaac Sim sets the physics device in the init function,
265+
# it does a render call which gets the wrong device.
266+
SimulationManager.set_physics_sim_device(self.cfg.device)
267+
268+
# obtain the parsed device
269+
# This device should be the same as "self.cfg.device". However, for cases, where users specify the device
270+
# as "cuda" and not "cuda:X", then it fetches the current device from SimulationManager.
271+
# Note: Since we fix the device from the configuration and don't expect users to change it at runtime,
272+
# we can obtain the device once from the SimulationManager.get_physics_sim_device() function.
273+
# This reduces the overhead of calling the function.
274+
self._physics_device = SimulationManager.get_physics_sim_device()
275+
262276
# create a simulation context to control the simulator
263277
if float(".".join(self._isaacsim_version[2])) < 5:
264278
# stage arg is not supported before isaac sim 5.0
@@ -283,126 +297,19 @@ def __init__(self, cfg: SimulationCfg | None = None):
283297
stage=self._initial_stage,
284298
)
285299

286-
def _apply_physics_settings(self):
287-
"""Sets various carb physics settings."""
288-
# enable hydra scene-graph instancing
289-
# note: this allows rendering of instanceable assets on the GUI
290-
set_carb_setting(self.carb_settings, "/persistent/omnihydra/useSceneGraphInstancing", True)
291-
# change dispatcher to use the default dispatcher in PhysX SDK instead of carb tasking
292-
# note: dispatcher handles how threads are launched for multi-threaded physics
293-
set_carb_setting(self.carb_settings, "/physics/physxDispatcher", True)
294-
# disable contact processing in omni.physx
295-
# note: we disable it by default to avoid the overhead of contact processing when it isn't needed.
296-
# The physics flag gets enabled when a contact sensor is created.
297-
if hasattr(self.cfg, "disable_contact_processing"):
298-
omni.log.warn(
299-
"The `disable_contact_processing` attribute is deprecated and always set to True"
300-
" to avoid unnecessary overhead. Contact processing is automatically enabled when"
301-
" a contact sensor is created, so manual configuration is no longer required."
302-
)
303-
# FIXME: From investigation, it seems this flag only affects CPU physics. For GPU physics, contacts
304-
# are always processed. The issue is reported to the PhysX team by @mmittal.
305-
set_carb_setting(self.carb_settings, "/physics/disableContactProcessing", True)
306-
# disable custom geometry for cylinder and cone collision shapes to allow contact reporting for them
307-
# reason: cylinders and cones aren't natively supported by PhysX so we need to use custom geometry flags
308-
# reference: https://nvidia-omniverse.github.io/PhysX/physx/5.4.1/docs/Geometry.html?highlight=capsule#geometry
309-
set_carb_setting(self.carb_settings, "/physics/collisionConeCustomGeometry", False)
310-
set_carb_setting(self.carb_settings, "/physics/collisionCylinderCustomGeometry", False)
311-
# hide the Simulation Settings window
312-
set_carb_setting(self.carb_settings, "/physics/autoPopupSimulationOutputWindow", False)
313-
314-
def _apply_render_settings_from_cfg(self):
315-
"""Sets rtx settings specified in the RenderCfg."""
316-
317-
# define mapping of user-friendly RenderCfg names to native carb names
318-
rendering_setting_name_mapping = {
319-
"enable_translucency": "/rtx/translucency/enabled",
320-
"enable_reflections": "/rtx/reflections/enabled",
321-
"enable_global_illumination": "/rtx/indirectDiffuse/enabled",
322-
"enable_dlssg": "/rtx-transient/dlssg/enabled",
323-
"enable_dl_denoiser": "/rtx-transient/dldenoiser/enabled",
324-
"dlss_mode": "/rtx/post/dlss/execMode",
325-
"enable_direct_lighting": "/rtx/directLighting/enabled",
326-
"samples_per_pixel": "/rtx/directLighting/sampledLighting/samplesPerPixel",
327-
"enable_shadows": "/rtx/shadows/enabled",
328-
"enable_ambient_occlusion": "/rtx/ambientOcclusion/enabled",
329-
}
330-
331-
not_carb_settings = ["rendering_mode", "carb_settings", "antialiasing_mode"]
332-
333-
# grab the rendering mode using the following priority:
334-
# 1. command line argument --rendering_mode, if provided
335-
# 2. rendering_mode from Render Config, if set
336-
# 3. lastly, default to "balanced" mode, if neither is specified
337-
rendering_mode = get_carb_setting(self.carb_settings, "/isaaclab/rendering/rendering_mode")
338-
if not rendering_mode:
339-
rendering_mode = self.cfg.render.rendering_mode
340-
if not rendering_mode:
341-
rendering_mode = "balanced"
342-
343-
# set preset settings (same behavior as the CLI arg --rendering_mode)
344-
if rendering_mode is not None:
345-
# check if preset is supported
346-
supported_rendering_modes = ["performance", "balanced", "quality"]
347-
if rendering_mode not in supported_rendering_modes:
348-
raise ValueError(
349-
f"RenderCfg rendering mode '{rendering_mode}' not in supported modes {supported_rendering_modes}."
350-
)
351-
352-
# grab isaac lab apps path
353-
isaaclab_app_exp_path = os.path.join(os.path.dirname(os.path.abspath(__file__)), *[".."] * 4, "apps")
354-
# for Isaac Sim 4.5 compatibility, we use the 4.5 rendering mode app files in a different folder
355-
if float(".".join(self._isaacsim_version[2])) < 5:
356-
isaaclab_app_exp_path = os.path.join(isaaclab_app_exp_path, "isaacsim_4_5")
357-
358-
# grab preset settings
359-
preset_filename = os.path.join(isaaclab_app_exp_path, f"rendering_modes/{rendering_mode}.kit")
360-
with open(preset_filename) as file:
361-
preset_dict = toml.load(file)
362-
preset_dict = dict(flatdict.FlatDict(preset_dict, delimiter="."))
363-
364-
# set presets
365-
for key, value in preset_dict.items():
366-
key = "/" + key.replace(".", "/") # convert to carb setting format
367-
set_carb_setting(self.carb_settings, key, value)
368-
369-
# set user-friendly named settings
370-
for key, value in vars(self.cfg.render).items():
371-
if value is None or key in not_carb_settings:
372-
# skip unset settings and non-carb settings
373-
continue
374-
if key not in rendering_setting_name_mapping:
375-
raise ValueError(
376-
f"'{key}' in RenderCfg not found. Note: internal 'rendering_setting_name_mapping' dictionary might"
377-
" need to be updated."
378-
)
379-
key = rendering_setting_name_mapping[key]
380-
set_carb_setting(self.carb_settings, key, value)
381-
382-
# set general carb settings
383-
carb_settings = self.cfg.render.carb_settings
384-
if carb_settings is not None:
385-
for key, value in carb_settings.items():
386-
if "_" in key:
387-
key = "/" + key.replace("_", "/") # convert from python variable style string
388-
elif "." in key:
389-
key = "/" + key.replace(".", "/") # convert from .kit file style string
390-
if get_carb_setting(self.carb_settings, key) is None:
391-
raise ValueError(f"'{key}' in RenderCfg.general_parameters does not map to a carb setting.")
392-
set_carb_setting(self.carb_settings, key, value)
300+
"""
301+
Properties - Override.
302+
"""
393303

394-
# set denoiser mode
395-
if self.cfg.render.antialiasing_mode is not None:
396-
try:
397-
import omni.replicator.core as rep
304+
@property
305+
def device(self) -> str:
306+
"""Device used by the simulation.
398307
399-
rep.settings.set_render_rtx_realtime(antialiasing=self.cfg.render.antialiasing_mode)
400-
except Exception:
401-
pass
402-
403-
# WAR: Ensure /rtx/renderMode RaytracedLighting is correctly cased.
404-
if get_carb_setting(self.carb_settings, "/rtx/rendermode").lower() == "raytracedlighting":
405-
set_carb_setting(self.carb_settings, "/rtx/rendermode", "RaytracedLighting")
308+
Note:
309+
In Omniverse, it is possible to configure multiple GPUs for rendering, while physics engine
310+
operates on a single GPU. This function returns the device that is used for physics simulation.
311+
"""
312+
return self._physics_device
406313

407314
"""
408315
Operations - New.
@@ -742,6 +649,127 @@ def clear_instance(cls):
742649
Helper Functions
743650
"""
744651

652+
def _apply_physics_settings(self):
653+
"""Sets various carb physics settings."""
654+
# enable hydra scene-graph instancing
655+
# note: this allows rendering of instanceable assets on the GUI
656+
set_carb_setting(self.carb_settings, "/persistent/omnihydra/useSceneGraphInstancing", True)
657+
# change dispatcher to use the default dispatcher in PhysX SDK instead of carb tasking
658+
# note: dispatcher handles how threads are launched for multi-threaded physics
659+
set_carb_setting(self.carb_settings, "/physics/physxDispatcher", True)
660+
# disable contact processing in omni.physx
661+
# note: we disable it by default to avoid the overhead of contact processing when it isn't needed.
662+
# The physics flag gets enabled when a contact sensor is created.
663+
if hasattr(self.cfg, "disable_contact_processing"):
664+
omni.log.warn(
665+
"The `disable_contact_processing` attribute is deprecated and always set to True"
666+
" to avoid unnecessary overhead. Contact processing is automatically enabled when"
667+
" a contact sensor is created, so manual configuration is no longer required."
668+
)
669+
# FIXME: From investigation, it seems this flag only affects CPU physics. For GPU physics, contacts
670+
# are always processed. The issue is reported to the PhysX team by @mmittal.
671+
set_carb_setting(self.carb_settings, "/physics/disableContactProcessing", True)
672+
# disable custom geometry for cylinder and cone collision shapes to allow contact reporting for them
673+
# reason: cylinders and cones aren't natively supported by PhysX so we need to use custom geometry flags
674+
# reference: https://nvidia-omniverse.github.io/PhysX/physx/5.4.1/docs/Geometry.html?highlight=capsule#geometry
675+
set_carb_setting(self.carb_settings, "/physics/collisionConeCustomGeometry", False)
676+
set_carb_setting(self.carb_settings, "/physics/collisionCylinderCustomGeometry", False)
677+
# hide the Simulation Settings window
678+
set_carb_setting(self.carb_settings, "/physics/autoPopupSimulationOutputWindow", False)
679+
680+
def _apply_render_settings_from_cfg(self):
681+
"""Sets rtx settings specified in the RenderCfg."""
682+
683+
# define mapping of user-friendly RenderCfg names to native carb names
684+
rendering_setting_name_mapping = {
685+
"enable_translucency": "/rtx/translucency/enabled",
686+
"enable_reflections": "/rtx/reflections/enabled",
687+
"enable_global_illumination": "/rtx/indirectDiffuse/enabled",
688+
"enable_dlssg": "/rtx-transient/dlssg/enabled",
689+
"enable_dl_denoiser": "/rtx-transient/dldenoiser/enabled",
690+
"dlss_mode": "/rtx/post/dlss/execMode",
691+
"enable_direct_lighting": "/rtx/directLighting/enabled",
692+
"samples_per_pixel": "/rtx/directLighting/sampledLighting/samplesPerPixel",
693+
"enable_shadows": "/rtx/shadows/enabled",
694+
"enable_ambient_occlusion": "/rtx/ambientOcclusion/enabled",
695+
}
696+
697+
not_carb_settings = ["rendering_mode", "carb_settings", "antialiasing_mode"]
698+
699+
# grab the rendering mode using the following priority:
700+
# 1. command line argument --rendering_mode, if provided
701+
# 2. rendering_mode from Render Config, if set
702+
# 3. lastly, default to "balanced" mode, if neither is specified
703+
rendering_mode = get_carb_setting(self.carb_settings, "/isaaclab/rendering/rendering_mode")
704+
if not rendering_mode:
705+
rendering_mode = self.cfg.render.rendering_mode
706+
if not rendering_mode:
707+
rendering_mode = "balanced"
708+
709+
# set preset settings (same behavior as the CLI arg --rendering_mode)
710+
if rendering_mode is not None:
711+
# check if preset is supported
712+
supported_rendering_modes = ["performance", "balanced", "quality"]
713+
if rendering_mode not in supported_rendering_modes:
714+
raise ValueError(
715+
f"RenderCfg rendering mode '{rendering_mode}' not in supported modes {supported_rendering_modes}."
716+
)
717+
718+
# grab isaac lab apps path
719+
isaaclab_app_exp_path = os.path.join(os.path.dirname(os.path.abspath(__file__)), *[".."] * 4, "apps")
720+
# for Isaac Sim 4.5 compatibility, we use the 4.5 rendering mode app files in a different folder
721+
if float(".".join(self._isaacsim_version[2])) < 5:
722+
isaaclab_app_exp_path = os.path.join(isaaclab_app_exp_path, "isaacsim_4_5")
723+
724+
# grab preset settings
725+
preset_filename = os.path.join(isaaclab_app_exp_path, f"rendering_modes/{rendering_mode}.kit")
726+
with open(preset_filename) as file:
727+
preset_dict = toml.load(file)
728+
preset_dict = dict(flatdict.FlatDict(preset_dict, delimiter="."))
729+
730+
# set presets
731+
for key, value in preset_dict.items():
732+
key = "/" + key.replace(".", "/") # convert to carb setting format
733+
set_carb_setting(self.carb_settings, key, value)
734+
735+
# set user-friendly named settings
736+
for key, value in vars(self.cfg.render).items():
737+
if value is None or key in not_carb_settings:
738+
# skip unset settings and non-carb settings
739+
continue
740+
if key not in rendering_setting_name_mapping:
741+
raise ValueError(
742+
f"'{key}' in RenderCfg not found. Note: internal 'rendering_setting_name_mapping' dictionary might"
743+
" need to be updated."
744+
)
745+
key = rendering_setting_name_mapping[key]
746+
set_carb_setting(self.carb_settings, key, value)
747+
748+
# set general carb settings
749+
carb_settings = self.cfg.render.carb_settings
750+
if carb_settings is not None:
751+
for key, value in carb_settings.items():
752+
if "_" in key:
753+
key = "/" + key.replace("_", "/") # convert from python variable style string
754+
elif "." in key:
755+
key = "/" + key.replace(".", "/") # convert from .kit file style string
756+
if get_carb_setting(self.carb_settings, key) is None:
757+
raise ValueError(f"'{key}' in RenderCfg.general_parameters does not map to a carb setting.")
758+
set_carb_setting(self.carb_settings, key, value)
759+
760+
# set denoiser mode
761+
if self.cfg.render.antialiasing_mode is not None:
762+
try:
763+
import omni.replicator.core as rep
764+
765+
rep.settings.set_render_rtx_realtime(antialiasing=self.cfg.render.antialiasing_mode)
766+
except Exception:
767+
pass
768+
769+
# WAR: Ensure /rtx/renderMode RaytracedLighting is correctly cased.
770+
if get_carb_setting(self.carb_settings, "/rtx/rendermode").lower() == "raytracedlighting":
771+
set_carb_setting(self.carb_settings, "/rtx/rendermode", "RaytracedLighting")
772+
745773
def _set_additional_physx_params(self):
746774
"""Sets additional PhysX parameters that are not directly supported by the parent class."""
747775
# obtain the physics scene api

0 commit comments

Comments
 (0)