HongzeFu commited on
Commit
2385631
·
1 Parent(s): 31ade5b

v2 locker docker cpu test stable

Browse files
docker-entrypoint.sh CHANGED
@@ -7,6 +7,7 @@ fi
7
 
8
  export CUDA_VISIBLE_DEVICES=-1
9
  export NVIDIA_VISIBLE_DEVICES=void
 
10
  unset NVIDIA_DRIVER_CAPABILITIES
11
  unset SAPIEN_RENDER_DEVICE
12
  unset MUJOCO_GL
@@ -18,6 +19,7 @@ echo "[entrypoint] Starting RoboMME Gradio app in CPU-only mode"
18
  echo "[entrypoint] OMP_NUM_THREADS=$OMP_NUM_THREADS"
19
  echo "[entrypoint] CUDA_VISIBLE_DEVICES=$CUDA_VISIBLE_DEVICES"
20
  echo "[entrypoint] NVIDIA_VISIBLE_DEVICES=$NVIDIA_VISIBLE_DEVICES"
 
21
  echo "[entrypoint] SAPIEN_RENDER_DEVICE=${SAPIEN_RENDER_DEVICE:-<unset>}"
22
  echo "[entrypoint] VK_ICD_FILENAMES=${VK_ICD_FILENAMES:-<unset>}"
23
  exec "$@"
 
7
 
8
  export CUDA_VISIBLE_DEVICES=-1
9
  export NVIDIA_VISIBLE_DEVICES=void
10
+ export ROBOMME_RENDER_BACKEND="${ROBOMME_RENDER_BACKEND:-pci:0}"
11
  unset NVIDIA_DRIVER_CAPABILITIES
12
  unset SAPIEN_RENDER_DEVICE
13
  unset MUJOCO_GL
 
19
  echo "[entrypoint] OMP_NUM_THREADS=$OMP_NUM_THREADS"
20
  echo "[entrypoint] CUDA_VISIBLE_DEVICES=$CUDA_VISIBLE_DEVICES"
21
  echo "[entrypoint] NVIDIA_VISIBLE_DEVICES=$NVIDIA_VISIBLE_DEVICES"
22
+ echo "[entrypoint] ROBOMME_RENDER_BACKEND=$ROBOMME_RENDER_BACKEND"
23
  echo "[entrypoint] SAPIEN_RENDER_DEVICE=${SAPIEN_RENDER_DEVICE:-<unset>}"
24
  echo "[entrypoint] VK_ICD_FILENAMES=${VK_ICD_FILENAMES:-<unset>}"
25
  exec "$@"
gradio-web/main.py CHANGED
@@ -16,9 +16,11 @@ VIDEOS_DIR = APP_DIR / "videos"
16
  TEMP_DEMOS_DIR = PROJECT_ROOT / "temp_demos"
17
  CWD_TEMP_DEMOS_DIR = Path.cwd() / "temp_demos"
18
  DEFAULT_LLVMPipe_ICD = Path("/usr/share/vulkan/icd.d/lvp_icd.x86_64.json")
 
19
  CPU_ONLY_ENV_OVERRIDES = {
20
  "CUDA_VISIBLE_DEVICES": "-1",
21
  "NVIDIA_VISIBLE_DEVICES": "void",
 
22
  }
23
  CPU_ONLY_ENV_CLEAR_KEYS = (
24
  "NVIDIA_DRIVER_CAPABILITIES",
@@ -115,6 +117,7 @@ def log_runtime_graphics_env():
115
  "NVIDIA_DRIVER_CAPABILITIES",
116
  "VK_ICD_FILENAMES",
117
  "OMP_NUM_THREADS",
 
118
  "SAPIEN_RENDER_DEVICE",
119
  "MUJOCO_GL",
120
  ]
 
16
  TEMP_DEMOS_DIR = PROJECT_ROOT / "temp_demos"
17
  CWD_TEMP_DEMOS_DIR = Path.cwd() / "temp_demos"
18
  DEFAULT_LLVMPipe_ICD = Path("/usr/share/vulkan/icd.d/lvp_icd.x86_64.json")
