Skip to content

Commit 0eb2589

Browse files
camevorooctipuskellyguo11
authored
[Newton] Delegate homogeneous world prefix generation to ModelBuilder.replicate() (#7453)
# Description This depends on newton-physics/newton#4012 and pins the Newton 1.6 development build that first provides `ModelBuilder.replicate(..., label_prefixes=...)`. The homogeneous Newton cloning path previously replicated the model and then walked every replicated entity label to replace the prototype environment with its destination environment. It now rebases only the retained prototype labels, restores them after the call, and lets `ModelBuilder.replicate()` assign each copy's destination prefix while it is created. String-valued custom attributes still use the existing targeted rewrite because Newton cannot identify which strings are entity paths. The destination itself is the source of identity: prefixes are derived from the queued source/destination mapping. No clone-plan environment metadata, scene discovery, fallback clone path, or retained prototype mutation is introduced. Labels exactly at a directly cloned asset root, including Newton's `_free_joint` and `_articulation` companion labels, are expressed relative to the nearest templated destination ancestor and remain on the same fast path. The Newton commit pin is mirrored in workspace and wheel installation inputs so every supported install receives the API this path requires. The final PR is `+195/-218`, net **-23 LOC**. ## Performance GPU 0, 4096 worlds, two samples per PR head. The targeted measurement uses one 48-body/48-shape Newton prototype and times replication plus all required label publication: | Head | Targeted path median | Versus develop | |---|---:|---:| | develop base (`3a31389a9`) | 1.428 s | — | | original PR (`cbb17ab6e`) | 1.160 s | -18.8% | | cleaned PR (`844f4c4db`) | 1.171 s | **-18.0%** | The cleanup is within 1.0% (11 ms) of the original PR result and preserves the removed-pass gain. The 257 ms reduction from develop is consistent with the original 215 ms observation on `Isaac-Velocity-Flat-G1`. Whole-workload check used: ```bash CUDA_VISIBLE_DEVICES=0 uv run --no-sync isaaclab zero_agent \ --task Isaac-Lift-KukaAllegro --num_envs 4096 --max_steps 1 \ --device cuda:0 --visualizer none physics=newton_mjwarp ``` | Head | Warm wall median | Scene creation median | |---|---:|---:| | original PR | 21.30 s | 6.324 s | | cleaned PR | 21.39 s | 6.345 s | That end-to-end difference is within startup noise; the cleanup introduces no measured workload regression. ## Type of change - Startup performance enhancement ## Validation - 81 focused clone, Newton, visualization-state, wheel-metadata, and install tests passed. - Ruff formatting and lint checks passed. - Exact-root, sparse-environment, hook-authored-label, custom-attribute, and retained-prototype cases are covered. - The changelog fragment is present for the changed Newton package. ## Checklist - [x] I have read and understood the contribution guidelines - [x] My changes generate no new warnings - [x] I have added tests that prove the fix is effective - [x] I have added the required changelog fragment - [x] My name already exists in `CONTRIBUTORS.md` --------- Signed-off-by: Kelly Guo <kellyg@nvidia.com> Co-authored-by: Octi Zhang <zhengyuz@nvidia.com> Co-authored-by: Kelly Guo <kellyg@nvidia.com>
1 parent 8fbdc38 commit 0eb2589

20 files changed

Lines changed: 305 additions & 225 deletions

docker/test/test_dockerfile_nonroot.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -169,6 +169,15 @@ def test_kitless_dockerfile_installs_newton_rl_ov_and_visualizers_without_isaac_
169169
)
170170

171171

172+
def test_container_test_runner_only_links_an_actual_isaac_sim_runtime():
173+
"""Cache mount points under /isaac-sim must not masquerade as an Isaac Sim installation."""
174+
runner_text = (REPO_ROOT / ".github/actions/run-tests/run_tests.sh").read_text(encoding="utf-8")
175+
guarded_link = re.compile(r"if \[ -x /isaac-sim/python\.sh \]; then\s+ln -s /isaac-sim _isaac_sim;?\s+fi")
176+
177+
assert guarded_link.search(runner_text)
178+
assert runner_text.count("ln -s /isaac-sim _isaac_sim") == 1
179+
180+
172181
# --------------------------------------------------------------------------- #
173182
# Volume mount-point writability
174183
#

