Skip to content

Route clone backends through ClonePlan - #7462

Merged
ooctipus merged 7 commits into
isaac-sim:developfrom
ooctipus:codex/flattened-clone-plan
Sep 4, 2026
Merged

Route clone backends through ClonePlan#7462
ooctipus merged 7 commits into
isaac-sim:developfrom
ooctipus:codex/flattened-clone-plan

Conversation

@ooctipus

@ooctipus ooctipus commented Aug 31, 2026

Copy link
Copy Markdown
Collaborator

Description

This is a narrow follow-up to merged #7453. It keeps that Newton fast path and makes the existing ClonePlan the single mapping consumed by USD, Newton, PhysX, and OvPhysX replication.

Planning records context_rows, mapping each simulation-owned clone-context type to the plan rows it consumes. cloner.replicate(plan) retrieves those already-registered contexts from SimulationContext, orders them by replication priority, and passes each the same plan. Backends no longer rebuild the mapping through local queue(...) or queue_mapping(...) state.

Clone planning is a NumPy host-side control plane. ClonePlan, its constructors, strategies, queries, and raw clone APIs use NumPy arrays; backend code no longer performs Torch device synchronization or detach().cpu().tolist() round trips. Runtime owners convert once when they need a device tensor. InteractiveScene derives its environment roots and device-side origins from the same plan instead of calculating a second grid.

The public structure stays small:

  • ClonePlan.global_paths remains the explicit declaration for shared scene prims.
  • ClonePlan.env_ids and positions remain optional for query-only plans; execution validates what it needs.
  • Per-asset cloning_contexts, cfg_rows, ReplicateSession, and the existing scene-construction lifecycle remain.
  • Standalone tooling keeps the raw USD, Newton, PhysX, and OvPhysX replication functions.
  • OVRTX camera/export/SDP architecture remains deferred to the renderer cutover; this PR only removes Torch round trips from its mechanical plan-array consumption.
  • No stage discovery, fallback context construction, registry-wide duck routing, or second clone mapping is introduced.

Migration

Custom clone contexts now implement replicate(plan) and must be registered with SimulationContext.get_or_create_backend(...) before dispatch. Remove context-local queue(...) / queue_mapping(...) calls and the former backend PHYSICS_CONTEXT aliases; raw standalone replication functions remain available.

The high-level stage= argument is removed from cloner.replicate(...) and ReplicateSession; each simulation-owned context already owns its stage.

Clone arrays and raw clone API arrays are now NumPy. The unused public device arguments are removed from CloneCfg, plan constructors, grid_transforms, ReplicateSession, clone strategies, and raw backend replication functions. Custom clone strategies now implement (combinations: np.ndarray, num_clones: int) -> np.ndarray.

Size

Added Deleted Net
1,267 1,700 -433

These counts are for this PR alone against current develop; merged #7453 code and dependency changes are no longer duplicated in the diff.

Performance

The targeted benchmark warms with 128 worlds, then times replication and required label publication for one 48-body/48-shape Newton prototype at 4,096 worlds. Measurements taken while #7453 was under review used physical GPU 0 and the same Newton revision:

Revision Targeted median Versus pre-#7453 develop
develop before #7453 1.428 s
#7453 1.171 s -18.0%
this follow-up before restacking 1.181 s -17.3%

The restack removed the duplicated #7453 implementation rather than reimplementing it. A file-by-file audit confirms this PR no longer changes #7453's label-prefix fast-path files, and the one-source/all-true Newton route still delegates to ModelBuilder.replicate(...).

Type of change

  • Breaking clone-context and NumPy API simplification
  • Documentation update

Validation

  • 84 passed — clone-plan algebra
  • 7 passed — replicate-session lifecycle
  • 15 passed — focused Newton label-prefix/root-name coverage from [Newton] Delegate homogeneous world prefix generation to ModelBuilder.replicate() #7453
  • Repository formatting, lint, RST, spelling, license, changelog, LFS, and hygiene hooks passed against current upstream/develop
  • git diff --check passed
  • Static audit found no Torch import or CPU/list materialization in the core, Newton, PhysX, or OvPhysX clone paths

Release backport

  • Backport this pull request to the active release branch after it merges into develop

Checklist

  • I have read and understood the contribution guidelines
  • I have run the relevant pre-commit checks
  • I have made corresponding documentation changes
  • I have added focused contract, routing, and lifecycle tests
  • I have added a changelog fragment for every touched source package
  • My name already exists in CONTRIBUTORS.md