19
+ DEFAULT_CPU_RENDER_BACKEND = "pci:0"
20
  CPU_ONLY_ENV_OVERRIDES = {
21
  "CUDA_VISIBLE_DEVICES": "-1",
22
  "NVIDIA_VISIBLE_DEVICES": "void",
23
+ "ROBOMME_RENDER_BACKEND": DEFAULT_CPU_RENDER_BACKEND,
24
  }
25
  CPU_ONLY_ENV_CLEAR_KEYS = (
26
  "NVIDIA_DRIVER_CAPABILITIES",
 
117
  "NVIDIA_DRIVER_CAPABILITIES",
118
  "VK_ICD_FILENAMES",
119
  "OMP_NUM_THREADS",
120
+ "ROBOMME_RENDER_BACKEND",
121
  "SAPIEN_RENDER_DEVICE",
122
  "MUJOCO_GL",
123
  ]
gradio-web/minimal_maniskill_cpu_step.py CHANGED
@@ -7,12 +7,29 @@ execution path stays as small as possible.
7
  from __future__ import annotations
8
 
9
  import argparse
 
 
10
  import warnings
 
11
 
12
  import gymnasium as gym
13
  import mani_skill.envs # noqa: F401 - registers ManiSkill environments
14
 
15
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
16
  warnings.filterwarnings(
17
  "ignore",
18
  message=r"CUDA reports that you have .* fork_rng",
@@ -32,7 +49,7 @@ def main() -> None:
32
  control_mode="pd_joint_pos",
33
  render_mode="rgb_array",
34
  sim_backend="physx_cpu",
35
- render_backend="sapien_cpu",
36
  )
37
 
38
  try:
 
7
  from __future__ import annotations
8
 
9
  import argparse
10
+ import os
11
+ import sys
12
  import warnings
13
+ from pathlib import Path
14
 
15
  import gymnasium as gym
16
  import mani_skill.envs # noqa: F401 - registers ManiSkill environments
17
 
18
 
19
+ PROJECT_ROOT = Path(__file__).resolve().parents[1]
20
+ SRC_DIR = PROJECT_ROOT / "src"
21
+
22
+ if str(PROJECT_ROOT) not in sys.path:
23
+ sys.path.insert(0, str(PROJECT_ROOT))
24
+ if str(SRC_DIR) not in sys.path:
25
+ sys.path.insert(0, str(SRC_DIR))
26
+
27
+ import robomme # noqa: F401,E402 - applies ManiSkill PCI render-backend patch
28
+
29
+
30
+ os.environ.setdefault("ROBOMME_RENDER_BACKEND", "pci:0")
31
+
32
+
33
  warnings.filterwarnings(
34
  "ignore",
35
  message=r"CUDA reports that you have .* fork_rng",
 
49
  control_mode="pd_joint_pos",
50
  render_mode="rgb_array",
51
  sim_backend="physx_cpu",
52
+ render_backend=os.environ["ROBOMME_RENDER_BACKEND"],
53
  )
54
 
55
  try:
gradio-web/minimal_robomme_env_cpu_step.py CHANGED
@@ -26,6 +26,7 @@ if str(SRC_DIR) not in sys.path:
26
  def configure_cpu_only_runtime() -> None:
27
  os.environ["CUDA_VISIBLE_DEVICES"] = "-1"
28
  os.environ["NVIDIA_VISIBLE_DEVICES"] = "void"
 
29
  os.environ.pop("NVIDIA_DRIVER_CAPABILITIES", None)
30
  os.environ.pop("SAPIEN_RENDER_DEVICE", None)
31
  os.environ.pop("MUJOCO_GL", None)
@@ -52,6 +53,7 @@ def main() -> None:
52
  args = parser.parse_args()
53
 
54
  import robomme.robomme_env as robomme_env
 
55
 
56
  env_cls = getattr(robomme_env, args.env_class)
57
  env = None
@@ -64,7 +66,7 @@ def main() -> None:
64
  render_mode="rgb_array",
65
  reward_mode="dense",
66
  sim_backend="physx_cpu",
67
- render_backend="sapien_cpu",
68
  seed=args.seed,
69
  )
70
  print("instantiate ok", flush=True)
 
26
  def configure_cpu_only_runtime() -> None:
27
  os.environ["CUDA_VISIBLE_DEVICES"] = "-1"
28
  os.environ["NVIDIA_VISIBLE_DEVICES"] = "void"