pyproject.toml

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -85,9 +85,8 @@ dependencies = [
8585
"rsl-rl-lib==5.4.1", # default RL framework
8686
"onnxscript>=0.5",
8787
# ----- newton (default physics engine) -----
88-
# Loose bound so the wheel co-resolves with isaacsim's newton[sim]==1.2.0 pin; the
89-
# exact PyPI release is forced via [tool.uv].override-dependencies (uv sync only).
90-
"newton[sim]>=1.2.0",
88+
# Pin the Newton build used by both workspace and wheel installs until the 1.6 release.
89+
"newton[sim] @ git+https://github.com/newton-physics/newton.git@24bd863528d6b91137408930d0fbe8fa216ad962",
9190
# Import and mesh-processing packages used by Newton, including the ones that honoring
9291
# USD-authored ``physics:approximation`` requires. Keep these explicit instead of selecting
9392
# newton[importers], whose standalone USD dependency would overlap with usd-exchange.
@@ -403,7 +402,7 @@ override-dependencies = [
403402
"numpy>=2",
404403
"mujoco~=3.11.0",
405404
"mujoco-warp~=3.11.0",
406-
"newton[sim]==1.5.1",
405+
"newton[sim] @ git+https://github.com/newton-physics/newton.git@24bd863528d6b91137408930d0fbe8fa216ad962",
407406
# Force the Newton-matched schemas over isaacsim's ==0.2.0 pin.
408407
"newton-usd-schemas>=0.4.1",
409408
"torch==2.11.0",
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
Fixed
2+
^^^^^
3+
4+
* Fixed Docker installs leaving dangling package links in expanded Isaac Sim prebundles.
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Dependency pin coverage is documented by the Newton package fragment.

source/isaaclab/isaaclab/cli/commands/install.py

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1062,10 +1062,14 @@ def _repoint_prebundle_packages() -> None:
10621062
print_debug("No pip_prebundle directories found under Isaac Sim.")
10631063
return
10641064

1065+
# Extras are expanded as wheel trees nested below pip_prebundle.
1066+
package_roots = prebundle_dirs | {
1067+
path for prebundle_dir in prebundle_dirs for path in prebundle_dir.glob("*[[]*[]]/*") if path.is_dir()
1068+
}
10651069
repointed = 0
1066-
for prebundle_dir in prebundle_dirs:
1070+
for package_root in package_roots:
10671071
for pkg_name in _PREBUNDLE_REPOINT_PACKAGES:
1068-
prebundled = prebundle_dir / pkg_name
1072+
prebundled = package_root / pkg_name
10691073
venv_pkg = site_packages / pkg_name
10701074

10711075
if not venv_pkg.exists():
@@ -1118,9 +1122,9 @@ def _repoint_prebundle_packages() -> None:
11181122
# env package into the prebundle, which is a real directory by design.
11191123
if use_symlinks and (site_packages / "torch").exists():
11201124
shadowing = [
1121-
prebundle_dir / "torch"
1122-
for prebundle_dir in prebundle_dirs
1123-
if (prebundle_dir / "torch").is_dir() and not (prebundle_dir / "torch").is_symlink()
1125+
package_root / "torch"
1126+
for package_root in package_roots
1127+
if (package_root / "torch").is_dir() and not (package_root / "torch").is_symlink()
11241128
]
11251129
if shadowing:
11261130
raise RuntimeError(

source/isaaclab/test/cli/test_install_commands.py

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -930,6 +930,25 @@ def test_repoints_across_multiple_prebundle_dirs(self, tmp_path):
930930
for pb in (pb1, pb2):
931931
assert (pb / "torch").is_symlink(), f"torch in {pb} should be repointed"
932932

933+
def test_repoints_package_inside_expanded_extra_bundle(self, tmp_path):
934+
"""Expanded extras bundles must not retain file links into a replaced package."""
935+
isaacsim_path, prebundle = self._sim_with_prebundle(tmp_path / "sim", ["newton"])
936+
shared_init = prebundle / "newton" / "legacy" / "__init__.py"
937+
shared_init.parent.mkdir()
938+
shared_init.write_text("")
939+
bundled_newton = prebundle / "newton[sim]" / "newton-wheel" / "newton"
940+
bundled_init = bundled_newton / "legacy" / "__init__.py"
941+
bundled_init.parent.mkdir(parents=True)
942+
bundled_init.symlink_to(shared_init)
943+
site_pkgs = _make_site_packages(tmp_path / "env", ["newton"])
944+
945+
with self._patch(isaacsim_path, site_pkgs, str(tmp_path / "env" / "bin" / "python")):
946+
_repoint_prebundle_packages()
947+
948+
assert (prebundle / "newton").resolve() == (site_pkgs / "newton").resolve()
949+
assert bundled_newton.is_symlink()
950+
assert bundled_newton.resolve() == (site_pkgs / "newton").resolve()
951+
933952
# ---- Windows: copy instead of symlink -----------------------------------
934953

935954
def test_copies_package_on_windows_instead_of_symlinking(self, tmp_path):

source/isaaclab/test/install_ci/uv_pip/test_uv_pip_install_isaaclab_all_trains_cartpole.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,8 @@
1515
Reinstall AFTER the wheel install: unsafe-best-match re-resolves torch from PyPI to CPU.)
1616
- (aarch64 only) export LD_PRELOAD=/lib/aarch64-linux-gnu/libgomp.so.1
1717
Tests:
18-
- python -c "import importlib.metadata as m; assert m.version('newton') == '1.5.1'"
19-
-> verify the wheel resolves Newton 1.5
18+
- python -c "import importlib.metadata as m; assert m.version('newton') == '1.6.0.dev0'"
19+
-> verify the wheel resolves the pinned Newton 1.6 development build
2020
- uv run isaaclab train --rl_library rsl_rl --task Isaac-Cartpole-Direct --num_envs 16
2121
presets=newton_mjwarp --max_iterations 5; uv run isaaclab train --rl_library rsl_rl
2222
--task Isaac-Cartpole-Camera-Direct --num_envs 16 presets=newton_mjwarp,newton_renderer --max_iterations 2
@@ -57,11 +57,11 @@ def test_uv_pip_install_isaaclab_all_trains_cartpole(self, isaaclab_root, wheel,
5757
assert result.returncode == 0, f"uv pip install {wheel}[all] failed:\n{result.stdout}\n{result.stderr}"
5858

5959
result = self.run_in_uv_env(
60-
["python", "-c", "import importlib.metadata as m; assert m.version('newton') == '1.5.1'"],
60+
["python", "-c", "import importlib.metadata as m; assert m.version('newton') == '1.6.0.dev0'"],
6161
cwd=isaaclab_root,
6262
)
6363
assert result.returncode == 0, (
64-
f"isaaclab[all] did not resolve Newton 1.5:\n{result.stdout}\n{result.stderr}"
64+
f"isaaclab[all] did not resolve the pinned Newton build:\n{result.stdout}\n{result.stderr}"
6565
)
6666

6767
# Restore the CUDA build selected for this architecture.

source/isaaclab/test/install_ci/uv_pip/uv-overrides.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
numpy>=2
22
mujoco~=3.11.0
33
mujoco-warp~=3.11.0
4-
newton[sim]==1.5.1
4+
newton[sim] @ git+https://github.com/newton-physics/newton.git@24bd863528d6b91137408930d0fbe8fa216ad962
55
newton-usd-schemas>=0.4.1
66
torch==2.11.0
77
torchvision==0.26.0

source/isaaclab/test/sim/test_newton_manager_visualization_state.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -836,8 +836,7 @@ def test_clone_visualization_builder_ignores_non_env_deformables_on_world_import
836836
monkeypatch.setattr(vb, "_restore_visible_colliders_without_visual_shapes", lambda *args, **kwargs: None)
837837
monkeypatch.setattr(vb, "import_builder_visual_material_paths", lambda *args, **kwargs: None)
838838
monkeypatch.setattr(vb, "build_source_builders", lambda *args, **kwargs: {})
839-
monkeypatch.setattr(vb, "replicate_builder_mapping", lambda *args, **kwargs: None)
840-
monkeypatch.setattr(vb, "rename_builder_labels", lambda *args, **kwargs: None)
839+
monkeypatch.setattr(vb, "replicate_builder_mapping", lambda *args, **kwargs: ({}, [], []))
841840

842841
_builder, (shadow_entities, registry_groups) = vb.build_visualization_builder_from_stage_envs(
843842
stage,
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
Changed
2+
^^^^^^^
3+
4+
* Changed homogeneous Newton cloning to assign labels during replication, avoiding a second full-model pass.

0 commit comments

Comments
 (0)