Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
225a32e
bench(collector): freeze Genesis lifecycle attribution baseline
TATP-233 Oct 25, 2026
2a829bb
bench(genesis): freeze production collector schema
TATP-233 Oct 25, 2026
94e08b1
fix(benchmark): complete production fixation fields
TATP-233 Oct 25, 2026
42ce2a4
fix(benchmark): sample backend read attribution
TATP-233 Oct 25, 2026
2898c38
docs(genesis): document collector benchmark and platform boundary
TATP-233 Oct 25, 2026
88c13bd
style: format collector runtime
TATP-233 Oct 25, 2026
4164eae
feat: integrate tensor ray observations
TATP-233 Oct 25, 2026
4024743
fix: publish shared ray batches with matching shapes
TATP-233 Oct 25, 2026
f524f4a
fix: bind packed ray pose views to the public host packet
TATP-233 Oct 25, 2026
677b709
feat(genesis): support ROCm collector runtime
TATP-233 Oct 26, 2026
76fccb6
Merge remote-tracking branch 'origin/main' into dev/issue-472-ray-per…
TATP-233 Oct 26, 2026
b825ca8
feat: integrate public rich ray perception queries
TATP-233 Oct 26, 2026
1da2b7e
fix(genesis): consume device-plane DR lifecycle
TATP-233 Oct 26, 2026
91bb031
Merge remote-tracking branch 'origin/dev/issue-2520-genesis-dr-lifecy…
TATP-233 Oct 26, 2026
a6690eb
Merge pull request #2522 from Motphys/dev/issue-472-ray-perception
TATP-233 Oct 26, 2026
a616c53
feat: compose parkour ray patterns downstream
TATP-233 Oct 26, 2026
e18d464
Merge Genesis DR lifecycle into ROCm collector runtime
TATP-233 Oct 26, 2026
26b91cf
Merge pull request #2519 from Motphys/feat/issue-471-genesis-rocm
TATP-233 Oct 26, 2026
c8e3dd3
Merge pull request #2524 from Motphys/dev/issue-472-ray-perception
TATP-233 Oct 26, 2026
1bf0017
chore(genesis): remove ROCm investigation scaffolding
TATP-233 Oct 26, 2026
3e29b22
feat(genesis): enable FlashMimic G1 DR owner
TATP-233 Oct 26, 2026
16156d3
feat: consume dynamic ray frames and geometry
TATP-233 Oct 26, 2026
c917531
Merge remote-tracking branch 'origin/dev/issue-2520-genesis-dr-lifecy…
TATP-233 Oct 26, 2026
6e4e282
Merge pull request #2527 from Motphys/dev/issue-472-ray-perception
TATP-233 Oct 26, 2026
e631a25
Merge pull request #2526 from Motphys/dev/issue-2521-genesis-flashmim…
TATP-233 Oct 26, 2026
c64fbe7
Merge pull request #2525 from Motphys/cleanup/issue-471-genesis-rocm
TATP-233 Oct 26, 2026
3313ed8
build(deps): consume published unisim and uniray releases
TATP-233 Oct 26, 2026
5d4633c
test(genesis): preserve device plane in CPU fake
TATP-233 Oct 26, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions docs/sphinx/source/adr/ADR-0000-index.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ orphan: true
| [ADR-0018 Collector Tensor Device Sole Placement Knob](ADR-0018-collector-tensor-device-sole-placement-knob.md) | Training config / off-policy placement | Proposed |
| [ADR-0019 CUDA Learner Forbids CPU Carrier](ADR-0019-cuda-learner-forbids-cpu-carrier.md) | Training config / carrier pairing contract | Proposed |
| [ADR-0020 FlashSAC DP Graph Ownership And Wire Precision](ADR-0020-flashsac-dp-graph-and-wire-precision.md) | RL algorithm / distributed runtime | Proposed |
| [ADR-0021 Genesis Device-Resident DR Lifecycle](ADR-0021-genesis-device-resident-dr-lifecycle.md) | Backend DR / Manager reset plane | Accepted |
| [ADR-0231 Integration-only K=1 MJWarp Collector CUDA Graph](ADR-0231-k1-mjwarp-collector-cuda-graph-integration-only.md) | Collector CUDA graph / historical pre-registration | Rejected / no-go at M2 |
| [ADR-0238 State-Update-Only CUDA Graph Boundary](ADR-0238-state-update-only-cuda-graph-boundary.md) | Manager CUDA graph / historical pre-registration | Rejected / no-go |

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
---
orphan: true
---

