Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
d7fb208
feat(rocke): share logical dtype and packed operand contracts
tenpercent Sep 23, 2026
239e0c6
fix(rocke): preserve HIP vector load alignment
tenpercent Sep 23, 2026
70ec174
fix(rocke): validate load alignment and fragment coordinates
tenpercent Sep 23, 2026
054d1b3
feat(rocke): migrate homogeneous FP6 GEMM onto shared storage
tenpercent Sep 24, 2026
29b5454
fix(rocke): validate storage descriptors and typed row strides
tenpercent Sep 24, 2026
40b9b82
fix(rocke): unify E4M3 dtype and storage identity
tenpercent Sep 24, 2026
d21f283
fix(rocke): wire native parity into the standard runner
tenpercent Sep 24, 2026
1956a34
fix(rocke): reject empty storage in fragment loaders
tenpercent Sep 24, 2026
699e6b8
fix(rocke): bound fragment offsets and discover configured CTests
tenpercent Sep 24, 2026
4b57104
refactor(rocke): keep bit packing without a duplicate tensor descriptor
tenpercent Sep 24, 2026
2bc6e0f
fix(rocke): tighten packing scope and prepare complete native tests
tenpercent Sep 25, 2026
2732998
docs(rocke): clarify complete native suite setup in test runner
tenpercent Sep 25, 2026
af73df5
feat(rocke): support contiguous 96-bit global and LDS loads
tenpercent Sep 25, 2026
33f4d96
fix(rocke): reject unsupported fragment padding before emission
tenpercent Sep 25, 2026
b03f86c
fix(rocke): preserve vector aliases in bare HIP output
tenpercent Sep 25, 2026
e47c76d
fix(rocke): load packed matrix fragments into word carriers
tenpercent Sep 25, 2026
4c7816d
fix(rocke): preserve override builds and scalar quant dtype contract
tenpercent Sep 25, 2026
6e536d1
fix(rocke): bound fragment load scratch capacity
tenpercent Sep 25, 2026
5e969e0
fix(rocke): adapt FP6 GEMM to simplified fragment API
tenpercent Sep 25, 2026
fa720cc
merge(rocke): resolve FP6 conflicts with develop
tenpercent Sep 30, 2026
8e86549
test(rocke): validate FP6 GEMM with FP16 output
tenpercent Sep 30, 2026
88fecec
Merge develop into FP6 scaled GEMM branch
tenpercent Sep 30, 2026
227bb95
test(rocke): check scale fragment carrier width
tenpercent Sep 30, 2026
fb3b6b1
feat(rocke): enable mixed scaled GEMM on shared operand storage
tenpercent Oct 1, 2026
72246e6
merge: resolve mixed scaled GEMM conflicts with develop
tenpercent Oct 3, 2026
c0227df
test(rocke): cover mixed scaled GEMM with FP16 output
tenpercent Oct 3, 2026
3f7eff2
docs(rocke): clarify scaled WMMA fixture operand formats
Copilot Oct 6, 2026
64c7c18
Merge branch 'develop' into users/mpodkory/rocke/mixed-scaled-gemm
tenpercent Oct 7, 2026
a5fd7b4
fix(rocke): refresh mixed scaled GEMM goldens and diagnostics
tenpercent Oct 8, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,7 @@
]
},
"gfx1250": {
"_comment": "gfx1250-class CDNA multi-chip device on the GFX12 programming model (wave32, WMMA, no MFMA). Primary fp16/bf16 WMMA atom is 16x16x32 (NOT gfx1201's 16x16x16). ABI empirically confirmed on ROCm 7.13 clang 23 (gfx1250 device target): __builtin_amdgcn_wmma_f32_16x16x32_f16 -> llvm.amdgcn.wmma.f32.16x16x32.f16.v8f32.v16f16(i1,<16 x half>,i1,<16 x half>,i16,<8 x float>,i1,i1); bf16 uses v16bf16 (<16 x bfloat>) directly, not the gfx11 <16 x i16> bitcast. Datalayout/triple byte-identical to gfx950/gfx1201. This catalog ships validated fp16/bf16 and fp8/bf8 WMMA atoms plus homogeneous FP8xFP8 and BF8xBF8 SCALE/SCALE16 with E8M0 scales; FP4/FP6/BF6 block-scaled forms remain intentionally omitted. Lane maps are a HYPOTHESIS verified by examples/gfx1250/wmma_probe.py. MEMORY: gfx1250 HAS async global->LDS DMA (its own GFX12 family: global_load_async_to_lds_b128 + s_wait_asynccnt -- NOT the gfx9 buffer_load_lds/global_load_lds, which do not select), so has_async_global_lds=true (GPU-validated via the DTLA path). It also HAS a hardware transpose-LDS read, ds_load_tr16_b128 (GPU-validated via compute_pv_dstr). The has_async_lds and has_ds_read_tr flags stay false on purpose: in this catalog they denote the gfx9/gfx950 ds_read_*_tr_* / async-LDS *ABI* used to admit the gfx950 MFMA tiled builder (attention_arch.py), which gfx1250 does NOT have -- its async/transpose use distinct GFX12 opcodes gated directly in the ISA backend, not via these MFMA-pipeline bits. has_tdm=false: TDM not verified on this part.",
"_comment": "gfx1250-class CDNA multi-chip device on the GFX12 programming model (wave32, WMMA, no MFMA). Primary fp16/bf16 WMMA atom is 16x16x32 (NOT gfx1201's 16x16x16). ABI empirically confirmed on ROCm 7.13 clang 23 (gfx1250 device target): __builtin_amdgcn_wmma_f32_16x16x32_f16 -> llvm.amdgcn.wmma.f32.16x16x32.f16.v8f32.v16f16(i1,<16 x half>,i1,<16 x half>,i16,<8 x float>,i1,i1); bf16 uses v16bf16 (<16 x bfloat>) directly, not the gfx11 <16 x i16> bitcast. Datalayout/triple byte-identical to gfx950/gfx1201. This catalog ships validated fp16/bf16 and fp8/bf8 WMMA atoms plus homogeneous and mixed FP8/BF8/FP6/BF6/FP4 SCALE/SCALE16 with E8M0 scales. Lane maps are a HYPOTHESIS verified by examples/gfx1250/wmma_probe.py. MEMORY: gfx1250 HAS async global->LDS DMA (its own GFX12 family: global_load_async_to_lds_b128 + s_wait_asynccnt -- NOT the gfx9 buffer_load_lds/global_load_lds, which do not select), so has_async_global_lds=true (GPU-validated via the DTLA path). It also HAS a hardware transpose-LDS read, ds_load_tr16_b128 (GPU-validated via compute_pv_dstr). The has_async_lds and has_ds_read_tr flags stay false on purpose: in this catalog they denote the gfx9/gfx950 ds_read_*_tr_* / async-LDS *ABI* used to admit the gfx950 MFMA tiled builder (attention_arch.py), which gfx1250 does NOT have -- its async/transpose use distinct GFX12 opcodes gated directly in the ISA backend, not via these MFMA-pipeline bits. has_tdm=false: TDM not verified on this part.",
"family": "cdna",
"target_family": "gfx12_cdna",
"matrix_path": "wmma",
Expand Down Expand Up @@ -188,7 +188,47 @@
{"family": "wmma_scaled", "a": "bf6", "b": "bf6", "c": "fp32", "a_scale_dtype": "e8m0", "b_scale_dtype": "e8m0", "scale_block_k": 16, "m": 16, "n": 16, "k": 128, "op_id": "wmma_gfx1250_f32_16x16x128_bf6_bf6_scale_e8m0_e8m0_k16"},
{"family": "wmma_scaled", "a": "fp4", "b": "fp4", "c": "fp32", "a_scale_dtype": "e8m0", "b_scale_dtype": "e8m0", "scale_block_k": 32, "m": 16, "n": 16, "k": 128, "op_id": "wmma_gfx1250_f32_16x16x128_fp4_fp4_scale_e8m0_e8m0_k32"},
{"family": "wmma_scaled", "a": "fp4", "b": "fp4", "c": "fp32", "a_scale_dtype": "e8m0", "b_scale_dtype": "e8m0", "scale_block_k": 16, "m": 16, "n": 16, "k": 128, "op_id": "wmma_gfx1250_f32_16x16x128_fp4_fp4_scale_e8m0_e8m0_k16"},
{"family": "wmma_scaled", "a": "bf8", "b": "bf8", "c": "fp32", "a_scale_dtype": "e8m0", "b_scale_dtype": "e8m0", "scale_block_k": 16, "m": 16, "n": 16, "k": 128, "op_id": "wmma_gfx1250_f32_16x16x128_bf8_bf8_scale_e8m0_e8m0_k16"}
{"family": "wmma_scaled", "a": "bf8", "b": "bf8", "c": "fp32", "a_scale_dtype": "e8m0", "b_scale_dtype": "e8m0", "scale_block_k": 16, "m": 16, "n": 16, "k": 128, "op_id": "wmma_gfx1250_f32_16x16x128_bf8_bf8_scale_e8m0_e8m0_k16"},
{"family": "wmma_scaled", "a": "fp8", "b": "bf8", "c": "fp32", "a_scale_dtype": "e8m0", "b_scale_dtype": "e8m0", "scale_block_k": 32, "m": 16, "n": 16, "k": 128, "op_id": "wmma_gfx1250_f32_16x16x128_fp8_bf8_scale_e8m0_e8m0_k32"},
{"family": "wmma_scaled", "a": "fp8", "b": "fp6", "c": "fp32", "a_scale_dtype": "e8m0", "b_scale_dtype": "e8m0", "scale_block_k": 32, "m": 16, "n": 16, "k": 128, "op_id": "wmma_gfx1250_f32_16x16x128_fp8_fp6_scale_e8m0_e8m0_k32"},
{"family": "wmma_scaled", "a": "fp8", "b": "bf6", "c": "fp32", "a_scale_dtype": "e8m0", "b_scale_dtype": "e8m0", "scale_block_k": 32, "m": 16, "n": 16, "k": 128, "op_id": "wmma_gfx1250_f32_16x16x128_fp8_bf6_scale_e8m0_e8m0_k32"},
{"family": "wmma_scaled", "a": "fp8", "b": "fp4", "c": "fp32", "a_scale_dtype": "e8m0", "b_scale_dtype": "e8m0", "scale_block_k": 32, "m": 16, "n": 16, "k": 128, "op_id": "wmma_gfx1250_f32_16x16x128_fp8_fp4_scale_e8m0_e8m0_k32"},
{"family": "wmma_scaled", "a": "bf8", "b": "fp8", "c": "fp32", "a_scale_dtype": "e8m0", "b_scale_dtype": "e8m0", "scale_block_k": 32, "m": 16, "n": 16, "k": 128, "op_id": "wmma_gfx1250_f32_16x16x128_bf8_fp8_scale_e8m0_e8m0_k32"},
{"family": "wmma_scaled", "a": "bf8", "b": "fp6", "c": "fp32", "a_scale_dtype": "e8m0", "b_scale_dtype": "e8m0", "scale_block_k": 32, "m": 16, "n": 16, "k": 128, "op_id": "wmma_gfx1250_f32_16x16x128_bf8_fp6_scale_e8m0_e8m0_k32"},
{"family": "wmma_scaled", "a": "bf8", "b": "bf6", "c": "fp32", "a_scale_dtype": "e8m0", "b_scale_dtype": "e8m0", "scale_block_k": 32, "m": 16, "n": 16, "k": 128, "op_id": "wmma_gfx1250_f32_16x16x128_bf8_bf6_scale_e8m0_e8m0_k32"},
{"family": "wmma_scaled", "a": "bf8", "b": "fp4", "c": "fp32", "a_scale_dtype": "e8m0", "b_scale_dtype": "e8m0", "scale_block_k": 32, "m": 16, "n": 16, "k": 128, "op_id": "wmma_gfx1250_f32_16x16x128_bf8_fp4_scale_e8m0_e8m0_k32"},
{"family": "wmma_scaled", "a": "fp6", "b": "fp8", "c": "fp32", "a_scale_dtype": "e8m0", "b_scale_dtype": "e8m0", "scale_block_k": 32, "m": 16, "n": 16, "k": 128, "op_id": "wmma_gfx1250_f32_16x16x128_fp6_fp8_scale_e8m0_e8m0_k32"},
{"family": "wmma_scaled", "a": "fp6", "b": "bf8", "c": "fp32", "a_scale_dtype": "e8m0", "b_scale_dtype": "e8m0", "scale_block_k": 32, "m": 16, "n": 16, "k": 128, "op_id": "wmma_gfx1250_f32_16x16x128_fp6_bf8_scale_e8m0_e8m0_k32"},
{"family": "wmma_scaled", "a": "fp6", "b": "bf6", "c": "fp32", "a_scale_dtype": "e8m0", "b_scale_dtype": "e8m0", "scale_block_k": 32, "m": 16, "n": 16, "k": 128, "op_id": "wmma_gfx1250_f32_16x16x128_fp6_bf6_scale_e8m0_e8m0_k32"},
{"family": "wmma_scaled", "a": "fp6", "b": "fp4", "c": "fp32", "a_scale_dtype": "e8m0", "b_scale_dtype": "e8m0", "scale_block_k": 32, "m": 16, "n": 16, "k": 128, "op_id": "wmma_gfx1250_f32_16x16x128_fp6_fp4_scale_e8m0_e8m0_k32"},
{"family": "wmma_scaled", "a": "bf6", "b": "fp8", "c": "fp32", "a_scale_dtype": "e8m0", "b_scale_dtype": "e8m0", "scale_block_k": 32, "m": 16, "n": 16, "k": 128, "op_id": "wmma_gfx1250_f32_16x16x128_bf6_fp8_scale_e8m0_e8m0_k32"},
{"family": "wmma_scaled", "a": "bf6", "b": "bf8", "c": "fp32", "a_scale_dtype": "e8m0", "b_scale_dtype": "e8m0", "scale_block_k": 32, "m": 16, "n": 16, "k": 128, "op_id": "wmma_gfx1250_f32_16x16x128_bf6_bf8_scale_e8m0_e8m0_k32"},
{"family": "wmma_scaled", "a": "bf6", "b": "fp6", "c": "fp32", "a_scale_dtype": "e8m0", "b_scale_dtype": "e8m0", "scale_block_k": 32, "m": 16, "n": 16, "k": 128, "op_id": "wmma_gfx1250_f32_16x16x128_bf6_fp6_scale_e8m0_e8m0_k32"},
{"family": "wmma_scaled", "a": "bf6", "b": "fp4", "c": "fp32", "a_scale_dtype": "e8m0", "b_scale_dtype": "e8m0", "scale_block_k": 32, "m": 16, "n": 16, "k": 128, "op_id": "wmma_gfx1250_f32_16x16x128_bf6_fp4_scale_e8m0_e8m0_k32"},
{"family": "wmma_scaled", "a": "fp4", "b": "fp8", "c": "fp32", "a_scale_dtype": "e8m0", "b_scale_dtype": "e8m0", "scale_block_k": 32, "m": 16, "n": 16, "k": 128, "op_id": "wmma_gfx1250_f32_16x16x128_fp4_fp8_scale_e8m0_e8m0_k32"},
{"family": "wmma_scaled", "a": "fp4", "b": "bf8", "c": "fp32", "a_scale_dtype": "e8m0", "b_scale_dtype": "e8m0", "scale_block_k": 32, "m": 16, "n": 16, "k": 128, "op_id": "wmma_gfx1250_f32_16x16x128_fp4_bf8_scale_e8m0_e8m0_k32"},
{"family": "wmma_scaled", "a": "fp4", "b": "fp6", "c": "fp32", "a_scale_dtype": "e8m0", "b_scale_dtype": "e8m0", "scale_block_k": 32, "m": 16, "n": 16, "k": 128, "op_id": "wmma_gfx1250_f32_16x16x128_fp4_fp6_scale_e8m0_e8m0_k32"},
{"family": "wmma_scaled", "a": "fp4", "b": "bf6", "c": "fp32", "a_scale_dtype": "e8m0", "b_scale_dtype": "e8m0", "scale_block_k": 32, "m": 16, "n": 16, "k": 128, "op_id": "wmma_gfx1250_f32_16x16x128_fp4_bf6_scale_e8m0_e8m0_k32"},
{"family": "wmma_scaled", "a": "fp8", "b": "bf8", "c": "fp32", "a_scale_dtype": "e8m0", "b_scale_dtype": "e8m0", "scale_block_k": 16, "m": 16, "n": 16, "k": 128, "op_id": "wmma_gfx1250_f32_16x16x128_fp8_bf8_scale_e8m0_e8m0_k16"},
{"family": "wmma_scaled", "a": "fp8", "b": "fp6", "c": "fp32", "a_scale_dtype": "e8m0", "b_scale_dtype": "e8m0", "scale_block_k": 16, "m": 16, "n": 16, "k": 128, "op_id": "wmma_gfx1250_f32_16x16x128_fp8_fp6_scale_e8m0_e8m0_k16"},
{"family": "wmma_scaled", "a": "fp8", "b": "bf6", "c": "fp32", "a_scale_dtype": "e8m0", "b_scale_dtype": "e8m0", "scale_block_k": 16, "m": 16, "n": 16, "k": 128, "op_id": "wmma_gfx1250_f32_16x16x128_fp8_bf6_scale_e8m0_e8m0_k16"},
{"family": "wmma_scaled", "a": "fp8", "b": "fp4", "c": "fp32", "a_scale_dtype": "e8m0", "b_scale_dtype": "e8m0", "scale_block_k": 16, "m": 16, "n": 16, "k": 128, "op_id": "wmma_gfx1250_f32_16x16x128_fp8_fp4_scale_e8m0_e8m0_k16"},
{"family": "wmma_scaled", "a": "bf8", "b": "fp8", "c": "fp32", "a_scale_dtype": "e8m0", "b_scale_dtype": "e8m0", "scale_block_k": 16, "m": 16, "n": 16, "k": 128, "op_id": "wmma_gfx1250_f32_16x16x128_bf8_fp8_scale_e8m0_e8m0_k16"},
{"family": "wmma_scaled", "a": "bf8", "b": "fp6", "c": "fp32", "a_scale_dtype": "e8m0", "b_scale_dtype": "e8m0", "scale_block_k": 16, "m": 16, "n": 16, "k": 128, "op_id": "wmma_gfx1250_f32_16x16x128_bf8_fp6_scale_e8m0_e8m0_k16"},
{"family": "wmma_scaled", "a": "bf8", "b": "bf6", "c": "fp32", "a_scale_dtype": "e8m0", "b_scale_dtype": "e8m0", "scale_block_k": 16, "m": 16, "n": 16, "k": 128, "op_id": "wmma_gfx1250_f32_16x16x128_bf8_bf6_scale_e8m0_e8m0_k16"},
{"family": "wmma_scaled", "a": "bf8", "b": "fp4", "c": "fp32", "a_scale_dtype": "e8m0", "b_scale_dtype": "e8m0", "scale_block_k": 16, "m": 16, "n": 16, "k": 128, "op_id": "wmma_gfx1250_f32_16x16x128_bf8_fp4_scale_e8m0_e8m0_k16"},
{"family": "wmma_scaled", "a": "fp6", "b": "fp8", "c": "fp32", "a_scale_dtype": "e8m0", "b_scale_dtype": "e8m0", "scale_block_k": 16, "m": 16, "n": 16, "k": 128, "op_id": "wmma_gfx1250_f32_16x16x128_fp6_fp8_scale_e8m0_e8m0_k16"},
{"family": "wmma_scaled", "a": "fp6", "b": "bf8", "c": "fp32", "a_scale_dtype": "e8m0", "b_scale_dtype": "e8m0", "scale_block_k": 16, "m": 16, "n": 16, "k": 128, "op_id": "wmma_gfx1250_f32_16x16x128_fp6_bf8_scale_e8m0_e8m0_k16"},
{"family": "wmma_scaled", "a": "fp6", "b": "bf6", "c": "fp32", "a_scale_dtype": "e8m0", "b_scale_dtype": "e8m0", "scale_block_k": 16, "m": 16, "n": 16, "k": 128, "op_id": "wmma_gfx1250_f32_16x16x128_fp6_bf6_scale_e8m0_e8m0_k16"},
{"family": "wmma_scaled", "a": "fp6", "b": "fp4", "c": "fp32", "a_scale_dtype": "e8m0", "b_scale_dtype": "e8m0", "scale_block_k": 16, "m": 16, "n": 16, "k": 128, "op_id": "wmma_gfx1250_f32_16x16x128_fp6_fp4_scale_e8m0_e8m0_k16"},
{"family": "wmma_scaled", "a": "bf6", "b": "fp8", "c": "fp32", "a_scale_dtype": "e8m0", "b_scale_dtype": "e8m0", "scale_block_k": 16, "m": 16, "n": 16, "k": 128, "op_id": "wmma_gfx1250_f32_16x16x128_bf6_fp8_scale_e8m0_e8m0_k16"},
{"family": "wmma_scaled", "a": "bf6", "b": "bf8", "c": "fp32", "a_scale_dtype": "e8m0", "b_scale_dtype": "e8m0", "scale_block_k": 16, "m": 16, "n": 16, "k": 128, "op_id": "wmma_gfx1250_f32_16x16x128_bf6_bf8_scale_e8m0_e8m0_k16"},
{"family": "wmma_scaled", "a": "bf6", "b": "fp6", "c": "fp32", "a_scale_dtype": "e8m0", "b_scale_dtype": "e8m0", "scale_block_k": 16, "m": 16, "n": 16, "k": 128, "op_id": "wmma_gfx1250_f32_16x16x128_bf6_fp6_scale_e8m0_e8m0_k16"},
{"family": "wmma_scaled", "a": "bf6", "b": "fp4", "c": "fp32", "a_scale_dtype": "e8m0", "b_scale_dtype": "e8m0", "scale_block_k": 16, "m": 16, "n": 16, "k": 128, "op_id": "wmma_gfx1250_f32_16x16x128_bf6_fp4_scale_e8m0_e8m0_k16"},
{"family": "wmma_scaled", "a": "fp4", "b": "fp8", "c": "fp32", "a_scale_dtype": "e8m0", "b_scale_dtype": "e8m0", "scale_block_k": 16, "m": 16, "n": 16, "k": 128, "op_id": "wmma_gfx1250_f32_16x16x128_fp4_fp8_scale_e8m0_e8m0_k16"},
{"family": "wmma_scaled", "a": "fp4", "b": "bf8", "c": "fp32", "a_scale_dtype": "e8m0", "b_scale_dtype": "e8m0", "scale_block_k": 16, "m": 16, "n": 16, "k": 128, "op_id": "wmma_gfx1250_f32_16x16x128_fp4_bf8_scale_e8m0_e8m0_k16"},
{"family": "wmma_scaled", "a": "fp4", "b": "fp6", "c": "fp32", "a_scale_dtype": "e8m0", "b_scale_dtype": "e8m0", "scale_block_k": 16, "m": 16, "n": 16, "k": 128, "op_id": "wmma_gfx1250_f32_16x16x128_fp4_fp6_scale_e8m0_e8m0_k16"},
{"family": "wmma_scaled", "a": "fp4", "b": "bf6", "c": "fp32", "a_scale_dtype": "e8m0", "b_scale_dtype": "e8m0", "scale_block_k": 16, "m": 16, "n": 16, "k": 128, "op_id": "wmma_gfx1250_f32_16x16x128_fp4_bf6_scale_e8m0_e8m0_k16"}
]
},
"gfx11-generic": {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1006,6 +1006,20 @@ class _FragInfo:
}


