CRITICAL ATTENTION KERNEL BUG FIXES OVER 0.14b
- flyc gfx950 kernel baked scaling factors to in-register fp16/bf16 Q tensor,
losing precision in proportion tosm_scale * sqrt(head_dim).- This is a known problem to Triton kernel, which was fixed in AOTriton 0.7.1b.
- Triton backward kernels mishandle scaling factor, which would produce NaN for
non-positive scaling factors
The following sections are the original 0.14b release notes, with updated performance numbers.
Overview
AOTriton 0.14 is a feature release in the maintenance-feature cadence
introduced in 0.13: it synchronizes Triton with upstream, adds kernel features,
and updates the tuning database.
Headline changes:
FlyDSL SDPA Kernel Ship as the flyc backend
- Available for gfx950/gfx1201
- Feature Parity with Triton kernel
Gfx950 Performance Boost from 0.13b
d_head
| fwd non-causal | fwd causal | bwd non-causal | bwd causal |
|---|---|---|---|---|
| 16 | 190.22 -> 281.60 (+48%) | 112.99 -> 264.19 (+134%) | 182.33 -> 235.04 (+29%) | 148.20 -> 213.27 (+44%) |
| 32 | 504.22 -> 524.55 (+4%) | 362.20 -> 486.40 (+34%) | 346.44 -> 444.47 (+28%) | 181.91 -> 448.87 (+147%) |
| 48 | 264.04 -> 550.03 (+108%) | 261.12 -> 491.72 (+88%) | 132.04 -> 122.59 (-7%) | 93.13 -> 123.92 (+33%) |
| 64 | 766.14 -> 702.96 (-8%) | 541.01 -> 647.96 (+20%) | 352.41 -> 575.62 (+63%) | 236.42 -> 512.58 (+117%) |
| 80 | 513.93 -> 553.47 (+8%) | 361.59 -> 501.04 (+39%) | 118.29 -> 139.90 (+18%) | 103.03 -> 143.44 (+39%) |
| 96 | 691.68 -> 779.73 (+13%) | 515.01 -> 727.48 (+41%) | 282.85 -> 572.99 (+103%) | 243.93 -> 314.80 (+29%) |
| 128 | 935.18 -> 954.24 (+2%) | 626.29 -> 833.67 (+33%) | 287.56 -> 313.02 (+9%) | 285.44 -> 313.63 (+10%) |
| 160 | 682.18 -> 769.90 (+13%) | 543.54 -> 635.24 (+17%) | 279.08 -> 497.56 (+78%) | 279.70 -> 468.14 (+67%) |
| 192 | 565.78 -> 772.51 (+37%) | 579.85 -> 628.40 (+8%) | 293.93 -> 540.77 (+84%) | 294.18 -> 478.10 (+63%) |
| 224 | 523.02 -> 798.72 (+53%) | 541.90 -> 650.04 (+20%) | 188.06 -> 408.00 (+117%) | 213.46 -> 333.53 (+56%) |
| 256 | 577.49 -> 805.72 (+40%) | 576.41 -> 623.51 (+8%) | 265.44 -> 534.89 (+102%) | 261.40 -> 342.45 (+31%) |
| 384 | 99.28 -> 248.74 (+151%) | 88.67 -> 233.98 (+164%) | 59.02 -> 50.69 (-14%) | 58.79 -> 50.84 (-14%) |
| 512 | 345.45 -> 489.85 (+42%) | 364.06 -> 375.48 (+3%) | 160.84 -> 298.87 (+86%) | 154.53 -> 306.42 (+98%) |
d_head=512 is measured with sq/sk=8192.
Geomean over all 100 points: forward 1.41x, backward 1.46x, overall 1.44x.
Gfx1201 Performance Boost from 0.13b
d_head
| fwd non-causal | fwd causal | bwd non-causal | bwd causal |
|---|---|---|---|---|
| 16 | 43.08 -> 57.04 (+32%) | 26.24 -> 50.94 (+94%) | 34.65 -> 40.28 (+16%) | 33.86 -> 33.33 (-2%) |
| 32 | 56.29 -> 69.99 (+24%) | 38.12 -> 67.55 (+77%) | 43.49 -> 53.53 (+23%) | 41.44 -> 49.29 (+19%) |
| 48 | 58.01 -> 72.87 (+26%) | 40.39 -> 71.34 (+77%) | 38.82 -> 51.54 (+33%) | 39.26 -> 49.58 (+26%) |
| 64 | 65.35 -> 89.19 (+36%) | 53.33 -> 78.17 (+47%) | 45.98 -> 59.36 (+29%) | 44.20 -> 56.26 (+27%) |
| 80 | 61.92 -> 92.67 (+50%) | 43.89 -> 87.98 (+100%) | 40.19 -> 56.40 (+40%) | 41.00 -> 53.24 (+30%) |
| 96 | 64.22 -> 91.62 (+43%) | 47.41 -> 86.75 (+83%) | 39.31 -> 57.80 (+47%) | 40.55 -> 55.25 (+36%) |
| 128 | 69.26 -> 80.30 (+16%) | 49.10 -> 78.54 (+60%) | 37.94 -> 57.24 (+51%) | 40.48 -> 52.91 (+31%) |
| 160 | 65.03 -> 85.88 (+32%) | 50.33 -> 79.92 (+59%) | 25.01 -> 48.88 (+95%) | 27.80 -> 47.44 (+71%) |
| 192 | 61.45 -> 54.91 (-11%) | 47.12 -> 46.93 (-0%) | 26.62 -> 45.71 (+72%) | 27.17 -> 44.61 (+64%) |
| 224 | 43.19 -> 84.08 (+95%) | 39.55 -> 81.23 (+105%) | 17.65 -> 39.50 (+124%) | 20.58 -> 37.90 (+84%) |
| 256 | 50.95 -> 84.32 (+65%) | 43.95 -> 80.61 (+83%) | 20.51 -> 45.45 (+122%) | 24.27 -> 29.95 (+23%) |
| 384 | 13.23 -> 19.93 (+51%) | 13.20 -> 19.55 (+48%) | 6.43 -> 5.86 (-9%) | 6.79 -> 6.09 (-10%) |
| 512 | 28.44 -> 20.19 (-29%) | 27.66 -> 19.73 (-29%) | 10.51 -> 26.58 (+153%) | 10.75 -> 28.12 (+162%) |
d_head=384/512 is measured with sq/sk=8192 due to VRAM limits.
Geomean over all 98 measured points: forward 1.47x, backward 1.45x, overall
1.46x.
VarlenBits supersedes VarlenType
VarlenBits massively expands the expressibility of specifying varlen inputs:
users can now configure sequence accessing independently for Q and K, along
three choice axes:
- Input tensor shape is BHSD or 1THD
- Certain varlen inputs are not stacked (
T) but padded toSuniformly
- Certain varlen inputs are not stacked (
- Sequence lengths are uniform, given as cumulative sums, or specified
individually by an array - Sequence offsets are uniform, re-used from the cumulative sums above, or
specified by a second array
Concretely, VarlenBits is defined as (abridged from
include/aotriton/flash.h):
struct VarlenMode { // one side's three axes, one byte
uint8_t stacked : 1, length : 2, position : 2, reserved : 3;
};
struct alignas(uint32_t) VarlenBits {
VarlenMode qmode; // bits 7:0 -- Q and K decode independently,
VarlenMode kmode; // bits 15:8 so mixed addressing is expressible
uint16_t lse_layout : 2; // bits 17:16
uint16_t reserved : 14; // bits 31:18
};The extra lse_layout enables both HT and TH memory layouts for the LSE
tensor.
API BREAKING, BUT ABI STABLE. AOTriton has no plan to promise
source-level compatibility, due to the maintenance cost. However, AOTriton
begins delivering ABI compatibility with 0.14b. Applications targeting 0.13b
can upgrade to 0.14b as a drop-in replacement (note that aotriton.images
needs to be replaced in this process as well). The library automatically
translates passed-in 0.13b params structs to 0.14b.
Full Modularization
The source tree is fully modularized: everything flash-specific now lives
under modules/flash/.
pip install . at the root of the source tree installs the Python package
aotriton into the environment, which serves as the family-neutral toolchain
that transforms Triton/FlyDSL kernels into a C++ library with precompiled GPU
kernels.
pytest-gpu-lease: one GPU per pytest-xdist worker
A standalone pytest plugin (#215, #223), shipped in-tree but useful to anyone
running GPU tests under pytest-xdist:
pip install ./python/pytest-gpu-leaseIt activates through the pytest11 entry point — no conftest.py wiring.
Each worker leases exactly one GPU through fcntl byte-range locks on a shared
lock file, and tests take it from the gpu_id (int) or gpu_device
('cuda:3') fixture. Set GPU_LEASE_PIN to bypass leasing and pin every
worker to one GPU instead.
The optional watchdog monitors the heartbeat timestamp each pytest-xdist
worker writes into the lock file, and terminates a worker that stops making
progress with a SIGTERM-then-SIGKILL escalation, separated by a grace period.
Monitoring out-of-process sidesteps the limits of in-process stall detection
like pytest-timeout, whose SIGALRM only takes effect at the next bytecode
boundary — which a thread parked in a blocking HIP call never reaches.
export GPU_LEASE_LOCKFILE=/dev/shm/gpu_lease.$$ # both sides must agree
python -m pytest_gpu_lease.watchdog --lockfile "$GPU_LEASE_LOCKFILE" --workers 4 &
pytest -n 4 ...Major Changes from Release 0.13 Beta
API Changes
- BREAKING
VarlenTypeis replaced byVarlenBits(#222).- Spells configurations the enum could not: mixed per-side addressing,
seqused_kon a packed KV cache, and TransformerEngine's(T, H)
logsumexp layout (VarlenLseLayout::TH; default staysHT). - Covers
torch.nn.attention.varlen.
- Spells configurations the enum could not: mixed per-side addressing,
- ABI backward compatibility is now formally supported (#222).
- Backends of the
flashmodule now have names (#230).- For use with
attn_options.force_backend_index. - Declared in the new generated public header
<aotriton/flash/backends.h>.OpAttnFwdBackend/OpAttnBwdBackendconstants.
- Also exposed under
pyaotriton.v3.flashfor the Python testing API.
- For use with
FlyDSL / flyc Backend (new)
- gfx1201 and gfx950 SDPA kernels developed in FlyDSL are vendored under
modules/flash/flyc/, cross-compiled ahead of time by
python/flyc_compile.py, and packed intoaotriton.images(#227, #230). - Operator tuning now probes
flyc; the shipped operator database selects it
for gfx950/gfx1201 training and inferencing on non-fp32 inputs (#239). - 0.14b must not be built from the released
flydsl==0.3.1wheel — upstream
LLVM miscompiles register spills and produces wrong kernels rather than
absent ones..ci/build_llvm_tarball.shand.ci/build_flydsl_wheel.sh
build the pinned LLVM and the compiler wheel from source; the pins live in
third_party/flydsl-{compiler,kernel,llvm}.txt(#234).
Triton Compiler and Databases
- Triton bumped to ROCm/triton
release/internal/3.8.x(3.8.0,aa3cf1a1). - AITER ASM kernels bumped to v0.1.22 (#238), including the backward
odo
argument ABI change — the vendored dispatchers and the pin move together. - Kernel tuning database fully re-tuned for gfx950 and gfx1100;
gfx90a/gfx942/gfx1201 validated against the level-3 UT (#239). - Operator tuning database updated for gfx950/gfx1201 (#239).
- Partial gfx1150/gfx1151 flash databases for
hdim=64,dropout=0.0
(#200) —attn_fwdaverages 61–76% faster than the default configuration.
Kernel Bug Fixes
attn_fwd: Fix incorrect early exits in persistent dynamic mode (#237,
#235).bwd_kernel_fuse: Fix addressingdOwithOut's strides in the dK/dV
phase (#237, #236).attn_fwd: Fix the causal early-exit+infLSE OOB writes, which corrupted
the next sequence's LSE under a stacked varlen layout (#222).attn_fwd: Fix scaling ofbias, which should be cast to fp32 first
(#228, #232).
Runtime Bug Fixes
- Thread safety: the following functions no longer rely on the caller holding
the GIL (#224):getGpuFromStream/isArchExperimentallySupported/isArchTechPreview.getMultiProcessorCount.TritonKernel::invoke/TritonKernel::direct_invokeand
AiterAsmKernel::launch_kernel- Now take the device from the stream (
hipStreamGetDevice) instead of the
calling thread's ambient current device, which can differ from the
stream's.
- Now take the device from the stream (
mha_fwd'sAiterAsmKernelcache:thread_localdropped, matching
mha_bwd. It built a separate copy of every kernel for each new thread.
OnDeviceKernel::get_kernelpropagateshipError_t; a missing kernel now
fails withhipErrorInvalidImage(#238).- Otherwise a later call would fail due to a null
hipFunction_t.
- Otherwise a later call would fail due to a null
Build and Infrastructure
- Modularization complete. Flash C++ sources, pybind bindings, tuning
database, test suite, Triton kernels and tuning logic all live under
modules/flash/(#195–#199);v3python/is deleted and the tuning stack is
theaotriton.tunepackage underpython/tune/(#212). - ROCm installed from pip wheels or a tarball is now supported (available
since ROCm 7.14):find_package(hip)honours$ENV{ROCM_PATH}instead of
assuming a system install at/opt/rocm(#207).
Minor Changes from Release 0.13 Beta
attn_options::KernelSlotgains the FlyDSL kernels (#230). Tuning builds
only — the enum lives behindAOTRITON_BUILD_FOR_TUNING.flycis registered asop_attn_fwdbackend 2 andop_attn_bwdbackend 3,
both metros mixing FlyDSL and Triton steps on one stream (#230).FWD_IMPL/BWD_IMPLtake a backend name (triton,aiter,flyc,
triton_split,triton_fuse);V3_API,FORCE_FWD_BACKENDand
FORCE_BWD_BACKENDare removed (#231).test_forward.pyis deprecated — useSKIP_BWD=1 test_backward.py(#231).- New level-0 tests:
test_prime_hdimandtest_memory_layouts(#231),
test_bottom_right_fully_masked_rows(#237),test_dropout_layout(#226),
andtest_varlen_bits(#222). bwd_preprocess_varlenis fused intobwd_preprocess, changing the kernel
numbering insideattn_options(#222).fast_philoxemitted[r0, r2, r1, r3]becausetl.joinappends a minor
axis; the four randoms of one offset now land in generation order (#226).
The API returns the same mask either way — the win is fewer registers and a
word order other Philox implementations can match.- "Plain Object Notation" (PON) formalizes the existing
k=v;k=vwire format
used byexaidand the flyc build targets (#225). __signature__gainsFLYC_VERSION(#234).- Flash kernel tuning configuration generators, left as single-config
placeholders during the ATI migration, are restored (#216). - Widened the gfx1100
attn_fwdtuning space for inference functionals, and
dropped the stale gfx11seqlen > 2048tuning gate (#220). Tuning-time
generation only; release builds come from database rows. - Operator tuning stores a second-best backend (
op$best1st/op$best2nd);
gfx1200 falls back toop$best2ndwhen the shared gfx1201 row picksflyc,
since no gfx1200 flyc kernel is shipped (#239). - Tuner v3.5: kernel-level and operator-level tuning are unified into one
module, discriminated by a newtuning_levelcolumn;dispatch flash_opis
nowdispatch flash --tuning_mode op(#213). The WebUI follows (#214).- CAVEAT: no migration path. Every existing tuning database must be
re-initialized and re-tuned, and the fleet must be drained and restarted.
Starting from a fresh work directory is recommended.
- CAVEAT: no migration path. Every existing tuning database must be
amd-smi: resolve the device by PCI BDF soHIP_VISIBLE_DEVICESis
honoured, readvram_totalas MB, and fall back between junction and edge
temperature sensors (#217).- Tests can force a CPU reference per test via
USE_ADIFFS_TXT=CPUREFor
AOTRITON_REF_DEVICE_OPTIONS=cpu, working around ROCm 7.14math_sdp
defects (#231, #239). AOTRITON_DEBUG_SKIP_TRITON_KERNELSbuilds only the Triton kernels the flyc
backend needs (#230).- CMake:
.nsvadded to the AKS2 packingDEPENDS, fixing stale packs when
the hsaco manifest changes (#239). - CI builds CPython >= 3.13 from source in
base.Dockerfile; AlmaLinux 8 has
no such package (#211).
Known Problems
- gfx1150 and gfx1151 are not fully validated against the updated Triton
compiler, due to hardware availability. - gfx1250 GPU images are not tested. A tech preview release built with an
internal compiler is planned for better gfx1250 support. - The
op$best2ndmechanism that protects gfx1200 from gfx1201'sflyc
selection has never been exercised on real gfx1200 hardware. - gfx950
flyckernels natively support head dimensions that are multiples of
32 only. flychsaco build rules have no proper dependency tracking, the same
limitation Triton hsaco rules have: neither DSL toolchain ships a-MD
equivalent.- On ROCm 7.14.x, Math SDP is unreliable on both gfx950 and gfx1201. It should
be documented with adiff files, which are not yet written. - The AITER forward
.copackaging globs every*.co, soaffine_kernels.zip
carries uncallablefp8bf16kernels (+383.9 KiB on gfx950). third_party/flydsl-llvm.txtmust be emptied once the upstream LLVM fix
lands, in the same change that bumpsflydsl-compiler.txt.
What's Changed (Auto-Generated)
- Modularization Step 1: Relocate flash attention specific C++ code to modules/flash/csrc by @xinyazhang in #195
- Modularization Step 2: Move tuning database to per-family modules/flash/database by @xinyazhang in #196
- Modularization Step 3: Relocate flash attention API bindings to modules/flash/bindings by @xinyazhang in #197
- Modularization Step 4: Make python/test self-contained and migrate tritonsrc dev harness to modules/flash/kernel by @xinyazhang in #198
- Modularization Step 5: Move SDPA test suite to modules/flash/tests by @xinyazhang in #199
- Add gfx1150 and gfx1151 flash tuning databases for hdim=64, dropout=0.0 by @amd-callumm in #200
- Port Fixes found in 0.13.50 Tech Preview to Mainline by @xinyazhang in #207
- ci: build Python >= 3.13 from source in base.Dockerfile by @xinyazhang in #211
- Modularization Step 6: Tuner v3.5 (Phase 1) by @xinyazhang in #212
- Add pytest-gpu-lease package for pytest-xdist GPU assignment by @xinyazhang in #215
- Modularization Step 6: Tuner v3.5 (Phase 2 - Tuning Level Unification) by @xinyazhang in #213
- Modularization Step 6: Tuner v3.5 (Phase 3 - WebUI) by @xinyazhang in #214
- Fix amd-smi usage related issues introduced in Tuner V3.5 by @xinyazhang in #217
- Restore flash kernel tuning config generators in ATI by @nemanjaudovic in #216
- Widen attn_fwd forward tuning space on gfx1100 by @nemanjaudovic in #220
- Replace VarlenType with VarlenBits; add ABI version translation by @xinyazhang in #222
- Fix various race conditions by @xinyazhang in #224
- Add watchdog to pytest-gpu-lease package by @xinyazhang in #223
- FlyDSL Integration PR1: Introduce PON and Deserializable ChoiceView by @xinyazhang in #225
- FlyDSL Integration PR2: Rearrange the Word Order Produced by the Triton fast_philox Kernel by @xinyazhang in #226
- fixed bias and alibi_block f32 asymmtry between the fwd and bwd by @Chi-Chu319 in #228
- FlyDSL Integration PR3: Vendor FlyDSL SDPA Kernels and Add the AOT Compiler Driver by @xinyazhang in #227
- FlyDSL Integration PR4: Prepare ATI Codegen for a Second Language by @xinyazhang in #229
- FlyDSL Integration PR5: Compile, Pack and Dispatch FlyDSL attention kernels as "Flyc" Backend by @xinyazhang in #230
- FlyDSL Integration PR6: Test the flyc Backend, and Fix the gfx950 Slab Bound by @xinyazhang in #231
- FlyDSL Integration PR7: CI Script to Build the FlyDSL/LLVM from Source by @xinyazhang in #234
- unit test added for bias asymmetry by @Chi-Chu319 in #232
- Bump AITER to v0.1.22 by @xinyazhang in #238
- Fix attn_fwd persistent-loop tile skipping and bwd_kernel_fuse dO strides by @xinyazhang in #237
- 0.14 Final Tuning: Triton 3.8 Databases and the Flyc Operator Backend by @xinyazhang in #239
- Tune: remove codegen's dependency on aotriton.tune by @xinyazhang in #243
- Split the Runtime into a ROCm-Independent aotriton_common and a HIP-Dependent Shim by @xinyazhang in #244
- Do not bake scales into the loaded Q tensor in the gfx950 flyc kernel, and fix non-positive scales in the triton backward kernels by @xinyazhang in #247
New Contributors
- @amd-callumm made their first contribution in #200
- @nemanjaudovic made their first contribution in #216
- @Chi-Chu319 made their first contribution in #228
Full Changelog: 0.13b...0.14.2b