Skip to content

perf(amggpu): G1 throughput optimizations enabled by Hyperloom agent - 1#73

Open
usaxena-4md wants to merge 1 commit into
amd-integrationfrom
perf/arbor/g1-rl-optimizations
Open

perf(amggpu): G1 throughput optimizations enabled by Hyperloom agent - 1#73
usaxena-4md wants to merge 1 commit into
amd-integrationfrom
perf/arbor/g1-rl-optimizations

Conversation

@usaxena-4md

Copy link
Copy Markdown
Collaborator

Summary

Performance optimizations for the Genesis rigid-body RL physics path. Some changes are AMD/gfx942-specific; others adjust kernel launch configuration and dispatch behavior that also apply to CUDA. No numerical behavior is changed.

Changes

Cross-backend (affects CUDA and AMD)

constraint/solver.py — CG solver dispatch interval
@qd.perf_dispatch(repeat_after_seconds=5 → 3600) on func_solve_body. The dispatcher periodically re-benchmarks the CG solver variants (tiled_wc, wavecoop, monolith) on a timer; each re-evaluation runs extra substeps on slower variants plus Python dispatch overhead and pipeline flushes between switches. Raising the interval keeps the initial variant selection during warmup while avoiding repeated mid-run re-benchmarking. This is backend-agnostic.

block_dim=64 on hot loops
Pinned block_dim=64 via qd.loop_config(...) on:

  • constraint/solver.py: add_collision_constraints, add_frictionloss_constraints, warmstart init loop in func_solve_init
  • collider/broadphase.py: func_collision_clear
  • collider/narrowphase.py: func_narrow_phase_convex_vs_convex, func_narrow_phase_convex_specializations, func_narrow_phase_any_vs_terrain, func_narrow_phase_nonconvex_vs_nonterrain

Motivation is AMD wave64 lane utilization (default 32-thread workgroups underfill the SIMD), but note block_dim also sets the CUDA block size, so this changes the launch configuration on CUDA as well (32 → 64 threads/block). Each environment is independent, so 64 threads/workgroup map cleanly onto envs with no data sharing. Metal serialize guards are preserved; the directive is skipped only on the pure-Python backend.

kinematic_solver.py — avoid full-tensor clones
get_links_quat / get_links_ang previously cloned the full (n_envs, n_links, 4) tensor before slicing. They now take a zero-copy view and clone only the requested slice when gs.use_zerocopy is enabled and links_idx is provided, falling back to the original path otherwise. use_zerocopy defaults on for both CUDA and AMD backends, so this path is exercised on CUDA too.

AMD-only (gfx942 / CDNA3)

collider/collider.py — multicontact thread-count tuning
Inside if torch.version.hip:, the CU multiplier is 256 → 64 and max_items_per_thread 128 → 512, keeping total processing capacity identical. The original launch oversubscribed wavefronts that mostly retire after a single empty-queue check; the tuned config gives each wavefront more real work, matching MI300X/MI325X occupancy. CUDA path is unchanged.

constraint/solver_amdgpu.py — CG kernel occupancy hint
amdgpu-waves-per-eu: "1,1" on _kernel_solve_body_tiled_wc_amdgpu (via fn_attrs={"amdgpu": ...}). Removes the JIT default "1,2" max constraint so the compiler can allocate VGPRs freely instead of spending effort on VGPR compression it can't satisfy. AMD compilation only.

rigid_solver.pykernel_step_1 occupancy hint
amdgpu-waves-per-eu: "3,4" → "1,4". The "3,4" target forced aggressive VGPR compression and triggered register spilling to scratch (compile-time occupancy warnings). "1,4" lets the compiler allocate VGPRs naturally while still packing waves where they fit. AMD compilation only.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant