Unverified Commit 03cee3ce authored by Mayank Mittal's avatar Mayank Mittal Committed by GitHub

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
parent 6131a573
......@@ -113,6 +113,7 @@ def main(env_cfg: ManagerBasedRLEnvCfg | DirectRLEnvCfg | DirectMARLEnvCfg, agen
# override configurations with non-hydra CLI arguments
env_cfg.scene.num_envs = args_cli.num_envs if args_cli.num_envs is not None else env_cfg.scene.num_envs
env_cfg.sim.device = args_cli.device if args_cli.device is not None else env_cfg.sim.device
env_cfg.seed = args_cli.seed if args_cli.seed is not None else env_cfg.sim.seed
# process distributed
world_size = 1
......
[package]
# Note: Semantic Versioning is used: https://semver.org/
version = "0.46.3"
version = "0.46.4"
# Description
title = "Isaac Lab framework for Robot Learning"
......
Changelog
---------
0.46.4 (2025-10-06)
~~~~~~~~~~~~~~~~~~~
Changed
^^^^^^^
* Fixed :attr:`~isaaclab.sim.simulation_context.SimulationContext.device` to return the device from the configuration.
Previously, it was returning the device from the simulation manager, which was causing a performance overhead.
0.46.3 (2025-09-17)
~~~~~~~~~~~~~~~~~~~
......@@ -10,6 +20,7 @@ Added
* Modified setter to support for viscous and dynamic joint friction coefficients in articulation based on IsaacSim 5.0.
* Added randomization of viscous and dynamic joint friction coefficients in event term.
0.46.2 (2025-09-13)
~~~~~~~~~~~~~~~~~~~
......
......@@ -26,6 +26,7 @@ import omni.log
import omni.physx
import omni.usd
from isaacsim.core.api.simulation_context import SimulationContext as _SimulationContext
from isaacsim.core.simulation_manager import SimulationManager
from isaacsim.core.utils.carb import get_carb_setting, set_carb_setting
from isaacsim.core.utils.viewports import set_camera_view
from isaacsim.core.version import get_version
......@@ -259,6 +260,19 @@ class SimulationContext(_SimulationContext):
" simulation step size if you run into physics issues."
)
# set simulation device
# note: Although Isaac Sim sets the physics device in the init function,
# it does a render call which gets the wrong device.
SimulationManager.set_physics_sim_device(self.cfg.device)
# obtain the parsed device
# This device should be the same as "self.cfg.device". However, for cases, where users specify the device
# as "cuda" and not "cuda:X", then it fetches the current device from SimulationManager.
# Note: Since we fix the device from the configuration and don't expect users to change it at runtime,
# we can obtain the device once from the SimulationManager.get_physics_sim_device() function.
# This reduces the overhead of calling the function.
self._physics_device = SimulationManager.get_physics_sim_device()
# create a simulation context to control the simulator
if float(".".join(self._isaacsim_version[2])) < 5:
# stage arg is not supported before isaac sim 5.0
......@@ -283,126 +297,19 @@ class SimulationContext(_SimulationContext):
stage=self._initial_stage,
)
def _apply_physics_settings(self):
"""Sets various carb physics settings."""
# enable hydra scene-graph instancing
# note: this allows rendering of instanceable assets on the GUI
set_carb_setting(self.carb_settings, "/persistent/omnihydra/useSceneGraphInstancing", True)
# change dispatcher to use the default dispatcher in PhysX SDK instead of carb tasking
# note: dispatcher handles how threads are launched for multi-threaded physics
set_carb_setting(self.carb_settings, "/physics/physxDispatcher", True)
# disable contact processing in omni.physx
# note: we disable it by default to avoid the overhead of contact processing when it isn't needed.
# The physics flag gets enabled when a contact sensor is created.
if hasattr(self.cfg, "disable_contact_processing"):
omni.log.warn(
"The `disable_contact_processing` attribute is deprecated and always set to True"
" to avoid unnecessary overhead. Contact processing is automatically enabled when"
" a contact sensor is created, so manual configuration is no longer required."
)
# FIXME: From investigation, it seems this flag only affects CPU physics. For GPU physics, contacts
# are always processed. The issue is reported to the PhysX team by @mmittal.
set_carb_setting(self.carb_settings, "/physics/disableContactProcessing", True)
# disable custom geometry for cylinder and cone collision shapes to allow contact reporting for them
# reason: cylinders and cones aren't natively supported by PhysX so we need to use custom geometry flags
# reference: https://nvidia-omniverse.github.io/PhysX/physx/5.4.1/docs/Geometry.html?highlight=capsule#geometry
set_carb_setting(self.carb_settings, "/physics/collisionConeCustomGeometry", False)
set_carb_setting(self.carb_settings, "/physics/collisionCylinderCustomGeometry", False)
# hide the Simulation Settings window
set_carb_setting(self.carb_settings, "/physics/autoPopupSimulationOutputWindow", False)
def _apply_render_settings_from_cfg(self):
"""Sets rtx settings specified in the RenderCfg."""
# define mapping of user-friendly RenderCfg names to native carb names
rendering_setting_name_mapping = {
"enable_translucency": "/rtx/translucency/enabled",
"enable_reflections": "/rtx/reflections/enabled",
"enable_global_illumination": "/rtx/indirectDiffuse/enabled",
"enable_dlssg": "/rtx-transient/dlssg/enabled",
"enable_dl_denoiser": "/rtx-transient/dldenoiser/enabled",
"dlss_mode": "/rtx/post/dlss/execMode",
"enable_direct_lighting": "/rtx/directLighting/enabled",
"samples_per_pixel": "/rtx/directLighting/sampledLighting/samplesPerPixel",
"enable_shadows": "/rtx/shadows/enabled",
"enable_ambient_occlusion": "/rtx/ambientOcclusion/enabled",
}
not_carb_settings = ["rendering_mode", "carb_settings", "antialiasing_mode"]
# grab the rendering mode using the following priority:
# 1. command line argument --rendering_mode, if provided
# 2. rendering_mode from Render Config, if set
# 3. lastly, default to "balanced" mode, if neither is specified
rendering_mode = get_carb_setting(self.carb_settings, "/isaaclab/rendering/rendering_mode")
if not rendering_mode:
rendering_mode = self.cfg.render.rendering_mode
if not rendering_mode:
rendering_mode = "balanced"
# set preset settings (same behavior as the CLI arg --rendering_mode)
if rendering_mode is not None:
# check if preset is supported
supported_rendering_modes = ["performance", "balanced", "quality"]
if rendering_mode not in supported_rendering_modes:
raise ValueError(
f"RenderCfg rendering mode '{rendering_mode}' not in supported modes {supported_rendering_modes}."
)
# grab isaac lab apps path
isaaclab_app_exp_path = os.path.join(os.path.dirname(os.path.abspath(__file__)), *[".."] * 4, "apps")
# for Isaac Sim 4.5 compatibility, we use the 4.5 rendering mode app files in a different folder
if float(".".join(self._isaacsim_version[2])) < 5:
isaaclab_app_exp_path = os.path.join(isaaclab_app_exp_path, "isaacsim_4_5")
# grab preset settings
preset_filename = os.path.join(isaaclab_app_exp_path, f"rendering_modes/{rendering_mode}.kit")
with open(preset_filename) as file:
preset_dict = toml.load(file)
preset_dict = dict(flatdict.FlatDict(preset_dict, delimiter="."))
# set presets
for key, value in preset_dict.items():
key = "/" + key.replace(".", "/") # convert to carb setting format
set_carb_setting(self.carb_settings, key, value)
# set user-friendly named settings
for key, value in vars(self.cfg.render).items():
if value is None or key in not_carb_settings:
# skip unset settings and non-carb settings
continue
if key not in rendering_setting_name_mapping:
raise ValueError(
f"'{key}' in RenderCfg not found. Note: internal 'rendering_setting_name_mapping' dictionary might"
" need to be updated."
)
key = rendering_setting_name_mapping[key]
set_carb_setting(self.carb_settings, key, value)
# set general carb settings
carb_settings = self.cfg.render.carb_settings
if carb_settings is not None:
for key, value in carb_settings.items():
if "_" in key:
key = "/" + key.replace("_", "/") # convert from python variable style string
elif "." in key:
key = "/" + key.replace(".", "/") # convert from .kit file style string
if get_carb_setting(self.carb_settings, key) is None:
raise ValueError(f"'{key}' in RenderCfg.general_parameters does not map to a carb setting.")
set_carb_setting(self.carb_settings, key, value)
"""
Properties - Override.
"""
# set denoiser mode
if self.cfg.render.antialiasing_mode is not None:
try:
import omni.replicator.core as rep
@property
def device(self) -> str:
"""Device used by the simulation.
rep.settings.set_render_rtx_realtime(antialiasing=self.cfg.render.antialiasing_mode)
except Exception:
pass
# WAR: Ensure /rtx/renderMode RaytracedLighting is correctly cased.
if get_carb_setting(self.carb_settings, "/rtx/rendermode").lower() == "raytracedlighting":
set_carb_setting(self.carb_settings, "/rtx/rendermode", "RaytracedLighting")
Note:
In Omniverse, it is possible to configure multiple GPUs for rendering, while physics engine
operates on a single GPU. This function returns the device that is used for physics simulation.
"""
return self._physics_device
"""
Operations - New.
......@@ -742,6 +649,127 @@ class SimulationContext(_SimulationContext):
Helper Functions
"""
def _apply_physics_settings(self):
"""Sets various carb physics settings."""
# enable hydra scene-graph instancing
# note: this allows rendering of instanceable assets on the GUI
set_carb_setting(self.carb_settings, "/persistent/omnihydra/useSceneGraphInstancing", True)
# change dispatcher to use the default dispatcher in PhysX SDK instead of carb tasking
# note: dispatcher handles how threads are launched for multi-threaded physics
set_carb_setting(self.carb_settings, "/physics/physxDispatcher", True)
# disable contact processing in omni.physx
# note: we disable it by default to avoid the overhead of contact processing when it isn't needed.
# The physics flag gets enabled when a contact sensor is created.
if hasattr(self.cfg, "disable_contact_processing"):
omni.log.warn(
"The `disable_contact_processing` attribute is deprecated and always set to True"
" to avoid unnecessary overhead. Contact processing is automatically enabled when"
" a contact sensor is created, so manual configuration is no longer required."
)
# FIXME: From investigation, it seems this flag only affects CPU physics. For GPU physics, contacts
# are always processed. The issue is reported to the PhysX team by @mmittal.
set_carb_setting(self.carb_settings, "/physics/disableContactProcessing", True)
# disable custom geometry for cylinder and cone collision shapes to allow contact reporting for them
# reason: cylinders and cones aren't natively supported by PhysX so we need to use custom geometry flags
# reference: https://nvidia-omniverse.github.io/PhysX/physx/5.4.1/docs/Geometry.html?highlight=capsule#geometry
set_carb_setting(self.carb_settings, "/physics/collisionConeCustomGeometry", False)
set_carb_setting(self.carb_settings, "/physics/collisionCylinderCustomGeometry", False)
# hide the Simulation Settings window
set_carb_setting(self.carb_settings, "/physics/autoPopupSimulationOutputWindow", False)
def _apply_render_settings_from_cfg(self):
"""Sets rtx settings specified in the RenderCfg."""
# define mapping of user-friendly RenderCfg names to native carb names
rendering_setting_name_mapping = {
"enable_translucency": "/rtx/translucency/enabled",
"enable_reflections": "/rtx/reflections/enabled",
"enable_global_illumination": "/rtx/indirectDiffuse/enabled",
"enable_dlssg": "/rtx-transient/dlssg/enabled",
"enable_dl_denoiser": "/rtx-transient/dldenoiser/enabled",
"dlss_mode": "/rtx/post/dlss/execMode",
"enable_direct_lighting": "/rtx/directLighting/enabled",
"samples_per_pixel": "/rtx/directLighting/sampledLighting/samplesPerPixel",
"enable_shadows": "/rtx/shadows/enabled",
"enable_ambient_occlusion": "/rtx/ambientOcclusion/enabled",
}
not_carb_settings = ["rendering_mode", "carb_settings", "antialiasing_mode"]
# grab the rendering mode using the following priority:
# 1. command line argument --rendering_mode, if provided
# 2. rendering_mode from Render Config, if set
# 3. lastly, default to "balanced" mode, if neither is specified
rendering_mode = get_carb_setting(self.carb_settings, "/isaaclab/rendering/rendering_mode")
if not rendering_mode:
rendering_mode = self.cfg.render.rendering_mode
if not rendering_mode:
rendering_mode = "balanced"
# set preset settings (same behavior as the CLI arg --rendering_mode)
if rendering_mode is not None:
# check if preset is supported
supported_rendering_modes = ["performance", "balanced", "quality"]
if rendering_mode not in supported_rendering_modes:
raise ValueError(
f"RenderCfg rendering mode '{rendering_mode}' not in supported modes {supported_rendering_modes}."
)
# grab isaac lab apps path
isaaclab_app_exp_path = os.path.join(os.path.dirname(os.path.abspath(__file__)), *[".."] * 4, "apps")
# for Isaac Sim 4.5 compatibility, we use the 4.5 rendering mode app files in a different folder
if float(".".join(self._isaacsim_version[2])) < 5:
isaaclab_app_exp_path = os.path.join(isaaclab_app_exp_path, "isaacsim_4_5")
# grab preset settings
preset_filename = os.path.join(isaaclab_app_exp_path, f"rendering_modes/{rendering_mode}.kit")
with open(preset_filename) as file:
preset_dict = toml.load(file)
preset_dict = dict(flatdict.FlatDict(preset_dict, delimiter="."))
# set presets
for key, value in preset_dict.items():
key = "/" + key.replace(".", "/") # convert to carb setting format
set_carb_setting(self.carb_settings, key, value)
# set user-friendly named settings
for key, value in vars(self.cfg.render).items():
if value is None or key in not_carb_settings:
# skip unset settings and non-carb settings
continue
if key not in rendering_setting_name_mapping:
raise ValueError(
f"'{key}' in RenderCfg not found. Note: internal 'rendering_setting_name_mapping' dictionary might"
" need to be updated."
)
key = rendering_setting_name_mapping[key]
set_carb_setting(self.carb_settings, key, value)
# set general carb settings
carb_settings = self.cfg.render.carb_settings
if carb_settings is not None:
for key, value in carb_settings.items():
if "_" in key:
key = "/" + key.replace("_", "/") # convert from python variable style string
elif "." in key:
key = "/" + key.replace(".", "/") # convert from .kit file style string
if get_carb_setting(self.carb_settings, key) is None:
raise ValueError(f"'{key}' in RenderCfg.general_parameters does not map to a carb setting.")
set_carb_setting(self.carb_settings, key, value)
# set denoiser mode
if self.cfg.render.antialiasing_mode is not None:
try:
import omni.replicator.core as rep
rep.settings.set_render_rtx_realtime(antialiasing=self.cfg.render.antialiasing_mode)
except Exception:
pass
# WAR: Ensure /rtx/renderMode RaytracedLighting is correctly cased.
if get_carb_setting(self.carb_settings, "/rtx/rendermode").lower() == "raytracedlighting":
set_carb_setting(self.carb_settings, "/rtx/rendermode", "RaytracedLighting")
def _set_additional_physx_params(self):
"""Sets additional PhysX parameters that are not directly supported by the parent class."""
# obtain the physics scene api
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment