FBTriton View on GitHub ↗

TLX documentation

TLX on gfx950 (MI350)

Supported ops and extension builtins on AMD MI350.

MI350X/MI355X: 256 CUs in 8 XCDs (32 CUs each), 160 KB LDS per CU, CDNA4 MFMA with 32-row tiles, direct HBM-to-LDS async copies (buffer_load_to_lds), in-LDS transpose reads, and inter-wave scheduling control. Tags follow tlx.md: gfx950 means confirmed on this target.

Supported tlx.ops

One blessed implementation per op from ops/_catalog.py. Dtypes are bare torch names listed explicitly (float16 is FP16 only, bfloat16 is BF16 only); Requires lists hardware capabilities; Backward is catalog supports_backward.

OpVariantImplDtypesRequiresBackwardWhat it does
mmheuristicmm/gfx950.py:mmfloat16, bfloat16—noGEMM dispatching over LocalSplitU, persistent, register-resident, and direct-to-LDS paths under a macro-tile cost model; 8-wave inter-wave pipelines, non-power-of-two tiles, Stream-K.
grouped_gemmheuristicgrouped_gemm/gfx950.py:grouped_gemmfloat16—noOne persistent kernel over all groups: 256x256 tiles as four 128x128 quadrants, double-buffered LDS half-tiles, 8-wave staged loop; fully ragged M/N/K; host cost model picks engines.
grouped_gemm_mxfp8persistent_warp_pipeline_mxfp8grouped_gemm_mxfp8/gfx950.py:grouped_gemm_mxfp8float8_e4m3fn—noGrouped GEMM for E4M3 + E8M0 microscales on the FP16 quadrant pipeline with CDNA4 scaled MFMA; scale slices ship direct-to-LDS; device-resident group scan.
mm_torchtlxinductor_gfx950_mminductor/gfx950_torch:mmfloat16, bfloat16—noInductor template entry so the gfx950 GEMM participates in PT2 template selection, autotuning, and fusion.
addmm_torchtlxinductor_gfx950_addmmaddmm/gfx950_torch:addmmfloat16, bfloat16—noInductor template entry for fused GEMM+bias on gfx950.
bmm_torchtlxinductor_gfx950_bmmbmm/gfx950_torch:bmmfloat16, bfloat16—noInductor template entry for batched GEMM on gfx950.
flash_attnrotated_cluster_pipelineflash_attn/gfx950.py:flash_attnbfloat16—yesFlash attention forward: rotated 4-cluster s_setprio schedule, LDS-resident KV, lazy rescale + exp2 math, short-N and persistent variants; square MHA D64/D128 differentiable path.
prepare_flash_attn_varlen_backwardhost_validatedflash_attn_varlen/gfx950_bwd.py:prepare_varlen_backwardint32—noHost-side validation of cu_seqlens/offsets producing the plan the prepared varlen backward consumes.
flash_attn_varlen_backwardpreparedflash_attn_varlen/gfx950_bwd.py:fa_varlen_backwardbfloat16—noPacked-varlen attention backward with on-device compact schedule builds, dynamic owner queues, AGPR/VGPR lifetime control, scheduled MFMA.
flash_attn_mxfp8mfma_mxfp8flash_attn_mxfp8/gfx950.py:flash_attn_mxfp8bfloat16—yesMXFP8 attention: E4M3 Q/K/V + E8M0 scales, both MFMAs scaled; persistent ping-pong forward; deterministic backward with KV and query owners, FP8 dS export, no atomics.
flash_attn_varlenmfma_interleavedflash_attn_varlen/gfx950.py:flash_attn_varlenfloat16, bfloat16—noPacked varlen forward, inference-only: 64-row query tiles, XCD round-robin schedule, small-tile latency regime.
hstu_attn_devtlxhstu_attn/gfx950.py:hstu_attnfloat16, bfloat16—yesRecSys HSTU attention: softmax+SiLU dual heads with TW/PW bias, DUALWAVE padded double-buffers, buffer atomics, XCD-whole-sequence schedule.
hstu_cross_attntlx_split_kvhstu_cross_attn/gfx950.py:hstu_cross_attnfloat16, bfloat16—yesHSTU cross attention: shared-KV single-fetch forward, split-KV + merge kernels, split-softmax backward, retained/small-shape paths.
kda_paged_prefilltlxkda/gfx950_prefill.py:kda_paged_prefillbfloat16—noChunk-parallel Delta Attention prefill: 64-token chunks, MFMA causal products, 16x16 solves merged into a 64x64 WY inverse, inter-chunk state scan.
kda_recurrent_decodetlxkda/gfx950_decode.py:kda_recurrent_decodebfloat16—noRecurrent Delta Attention decode: one packed token per row into an FP32 state pool with independent R/W indices.

Supported extension builtins (tlx.*)

Scalars, types, diagnostics

