Commit f1f9576
Fix OVPhysX device routing for CPU-resident tensor types (#7563)
# Description
`_CPU_ONLY_TYPES` in `isaaclab_ov` is the single constant deciding
whether an `OvPhysxView` tensor buffer is allocated on, and validated
against, host or device memory. It omitted eight tensor types that are
CPU-resident even on a GPU simulation:
| tensor type | alias | shape |
|---|---|---|
| `ARTICULATION_CONTACT_OFFSET` | `CONTACT_OFFSET` | `[N, S]` |
| `ARTICULATION_REST_OFFSET` | `REST_OFFSET` | `[N, S]` |
| `RIGID_BODY_CONTACT_OFFSET` | `RIGID_BODY_CONTACT_OFFSET` | `[N, S]` |
| `RIGID_BODY_REST_OFFSET` | `RIGID_BODY_REST_OFFSET` | `[N, S]` |
| `ARTICULATION_BODY_DISABLE_GRAVITY` | `BODY_DISABLE_GRAVITY` | `[N,
L]` |
| `RIGID_BODY_DISABLE_GRAVITY` | `RIGID_BODY_DISABLE_GRAVITY` | `[N]` |
| `ARTICULATION_DOF_DRIVE_TYPE` | `DOF_DRIVE_TYPE` | `[N, D]` |
| `ARTICULATION_DOF_DRIVE_MODEL` | `DOF_DRIVE_MODEL` | `[N, D, 3]` |
Because `_native_device` consults this set, it returned the simulation
device for host-resident data. Two consequences:
1. A hidden per-call host-to-device staging copy on every access, on a
path the view believed was device-native. Silent, and not attributable
to Isaac Lab in a profile. Values are still correct — ovphysx stages the
mismatch transparently, so this is not a data-integrity bug.
2. `_check_device` rejected a **correctly** placed buffer: allocating
one of these on the host, where the data actually lives, raised
`OvPhysxView.DeviceMismatch`, whose message advises moving the buffer
yourself — precisely the advice that fails here.
No shipped Isaac Lab workflow reads these eight through the tensor path
today, so this is latent rather than a live outage. It is not an obscure
corner: Isaac Lab already authors these same properties through USD
schema writes at scene construction, and the tensor path exists to
change such values per-env at runtime.
Each of the eight is also exposed as a public alias carrying its shape,
dtype and units, taken from the wheel's own type table. This module is
the alias layer over the ovphysx enum, so referencing them raw would
have left the candidate tuple a mix of aliases and raw enum members with
no stated reason why these eight differed. Naming follows the existing
convention: the `ARTICULATION_` prefix is dropped for articulation
types, as with `DOF_STIFFNESS` and `BODY_MASS`, and retained for
rigid-body ones, as with `RIGID_BODY_MASS`.
A second, orthogonal gap surfaced during the audit: ovphysx documents
`ARTICULATION_DOF_DRIVE_TYPE` as read-only, but it was missing from
`_READ_ONLY_NAMES`, so `set_attribute` accepted writes and forwarded
them. An audit of the full classification against the wheel's type table
found this to be the only such gap — of the 21 types ovphysx documents
read-only, 20 were already classified, with no misclassified members.
## Type of change
- Bug fix (non-breaking change which fixes an issue)
- New feature (non-breaking change which adds functionality)
- **Breaking change** — writes to `articulation_dof_drive_type` now
raise `OvPhysxView.ReadOnlyAttribute` instead of being silently
forwarded. Migration: remove the write; drive type is authored through
the USD drive schema, not the tensor path.
## Release backport
- [x] <!-- backport-active-release --> Backport this pull request to the
active release branch after it merges into `develop`
## Screenshots
Not applicable.
## Checklist
- [x] I have run the [`pre-commit` checks](https://pre-commit.com/) with
`./isaaclab.sh --format`
- [x] I have made corresponding changes to the documentation
- [x] My changes generate no new warnings
- [x] I have added tests that prove my fix is effective or that my
feature works
- [x] I have updated the changelog and the corresponding version in the
extension's `config/extension.toml` file
- [x] I have added my name to the `CONTRIBUTORS.md` or my name already
exists there
## How it was tested
ovphysx exposes no residency query (`ovphysx_tensor_spec_t` carries
dtype/ndim/shape and no device field), so residency was **measured**,
not assumed: CUDA memcpys were counted via CUPTI around each binding
read into a host buffer and into a device buffer, under the DirectGPU
configuration `isaaclab_ov` itself sets (`"/physics/suppressReadback":
True`). A host read showing `DtoH` means GPU-resident; no memcpy on the
host read plus `HtoD` on the device read means CPU-resident.
Measured across every GPU sample scene in the ovphysx 0.5.11 wheel:
| scene | before | after |
|---|---|---|
| `two_articulations_gpu` | `agree=40 MISMATCH=8` | `agree=48
MISMATCH=0` |
| `links_chain_sample_gpu` | `agree=40 MISMATCH=8` | `agree=48
MISMATCH=0` |
| `mixed_base_articulations_gpu` | `agree=36 MISMATCH=8` | `agree=44
MISMATCH=0` |
| `boxes_falling_on_groundplane_gpu` | `agree=9 MISMATCH=3` | `agree=12
MISMATCH=0` |
| `volume_deformable_multi` | `MISMATCH=0` | `MISMATCH=0` |
| `surface_deformable_material` | `MISMATCH=0` | `MISMATCH=0` |
Every previously classified member measured CPU-resident as declared in
all scenes, so the set was incomplete rather than wrong — there were no
false positives to correct.
The guarding test was a tautology: it compared the view's derived set
against the canonical set it is derived from, so it could not fail for
any contents. It now asserts against an independent inventory of
measured residency, mirroring the existing `_EXPECTED_READ_ONLY_NAMES`
pattern. Both new assertions were confirmed to fail before the fix and
pass after it; the read-only case fails with `DID NOT RAISE
ReadOnlyAttribute` without the fix.
- `pytest source/isaaclab_ov/test/sim/test_ovphysx_view.py` — 81 passed
- `test_articulation_helpers`, `test_rigid_object_helpers`,
`test_deformable_object_helpers`, `test_ovphysx_scene_data_backend`,
`test_randomize_rigid_body_material_mdp` — all pass
- `uv run isaaclab -f` — passes
- `tools/changelog/cli.py check develop` — passes
`test_views_xform_prim_ovphysx.py` reports 23 failed / 28 passed both
with and without this change; every failure is the process-global device
lock covered by the `device_split` marker, which requires per-device
re-invocation. Baselined on a clean tree to confirm it is unrelated.
Environment: ovphysx 0.5.11, Linux x86_64, Python 3.12, NVIDIA RTX 5000
Ada Generation Laptop GPU.
(cherry picked from commit ec58631)1 parent 1c75487 commit f1f9576
4 files changed
Lines changed: 132 additions & 2 deletions
File tree
- source/isaaclab_ov
- changelog.d
- isaaclab_ov
- sim/views
- test/sim
Lines changed: 30 additions & 0 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
79 | 79 | | |
80 | 80 | | |
81 | 81 | | |
| 82 | + | |
82 | 83 | | |
83 | 84 | | |
84 | 85 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
149 | 149 | | |
150 | 150 | | |
151 | 151 | | |
| 152 | + | |
| 153 | + | |
| 154 | + | |
| 155 | + | |
| 156 | + | |
| 157 | + | |
| 158 | + | |
| 159 | + | |
| 160 | + | |
| 161 | + | |
| 162 | + | |
| 163 | + | |
| 164 | + | |
152 | 165 | | |
153 | 166 | | |
154 | 167 | | |
| |||
193 | 206 | | |
194 | 207 | | |
195 | 208 | | |
| 209 | + | |
| 210 | + | |
| 211 | + | |
| 212 | + | |
| 213 | + | |
| 214 | + | |
| 215 | + | |
| 216 | + | |
| 217 | + | |
| 218 | + | |
| 219 | + | |
| 220 | + | |
| 221 | + | |
| 222 | + | |
| 223 | + | |
| 224 | + | |
| 225 | + | |
| 226 | + | |
196 | 227 | | |
197 | 228 | | |
198 | 229 | | |
| |||
225 | 256 | | |
226 | 257 | | |
227 | 258 | | |
| 259 | + | |
| 260 | + | |
| 261 | + | |
| 262 | + | |
| 263 | + | |
| 264 | + | |
| 265 | + | |
| 266 | + | |
| 267 | + | |
| 268 | + | |
228 | 269 | | |
229 | 270 | | |
230 | 271 | | |
| |||
433 | 474 | | |
434 | 475 | | |
435 | 476 | | |
| 477 | + | |
| 478 | + | |
436 | 479 | | |
437 | 480 | | |
438 | 481 | | |
439 | 482 | | |
440 | 483 | | |
| 484 | + | |
| 485 | + | |
| 486 | + | |
441 | 487 | | |
442 | 488 | | |
443 | 489 | | |
444 | 490 | | |
| 491 | + | |
| 492 | + | |
| 493 | + | |
445 | 494 | | |
446 | 495 | | |
447 | 496 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
54 | 54 | | |
55 | 55 | | |
56 | 56 | | |
| 57 | + | |
57 | 58 | | |
58 | 59 | | |
59 | 60 | | |
| |||
70 | 71 | | |
71 | 72 | | |
72 | 73 | | |
| 74 | + | |
| 75 | + | |
| 76 | + | |
| 77 | + | |
| 78 | + | |
| 79 | + | |
| 80 | + | |
| 81 | + | |
| 82 | + | |
| 83 | + | |
| 84 | + | |
| 85 | + | |
| 86 | + | |
| 87 | + | |
| 88 | + | |
| 89 | + | |
| 90 | + | |
| 91 | + | |
| 92 | + | |
| 93 | + | |
| 94 | + | |
| 95 | + | |
| 96 | + | |
| 97 | + | |
| 98 | + | |
| 99 | + | |
| 100 | + | |
| 101 | + | |
| 102 | + | |
| 103 | + | |
| 104 | + | |
| 105 | + | |
| 106 | + | |
| 107 | + | |
| 108 | + | |
| 109 | + | |
| 110 | + | |
| 111 | + | |
| 112 | + | |
| 113 | + | |
| 114 | + | |
| 115 | + | |
73 | 116 | | |
74 | 117 | | |
75 | 118 | | |
| |||
201 | 244 | | |
202 | 245 | | |
203 | 246 | | |
| 247 | + | |
204 | 248 | | |
205 | 249 | | |
206 | 250 | | |
| 251 | + | |
| 252 | + | |
207 | 253 | | |
208 | 254 | | |
209 | 255 | | |
210 | 256 | | |
211 | | - | |
| 257 | + | |
| 258 | + | |
| 259 | + | |
212 | 260 | | |
213 | 261 | | |
214 | 262 | | |
215 | | - | |
| 263 | + | |
| 264 | + | |
| 265 | + | |
216 | 266 | | |
217 | 267 | | |
218 | 268 | | |
| |||
0 commit comments