# ADR-0021 Genesis Device-Resident DR Lifecycle

语言: 简体中文

- Status: Accepted
- Date: 2026-10-26
- Owners: Simulation backend / Manager runtime maintainers
- Supersedes: None
- Superseded by: None
- Roadmap: [Issue #2520](https://github.com/Motphys/UniLab/issues/2520);
FlashMimic subset extension:
[Issue #2521](https://github.com/Motphys/UniLab/issues/2521)

## Context

Genesis previously carried two runtime-DR profiles. The whole-MJCF exact-CUDA lane exposed a
narrow device-resident packed reset contract, while portable `entity_assets` scenes retained
host-plane model-field setters and a portable-only wrench path. Capability wording also mixed
payload plane with lifecycle support: portable host setters could look like Manager runtime DR
even though the Manager reset transaction requires a device-resident packed commit.

This crossed the public `SimBackend` DR capability boundary and the Manager reset/interval
execution contract. UniSim issue #2520 therefore approved one adapter-level lifecycle decision
before this integration; the authoritative adapter ADR and implementation live in `unisim-core`
(`docs/en/adr-genesis-dr-lifecycle.md`).

## Decision

UniLab consumes the unified contract as device-only Genesis runtime DR:

- Genesis declares reset terms only in `supported_device_reset_terms`, and interval terms only
in `supported_device_interval_terms`. The host term sets are empty, including for portable
scenes and sessions without the exact CUDA/AMDGPU lifecycle.
- Manager capability negotiation selects the plane from the backend-bound tensor device. It never
treats default host capability wording as a fallback for a device-resident runtime.
- The packed reset device is declared before cold event-term binds, so owner terms negotiate
against the same plane that will commit after backend materialization.
- Reset DR is limited to the audited device lifecycle (`body_mass`, `base_mass_delta`,
`body_ipos`, `base_com_offset`, `kp`, `kd`); interval DR is limited to `body_force`,
`body_torque`, world-frame root linear velocity delta, and root-local angular velocity delta.
Unsupported, host-plane, mixed-plane, and CPU/host payloads fail closed with the term and plane
named.
- Genesis owner YAML enables `pd_gains` only because that device-plane packed lane declares
`kp`/`kd`. It does not re-enable broad portable host setters, geometry, gravity, DOF, or the
opaque legacy push descriptor. Startup body mass and the six-axis velocity-delta event use
their audited public device lifecycle; absolute `geom_friction` remains intentionally
fail-closed because upstream Genesis has no equivalent per-environment absolute friction API.
- Event operands and interval body IDs are lifted to the backend-bound device before entering the
public interval plan. A host RNG or NumPy input at a Manager leaf is a cold compatibility edge,
not permission to execute runtime DR on CPU.

## Stable Contracts

- `DomainRandomizationCapabilities` plane sets are authoritative; aggregate projections keep
`dr.reset.*`/`dr.interval.*` and `dr.device.reset.*`/`dr.device.interval.*` independent.
- The Manager packed reset transaction declares its device before reset event construction.
- Genesis interval dispatch uses public `IntervalTermOp` values only; backend IDs are Torch int64
on the backend device and wrench payloads are float32 on that same device.
- Genesis owners cannot declare backend capability by comments or backend-name branches; owner
YAML may only enable terms whose plane the current backend declares.

## Alternatives Considered

- **Default to the historical host plane before packed-device declaration:** rejected. It made a
portable host setter look valid during cold binds and could accept a term that the eventual
device commit must reject.
- **Convert host operands inside each backend adapter:** rejected as the Manager contract. It
reintroduces hidden hot-path H2D detours and plane ambiguity at every adapter boundary.
- **Keep `events.pd_gains: null` until every Genesis reset term is device-capable:** rejected.
`kp`/`kd` have one audited lifecycle; unrelated unsupported terms already fail closed and need
no owner-level blanket disable.

## Consequences

- Genesis SAC and PPO walk owners have the same PD-gain DR default as their MuJoCo counterparts.
- The SAC G1 motion-tracking owner carries the FlashMimic-compatible DR subset: startup
pelvis/torso mass scaling without inertia recomputation, torso COM and full-actuator PD gain
reset writes, and six-axis velocity kicks. Its foot-friction event stays disabled.
- Portable Genesis scenes have a smaller reset contract, and removed portable host runtime paths
have no compatibility alias in UniLab.
- Owners must sample device-resident operands on the Manager RNG/backend device. CPU-only Genesis
sessions do not advertise runtime DR.
- Adding a Genesis reset or interval term requires first extending the audited device lifecycle
and capability declaration in `unisim-core`, then updating owners/docs here.

## Evidence In Repo

- `src/unilab/base/entity.py` — interval plane negotiation and device-resident interval ops.
- `src/unilab/envs/manager_based_rl_env.py` — packed reset device declaration before event binds.
- `src/unilab/base/reset_state.py` — plane-aware capability checks.
- `src/unilab/conf/{ppo,sac}/task/g1_walk_flat/genesis.yaml` — walk owner parity.
- `src/unilab/conf/sac/task/g1_motion_tracking/genesis.yaml` — FlashMimic DR subset owner.
- `tests/base/test_genesis_backend.py`; `tests/envs/mdp/test_events.py`;
`tests/envs/locomotion/g1/test_g1_owner_contract.py`.
- Generated backend support evidence:
`docs/sphinx/source/{en,zh_CN}/5-reference/5-support_matrix.md`.
- Adapter decision: `unisim-core` `docs/en/adr-genesis-dr-lifecycle.md`.

## Related Documents

- {doc}`ADR Index </adr/ADR-0000-index>`
- {doc}`ADR-0012 Sole Tensor Manager And Scoped Backends </adr/ADR-0012-sole-tensor-manager-and-scoped-backends>`
- {doc}`Genesis Backend </en/2-user_guide/3-backends/5-genesis>`
66 changes: 66 additions & 0 deletions docs/sphinx/source/changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,72 @@ UniLab 遵循[语义化版本](https://semver.org/)。本共享页面以中英
PyPI 版本变更与未发布变更;发布日期采用 PyPI 上传日期。完整提交历史请参阅
[UniLab 仓库](https://github.com/unilabsim/UniLab)。

## Unreleased / 未发布

### Added / 新增

- The Manager tensor ray observation now consumes UniSim's full-scene public
`RayCollisionDescription`, so mesh/hfield materialization no longer requires
a backend-specific `uni_ray` builder, and entity-local packed pose reads are
aggregated onto the public full-scene body axis. `RayPatternCfg` supports
ring, parallel-grid, and pinhole-camera ray patterns; body, yaw-only, and
world alignment; body or public-site attachment with a local sensor offset;
`min_distance`; public geom/tag/body/ancestor filters; optional normal and
hit-point outputs in addition to distance; and reset-boundary per-row geometry
synchronization. The optional `ray` extra now resolves the published
`uniray[warp]==0.1.0` distribution in both CUDA and ROCm lockfiles
([UniSim #472](https://github.com/unilabsim/unisim/issues/472)).
Manager tensor ray observation 现在消费 UniSim 公开 full-scene
`RayCollisionDescription`,mesh/hfield materialization 不再要求 backend-specific
`uni_ray` builder,并将 entity-local packed pose read 聚合到公开 full-scene body
轴。`RayPatternCfg` 支持 ring、平行 grid 与 pinhole-camera ray pattern,
body/yaw-only/world alignment、body/public-site attachment 与本地 sensor
offset、`min_distance`、公开 geom/tag/body/ancestor filter、可选 normal 与
hit-point 输出,以及 reset 边界的逐行 geometry 同步。可选 `ray` extra
在 CUDA 与 ROCm lockfile 中均解析已发布的 `uniray[warp]==0.1.0` 发行版
([UniSim #472](https://github.com/unilabsim/unisim/issues/472))。
The first facade is a minimal grouped ray sensor, not a camera: intrinsics,
image projection, noise, history, and scheduling remain application logic.
Full-scene pose aggregation covers entity-owned bodies plus the identity
world root; uncovered non-root bodies fail closed. MuJoCo and MJWarp
fixed-variant collision descriptors now publish per-row geometry through the
capability added by [UniSim #479](https://github.com/unilabsim/unisim/issues/479);
Motrix source mesh/hfield scenes follow the UniSim fail-closed boundary.
The real end-to-end fixture covers
primitive geometry, static filtering, minimum distance, attachment
transformation, site attachment, and normals; focused fake-caster tests cover
grid and pinhole ray geometry, yaw/world alignment, hit-point packing, and
geometry synchronization; mesh/hfield
numerical parity is owned by the UniSim and `uni_ray` contract suites.
首个 facade 是最小 grouped ray sensor,不是 camera:intrinsics、图像投影、
noise、history 与 scheduling 仍属于应用逻辑。full-scene pose 聚合覆盖
entity-owned body 与 identity world root;未覆盖的非 root body fail closed。
MuJoCo 与 MJWarp fixed-variant collision scene 以及 Motrix source
mesh/hfield scene 遵循 UniSim fail-closed 边界;fixed-variant collision
descriptor 通过 [UniSim #479](https://github.com/unilabsim/unisim/issues/479)
新增的能力发布逐行 geometry。真实端到端 fixture 覆盖
primitive geometry、static filtering、minimum distance、attachment
transformation、site attachment 与 normal;grid/pinhole ray 几何、yaw/world alignment、hit-point packing 与 geometry synchronization 由 focused fake-caster test 覆盖;mesh/hfield 数值 parity 由 UniSim 与 `uni_ray` contract suite 负责。

### Changed / 变更

- Genesis runtime domain randomization now follows the unified device-resident
`unisim-core` lifecycle. Manager interval negotiation selects the
backend-bound device plane, wrench payloads and body IDs enter the interval
plan on that device, and the packed reset device is declared before cold
event-term binds. The Genesis G1 walk SAC owner re-enables `pd_gains` with
the PPO owner because Genesis declares device-plane packed reset `kp`/`kd`;
host-plane runtime DR, push, velocity-delta, and other undeclared terms
still fail closed
([#2520](https://github.com/Motphys/UniLab/issues/2520)).
Genesis 运行时域随机化现在遵循 `unisim-core` 统一的 device-resident 生命
周期。Manager interval 协商选择 backend 绑定的 device plane;wrench payload
与 body ID 在该设备上进入 interval plan;packed reset 设备会在冷路径
event-term bind 之前声明。Genesis G1 walk SAC owner 与 PPO owner 一致重新
启用 `pd_gains`,因为 Genesis 声明了 device-plane packed reset 的
`kp`/`kd`;host-plane 运行时 DR、push、velocity-delta 以及其他未声明 term
仍会 fail closed([#2520](https://github.com/Motphys/UniLab/issues/2520))。

## 1.5.1 (2026-10-23)

### Added / 新增
Expand Down
5 changes: 3 additions & 2 deletions docs/sphinx/source/en/1-getting_started/2-installation.md
Original file line number Diff line number Diff line change
Expand Up @@ -250,8 +250,9 @@ ROCm notes:
explicit `training.collector_tensor_device=cuda` forces the same routing for
other learner devices. Direct environment construction remains CPU.
Host-bridge physics stays on CPU; packed transfers connect it to the GPU
observations, actions, rewards, and resets. CUDA-only physics backends remain
unsupported on ROCm. See
observations, actions, rewards, and resets. Genesis additionally supports its
existing device-resident direct lifecycle with HIP/ROCm Torch and exact
`gs.amdgpu`; other CUDA-only physics backends remain unsupported on ROCm. See
{doc}`/adr/ADR-0012-sole-tensor-manager-and-scoped-backends`.
- When installing from PyPI instead of a source checkout, `make sync-rocm` does
not apply. Install the torch build validated by the repository from the
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,9 +58,10 @@ actions use the CPU inference ring; in the default-legal pairings the learner
itself is CPU or Apple MPS — see the pairing contract below for CUDA
learners), and `cuda` derives the CUDA ring. `cuda` follows Torch device-type
semantics and covers both NVIDIA CUDA and AMD ROCm. It does not relax separate
platform gates: CUDA-only tensor backends still fail closed on ROCm/HIP, and
`training.cuda_process_sharing` remains available only to the NVIDIA-specific
CUDA MPS daemon and native H2D implementation.
platform gates: CUDA-only tensor backends still fail closed on ROCm/HIP, while
Genesis separately admits only its reviewed HIP/ROCm + exact `gs.amdgpu`
profile. `training.cuda_process_sharing` remains available only to the
NVIDIA-specific CUDA MPS daemon and native H2D implementation.

Removed keys fail closed with a migration error: use
`training.collector_tensor_device` instead of `training.sim_carrier_device`
Expand Down
29 changes: 22 additions & 7 deletions docs/sphinx/source/en/2-user_guide/3-backends/5-genesis.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,14 +52,24 @@ compensates on the materialize cold path — hot paths never parse XML:
reproduction of it.
- **Actuators**: `<position kp kv>` actuators import losslessly and are
driven with `control_dofs_position`; kp/kd reset randomization is supported
(the DR capability set declares only the per-env round-trip-measured terms:
body mass, base mass, kp, kd, plus interval body force).
on the device plane (the DR capability sets declare only the measured device
reset terms: body mass, base-mass delta, body CoM / base-CoM delta, kp,
kd; the device interval set additionally covers body force, body torque,
and world-frame root linear plus root-local angular velocity deltas).

## Prerequisites

- Linux x86_64 with an NVIDIA GPU and driver. Only the `gs.gpu` lane is
validated by the feasibility probe; the CPU backend is not a validated
support lane.
- Linux x86_64 with a supported GPU runtime for the Manager tensor runtime.
UniSim's reviewed Genesis tensor profile requires Genesis zero-copy and one
exact runtime pairing: non-HIP Torch CUDA with `gs.cuda`, or HIP/ROCm Torch
with `gs.amdgpu`. Both negotiate `DEVICE_RESIDENT`, in-process, `DIRECT` and
retain the public `cuda` Torch device namespace.
- Genesis 1.3.3 itself natively supports `gs.metal` on Apple Silicon and
`gs.amdgpu` on Linux HIP, as shown by the direct-engine G1 throughput work
(UniLab PR #2518 / discussion #2517). Metal remains outside the UniSim
Genesis adapter tensor lifecycle. On ROCm, `gs.cuda` is rejected as a runtime
mismatch; on non-HIP CUDA, `gs.amdgpu` is likewise rejected. CPU, portable
Genesis, Metal, MPS, and substitute backends are never silent fallbacks.
- The repository's pinned torch window (torch 2.8 on x86_64): the
IMUSensor + contact-force sensor combination crashed under torch 2.7 in
the probe (REPORT §3.4/§8).
Expand Down Expand Up @@ -145,8 +155,13 @@ degrading:
- **Absolute geom-friction DR**: upstream Genesis only offers a per-env
friction *ratio* API, so `geom_friction` reset randomization and
`get_geom_friction` fail closed.
- **Interval push / body-velocity-delta DR**: rejected at construction/plan
time (`push_body_name`, push perturbation).
- **Legacy interval push term**: the opaque `push` descriptor is rejected at
construction/plan time. Use the six-axis velocity-delta event, which commits
world-frame linear and root-local angular deltas through Genesis public
state without touching qpos, controls, solver state, or unrelated rows.
- **Host-plane runtime DR**: Genesis accepts reset and interval payloads only
on its backend-bound CUDA/AMDGPU device. Host payloads fail closed with the
term and plane named; there is no NumPy or host-bridge fallback.
- **Repeated `gs.init`** in one process (see above).

## Cross-Backend Migration (sim2sim)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ These three paths correspond to three lifecycle classes:
| Task | Currently implemented reset domain randomization | Currently implemented interval domain randomization | Default state |
| --- | --- | --- | --- |
| `Go2JoystickFlat` | base xy/yaw and base qvel via `reset_root_state_uniform`; command sampling; kp/kd via `pd_gains` | none | event terms declared and enabled by default in `src/unilab/conf/ppo/task/go2_joystick_flat/base.yaml` |
| `G1WalkFlat` | base xy/yaw and base qvel via `reset_root_state_uniform`; command sampling with a planar dead zone; `gait_phase` sampling; kp/kd randomization via `pd_gains` | none | kp/kd enabled on mujoco owners by default; disabled on motrix/mjwarp owners |
| `G1WalkFlat` | base xy/yaw and base qvel via `reset_root_state_uniform`; command sampling with a planar dead zone; `gait_phase` sampling; kp/kd randomization via `pd_gains` | none | kp/kd enabled on the mujoco and genesis owners by default; disabled on motrix/mjwarp owners |
| `G1MotionTracking` | Motion-command frame sampling; root pose perturbation `x/y/z/roll/pitch/yaw`; root velocity perturbation `x/y/z/roll/pitch/yaw`; joint-position noise clipped through the public entity soft limits; action-manager state reset | none | `pose_range`, `velocity_range`, and `joint_position_range` have non-zero perturbations in the base owner |

## Current DR Capabilities and Boundaries
Expand Down
Loading
Loading