feat(hip,aiter): default silu_and_mul and rope auto backend to native#259
Merged
demandal25 merged 2 commits intoJun 17, 2026
Merged
Conversation
Experimentation found the in-tree HIP native kernels to be the better default for silu_and_mul and the cos/sin-cache rope, so backend="auto" now resolves to native for both ops instead of routing to AITER on gfx942/gfx950. The C++ AITER path stays reachable via an explicit backend="aiter". Move the auto-selection tests to the native test modules so the native-default contract is exercised on any HIP build, independent of whether the aiter package is installed. Also reconcile the inplace rope docstring, which incorrectly claimed AITER consumes cos/sin in the query dtype (the C++ shim passes them as float32). Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
There was a problem hiding this comment.
Pull request overview
This PR changes the HIP backend="auto" routing for silu_and_mul and cos/sin-cache RoPE ops to always select the in-tree native implementation (leaving AITER reachable only via backend="aiter"), and updates docs/tests/README to match that contract.
Changes:
- Make
_auto_select_silu_and_mul_backendand_auto_select_rope_backendalways return"native". - Update public docstrings and README AITER/auto-routing documentation to reflect auto→native for these ops.
- Move/add tests so auto-backend-selection assertions run independent of the
aiterPython package.
Reviewed changes
Copilot reviewed 7 out of 7 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
flashinfer/activation.py |
Forces auto backend selection for silu_and_mul to native and updates docstring. |
flashinfer/rope.py |
Forces auto backend selection for cached RoPE to native and updates docstrings. |
tests/rocm_tests/test_activation_hip.py |
Adds an auto-backend-selection test asserting auto→native. |
tests/rocm_tests/test_activation_aiter_hip.py |
Removes the old auto-selection test from the AITER-gated suite. |
tests/rocm_tests/test_rope_hip.py |
Adds an auto-backend-selection test asserting auto→native (including mixed dtype case). |
tests/rocm_tests/test_rope_aiter_hip.py |
Removes the old auto-selection test from the AITER-gated suite. |
README.md |
Updates the support matrix and AITER support section to document auto→native for these two ops. |
Comments suppressed due to low confidence (1)
flashinfer/rope.py:1220
- The docs now state that
backendsupports only'auto','native', and'aiter', and that'aiter'is ROCm-only. However, on non-HIP platforms the function currently performs no backend validation (because the checks are underif IS_HIP:), sobackend='aiter'or any unknown string silently falls back to the native implementation. This is inconsistent with the documented/expected API behavior and withactivation.silu_and_mul, which raises on unsupported backends.
backend : str
Kernel backend to use. ``"auto"`` (default) resolves to the native
FlashInfer JIT kernel on all platforms.
``"native"`` uses the FlashInfer JIT kernel on all platforms.
``"aiter"`` uses AMD AITER's C++ ``rope_cached_positions_2c_fwd_impl``
kernel — ROCm (gfx942/gfx950) only; requires the ``aiter`` package and
query/key to share a dtype.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Move the backend-string check and explicit-aiter validation to the top of apply_rope_with_cos_sin_cache and its inplace variant, matching silu_and_mul. Previously these checks lived inside `if IS_HIP:`, so on non-HIP platforms backend="aiter" or an unknown backend string silently fell through to the native kernel instead of raising — inconsistent with the documented contract. Addresses Copilot review feedback on PR ROCm#259. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
4 tasks
demandal25
added a commit
that referenced
this pull request
Jun 24, 2026
) ## Summary Adds a committable, reproducible cos/sin-cache RoPE benchmark for ROCm, mirroring `bench_silu_and_mul.py`. Until now the `backend="auto"` routing decisions for RoPE (PR #252, then the auto→native default in #259) rested on ad-hoc experimentation with no committed script or recorded methodology — the numbers couldn't be reproduced from the tree. This script makes that comparison a first-class, re-runnable artifact: native (in-tree HIP JIT) vs AITER, swept across nnz × dtype × op mode, plus an accuracy axis for the numerical-error half of the policy. ### What changed - **`benchmarks/rocm_benchmarks/bench_rope.py`** (new) — drives `apply_rope_with_cos_sin_cache` / `_inplace` through the existing `RocmProfiler` harness. Sweeps nnz `[8 … 32768]` × {f16, bf16} × {native, aiter} × {inplace, out-of-place} on the Llama-3 8B attention shape (q32 / k8, head_size 128, full rotary). `--accuracy` prints AITER-vs-native max-abs-error; `--op inplace|outplace` restricts the op mode; falls back to native-only when AITER is unavailable. No vLLM dependency (unlike the upstream `benchmarks/bench_rope.py`). ### Design notes Two op modes are benchmarked because they diverge for AITER: the inplace path rotates q/k in place, while the out-of-place path uses AITER's zero-copy `_impl` entry point (no q/k copy) — which is where AITER's largest wins land. The accuracy axis exists because the auto policy turns partly on bf16 numerical error sitting near the test tolerance edge, so latency alone doesn't capture the trade-off. The kernel is memory-bandwidth bound (reads + writes q and k per token), so tokens/sec against the HBM ceiling is the headline metric. ## Benchmark results MI300X (gfx942), median kernel time via `bench_rope.py --timing-only`. Native leads at every nnz on the inplace path; AITER crosses ahead only at large nnz out-of-place (its zero-copy entry point), consistent with PR #252's finding that the out-of-place path is where AITER wins. **Inplace** (`apply_rope_with_cos_sin_cache_inplace`), median µs: | nnz | native f16 | aiter f16 | native bf16 | aiter bf16 | |---:|---:|---:|---:|---:| | 8 | 7 | 33 | 6 | 33 | | 512 | 10 | 36 | 12 | 35 | | 2048 | 24 | 46 | 28 | 46 | | 8192 | 71 | 88 | 72 | 89 | | 32768 | 218 | 237 | 218 | 237 | **Out-of-place** (`apply_rope_with_cos_sin_cache`), median µs: | nnz | native f16 | aiter f16 | native bf16 | aiter bf16 | |---:|---:|---:|---:|---:| | 8 | 6 | 34 | 6 | 34 | | 512 | 9 | 36 | 10 | 36 | | 2048 | 20 | 45 | 26 | 45 | | 8192 | 69 | 85 | 70 | 85 | | 32768 | 225 | 207 | 226 | 209 | **Accuracy** (AITER vs native, max abs error): fp16 tops out ~7.8e-3; bf16 reaches ~3.1e-2 at nnz=32768 — near the test tolerance edge, matching the auto policy's bf16→native rationale. ## Test plan - [x] `python benchmarks/rocm_benchmarks/bench_rope.py --timing-only` — both op modes, 80 configs, ran clean on gfx942 with AITER installed (numbers above) - [x] `python benchmarks/rocm_benchmarks/bench_rope.py --accuracy` — native-vs-AITER error table, ran clean - [x] `--op` argument guards (missing value / bad value) exit with a clear message - [x] `pre-commit run -a` --------- Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Make
backend="auto"resolve to the in-tree HIPnativekernel (instead of routing to AITER on gfx942/gfx950) forsilu_and_muland the cos/sin-cacheropeops. Experimentation found the native kernels to be the better default for these two ops; the C++ AITER path stays reachable via an explicitbackend="aiter".What changed
flashinfer/activation.py—_auto_select_silu_and_mul_backendnow always returns"native"; thesilu_and_muldocstring describes the new auto behavior.flashinfer/rope.py—_auto_select_rope_backendnow always returns"native"; bothapply_rope_with_cos_sin_cacheand its inplace variant document the new auto behavior. Also reconciled the inplace docstring, which incorrectly claimed AITER consumes the cos/sin tables in the query dtype — the C++ shim (rope_aiter.cu) passes them as float32.tests/rocm_tests/test_activation_hip.py,test_rope_hip.py— addedtest_*_auto_backend_selectionasserting auto resolves to"native".tests/rocm_tests/test_activation_aiter_hip.py,test_rope_aiter_hip.py— removed the old auto-selection tests from the AITER modules. Those modules are gated behindrequires_aiter(skipped when the aiter package is absent), but the auto-default contract is aiter-independent, so the tests now live in the native modules where they run on any HIP build.README.md— Feature Support Matrix (RoPE, Activation rows) and the AITER Support prose updated to reflect auto→native for these two ops; the C++ AITER path remains opt-in.Architecture / design notes
The four C++-level AITER ops now split on auto-routing:
backend="auto"resolves tormsnormfused_add_rmsnormsilu_and_mulbackend="aiter")rope(cos/sin-cache)backend="aiter")The
_auto_select_*_backendhelpers are kept (rather than inlining"native") as the uniform extension point and test seam, matching the pattern innorm.py.Test plan
pytest tests/rocm_tests/test_activation_hip.py tests/rocm_tests/test_activation_aiter_hip.py tests/rocm_tests/test_rope_hip.py tests/rocm_tests/test_rope_aiter_hip.py -n auto --reruns 2— all pass on gfx942 with aiter installedpre-commit run -a