Skip to content

Commit a1183e9

Browse files
committed
Extend benchmark_view_comparison with local-pose and interleaved cases
The shared _run_pose_benchmarks helper previously only timed get/set world poses. Add three more cases so the script covers the full read/write surface of FabricFrameView: * Interleaved set->get on world poses (the realistic camera-update pattern). * get_local_poses (now that FabricFrameView computes local from Fabric world matrices instead of falling back to stale USD). * set_local_poses (now that FabricFrameView composes child_world = parent_world * local through Fabric). Also tolerate the ProxyArray return contract introduced in 0.5.23+: view.get_world_poses() can return either wp.array (older callers) or ProxyArray (current). Read .warp / .torch when present.
1 parent fad047e commit a1183e9

1 file changed

Lines changed: 54 additions & 6 deletions

File tree

scripts/benchmarks/benchmark_view_comparison.py

Lines changed: 54 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -271,26 +271,71 @@ def _run_pose_benchmarks(
271271
positions: wp.array,
272272
orientations: wp.array,
273273
):
274-
"""Shared benchmark loop for get/set world poses on any FrameView."""
274+
"""Shared benchmark loop for get/set {world,local} poses on any FrameView."""
275+
276+
# FrameView getters now return ProxyArray; older callers worked with wp.array
277+
# directly. Support both transparently.
278+
def _as_wp(a):
279+
return a.warp if hasattr(a, "warp") else a
280+
281+
positions_wp = _as_wp(positions)
282+
orientations_wp = _as_wp(orientations)
283+
275284
start_time = time.perf_counter()
276285
for _ in range(num_iterations):
277286
view.get_world_poses()
278287
timing_results["get_world_poses"] = (time.perf_counter() - start_time) / num_iterations
279288

280-
new_positions = wp.clone(positions)
289+
new_positions = wp.clone(positions_wp)
281290
new_positions_t = wp.to_torch(new_positions)
282291
new_positions_t[:, 2] += 0.5
283292
expected_positions = new_positions_t.clone()
284293

285294
start_time = time.perf_counter()
286295
for _ in range(num_iterations):
287-
view.set_world_poses(new_positions, orientations)
296+
view.set_world_poses(new_positions, orientations_wp)
288297
timing_results["set_world_poses"] = (time.perf_counter() - start_time) / num_iterations
289298

299+
# Interleaved set→get on world poses — the realistic write/read pattern for
300+
# downstream consumers (e.g. cameras updating their pose then immediately
301+
# querying it).
302+
start_time = time.perf_counter()
303+
for _ in range(num_iterations):
304+
view.set_world_poses(new_positions, orientations_wp)
305+
view.get_world_poses()
306+
timing_results["interleaved_world"] = (time.perf_counter() - start_time) / num_iterations
307+
308+
# Local poses — Fabric-aware path on FabricFrameView, USD path otherwise.
309+
if hasattr(view, "get_local_poses"):
310+
start_time = time.perf_counter()
311+
for _ in range(num_iterations):
312+
view.get_local_poses()
313+
timing_results["get_local_poses"] = (time.perf_counter() - start_time) / num_iterations
314+
315+
if hasattr(view, "set_local_poses"):
316+
local_pos, local_ori = view.get_local_poses()
317+
local_pos_t = (
318+
local_pos.torch
319+
if hasattr(local_pos, "torch")
320+
else (wp.to_torch(local_pos) if isinstance(local_pos, wp.array) else local_pos)
321+
)
322+
local_ori_t = (
323+
local_ori.torch
324+
if hasattr(local_ori, "torch")
325+
else (wp.to_torch(local_ori) if isinstance(local_ori, wp.array) else local_ori)
326+
)
327+
new_local_pos = wp.from_torch(local_pos_t.clone().contiguous())
328+
new_local_ori = wp.from_torch(local_ori_t.clone().contiguous())
329+
330+
start_time = time.perf_counter()
331+
for _ in range(num_iterations):
332+
view.set_local_poses(translations=new_local_pos, orientations=new_local_ori)
333+
timing_results["set_local_poses"] = (time.perf_counter() - start_time) / num_iterations
334+
290335
ret_pos, ret_quat = view.get_world_poses()
291-
ret_pos_t = wp.to_torch(ret_pos)
292-
ret_quat_t = wp.to_torch(ret_quat)
293-
ori_t = wp.to_torch(orientations)
336+
ret_pos_t = ret_pos.torch if hasattr(ret_pos, "torch") else wp.to_torch(ret_pos)
337+
ret_quat_t = ret_quat.torch if hasattr(ret_quat, "torch") else wp.to_torch(ret_quat)
338+
ori_t = wp.to_torch(orientations_wp)
294339

295340
pos_ok = torch.allclose(ret_pos_t, expected_positions, atol=1e-4, rtol=0)
296341
quat_ok = torch.allclose(ret_quat_t, ori_t, atol=1e-4, rtol=0)
@@ -327,6 +372,9 @@ def print_results(results_dict: dict[str, dict[str, float]], num_prims: int, num
327372
("Initialization", "init"),
328373
("Get World Poses", "get_world_poses"),
329374
("Set World Poses", "set_world_poses"),
375+
("Interleaved Set->Get", "interleaved_world"),
376+
("Get Local Poses", "get_local_poses"),
377+
("Set Local Poses", "set_local_poses"),
330378
]
331379

332380
for op_name, op_key in operations:

0 commit comments

Comments
 (0)