# Mixed operands keep the same padded ABI and scale-coordinate maps.
_MMA_FRAGMENT_INFO.update(
{
f"wmma_gfx1250_f32_16x16x128_{a}_{b}_scale_e8m0_e8m0_k{block_k}": _MMA_FRAGMENT_INFO[
f"wmma_gfx1250_f32_16x16x128_fp8_fp8_scale_e8m0_e8m0_k{block_k}"
]
for block_k in (32, 16)
for a in ("fp8", "bf8", "fp6", "bf6", "fp4")
for b in ("fp8", "bf8", "fp6", "bf6", "fp4")
if a != b
}
)


def _frag_info(op_id: str) -> _FragInfo:
info = _MMA_FRAGMENT_INFO.get(op_id)
if info is None:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ LLVM 23 ROCm libraries, NumPy, and `ml_dtypes`. Torch is optional.
| `mxfp8_gemm` | FP8 E4M3 (`fp8`) or BF8 E5M2 (`bf8`) on both operands | E8M0 |
| `mxfp6_gemm` | Packed FP6 E2M3 or E3M2 on both operands | E8M0 |
| `mxfp4_gemm` | Packed FP4 E2M1 on both operands | E8M0 |
| [`mixed_scaled_gemm`](mixed_scaled_gemm.py) | Different A/B formats from FP8, BF8, FP6, BF6, and FP4 | E8M0 |

