Repository navigation
Update README and remove the examples - #398
Merged
Merged
Conversation
The three *_example.py scripts called the public API (single_prefill_with_kv_cache and the batch wrappers' plan()/run()) and checked each result against an element-wise Python reference: test drivers, not usage examples. No CI job or pytest path runs them, tests/rocm/ covers every case they hit, and each release needed hand fixes to keep them true. The notebook duplicated the README's setup text and stored outputs that went stale every release (version string, a PDL warning #382 removed). Its two walkthroughs with no README equivalent, paged batch prefill and a LogitsPipe sampling chain, use upstream APIs that upstream's documentation covers, which the README now links. run_jupyter_server.sh existed only to serve it. examples/pytorch/ is upstream's and stays. Co-Authored-By: Claude <noreply@anthropic.com>
…viour Supported hardware: the paragraph saying gfx942 had run only the prefill, arch-caps and AITER-routing suites is replaced by the full suite at the release head e1054f3 in docker/Dockerfile.rocm, one card per arch, anchored in the README to the v0.6.18+amd.2 tag: gfx942 not slow: 33867 passed, 4024 skipped, 0 failed slow: 72 passed gfx950 not slow: 33875 passed, 4016 skipped, 0 failed slow: 72 passed On gfx950 four git-dependent tests (test_amd_coverage's two manifest tests, test_redistribution_licences' sdist/wheel exclusions) failed because that copy of the tree had no .git; both files pass, 125 of 125, in a git checkout of the same commit, and are counted as passed. torch.compile: the section said the flag-off path "raises a clear error". Measured in bf16 at afb6440 on both arches (fa2 and aiter, flag 0/1, default and fullgraph; the two matrices are identical row for row) and re-measured at e1054f3 on both arches with every compiled result compared to eager (all match), adding append: paged/ragged prefill and decode run() compile under fullgraph; single prefill and aiter_fused_moe fetch a cached module inside the traced frame and break it; MLA compiles with the flag off too and fails fullgraph. #388 then made AITER decode with return_lse=True compile by breaking the graph, so fullgraph there needs backend="fa2" (footnote). With the flag off the error is usually torch's fake-tensor error; FlashInfer's own message appears only for the guarded fa2 ops under fullgraph. The flag does not register sampling ops taking a generator or jit_args custom variants (schema inference rejects them, so they keep the guard), nor AITER's opt-in norm/RoPE/activation shims. plan() stays outside any compiled region: the plan ops are deliberately unregistered. Append rows: append_paged_kv_cache and append_paged_mla_kv_cache fail with the flag off and compile with it on, under fullgraph too, except append with backend="aiter", which breaks the graph. The re-measured matrix is identical on gfx942 and gfx950. The fp8-quantizing norms join the list of ops the flag cannot register (schema inference rejects them). Known issue: #397 stopped the read-only attention ops declaring the KV cache mutated and added a README note for append, which still does. Four review rounds each found a view layout or compile mode that the previous wording of torch's trigger missed, so the README now states the rule every measurement fits rather than the trigger: give every tensor an op writes its own storage. Max |compiled - eager| at e1054f3, identical on gfx942 and gfx950: dynamic=False default True append into kv[0], kv[1] passed in 4.594 4.594 - fused_add_rmsnorm(pool[1,0], pool[1,1]) 8.25 8.25 - append into one [pages, 2, ...] cache 0 0 5.484 append into separate K and V 0 0 0 Default compile also fails once a size goes dynamic: one compiled function at T = 32/48/64/80 gave 0/12.1/12.4/13 for fused_add_rmsnorm on a pool shaped by T and 0/8.94/12.5/9.44 for rmsnorm(out=o[1]). The single [pages, 2, ...] cache is append's documented layout, split into K and V views inside the wrapper, so the README tells append users to pass two separate caches. In-place RoPE on qkv.split views and MLA append on torch.split views measured exact and are named as the exceptions: separate ckv/kpe buffers would cost MLA run() a copy of the page pool on every step, and splitting qkv is how RoPE is called. The rule says to allocate written tensors up front because a per-call .clone() satisfies "own storage" while dropping the write. For reduce-overhead the README keeps only what #397 measured on both arches: AITER decode copies a KV cache passed as an argument into the graph on every replay, and a module buffer avoids it. Advice to hold the wrapper on the module too was measured harmful in review (a crash on the second call when the first fa2 run is captured, and a re-record per plan()), so it is not given. The paragraph this commit carried before #397, which scoped the issue to dynamic=True and called default compile unaffected, is dropped. Flag-on dispatch is host-side, so the README names the test hosts. Single prefill qo16/kv128, min of 3 interleaved rounds on an idle allocated card: gfx942 21.61 -> 42.42 us (+20.8; fa2 +18.7), gfx950 12.65 -> 23.38 us (+10.7; fa2 +8.2). The usage pointer now names upstream's docs as tracking upstream's latest release and links docs/rocm/backends.md#cuda-only-arguments, and the Benchmarking paragraph names the support matrix explicitly. Co-Authored-By: Claude <noreply@anthropic.com>
There was a problem hiding this comment.
🟢 Approval recommended
The documentation matches the supplied validation and implementation evidence, and the example deletions leave no identified dangling references.
No open issues 🎉
What changed in this PR
Prepares the ROCm port’s documentation for v0.6.18+amd.2 by recording the validated configuration and compilation limits, while removing duplicated, untested examples.
Changes:
- Records full-suite results on gfx942 and gfx950 in the supported development image.
- Documents measured
torch.compilesupport, dispatch overhead, and remaining workarounds following #397 and #388. - Replaces ROCm example links with upstream API documentation and ROCm-specific restrictions, then removes five fork-added example files.
| File | Description |
|---|---|
README.md |
Updates release validation, compilation guidance, and API documentation links. |
examples/single_prefill_example.py |
Removes the standalone single-prefill example. |
examples/run_jupyter_server.sh |
Removes the tutorial’s Jupyter launcher. |
examples/batch_prefill_example.py |
Removes the paged and ragged prefill examples. |
examples/batch_decode_example.py |
Removes the standalone batch-decode example. |
examples/amd_flashinfer_rocm_tutorial.ipynb |
Removes the duplicated ROCm tutorial notebook. |
Review effort: Balanced
Security scan found no critical or high findings on lines changed by this pull requestView the security scan run for complete reports. “New” means the finding is located in a changed file on an added or modified line; it is not a base-versus-head findings delta. |
The README had grown to 397 lines, two-thirds of it reference for a
reader already debugging rather than one getting started. It keeps
what a developer needs first: quick start, usage, the supported
configuration, the full support matrix and the list of what upstream
has that this does not. It drops to 292 lines.
Moved verbatim to new pages:
docs/rocm/torch-compile.md per-op compile table, footnotes,
unregistered ops, the full known issue
docs/rocm/environment.md all 19 runtime variables and the
runtime-helper snippet
The README keeps a summary of each: how to enable torch.compile, to call
plan() outside the compiled region, and the known issue in the form a
user acts on (separate K and V caches for append, a whole tensor for
out=); and the four variables a user typically sets, in environment.md's
wording so the two do not drift. The container gotchas and the
torch-version detail are already in CONTRIBUTING.md and are linked
rather than repeated; the two gfx950 routing paragraphs are already in
the per-op notes of docs/rocm/backends.md and become a pointer ahead of
the upstream-gaps subsection. Quick start keeps the base image name
(pyproject.toml points readers there for it), the note that AITER decode
builds at plan() and MoE on first use, and the jit-cache wheel's scope.
The pr-workflow skill's doc-ownership table names the two new pages.
CONTRIBUTING.md's link to the README's env-var table now points at
environment.md. README links stay absolute because pyproject.toml uses
it as the package description; the new pages link relatively. Quick
start also states the image build time (~35 min), that the image carries
no source, that outside the image amd-aiter must be source-built at its
tag or every AITER route silently runs on fa2, and that the jit-cache
wheel is built, not published. The supported-configuration section says
the suite needs a git checkout (four tests read the git index) and keeps
the sentence the CPU-only-torch error in hip_utils.py points readers to.
The routing pointer names all four per-arch differences.
Co-Authored-By: Claude <noreply@anthropic.com>
The quick start said every AITER route silently runs on fa2 without amd-aiter. Only auto prefill and decode do: MLA (_require_aiter_mla), aiter_fused_moe and the opt-in norm, RoPE and append shims call require_aiter, and an explicit backend="aiter" request raises, so a reader skipping the AITER build would find those unusable rather than slower. Co-Authored-By: Claude <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
The README now states what was validated at the release head (the full suite on both architectures, in the supported image), what
torch.compiledoes per op, and the onetorch.compileknown issue left after #397, with its workaround. The ROCm example scripts and tutorial notebook are removed: they duplicated the README's quick start and upstream's documentation, and nothing tested them. The README is also cut from 397 to 292 lines: it keeps quick start, usage, the supported configuration, the full support matrix and what upstream has that this does not, and moves thetorch.compileand environment-variable reference intodocs/rocm/.What changed
README.md, Supported hardware and toolchain: the paragraph saying gfx942 had only run the prefill, arch-caps and AITER-routing suites is replaced by the full-suite result on both arches, anchored to thev0.6.18+amd.2tag.docs/rocm/torch-compile.md(new; the README keeps a summary and a one-line warning): adds an append row (append_paged_kv_cacheandappend_paged_mla_kv_cachecompile with the flag on, underfullgraphtoo exceptbackend="aiter"append), adds the fp8-quantizing norms to the ops the flag cannot register, and replaces "raises a clear error" with a measured per-op table (flag off, flag on,fullgraph=True), a footnote that AITER decode withreturn_lse=Trueneedsbackend="fa2"underfullgraph(Compile AITER decode with return_lse=True under custom ops #388), the host-side flag-on dispatch cost, and what the flag does not cover:plan()stays outside any compiled region, and sampling ops taking agenerator,jit_argscustom variants and AITER's opt-in norm/RoPE/activation shims are not registered. With the flag off the error is usually torch'sRuntimeError when making fake tensor call.docs/rocm/torch-compile.md, Known issue: merges Stop declaring the paged KV cache mutated on read-only attention ops #397's append note into one rule: give every tensor an op writes its own storage, because PyTorch 2.12 can miscompile a write into a view of a larger tensor under everydynamicsetting (tables below). That includes append's own single[pages, 2, ...]cache, which the wrapper splits into views, so append users are told to pass two separate caches. Four review rounds each found a layout or mode the previous statement of torch's trigger missed, so the README states the rule rather than the trigger. Forreduce-overheadit keeps only Stop declaring the paged KV cache mutated on read-only attention ops #397's measured advice: register the KV cache as a module buffer, since AITER decode copies an argument cache on every replay. The paragraph this branch carried before Stop declaring the paged KV cache mutated on read-only attention ops #397, which scoped the issue todynamic=True, is dropped.README.md, Basic usage: the pointer toexamples/is now a pointer to upstream'splan()/run()documentation, flagged as tracking upstream's latest release, plus the ROCm list of refused CUDA-only arguments.README.md, the rest (third commit): quick start keeps its commands and linksCONTRIBUTING.mdfor the container gotchas; the two gfx950 routing paragraphs become a pointer to the per-op notes indocs/rocm/backends.md, which already hold them; benchmark caveats are left tobenchmarks/rocm/README.md; the env-var table keeps the four variables a user typically sets.docs/rocm/environment.md(new): the full runtime env-var table and the runtime-helper snippet, moved verbatim.CONTRIBUTING.md's link to the README table now points here. The doc-ownership table in.claude/skills/pr-workflow/SKILL.mdnames both new pages.examples/: removessingle_prefill_example.py,batch_prefill_example.py,batch_decode_example.py,amd_flashinfer_rocm_tutorial.ipynbandrun_jupyter_server.sh. All five were fork-added (none exists atv0.6.18), so the additive-only rule is untouched; upstream'sexamples/pytorch/stays.Benchmark results
None: documentation and deleted example scripts only, so no kernel or dispatch path changes.
Test plan
Full suite at e1054f3, the release head (this PR is docs and deletions only), in
docker/Dockerfile.rocm, one allocated card per arch (bus id checked on gfx950):-n auto --reruns 2 -m "not slow"-n 1 --reruns 2 -m slow¹ Four git-dependent tests (
test_amd_coverage's two manifest tests,test_redistribution_licences' sdist and wheel exclusions) failed on gfx950 because that copy of the tree had no.git. Both files pass, 125 of 125, in a git checkout of the same commit, and are counted as passed. No other test needed a rerun on either arch.Flag-on dispatch at afb6440, single prefill qo16/kv128, minimum of 3 interleaved rounds on an idle allocated card:
torch.compilematrix in bf16 at e1054f3 on gfx942 and gfx950, identical cell for cell (fa2 and aiter; single/paged/ragged prefill, decode, MLA, MoE, append, MLA append; flag 0/1; default andfullgraph=True), every compiled result compared to eager: all match. The README table is that result.dynamic=Falsedynamic=Truekv[0],kv[1]passed infused_add_rmsnorm(pool[1,0], pool[1,1])passed in[pages, 2, ...]cacheOne default-compiled function called at T = 32/48/64/80, once a size goes dynamic:
fused_add_rmsnorm(pool[1,0], pool[1,1]), pool shaped by Trmsnorm(out=o[1]),oshaped by TIn-place RoPE on
qkv.splitviews and MLA append ontorch.split(buf, [512, 64])were exact withdynamic=None,FalseandTrueon both arches.git grepfor the file names,ipynb,jupyter; the matches left are upstream's)./code-review xhighonorigin/amd-integration...HEADpre-commit run -a