BuiltinPurpose
assume_uniformAssert scalar wave-uniform (v_readfirstlane)
zerosZero tensor, optional explicit register layout
dtype_of / size_ofElement type / byte size (host-side)
get_fp8_format_namee5m2/e4m3 for scaled-MMA format args
amd_scaled_downcast_fp8FP32 × power-of-two scale to E4M3FN or E5M2 in one scaled conversion instruction
clock6464-bit hardware timer read
assert_same_layoutCompile-time assert two final layouts match
dump_layoutCompile-time log of resolved layout

Local memory

BuiltinPurpose
local_allocAllocate num LDS buffers, with reuse/layout control
local_viewSubview of buffer array at index (buf[i])
local_sliceSame-rank subview; runtime offsets allowed
local_storeRegisters into LDS buffer
local_loadLDS buffer into registers, with token/layout options
local_gather / local_scatterIndexed gather/scatter along an axis
storage_alias_specSized/unsized shared-buffer alias spec
buffered_tensor / buffered_tensor_typeMemory-backed buffer value and its type

Async copy (HBM to LDS)

Lowers to buffer_load_to_lds: data moves directly into LDS without register staging.

BuiltinPurpose
async_loadAsync global-to-LDS copy, returns token
async_load_commit_groupBundle outstanding loads into a group
async_load_wait_groupWait until at most N groups remain in flight

AMD buffer ops

BuiltinPurpose
buffer_load / buffer_storeGlobal access via scalar base + i32 offsets
buffer_atomic_addBuffer atomic add preserving scalar descriptor
buffer_load_to_localRaw global-to-LDS copy primitive behind async_load
extract_sliceAligned register slice, no cross-thread movement
rematerialized_rangeCSE-proof range recomputed at use; cuts live ranges

Layout control

BuiltinPurpose
local_transPermute descriptor dims (zero data movement)
local_reshapeReshape descriptor without moving data
local_reinterpretReinterpret dtype/shape/layout, incl. CDNA4 transpose-read
require_layout / release_layoutPin / release register layouts
amd_mfma_layoutMFMA distributed layout, versions 1-4
dot_operand_layoutExplicit MFMA dot-operand view
require_amd_wmma_layoutPin tensor to explicit WMMA layout
slice_layoutRank-reduced view of a distributed parent
layoutUser register layout as Shape:Stride
layout_encoding / shared_layout_encodingBase layout classes
swizzled_shared_layout_encoding / swizzled_layoutSwizzled LDS layouts
padded_shared_layout_encodingPadded LDS layout (bank-conflict relief)
shared_linear_layout_encodingExplicit linear SMEM mapping
DummyRegisterLayoutEncodingPlaceholder layout resolved post-inline
storage_kindBuffer storage selector enum
reuse_group / reuse_group_type / reuse_group_ir_typeBuffer overlap trees for aliasing
storage_alias_spec_type / storage_alias_spec_type_classAlias-spec MLIR types

Compute and register control

BuiltinPurpose
amd_packed_dot2Intra-lane FP32 dot of packed FP16/BF16 pairs; LLVM owns dependency waits
dot_scaledScaled dot with optional tile schedule
amd_scheduled_mfmaNative MFMA fragment chains with residency control
amd_mfma_commitWave-local MFMA completion boundary
amd_register_residentConstrain packed register groups (AGPR/VGPR)
amd_register_class_anchorPer-register tied allocator anchor

Synchronization

BuiltinPurpose
alloc_barriers / alloc_warp_barrierAllocate SMEM / warp barriers
barrier_wait / barrier_arrivePhase wait / arrival (arrive_count must be 1)
cluster_barrierSync all threads in all cluster CTAs
cond_barrierConditional s_barrier phase-shift primitive
workgroup_barrierFull workgroup barrier + LDS fence
mbarrier / mbarrier_typeBarrier values and types
async_tokenTracks async-op completion
allocate_tensor_descriptor128B-aligned descriptor scratch (host-side alloc)

Scheduling and threads

BuiltinPurpose
warp_pipeline_stageInter/intra-wave stage marker → s_setprio biasing
amd_sched_barrierCompiler scheduling marker (no sync/fence)
amd_iglp_optIGLP interleave hint
warp_predicateExecute body under per-lane predicate
cluster_cta_rank / cluster_size_1dCTA rank / cluster size
thread_id / num_warpsThread id / kernel warp count
warp_all / warp_anyLane votes

Notes

buffer_load_to_local needs 32/128-bit width plus an aligned mask;

f16/bf16 buffer_atomic_add needs width 2 plus a pair-uniform mask.

amd_scheduled_mfma distinguishes transient vs persistent accumulator

chains; persistent dV stays in AGPRs while dK stays in VGPRs in the tuned backward paths.

amd_packed_dot2 requires same-shaped uint32 packed inputs and an FP32

accumulator. Pass input_dtype=tl.float16 or tl.bfloat16; see other operations for the full contract.

TDM descriptor ops (async_amd_descriptor_*) are gfx1250+, not gfx950;

see TLX on gfx1250.