@ooctipus
ooctipus requested a review from a team August 31, 2026 23:33
@ooctipus ooctipus added the documentation Improvements or additions to documentation label Aug 31, 2026
@ooctipus ooctipus added the isaac-lab Related to Isaac Lab team label Aug 31, 2026
@greptile-apps

greptile-apps Bot commented Aug 31, 2026

Copy link
Copy Markdown
Contributor

Too many files changed for review (295 files, 100 file limit).

Bypass the limit by tagging @greptile-apps to review.

@github-actions github-actions Bot added the asset New asset feature or request label Aug 31, 2026

@isaaclab-review-bot isaaclab-review-bot Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Isaac Lab Review Bot

The flattened ClonePlan/ReplicateSession lifecycle is coherent overall, but cfg discovery can incorrectly turn sensor visualizer configs into conflicting plan rows, camera spawning removes established redirect/existence behavior, the RayCasterCfg.spawn default change lacks migration guidance, and startup profiling still targets the removed dispatch name.

  • Design and architecture: Publishing one immutable plan before construction and dispatching it to registered backends provides a single description of clone ownership. However, _plan_cfgs also classifies visualizer marker configs as prim authors; sensors sharing a default marker path can therefore fail planning with duplicate ownership. Visualizer-only configs should be excluded from clone-plan rows.
  • API: The major changelog covers the removed cloner entry points and most cfg/spawner field removals. It does not cover the RayCasterCfg.spawn default changing from SensorFrameCfg() to None. Camera construction also drops the previous physics-body-to-child redirect and existing-prim guard, changing behavior for public CameraCfg usages that target bodies or pre-authored cameras.
  • Implementation: Plan construction, source-path resolution, and backend dispatch were traced. The remaining implementation integration issue is the startup profiler whitelist still matching cloner.*:replicate after dispatch was renamed to _replicate, causing clone-dispatch measurements to be reported as zero placeholders.

Significant concerns. Posted 4 actionable findings inline.

The full PR diff was reviewed; some supplemental surrounding file context was omitted.

Automated review; human maintainers own approval decisions.

Comment thread source/isaaclab/isaaclab/cloner/clone_plan.py Outdated
Comment thread source/isaaclab/isaaclab/sensors/camera/camera.py Outdated
Comment thread source/isaaclab/isaaclab/cloner/replicate_session.py Outdated
Comment thread source/isaaclab/isaaclab/sensors/ray_caster/ray_caster_cfg.py Outdated
@ooctipus ooctipus changed the title Flatten clone planning into one lifecycle Use one cfg-derived clone plan and lifecycle Sep 1, 2026
@github-actions github-actions Bot added isaac-mimic Related to Isaac Mimic team infrastructure labels Sep 1, 2026
@ooctipus
ooctipus force-pushed the codex/flattened-clone-plan branch from 5c3ba34 to 5f7619e Compare September 2, 2026 04:10
@ooctipus ooctipus changed the title Use one cfg-derived clone plan and lifecycle Route clone backends through ClonePlan Sep 2, 2026
@ooctipus

ooctipus commented Sep 2, 2026

Copy link
Copy Markdown
Collaborator Author

PR 3 has now been split at the execution/lifecycle boundary.

This PR contains only the existing ClonePlan execution contract and backend routing. The declarative cfg inventory, pre-construction lifecycle, queue deletion, camera/raycaster declaration changes, startup-profiler migration, and broad workflow call-site changes are in the follow-up PR 3B branch.

Accordingly, the earlier automated inline findings on _plan_cfgs, camera spawning, RayCasterCfg.spawn, and the renamed startup-profiler target refer to the previous full head and are no longer present in this diff. The preserved full tip is available on ooctipus:codex/flattened-clone-plan-full.

@ooctipus

ooctipus commented Sep 2, 2026

Copy link
Copy Markdown
Collaborator Author

run-ci

@isaaclab-bot isaaclab-bot Bot added ci:run-docker Trigger the on-demand Docker and GPU CI workflow and removed ci:run-docker Trigger the on-demand Docker and GPU CI workflow labels Sep 2, 2026
@isaaclab-bot isaaclab-bot Bot removed the ci:run-docker Trigger the on-demand Docker and GPU CI workflow label Sep 3, 2026
@ooctipus

ooctipus commented Sep 3, 2026

Copy link
Copy Markdown
Collaborator Author

run-ci

