Working with ProxyArray#
Isaac Lab data classes return ProxyArray — a lightweight, warp-first wrapper that
provides zero-copy access to simulation data as either a warp.array or a
torch.Tensor.
Note
ProxyArray is inspired by the ProxyArray class from
mujocolab/mjlab (BSD-3-Clause).
The design adapts the same dual-accessor pattern to Isaac Lab’s warp-based data pipeline.
Quick Start#
Every property on asset and sensor data classes (e.g., robot.data.joint_pos,
sensor.data.net_forces_w) returns a ProxyArray:
robot = env.scene["robot"]
# Explicit torch access (preferred)
joint_positions = robot.data.joint_pos.torch # torch.Tensor, cached zero-copy view
gravity_proj = robot.data.projected_gravity_b.torch # torch.Tensor
# Explicit warp access (for kernel interop)
wp_array = robot.data.joint_pos.warp # warp.array, the original buffer
# Pass directly to warp kernels — no unwrapping needed
wp.launch(my_kernel, inputs=[robot.data.joint_pos], ...) # works via __cuda_array_interface__
The .torch and .warp Accessors#
.torchreturns a cached, zero-copytorch.Tensorview of the underlying warp array (viawarp.to_torch()). The tensor is created on first access and reused on subsequent calls. Since it is a zero-copy view, writes to the tensor are visible through the warp array and vice versa..warpreturns the originalwarp.array. Use this when you need to pass data to warp kernels explicitly or access warp-specific attributes (ptr,strides, etc.).
Deprecation Bridge#
To ease migration, ProxyArray includes a deprecation bridge that allows existing code to
treat it as a torch.Tensor temporarily:
# These still work but emit a one-time DeprecationWarning:
result = torch.sum(robot.data.joint_pos) # via __torch_function__
value = robot.data.joint_pos[0, 3] # via __getitem__
result = robot.data.joint_pos + 1.0 # via __add__
legacy = wp.to_torch(robot.data.joint_pos) # temporary shim
# Preferred (no warning):
result = torch.sum(robot.data.joint_pos.torch)
value = robot.data.joint_pos.torch[0, 3]
result = robot.data.joint_pos.torch + 1.0
tensor = robot.data.joint_pos.torch
The wp.to_torch() compatibility path is a temporary shim for code that was migrated
before ProxyArray exposed explicit accessors. It returns the same zero-copy tensor as
.torch and emits a one-time DeprecationWarning. The shim and the other deprecation
bridges will be removed in a future release. Migrate to explicit .torch access now.
Migrating from Isaac Lab 2.x#
In Isaac Lab 2.x, data properties returned torch.Tensor directly. In 3.0, they return
ProxyArray. Append .torch to get the tensor:
# BEFORE (Isaac Lab 2.x) — properties returned torch.Tensor directly
joint_pos = robot.data.joint_pos
first_contact = sensor.compute_first_contact(dt)
# AFTER (Isaac Lab 3.0) — properties return ProxyArray
joint_pos = robot.data.joint_pos.torch
first_contact = sensor.compute_first_contact(dt).torch
Note
Passing a ProxyArray to wp.to_torch() is temporarily supported by a compatibility
shim and returns the same cached zero-copy tensor as .torch. This path emits a
one-time DeprecationWarning and will be removed in a future release. Use .torch
in new code.
Backend Differences#
While the ProxyArray interface is identical across backends, the underlying data refresh
model differs:
- PhysX (pull-to-refresh):
Properties pull fresh data from the PhysX tensor API on first access per simulation step, then cache the result. The underlying GPU buffers are stable and pre-allocated — the
ProxyArraywrapper is created once and reused safely across steps.- Newton (auto-refresh with wrapper replacement):
The simulation automatically refreshes GPU buffers each step. On full simulation resets, buffers may be re-created. The Newton backend creates new
ProxyArraywrappers for the new warp arrays, invalidating any previously cached torch tensors.
In both cases, .torch always returns a view of the current simulation state for the
current step.
Warning
Do not cache .torch results across simulation resets. After a reset (especially on
Newton), previously obtained tensors may point to stale or freed GPU memory. Always
re-access the property after a reset.
API Reference#
- class isaaclab.utils.warp.ProxyArray[source]
Warp-first array wrapper providing cached zero-copy
.torchand.warpaccessors.This class wraps a
warp.arrayand provides:A
.warpproperty that returns the original warp array (for kernel interop).A
.torchproperty that returns a cached, zero-copytorch.Tensorview (viawarp.to_torch()).Convenience properties (
shape,dtype,device) delegated to the warp array.A deprecation bridge for common torch functions, indexing, and arithmetic/comparison operators while emitting a one-time
DeprecationWarning. Tensor instance methods such asclone()are not forwarded; use explicit.torchaccess for those.
Example:
import warp as wp from isaaclab.utils.warp.proxy_array import ProxyArray arr = wp.zeros(100, dtype=wp.vec3f, device="cuda:0") ta = ProxyArray(arr) # Explicit access (preferred) ta.warp # -> wp.array, shape (100,), dtype vec3f ta.torch # -> torch.Tensor, shape (100, 3) # Deprecation bridge (warns once, then silent) result = ta + 1.0 # works, emits DeprecationWarning
Methods:
__init__(wp_array)Initialize the ProxyArray wrapper.
Attributes:
The underlying warp array.
A cached, zero-copy
torch.Tensorview of the warp array.Shape of the underlying warp array.
Warp dtype of the underlying array.
Device string of the underlying warp array.
- __init__(wp_array: warp.array) None[source]
Initialize the ProxyArray wrapper.
The instance is immutable after construction: the wrapped
wp.arraycannot be reassigned. If the underlying simulation memory is re-allocated, construct a newProxyArrayinstead of mutating an existing one.- Parameters:
wp_array – The warp array to wrap.
- Raises:
TypeError – If
wp_arrayis not awarp.array.
- property warp: warp.array
The underlying warp array.
- property torch: torch.Tensor
A cached, zero-copy
torch.Tensorview of the warp array.The tensor is created on first access via
warp.to_torch()and cached for subsequent calls. Since this is a zero-copy view, modifications to the tensor are visible through the warp array and vice versa.When the underlying warp array has dtype
wp.quatfand theWARN_ON_TORCH_QUATF_ACCESSenvironment variable is set to"1", each read emits aUserWarningpointing at the call site. This is a runtime aid for migrating Isaac Lab 2.x code (which used the(w, x, y, z)quaternion convention) to Isaac Lab 3.x’s(x, y, z, w)convention.
- property dtype
Warp dtype of the underlying array.
- property device: str
Device string of the underlying warp array.