Skip to content

[ROCm][RDNA] Load and call hippihx V1 from RDNA_ATTN decode (opt-in) - #27

Merged
BlivionIaG merged 1 commit into
rdna_extrasfrom
claude/exciting-edison-8wfd1f
Sep 27, 2026
Merged

BlivionIaG merged 1 commit into
rdna_extrasfrom
claude/exciting-edison-8wfd1f

Conversation

@BlivionIaG

Copy link
Copy Markdown

Purpose

Adds the serve half of the hippihx V1 consume ABI, so this fork can load hippihx and call it from the RDNA_ATTN decode path. hippihx owns the RDNA tile contracts and a torch-free C ABI (include/hippihx/v1.h, rev 4). The change is opt-in and does nothing by default.

  • vllm/model_executor/layers/hippihx_v1.py (new). With VLLM_HIPPIHX=1, it opens VLLM_HIPPIHX_LIB (libhippihx_v1.so) through hippihx.v1_ctypes. It then calls hippihx_v1_load with the current device's arch and its hippihx_<arch>.hsaco from VLLM_HIPPIHX_CODE_OBJECT, which can be the file or its directory. hippihx refuses a wrong-arch object, or any process with HSA_OVERRIDE_GFX_VERSION set, with ERR_FOREIGN_ISA. Plans are cached per op and params and are never created during graph capture. Each plan owns a scratch buffer that is 256-byte aligned and zeroed once. A run builds V1 tensor descriptors from torch views and uses the current stream.
  • vllm/v1/attention/backends/rdna_attn.py. The decode branch (max_seqlen_q <= 1) tries attention.fa_fdot2 first and writes straight into output. It returns early only when the plan is ready and the run is accepted. Otherwise fa_rdna2_decode_paged runs exactly as before, with the same arguments.
  • vllm/envs.py: VLLM_HIPPIHX (off by default; only "1" enables it), VLLM_HIPPIHX_LIB, VLLM_HIPPIHX_CODE_OBJECT.

What changes today

  • Flag off: nothing. hippihx is never imported, and the decode path pays one cached function call.
  • Flag on: hippihx loads and plans, but every hippihx op still plans as not ready, so the extras kernels keep running. FA switches over once hippihx marks attention.fa_fdot2 ready.

CUDA graphs. RDNA_ATTN captures uniform single-token decode in full graphs. Whenever graphs are on, vLLM sets cudagraph_num_of_warmups = 1 and runs each FULL capture's warmup eagerly with force_attention=True, so hippihx loads and plans outside capture. As a backstop, plan() never creates a plan while the stream is capturing, and that shape keeps the extras kernel.

Depends on BlivionIaG/hippihx#25 (commit 51dc4ad). It adds the public hippihx.v1_ctypes and hippihx.v1.find_spec that this module imports, instead of hippihx._lib. If hippihx is not installed, VLLM_HIPPIHX=1 logs a warning and falls back.

Not a duplicate. No PR in this repo, open or closed, mentions hippihx. None of the open PRs against rdna_extras touch the RDNA_ATTN decode path.

AI assistance. This change was written with AI assistance (Claude Code). The human submitter must review every changed line and run the on-hardware check below before this is marked ready.

Test Plan

Host-only (done, see results):

# CPU torch + hippihx (BlivionIaG/hippihx#25) built without ROCm (host stub)
VLLM_HIPPIHX_LIB=/path/to/host-stub/libhippihx_v1.so \
  python -m pytest tests/kernels/attention/test_rdna_v1_consume.py -v

# Lint and types, as CI runs them (ruff 0.14.0 from .pre-commit-config.yaml)
ruff check <changed files> && ruff format --check <changed files>
pre-commit run mypy-3.12 --hook-stage manual --files <changed files>