```sh
ROCKE_LLVM_FLAVOR=llvm23 python -m rocke.examples.gfx1250.gemm.mxfp8_gemm
Expand Down Expand Up @@ -54,6 +55,17 @@ or `--dtype both` explicitly. Both operands use the selected format with E8M0
scales. `mxfp6_gemm` similarly defaults to both homogeneous FP6 encodings;
use `--dtype fp6` or `--dtype bf6` to select one. Mixed matrix formats are outside these examples.

[`mixed_scaled_gemm`](mixed_scaled_gemm.py) defaults to FP8 E4M3 x FP4 E2M1.
Use `--dtype-a` and `--dtype-b` to select either operand independently; equal
normalized formats are rejected with guidance to the homogeneous examples.
All 20 ordered mixed pairs have SCALE and SCALE16 catalog entries. The builder
uses each operand's atom-selected layout and shared packed-storage helpers.

```sh
ROCKE_LLVM_FLAVOR=llvm23 python -m rocke.examples.gfx1250.gemm.mixed_scaled_gemm --case all
ROCKE_LLVM_FLAVOR=llvm23 python -m rocke.examples.gfx1250.gemm.mixed_scaled_gemm --dtype-a fp6 --dtype-b fp4 --matrix-path wmma_scale16 --compile-route hip
```

The target-independent aliases in `core/dtypes.py` normalize logical format
names. Recognition does not imply that a target supports an atom; use its
catalog to query supported operand formats and shapes. Each example defines
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
"""Launch gfx1250 block-scaled GEMM and compare with an independent reference.

The default invocation keeps the K=64 FP8/BF8 WMMA + FP32-scale verifier.
Native ``--matrix-path wmma_scale`` / ``wmma_scale16`` use homogeneous FP8, FP6, or FP4 and
Native ``--matrix-path wmma_scale`` / ``wmma_scale16`` use independent FP8/BF8, FP6/BF6, or FP4 operands and
E8M0 scales with K=32 / K=16 groups. Native fixtures cover K=128 or 256 and use
bounded dyadic values, permitting exact comparison after output-type rounding.
Numerical equality treats positive and negative zero as equal; output zero-sign
Expand Down Expand Up @@ -364,7 +364,7 @@ def run_cases(
dtype_c=spec.dtype_c,
)
label = (
f"{spec.resolved_matrix_path()}/{spec.dtype_a}/{compile_route}/{case} "
f"{spec.resolved_matrix_path()}/{spec.dtype_a}x{spec.dtype_b}/{compile_route}/{case} "
f"{spec.M}x{spec.N}x{spec.K} bk{spec.block_k}"
)
got = _launch(rt, fn, spec, inputs)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
# Copyright (c) Advanced Micro Devices, Inc., or its affiliates.
# SPDX-License-Identifier: MIT
"""GEMM with different A/B matrix formats and E8M0 scales on gfx1250."""

from __future__ import annotations

from ....core.dtypes import normalize_dtype
from ....instances.gfx1250.block_scaled_gemm import BlockScaledGemmSpec, _LOWBIT_DTYPES
from ._scaled_gemm_example import argument_parser, verify

FORMATS = tuple(sorted(_LOWBIT_DTYPES))


def make_spec(args) -> BlockScaledGemmSpec:
if normalize_dtype(args.dtype_a) == normalize_dtype(args.dtype_b):
raise ValueError(
"choose different A/B formats or use a homogeneous mxfp example"
)
return BlockScaledGemmSpec(
name="mixed_scaled_gemm",
M=args.m,
N=args.n,
K=args.k,
dtype_a=args.dtype_a,
dtype_b=args.dtype_b,
dtype_c=args.output_dtype,
scale_dtype="e8m0",
matrix_path=args.matrix_path,
block_k=16 if args.matrix_path == "wmma_scale16" else 32,
)


def main(argv: list[str] | None = None) -> int:
parser = argument_parser(__doc__)
parser.add_argument(
"--dtype-a", type=normalize_dtype, choices=FORMATS, default="fp8e4m3"
)
parser.add_argument(
"--dtype-b", type=normalize_dtype, choices=FORMATS, default="fp4e2m1"
)
args = parser.parse_args(argv)
try:
spec = make_spec(args)
except ValueError as exc:
parser.error(str(exc))
return verify(spec, args)


if __name__ == "__main__":
raise SystemExit(main())
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ These emit generic AMDGPU IR; arch only sets the comgr target triple.

## gfx1250 native scaled GEMM

`block_scaled_gemm` supports homogeneous FP8 E4M3, BF8 E5M2, FP6 E2M3, FP6 E3M2,
`block_scaled_gemm` supports homogeneous and mixed FP8 E4M3, BF8 E5M2, FP6 E2M3, FP6 E3M2,
and FP4 E2M1 through SCALE and SCALE16 with LLVM 23 and E8M0 scales.
See the [packed FP6 input contract](../examples/gfx1250/gemm/FP6.md).

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -179,8 +179,6 @@ def is_valid_spec(spec: BlockScaledGemmSpec, arch: str = "gfx1250") -> Tuple[boo
)
matrix_path = spec.resolved_matrix_path()
native_scale = matrix_path in ("wmma_scale", "wmma_scale16")
if native_scale and _canon_lowbit(spec.dtype_a) != _canon_lowbit(spec.dtype_b):
return False, "native gfx1250 SCALE/SCALE16 requires matching matrix formats"
family = matrix_path if native_scale else "wmma"
atom_k = _WMMA_SCALE_K if native_scale else _WMMA_K
if not native_scale and not target.mma.has_shape(
Expand Down Expand Up @@ -238,7 +236,8 @@ def is_valid_spec(spec: BlockScaledGemmSpec, arch: str = "gfx1250") -> Tuple[boo
if native_scale:
return (
True,
f"ok: gfx1250 K=128 native {matrix_path} {_canon_lowbit(spec.dtype_a)} GEMM",
f"ok: gfx1250 K=128 native {matrix_path} "
f"{_canon_lowbit(spec.dtype_a)}x{_canon_lowbit(spec.dtype_b)} GEMM",
)
return True, "ok: gfx1250 K=64 FP8/BF8 WMMA block-scaled GEMM"

Expand Down
Loading
Loading