From 16bd193fdcc05299e2b2949cb55446bdfeef0eb5 Mon Sep 17 00:00:00 2001 From: TATP-233 Date: Mon, 2 Nov 2026 16:50:31 +0800 Subject: [PATCH 1/2] release: unilab 1.5.5 Co-Authored-By: Claude Code --- docs/sphinx/source/changelog.md | 9 +++++++++ pyproject.rocm.toml | 6 +++--- pyproject.toml | 8 ++++---- uv.lock | 14 +++++++------- uv.rocm.lock | 12 ++++++------ 5 files changed, 29 insertions(+), 20 deletions(-) diff --git a/docs/sphinx/source/changelog.md b/docs/sphinx/source/changelog.md index 05cf084c4..2ba7da7c5 100644 --- a/docs/sphinx/source/changelog.md +++ b/docs/sphinx/source/changelog.md @@ -13,6 +13,15 @@ UniLab 遵循[语义化版本](https://semver.org/)。本共享页面以中英 PyPI 版本变更与未发布变更;发布日期采用 PyPI 上传日期。完整提交历史请参阅 [UniLab 仓库](https://github.com/unilabsim/UniLab)。 +## 1.5.5 (2026-11-02) + +### Changed / 变更 + +- The default and ROCm profiles now pin `unisim-core==2.4.0`, including the + Motrix and SuperDex extras. + 默认与 ROCm profile 现在均钉定 `unisim-core==2.4.0`,包括 Motrix 与 + SuperDex extra。 + ## 1.5.4 (2026-10-31) ### Changed / 变更 diff --git a/pyproject.rocm.toml b/pyproject.rocm.toml index 26f1b68af..07c9c5a73 100644 --- a/pyproject.rocm.toml +++ b/pyproject.rocm.toml @@ -4,7 +4,7 @@ build-backend = "uv_build" [project] name = "unilab" -version = "1.5.4" +version = "1.5.5" description = "Universal Lab for Robot Learning" readme = "README.md" license = "Apache-2.0" @@ -23,7 +23,7 @@ classifiers = [ requires-python = ">=3.10,<3.14" dependencies = [ "numpy", - "unisim-core==2.3.0", + "unisim-core==2.4.0", "prettytable>=3.10", "torch==2.14.0", "triton-rocm==3.8.0 ; sys_platform == 'linux' and platform_machine == 'x86_64'", @@ -68,7 +68,7 @@ mujoco = [ "mujoco~=3.11.0", "mjbatch-uni~=0.2.5", ] -motrix = ["unisim-core[motrix]==2.3.0"] +motrix = ["unisim-core[motrix]==2.4.0"] genesis = ["genesis-world==1.3.3"] # Keep the training-stack extra aligned with pyproject.toml. unirl = [ diff --git a/pyproject.toml b/pyproject.toml index 012f2df13..774b796ce 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -14,7 +14,7 @@ source-exclude = [ [project] name = "unilab" -version = "1.5.4" +version = "1.5.5" description = "Configurable, contract-driven robot learning across physics backends" readme = "README.md" license = "Apache-2.0" @@ -33,7 +33,7 @@ classifiers = [ requires-python = ">=3.10,<3.14" dependencies = [ "numpy", - "unisim-core==2.3.0", + "unisim-core==2.4.0", "prettytable>=3.10", # A range (not an exact pin) lets ROCm users substitute a ROCm torch # build; uv.lock pins the tested CUDA builds via tool.uv.sources. @@ -102,12 +102,12 @@ newton = [ "pyglet>=2.1.6,<3", "imgui-bundle>=1.92.0", ] -motrix = ["unisim-core[motrix]==2.3.0"] +motrix = ["unisim-core[motrix]==2.4.0"] genesis = ["genesis-world==1.3.3"] # Wheels are CPython 3.12/3.13 Linux x86_64 only; the marker keeps uv lock # resolvable for the other required-environments. superdex = [ - "unisim-core[superdex]==2.3.0 ; python_version >= '3.12' and sys_platform == 'linux' and platform_machine == 'x86_64'", + "unisim-core[superdex]==2.4.0 ; python_version >= '3.12' and sys_platform == 'linux' and platform_machine == 'x86_64'", ] # Tensor ray perception is optional and is discovered through UniSim's public # caster factory. The PyPI distribution is `uniray`; the import namespace is diff --git a/uv.lock b/uv.lock index 7c39c75c8..f04552cfa 100644 --- a/uv.lock +++ b/uv.lock @@ -5155,7 +5155,7 @@ wheels = [ [[package]] name = "unilab" -version = "1.5.4" +version = "1.5.5" source = { editable = "." } dependencies = [ { name = "etils", version = "1.13.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11'" }, @@ -5274,9 +5274,9 @@ requires-dist = [ { name = "trimesh", specifier = ">=3.21.7" }, { name = "typing-extensions" }, { name = "uniray", extras = ["warp"], marker = "extra == 'ray'", specifier = "==0.1.1" }, - { name = "unisim-core", specifier = "==2.3.0" }, - { name = "unisim-core", extras = ["motrix"], marker = "extra == 'motrix'", specifier = "==2.3.0" }, - { name = "unisim-core", extras = ["superdex"], marker = "python_full_version >= '3.12' and platform_machine == 'x86_64' and sys_platform == 'linux' and extra == 'superdex'", specifier = "==2.3.0" }, + { name = "unisim-core", specifier = "==2.4.0" }, + { name = "unisim-core", extras = ["motrix"], marker = "extra == 'motrix'", specifier = "==2.4.0" }, + { name = "unisim-core", extras = ["superdex"], marker = "python_full_version >= '3.12' and platform_machine == 'x86_64' and sys_platform == 'linux' and extra == 'superdex'", specifier = "==2.4.0" }, { name = "viser", specifier = ">=1.0.26" }, { name = "wandb", marker = "extra == 'unirl'", specifier = ">=0.22.3" }, { name = "warp-lang", marker = "extra == 'mjwarp'", specifier = "==1.16.0" }, @@ -5314,15 +5314,15 @@ warp = [ [[package]] name = "unisim-core" -version = "2.3.0" +version = "2.4.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "numpy", version = "2.2.6", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11'" }, { name = "numpy", version = "2.4.4", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/31/ba/960eb850827015f38c9533aa634fdd9cecfdfe9bfcb13c5ab73afc8dc9fe/unisim_core-2.3.0.tar.gz", hash = "sha256:72a2cf426c871bbc8ebdd9fe67aceac605bb7f565f6a089a4c2d4a6979e50b08", size = 760373, upload-time = "2026-10-31T09:33:04.774Z" } +sdist = { url = "https://files.pythonhosted.org/packages/15/2d/e7bc4b34ae8151d9c60cc9a71999f75a0a836f694b25f5d9fff62ee6fe28/unisim_core-2.4.0.tar.gz", hash = "sha256:2e02996c0d8e0cd8a3835778dead20f9b9d85a6ede3993e4f9f4d053c4280cb3", size = 761193, upload-time = "2026-11-02T08:35:07.48Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/1c/01/eae91b154d0873f61aa35e3a8b1887feb4230aa0c4c0421109fc4bd922d9/unisim_core-2.3.0-py3-none-any.whl", hash = "sha256:5525bf7260c50d9ec684c1cc43cb0761fc7e65ac9ba3d44731e7dcfb0c96157b", size = 808722, upload-time = "2026-10-31T09:33:02.623Z" }, + { url = "https://files.pythonhosted.org/packages/71/b8/9dadd2628879d3f4d288a7ed7a12a52020d5a172d2214cea334d5ae57208/unisim_core-2.4.0-py3-none-any.whl", hash = "sha256:e4244848a9a1baa40f6986c3b887c28df243a0ea259b007ee2ca2012e28104aa", size = 809541, upload-time = "2026-11-02T08:35:05.731Z" }, ] [package.optional-dependencies] diff --git a/uv.rocm.lock b/uv.rocm.lock index 8197da5f7..05165f98c 100644 --- a/uv.rocm.lock +++ b/uv.rocm.lock @@ -4688,7 +4688,7 @@ wheels = [ [[package]] name = "unilab" -version = "1.5.4" +version = "1.5.5" source = { editable = "." } dependencies = [ { name = "etils", version = "1.13.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11'" }, @@ -4782,8 +4782,8 @@ requires-dist = [ { name = "trimesh", specifier = ">=3.21.7" }, { name = "triton-rocm", marker = "platform_machine == 'x86_64' and sys_platform == 'linux'", specifier = "==3.8.0", index = "https://download.pytorch.org/whl/rocm7.2" }, { name = "typing-extensions" }, - { name = "unisim-core", specifier = "==2.3.0" }, - { name = "unisim-core", extras = ["motrix"], marker = "extra == 'motrix'", specifier = "==2.3.0" }, + { name = "unisim-core", specifier = "==2.4.0" }, + { name = "unisim-core", extras = ["motrix"], marker = "extra == 'motrix'", specifier = "==2.4.0" }, { name = "viser", specifier = ">=1.0.26" }, { name = "wandb", marker = "extra == 'unirl'", specifier = ">=0.22.3" }, ] @@ -4800,15 +4800,15 @@ dev = [ [[package]] name = "unisim-core" -version = "2.3.0" +version = "2.4.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "numpy", version = "2.2.6", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11'" }, { name = "numpy", version = "2.4.4", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/31/ba/960eb850827015f38c9533aa634fdd9cecfdfe9bfcb13c5ab73afc8dc9fe/unisim_core-2.3.0.tar.gz", hash = "sha256:72a2cf426c871bbc8ebdd9fe67aceac605bb7f565f6a089a4c2d4a6979e50b08", size = 760373, upload-time = "2026-10-31T09:33:04.774Z" } +sdist = { url = "https://files.pythonhosted.org/packages/15/2d/e7bc4b34ae8151d9c60cc9a71999f75a0a836f694b25f5d9fff62ee6fe28/unisim_core-2.4.0.tar.gz", hash = "sha256:2e02996c0d8e0cd8a3835778dead20f9b9d85a6ede3993e4f9f4d053c4280cb3", size = 761193, upload-time = "2026-11-02T08:35:07.48Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/1c/01/eae91b154d0873f61aa35e3a8b1887feb4230aa0c4c0421109fc4bd922d9/unisim_core-2.3.0-py3-none-any.whl", hash = "sha256:5525bf7260c50d9ec684c1cc43cb0761fc7e65ac9ba3d44731e7dcfb0c96157b", size = 808722, upload-time = "2026-10-31T09:33:02.623Z" }, + { url = "https://files.pythonhosted.org/packages/71/b8/9dadd2628879d3f4d288a7ed7a12a52020d5a172d2214cea334d5ae57208/unisim_core-2.4.0-py3-none-any.whl", hash = "sha256:e4244848a9a1baa40f6986c3b887c28df243a0ea259b007ee2ca2012e28104aa", size = 809541, upload-time = "2026-11-02T08:35:05.731Z" }, ] [package.optional-dependencies] From bdad5abd163e32c180f619213c8fc09410ca5037 Mon Sep 17 00:00:00 2001 From: TATP-233 Date: Mon, 2 Nov 2026 17:11:54 +0800 Subject: [PATCH 2/2] fix(tests): align motrix root-state layout test with unisim-core 2.4.0 unisim-core 2.4.0 gates the non-portable Motrix get_root_state_layout on the configured base name and publishes fixed 7/6 root columns instead of the selected body's floating-base indices. Update the unit test and regenerate the stale support matrix (Motrix fixed-variants capability now reports "unknown"). Co-Authored-By: Claude Code --- .../source/en/5-reference/5-support_matrix.md | 2 +- .../zh_CN/5-reference/5-support_matrix.md | 2 +- tests/base/test_motrix_backend_options.py | 17 +++++++---------- 3 files changed, 9 insertions(+), 12 deletions(-) diff --git a/docs/sphinx/source/en/5-reference/5-support_matrix.md b/docs/sphinx/source/en/5-reference/5-support_matrix.md index 96f21f0dd..66f71e6e7 100644 --- a/docs/sphinx/source/en/5-reference/5-support_matrix.md +++ b/docs/sphinx/source/en/5-reference/5-support_matrix.md @@ -76,7 +76,7 @@ This table is derived from UniSim's SDK-free public static inventory. It describ | Backend | Execution / process / data plane | Torch devices | CUDA runtime | Linux+CUDA | macOS | ROCm | Worker | Reset randomization | Fixed variants | Host callbacks | Packed bridge | |---|---|---|---|---|---|---|---|---|---|---|---| | `mujoco` | Host bridge / in-process / host bridge | CPU / CUDA | Required only when the learner requests CUDA state/control buffers | Supported: CPU-authoritative physics with optional CUDA Torch buffers | CPU-authoritative host bridge only; no CUDA physics claim | CPU-authoritative host bridge with explicit ROCm Torch buffers (`cuda`) | In-process; no external Python worker | unknown | unknown | Unsupported | Exact | -| `motrix` | Host bridge / in-process / host bridge | CPU / CUDA | Required only when the learner requests CUDA state/control buffers | Supported: CPU-authoritative physics with optional CUDA Torch buffers | CPU-authoritative host bridge only; no CUDA physics claim | CPU-authoritative host bridge with explicit ROCm Torch buffers (`cuda`) | In-process; no external Python worker | unknown | Unsupported | Unsupported | Exact | +| `motrix` | Host bridge / in-process / host bridge | CPU / CUDA | Required only when the learner requests CUDA state/control buffers | Supported: CPU-authoritative physics with optional CUDA Torch buffers | CPU-authoritative host bridge only; no CUDA physics claim | CPU-authoritative host bridge with explicit ROCm Torch buffers (`cuda`) | In-process; no external Python worker | unknown | unknown | Unsupported | Exact | | `drake` | Host bridge / in-process / host bridge | CPU / CUDA | Required only when the learner requests CUDA state/control buffers | Supported: CPU-authoritative physics with optional CUDA Torch buffers | CPU-authoritative host bridge only; no CUDA physics claim | CPU-authoritative host bridge with explicit ROCm Torch buffers (`cuda`) | In-process; no external Python worker | Unsupported | Unsupported | Unsupported | Exact | | `mjwarp` | Device-resident / in-process / direct | CUDA | Required for the entire tensor lifecycle | Supported: Linux CUDA only | Unsupported; no CPU, MPS, or ROCm fallback | Unsupported; no CPU, MPS, or ROCm fallback | In-process; no external Python worker | Unsupported | Unsupported | Unsupported | Unsupported | | `newton` | Device-resident / in-process / direct | CUDA | Required for the entire tensor lifecycle | Supported: Linux CUDA only | Unsupported; no CPU, MPS, or ROCm fallback | Unsupported; no CPU, MPS, or ROCm fallback | In-process; no external Python worker | Exact | Unsupported | Unsupported | Unsupported | diff --git a/docs/sphinx/source/zh_CN/5-reference/5-support_matrix.md b/docs/sphinx/source/zh_CN/5-reference/5-support_matrix.md index c39629725..80ca0f8ec 100644 --- a/docs/sphinx/source/zh_CN/5-reference/5-support_matrix.md +++ b/docs/sphinx/source/zh_CN/5-reference/5-support_matrix.md @@ -68,7 +68,7 @@ uv run scripts/generate_support_matrix.py --write | Backend | Execution / process / data plane | Torch devices | CUDA runtime | Linux+CUDA | macOS | ROCm | Worker | Reset randomization | Fixed variants | Host callbacks | Packed bridge | |---|---|---|---|---|---|---|---|---|---|---|---| | `mujoco` | Host bridge / in-process / host bridge | CPU / CUDA | Required only when the learner requests CUDA state/control buffers | Supported: CPU-authoritative physics with optional CUDA Torch buffers | CPU-authoritative host bridge only; no CUDA physics claim | CPU-authoritative host bridge with explicit ROCm Torch buffers (`cuda`) | In-process; no external Python worker | unknown | unknown | 不支持 | 支持 | -| `motrix` | Host bridge / in-process / host bridge | CPU / CUDA | Required only when the learner requests CUDA state/control buffers | Supported: CPU-authoritative physics with optional CUDA Torch buffers | CPU-authoritative host bridge only; no CUDA physics claim | CPU-authoritative host bridge with explicit ROCm Torch buffers (`cuda`) | In-process; no external Python worker | unknown | 不支持 | 不支持 | 支持 | +| `motrix` | Host bridge / in-process / host bridge | CPU / CUDA | Required only when the learner requests CUDA state/control buffers | Supported: CPU-authoritative physics with optional CUDA Torch buffers | CPU-authoritative host bridge only; no CUDA physics claim | CPU-authoritative host bridge with explicit ROCm Torch buffers (`cuda`) | In-process; no external Python worker | unknown | unknown | 不支持 | 支持 | | `drake` | Host bridge / in-process / host bridge | CPU / CUDA | Required only when the learner requests CUDA state/control buffers | Supported: CPU-authoritative physics with optional CUDA Torch buffers | CPU-authoritative host bridge only; no CUDA physics claim | CPU-authoritative host bridge with explicit ROCm Torch buffers (`cuda`) | In-process; no external Python worker | 不支持 | 不支持 | 不支持 | 支持 | | `mjwarp` | Device-resident / in-process / direct | CUDA | Required for the entire tensor lifecycle | Supported: Linux CUDA only | Unsupported; no CPU, MPS, or ROCm fallback | Unsupported; no CPU, MPS, or ROCm fallback | In-process; no external Python worker | 不支持 | 不支持 | 不支持 | 不支持 | | `newton` | Device-resident / in-process / direct | CUDA | Required for the entire tensor lifecycle | Supported: Linux CUDA only | Unsupported; no CPU, MPS, or ROCm fallback | Unsupported; no CPU, MPS, or ROCm fallback | In-process; no external Python worker | 支持 | 不支持 | 不支持 | 不支持 | diff --git a/tests/base/test_motrix_backend_options.py b/tests/base/test_motrix_backend_options.py index 0c592cb46..63fad5af4 100644 --- a/tests/base/test_motrix_backend_options.py +++ b/tests/base/test_motrix_backend_options.py @@ -332,27 +332,24 @@ def test_motrix_body_sensor_views_use_canonical_world_state() -> None: np.testing.assert_allclose(views["track_angvel_w_base"], [[13, 14, 15], [16, 17, 18]]) -def test_motrix_root_layout_uses_selected_body_floating_base_indices() -> None: +def test_motrix_root_layout_gates_on_configured_base_and_returns_fixed_columns() -> None: import unisim.backend.motrix.backend as mod - floating_base = SimpleNamespace( - dof_pos_indices=[4, 5, 6, 7, 8, 9, 10], - dof_vel_indices=[3, 4, 5, 6, 7, 8], - ) bodies = { "fixed": SimpleNamespace(floatingbase=None), - "floating": SimpleNamespace(floatingbase=floating_base), + "floating": SimpleNamespace(floatingbase=SimpleNamespace()), } backend = object.__new__(mod.MotrixBackend) backend._portable_mode = False + backend._base_name = "floating" backend._model = SimpleNamespace(get_body=lambda name: bodies.get(name)) layout = backend.get_root_state_layout("floating") - assert layout.qpos_indices == tuple(range(4, 11)) - assert layout.qvel_indices == tuple(range(3, 9)) - with pytest.raises(NotImplementedError, match="fixed.*floating base"): + assert layout.qpos_indices == tuple(range(7)) + assert layout.qvel_indices == tuple(range(6)) + with pytest.raises(NotImplementedError, match="configured base"): backend.get_root_state_layout("fixed") - with pytest.raises(ValueError, match="missing.*not found"): + with pytest.raises(NotImplementedError, match="configured base"): backend.get_root_state_layout("missing")