On gfx1030 (V620), still to do before merge:

  1. Flag off: serve as usual. Expect no hippihx: log lines and unchanged output.
  2. Flag on, with a hippihx HIP build:
    VLLM_HIPPIHX=1 VLLM_HIPPIHX_LIB=/path/libhippihx_v1.so VLLM_HIPPIHX_CODE_OBJECT=/path/to/hsaco_dir vllm serve ...
    Expect hippihx: loaded .../hippihx_gfx1030.hsaco (gfx1030), V1 ABI rev 4. and no plan refused or run refused warnings. Greedy output should match flag off, because FA is not ready yet and the extras kernel still runs.

No model eval is attached. This PR changes no kernel, and output is unchanged with the flag on or off until attention.fa_fdot2 is ready. The hippihx change that flips it ready needs an eval.

Test Result

  • tests/kernels/attention/test_rdna_v1_consume.py: 5 passed, with CPU torch and a host-stub hippihx build. This ran in an earlier session on base cd38a1d, against minimal stand-ins for vllm.envs and vllm.logger, because the full vLLM stack could not be installed in that sandbox. In this rebased version, the new module, the test and the rdna_attn.py hunk are byte-identical to what was tested (same blob hashes).
  • Rebased onto rdna_extras at bcdaadd. The only conflict was context in vllm/envs.py (the rewritten VLLM_RDNA_AR comment), resolved by keeping both sides.
  • ruff 0.14.0: the two new files and envs.py are clean. rdna_attn.py shows the same two findings (I001 import order, SIM103) and the same ruff format drift before and after this change.
  • mypy-3.12 hook: hippihx_v1.py, envs.py and the test pass. The one error, supported_kv_cache_dtypes typing in rdna_attn.py, reproduces on the base branch.
  • envs.py evaluated standalone: VLLM_HIPPIHX defaults off, only "1" enables it, and both path variables pass through.
  • Not run inside a real vLLM process or on hardware. In CI the new test skips, because hippihx is not installed.

Essential Elements of an Effective PR Description Checklist
  • The purpose of the PR, such as "Fix some issue (link existing issues this PR will resolve)".
  • The test plan, such as providing test command.
  • The test results, such as pasting the results comparison before and after, or e2e results (host-only results above; on-hardware results pending)
  • (Optional) The necessary documentation update, such as updating supported_models.md and examples for a new model.

🤖 Generated with Claude Code

https://claude.ai/code/session_0147zxyqwsKMmBLRn8xgBaHL


Generated by Claude Code

hippihx (github.com/BlivionIaG/hippihx) owns the RDNA tile contracts
and a torch-free C consume ABI (include/hippihx/v1.h, rev 4). This adds
the serve half, so the fork can load and call it:

- vllm/model_executor/layers/hippihx_v1.py: with VLLM_HIPPIHX=1, dlopen
  VLLM_HIPPIHX_LIB (libhippihx_v1.so) through hippihx.v1_ctypes, then
  hippihx_v1_load the current device's hippihx_<arch>.hsaco from
  VLLM_HIPPIHX_CODE_OBJECT. The load is refused for a wrong-arch object
  or when HSA_OVERRIDE_GFX_VERSION is set. Plans are cached per op and
  params, made outside graph capture, and their scratch is zeroed once
  (256-byte aligned). Run builds V1 tensor descriptors from torch views
  and passes the current stream.
- RDNA_ATTN decode tries attention.fa_fdot2 first and writes straight
  into `output`. It uses hippihx only when the plan is ready; otherwise
  fa_rdna2_decode_paged runs exactly as before.
- vllm/envs.py: VLLM_HIPPIHX (default off), VLLM_HIPPIHX_LIB,
  VLLM_HIPPIHX_CODE_OBJECT.

No behavior change by default. With the flag on, every hippihx op still
plans as not ready until its body migrates, so the extras kernels keep
running.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01YM2kXWFyL3J2Gs4F1oZk7Y
Claude-Session: https://claude.ai/code/session_0147zxyqwsKMmBLRn8xgBaHL
@BlivionIaG
BlivionIaG marked this pull request as ready for review September 27, 2026 20:33
@BlivionIaG
BlivionIaG merged commit a3f7e5d into rdna_extras Sep 27, 2026
1 check failed
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.

2 participants