@isaaclab-bot isaaclab-bot Bot added ci:run-docker Trigger the on-demand Docker and GPU CI workflow and removed ci:run-docker Trigger the on-demand Docker and GPU CI workflow labels Sep 3, 2026
Comment thread source/isaaclab/isaaclab/cloner/clone_plan.py Outdated
contexts = (
(() if physics_context is None else (physics_context,))
if references is None
else tuple(string_to_callable(value) if isinstance(value, str) else value for value in references)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Optional: I'm not a fan of the usage of string_to_callable, you can create a strictly types dictionary instead that maps the string to specific functions.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Built-in USD and physics contexts are concrete types now. I kept string_to_callable only for the documented user-configurable AssetBaseCfg.cloning_contexts string boundary; a closed core dictionary would make core enumerate backend packages and would exclude custom context classes.

Comment thread source/isaaclab/isaaclab/cloner/clone_plan.py Outdated
Comment thread source/isaaclab/isaaclab/cloner/clone_plan.py Outdated
Comment thread source/isaaclab/isaaclab/cloner/usd.py Outdated
mujoco~=3.11.0
mujoco-warp~=3.11.0
newton[sim]==1.5.1
newton[sim] @ git+https://github.com/newton-physics/newton.git@24bd863528d6b91137408930d0fbe8fa216ad962

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This PR is mixing a newton bump as well?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is temporary stack overlap with #7453, which is still open. That predecessor uses the new ModelBuilder.replicate(..., label_prefixes=...) API and therefore carries the Newton 1.6 development pin. The pin and fast-path files disappear from this PR after #7453 merges and this branch is restacked.


label_groups = _label_groups(source_builder)
original_labels = {name: list(labels) for name, labels in label_groups.items()}
try:

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why try, finally? Are we expecting possible failure?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

_rebase_labels temporarily mutates the retained source builder and can itself fail after a partial mutation; builder.replicate can also fail. The finally restores the snapshot on both paths. Restoration also matters on success because these source builders are retained in NewtonManager._cl_protos for later consumers.

Comment thread source/isaaclab/isaaclab/cloner/clone_plan.py Outdated
Comment thread source/isaaclab_newton/isaaclab_newton/cloner/replicate.py
Comment thread source/isaaclab_ov/isaaclab_ov/cloner/replicate.py Outdated
@ooctipus ooctipus moved this to In progress in Isaac Lab Sep 3, 2026
@ooctipus
ooctipus force-pushed the codex/flattened-clone-plan branch from bc71259 to 987f764 Compare September 4, 2026 07:35
@ooctipus

ooctipus commented Sep 4, 2026

Copy link
Copy Markdown
Collaborator Author

run-ci

@isaaclab-bot isaaclab-bot Bot added ci:run-docker Trigger the on-demand Docker and GPU CI workflow and removed ci:run-docker Trigger the on-demand Docker and GPU CI workflow labels Sep 4, 2026
@ooctipus
ooctipus force-pushed the codex/flattened-clone-plan branch from 987f764 to 91288ba Compare September 4, 2026 10:42
@ooctipus

ooctipus commented Sep 4, 2026

Copy link
Copy Markdown
Collaborator Author

run-ci

@isaaclab-bot isaaclab-bot Bot added ci:run-docker Trigger the on-demand Docker and GPU CI workflow and removed ci:run-docker Trigger the on-demand Docker and GPU CI workflow labels Sep 4, 2026
@ooctipus
ooctipus merged commit 644acf5 into isaac-sim:develop Sep 4, 2026
53 checks passed
@github-project-automation github-project-automation Bot moved this from In progress to Done in Isaac Lab Sep 4, 2026
kellyguo11 pushed a commit that referenced this pull request Sep 4, 2026
# Description

Revives #6308 on current `develop` and supersedes #3728 with a single
backend-neutral contract for kinematic rigid-object rendering.

## Architecture

`source/isaaclab/test/renderers/rigid_object_rendering_contract.py` is
the composition root. It owns the cloned scene, kinematic pose sequence,
depth measurements, and assertions. Package-local adapters own only
availability checks, simulation/renderer selection, and backend cleanup:

- Isaac RTX + PhysX on CPU and CUDA, with and without a coexisting
articulation;
- Newton Warp + PhysX on CUDA;
- OVRTX + OVPhysX on CUDA through both legacy and OVStage scene
ownership (OVStage runs when installed).

The dependency direction is adapter -> shared test contract -> public
Isaac Lab APIs. An AST architecture gate rejects backend imports in the
shared contract and rejects scene, asset, sensor, or class ownership in
adapters.

The contract creates two cloned instanceable DexCubes with root-level
nonuniform scale, verifies their depth silhouettes, moves both kinematic
bodies through the public rigid-object tensor API, verifies the physics
poses, and requires opposite rendered centroid displacement.

## Current-develop audit

Most production changes in the old PR have since landed through newer
ownership boundaries: Isaac RTX render-product lifetime in #6729, Newton
shadow-state copying in #6773, OVRTX scale-aware transform writes in
#7010, and Newton Fabric scale preservation in #7481. This revival
removes those stale patches rather than carrying duplicate
implementations.

The revived contract exposed one remaining OVRTX bug: composed scale was
captured only for clone-plan source paths, while OVRTX creates
non-source destinations after exporting the host USD stage. Those
destinations therefore defaulted to unit scale. As a deliberately
temporary bridge, this PR projects only captured non-unit scales through
the existing `isaaclab.cloner.query.path_env_ids` and `path_to_clone`
boundary using the already-validated `ClonePlan`; real destination
scales take precedence. It adds no plan fields, query APIs, renderer
configuration, or per-body fallback, and the bridge can be deleted as
one unit when SDP supplies composed scale aligned with canonical
rigid-body paths.

Historical context: [Isaac Sim forum
report](https://forums.developer.nvidia.com/t/rigidbody-prim-is-not-updated-in-rendering-pipeline-if-set-to-kinematic/346608).

## Type of change

- Bug fix
- Shared regression coverage

## Testing

- Isaac RTX contract: 4 passed (CUDA/CPU x articulation absent/present).
- Newton Warp contract: 1 passed.
- OVRTX contract: 2 passed (legacy and OVStage).
- OVRTX renderer unit surface: 167 passed.
- Core architecture and Newton visualization suites: 25 passed.
- OVRTX clone-plan suite: 17 passed.
- Cloner query and rendering-contract architecture suites: 87 passed.
- Controlled OVRTX regression: failed before the production fix with
clone silhouettes of 264 vs. 36 pixels; passed after the fix.
- Incoming #7462 NumPy-backed `ClonePlan` query-boundary smoke check:
passed unchanged, including non-dense environment ids.
- `uv run isaaclab -f`: all hooks passed against the exact upstream
`develop` base, including changelog validation.

## Checklist

- [x] I have read and understood the contribution guidelines
- [x] I have run the pre-commit checks
- [x] Documentation changes are not applicable
- [x] I have added unit and integration regression coverage
- [x] I have added changelog fragments for every touched package
- [x] My name is already present in `CONTRIBUTORS.md`
@kellyguo11 kellyguo11 mentioned this pull request Sep 4, 2026
8 tasks
kellyguo11 added a commit that referenced this pull request Sep 4, 2026
# Description

Restores the missing `torch` import in `test_ovrtx_clone_plan.py`.

#7462 converted the existing clone-plan test inputs from Torch tensors
to NumPy arrays and removed the then-unused import. #6308 subsequently
added a new object-scale test using `torch.ones` and `torch.arange`
without restoring the import, causing the repository-wide Ruff
pre-commit check to fail with `F821 Undefined name torch`.

This PR contains only the import repair and an `isaaclab_ov` `.skip`
changelog fragment. It unblocks #7579 and other changes based on the
current `develop` branch.

## Type of change

- Bug fix (non-breaking test fix)

## Release backport

- [ ] <!-- backport-active-release --> Backport this pull request to the
active release branch after it merges into `develop`

No release backport is required: `release/3.0.0` already imports `torch`
in this test.

## Screenshots

Not applicable.

## Testing

- `uv run --no-project --with pre-commit python -m pre_commit run
--all-files`
- `uv run --no-project python tools/changelog/cli.py check
--include-worktree`
- `git diff --check upstream/develop...HEAD`

## Checklist

- [x] I have read and understood the contribution guidelines
- [x] I have run the full pre-commit checks
- [x] Documentation changes are not required because no public API
changed
- [x] My changes generate no new warnings
- [x] The fix directly covers the Ruff `F821` failure
- [x] I have added an `isaaclab_ov` changelog fragment
- [x] My name already exists in `CONTRIBUTORS.md`
@ooctipus
ooctipus deleted the codex/flattened-clone-plan branch September 5, 2026 00:10
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

asset New asset feature or request documentation Improvements or additions to documentation infrastructure isaac-lab Related to Isaac Lab team isaac-mimic Related to Isaac Mimic team

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

2 participants