29
+ os.environ.setdefault("ROBOMME_RENDER_BACKEND", "pci:0")
30
  os.environ.pop("NVIDIA_DRIVER_CAPABILITIES", None)
31
  os.environ.pop("SAPIEN_RENDER_DEVICE", None)
32
  os.environ.pop("MUJOCO_GL", None)
 
53
  args = parser.parse_args()
54
 
55
  import robomme.robomme_env as robomme_env
56
+ from robomme.env_record_wrapper.episode_config_resolver import resolve_render_backend
57
 
58
  env_cls = getattr(robomme_env, args.env_class)
59
  env = None
 
66
  render_mode="rgb_array",
67
  reward_mode="dense",
68
  sim_backend="physx_cpu",
69
+ render_backend=resolve_render_backend(),
70
  seed=args.seed,
71
  )
72
  print("instantiate ok", flush=True)
gradio-web/test/test_episode_builder_cpu_backend.py CHANGED
@@ -64,8 +64,56 @@ def test_builder_make_env_for_episode_forces_cpu_backends(monkeypatch, reload_mo
64
  assert captured["kwargs"]["render_mode"] == "rgb_array"
65
  assert captured["kwargs"]["reward_mode"] == "dense"
66
  assert captured["kwargs"]["sim_backend"] == "physx_cpu"
67
- assert captured["kwargs"]["render_backend"] == "sapien_cpu"
68
  assert captured["kwargs"]["seed"] == 123
69
  assert captured["kwargs"]["difficulty"] == "hard"
70
  assert _FakeDemonstrationWrapper.last_kwargs["gui_render"] is False
71
  assert _FakeFailAwareWrapper.last_env is env.env
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
64
  assert captured["kwargs"]["render_mode"] == "rgb_array"
65
  assert captured["kwargs"]["reward_mode"] == "dense"
66
  assert captured["kwargs"]["sim_backend"] == "physx_cpu"
67
+ assert captured["kwargs"]["render_backend"] == "pci:0"
68
  assert captured["kwargs"]["seed"] == 123
69
  assert captured["kwargs"]["difficulty"] == "hard"
70
  assert _FakeDemonstrationWrapper.last_kwargs["gui_render"] is False
71
  assert _FakeFailAwareWrapper.last_env is env.env
72
+
73
+
74
+ def test_builder_make_env_for_episode_honors_render_backend_override(monkeypatch, reload_module):
75
+ resolver = reload_module("robomme.env_record_wrapper.episode_config_resolver")
76
+ captured = {}
77
+
78
+ monkeypatch.setitem(
79
+ sys.modules,
80
+ "robomme.env_record_wrapper.DemonstrationWrapper",
81
+ types.SimpleNamespace(DemonstrationWrapper=_FakeDemonstrationWrapper),
82
+ )
83
+ monkeypatch.setitem(
84
+ sys.modules,
85
+ "robomme.env_record_wrapper.FailAwareWrapper",
86
+ types.SimpleNamespace(FailAwareWrapper=_FakeFailAwareWrapper),
87
+ )
88
+
89
+ def fake_make(env_id, **kwargs):
90
+ captured["env_id"] = env_id
91
+ captured["kwargs"] = kwargs
92
+ return _FakeEnv()
93
+
94
+ monkeypatch.setattr(resolver.gym, "make", fake_make)
95
+ monkeypatch.setenv("ROBOMME_RENDER_BACKEND", "pci:42")
96
+
97
+ builder = resolver.BenchmarkEnvBuilder(
98
+ env_id="BinFill",
99
+ dataset="train",
100
+ action_space="joint_angle",
101
+ gui_render=False,
102
+ )
103
+ monkeypatch.setattr(builder, "resolve_episode", lambda episode_idx: (None, None))
104
+
105
+ builder.make_env_for_episode(1)
106
+
107
+ assert captured["kwargs"]["render_backend"] == "pci:42"
108
+
109
+
110
+ def test_robomme_patches_maniskill_to_preserve_pci_render_backend(reload_module):
111
+ robomme = reload_module("robomme")
112
+ assert robomme is not None
113
+
114
+ from mani_skill.envs.utils.system import backend as ms_backend
115
+
116
+ backend_name, device_id = ms_backend.parse_backend_device_id("pci:0000:00:00.0")
117
+
118
+ assert backend_name == "pci:0000:00:00.0"
119
+ assert device_id is None
gradio-web/test/test_main_launch_config.py CHANGED
@@ -7,6 +7,7 @@ from pathlib import Path
7
 
8
 
9
  DEFAULT_LLVMPipe_ICD = "/usr/share/vulkan/icd.d/lvp_icd.x86_64.json"
 
10
 
11
 
12
  class _FakeDemo:
@@ -54,6 +55,7 @@ def test_main_launch_passes_ui_css_and_forces_cpu_runtime(monkeypatch, reload_mo
54
  assert fake_demo.launch_kwargs["head"] == fake_demo.head
55
  assert os.environ["CUDA_VISIBLE_DEVICES"] == "-1"
56
  assert os.environ["NVIDIA_VISIBLE_DEVICES"] == "void"
 
57
  assert os.environ["VK_ICD_FILENAMES"] == "/tmp/another_nvidia_icd.json"
58
  assert "NVIDIA_DRIVER_CAPABILITIES" not in os.environ
59
  assert "SAPIEN_RENDER_DEVICE" not in os.environ
@@ -83,6 +85,7 @@ def test_configure_cpu_only_runtime_autosets_llvmpipe_icd(monkeypatch, reload_mo
83
 
84
  assert os.environ["CUDA_VISIBLE_DEVICES"] == "-1"
85
  assert os.environ["NVIDIA_VISIBLE_DEVICES"] == "void"
 
86
  assert os.environ["VK_ICD_FILENAMES"] == DEFAULT_LLVMPipe_ICD
87
  assert "NVIDIA_DRIVER_CAPABILITIES" not in os.environ
88
  assert "SAPIEN_RENDER_DEVICE" not in os.environ
@@ -92,6 +95,7 @@ def test_configure_cpu_only_runtime_autosets_llvmpipe_icd(monkeypatch, reload_mo
92
  def test_configure_cpu_only_runtime_preserves_existing_vk_icd(monkeypatch, reload_module):
93
  monkeypatch.setenv("CUDA_VISIBLE_DEVICES", "4")
94
  monkeypatch.setenv("NVIDIA_VISIBLE_DEVICES", "all")
 
95
  monkeypatch.setenv("SAPIEN_RENDER_DEVICE", "cuda")
96
  monkeypatch.setenv("NVIDIA_DRIVER_CAPABILITIES", "graphics")
97
  monkeypatch.setenv("VK_ICD_FILENAMES", "/tmp/custom_icd.json")
@@ -100,6 +104,7 @@ def test_configure_cpu_only_runtime_preserves_existing_vk_icd(monkeypatch, reloa
100
  main = reload_module("main")
101
  monkeypatch.setenv("CUDA_VISIBLE_DEVICES", "5")
102
  monkeypatch.setenv("NVIDIA_VISIBLE_DEVICES", "all")
 
103
  monkeypatch.setenv("SAPIEN_RENDER_DEVICE", "cuda")
104
  monkeypatch.setenv("NVIDIA_DRIVER_CAPABILITIES", "graphics")
105
  monkeypatch.setenv("VK_ICD_FILENAMES", "/tmp/preserved_icd.json")
@@ -109,6 +114,7 @@ def test_configure_cpu_only_runtime_preserves_existing_vk_icd(monkeypatch, reloa
109
 
110
  assert os.environ["CUDA_VISIBLE_DEVICES"] == "-1"
111
  assert os.environ["NVIDIA_VISIBLE_DEVICES"] == "void"
 
112
  assert os.environ["VK_ICD_FILENAMES"] == "/tmp/preserved_icd.json"
113
  assert "NVIDIA_DRIVER_CAPABILITIES" not in os.environ
114
  assert "SAPIEN_RENDER_DEVICE" not in os.environ
@@ -127,4 +133,5 @@ def test_configure_cpu_only_runtime_clears_stale_sapien_render_device(monkeypatc
127
 
128
  assert os.environ["CUDA_VISIBLE_DEVICES"] == "-1"
129
  assert os.environ["NVIDIA_VISIBLE_DEVICES"] == "void"
 
130
  assert "SAPIEN_RENDER_DEVICE" not in os.environ
 
7
 
8
 
9
  DEFAULT_LLVMPipe_ICD = "/usr/share/vulkan/icd.d/lvp_icd.x86_64.json"
10
+ DEFAULT_CPU_RENDER_BACKEND = "pci:0"
11
 
12
 
13
  class _FakeDemo:
 
55
  assert fake_demo.launch_kwargs["head"] == fake_demo.head
56
  assert os.environ["CUDA_VISIBLE_DEVICES"] == "-1"
57
  assert os.environ["NVIDIA_VISIBLE_DEVICES"] == "void"
58
+ assert os.environ["ROBOMME_RENDER_BACKEND"] == DEFAULT_CPU_RENDER_BACKEND
59
  assert os.environ["VK_ICD_FILENAMES"] == "/tmp/another_nvidia_icd.json"
60
  assert "NVIDIA_DRIVER_CAPABILITIES" not in os.environ
61
  assert "SAPIEN_RENDER_DEVICE" not in os.environ
 
85
 
86
  assert os.environ["CUDA_VISIBLE_DEVICES"] == "-1"
87
  assert os.environ["NVIDIA_VISIBLE_DEVICES"] == "void"
88
+ assert os.environ["ROBOMME_RENDER_BACKEND"] == DEFAULT_CPU_RENDER_BACKEND
89
  assert os.environ["VK_ICD_FILENAMES"] == DEFAULT_LLVMPipe_ICD
90
  assert "NVIDIA_DRIVER_CAPABILITIES" not in os.environ
91
  assert "SAPIEN_RENDER_DEVICE" not in os.environ
 
95
  def test_configure_cpu_only_runtime_preserves_existing_vk_icd(monkeypatch, reload_module):
96
  monkeypatch.setenv("CUDA_VISIBLE_DEVICES", "4")
97
  monkeypatch.setenv("NVIDIA_VISIBLE_DEVICES", "all")
98
+ monkeypatch.setenv("ROBOMME_RENDER_BACKEND", "pci:9")
99
  monkeypatch.setenv("SAPIEN_RENDER_DEVICE", "cuda")
100
  monkeypatch.setenv("NVIDIA_DRIVER_CAPABILITIES", "graphics")
101
  monkeypatch.setenv("VK_ICD_FILENAMES", "/tmp/custom_icd.json")
 
104
  main = reload_module("main")
105
  monkeypatch.setenv("CUDA_VISIBLE_DEVICES", "5")
106
  monkeypatch.setenv("NVIDIA_VISIBLE_DEVICES", "all")
107
+ monkeypatch.setenv("ROBOMME_RENDER_BACKEND", "pci:7")
108
  monkeypatch.setenv("SAPIEN_RENDER_DEVICE", "cuda")
109
  monkeypatch.setenv("NVIDIA_DRIVER_CAPABILITIES", "graphics")
110
  monkeypatch.setenv("VK_ICD_FILENAMES", "/tmp/preserved_icd.json")
 
114
 
115
  assert os.environ["CUDA_VISIBLE_DEVICES"] == "-1"
116
  assert os.environ["NVIDIA_VISIBLE_DEVICES"] == "void"
117
+ assert os.environ["ROBOMME_RENDER_BACKEND"] == "pci:0"
118
  assert os.environ["VK_ICD_FILENAMES"] == "/tmp/preserved_icd.json"
119
  assert "NVIDIA_DRIVER_CAPABILITIES" not in os.environ
120
  assert "SAPIEN_RENDER_DEVICE" not in os.environ
 
133
 
134
  assert os.environ["CUDA_VISIBLE_DEVICES"] == "-1"
135
  assert os.environ["NVIDIA_VISIBLE_DEVICES"] == "void"
136
+ assert os.environ["ROBOMME_RENDER_BACKEND"] == DEFAULT_CPU_RENDER_BACKEND
137
  assert "SAPIEN_RENDER_DEVICE" not in os.environ
human_readme.md CHANGED
@@ -155,6 +155,7 @@ A2: This Docker image is configured for CPU-only execution and should not rely o
155
  ```python
156
  os.environ['CUDA_VISIBLE_DEVICES'] = '-1'
157
  os.environ['NVIDIA_VISIBLE_DEVICES'] = 'void'
 
158
  os.environ.pop('SAPIEN_RENDER_DEVICE', None)
159
  os.environ.pop('NVIDIA_DRIVER_CAPABILITIES', None)
160
  os.environ.pop('MUJOCO_GL', None)
 
155
  ```python
156
  os.environ['CUDA_VISIBLE_DEVICES'] = '-1'
157
  os.environ['NVIDIA_VISIBLE_DEVICES'] = 'void'
158
+ os.environ.setdefault('ROBOMME_RENDER_BACKEND', 'pci:0') # llvmpipe software Vulkan on CPU
159
  os.environ.pop('SAPIEN_RENDER_DEVICE', None)
160
  os.environ.pop('NVIDIA_DRIVER_CAPABILITIES', None)
161
  os.environ.pop('MUJOCO_GL', None)
src/robomme/__init__.py CHANGED
@@ -0,0 +1,28 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """RoboMME package initialization."""
2
+
3
+ from __future__ import annotations
4
+
5
+
6
+ def _patch_maniskill_pci_render_backend() -> None:
7
+ """Allow ManiSkill to pass PCI-style Vulkan device strings through intact."""
8
+ try:
9
+ from mani_skill.envs.utils.system import backend as ms_backend
10
+ except Exception:
11
+ return
12
+
13
+ if getattr(ms_backend, "_robomme_pci_backend_patch", False):
14
+ return
15
+
16
+ original = ms_backend.parse_backend_device_id
17
+
18
+ def patched_parse_backend_device_id(backend: str):
19
+ if isinstance(backend, str) and backend.startswith("pci:"):
20
+ return backend, None
21
+ return original(backend)
22
+
23
+ ms_backend.parse_backend_device_id = patched_parse_backend_device_id
24
+ ms_backend._robomme_pci_backend_patch = True
25
+
26
+
27
+ _patch_maniskill_pci_render_backend()
28
+
src/robomme/env_record_wrapper/episode_config_resolver.py CHANGED
@@ -14,6 +14,7 @@ DATASET_ROOT = Path(__file__).resolve().parents[1] / "env_metadata"
14
 
15
  _ALLOWED_DATASETS = {"train", "test"}
16
  _ALLOWED_ACTION_SPACES = {"joint_angle", "ee_pose", "waypoint", "multi_choice"}
 
17
  _DEFAULT_TASK_LIST = [
18
  "PickXtimes",
19
  "StopCube",
@@ -87,6 +88,16 @@ def get_episode_metadata(
87
  return metadata_index.get((task, episode))
88
 
89
 
 
 
 
 
 
 
 
 
 
 
90
  class BenchmarkEnvBuilder:
91
  """
92
  Episode environment builder.
@@ -196,7 +207,7 @@ class BenchmarkEnvBuilder:
196
  render_mode=self.render_mode,
197
  reward_mode="dense",
198
  sim_backend="physx_cpu",
199
- render_backend="sapien_cpu",
200
  )
201
  if seed is not None:
202
  env_kwargs["seed"] = seed
 
14
 
15
  _ALLOWED_DATASETS = {"train", "test"}
16
  _ALLOWED_ACTION_SPACES = {"joint_angle", "ee_pose", "waypoint", "multi_choice"}
17
+ _DEFAULT_CPU_RENDER_BACKEND = "pci:0"
18
  _DEFAULT_TASK_LIST = [
19
  "PickXtimes",
20
  "StopCube",
 
88
  return metadata_index.get((task, episode))
89
 
90
 
91
+ def resolve_render_backend(default: str = _DEFAULT_CPU_RENDER_BACKEND) -> str:
92
+ """Resolve the render backend for CPU-only execution.
93
+
94
+ Docker CPU mode uses llvmpipe, which SAPIEN exposes as a Vulkan PCI device
95
+ rather than the string "cpu".
96
+ """
97
+ value = str(os.environ.get("ROBOMME_RENDER_BACKEND", default)).strip()
98
+ return value or default
99
+
100
+
101
  class BenchmarkEnvBuilder:
102
  """
103
  Episode environment builder.
 
207
  render_mode=self.render_mode,
208
  reward_mode="dense",
209
  sim_backend="physx_cpu",
210
+ render_backend=resolve_render_backend(),
211
  )
212
  if seed is not None:
213
  env_kwargs["seed"] = seed