Skip to content
KernelIndex
Search⌘K

submission 601415

samxuality · python · License unknown

Use it

Vendorable · source mirrored · license unknownView source →

No package. Vendor the mirrored source: 145 lines, June 9 Researcher Reciprocity License v1.0.

submission.py
curl "https://kernelindex.com/api/v1/implementations/kernelbot-amd-mixed-mla-601415?include=source"
interfacepython
Compatibility
measured onAMD Instinct MI355X
declared hardwareAMD Instinct MI355X
architecturesgfx950
dtypesbf16, int32

Benchmark evidence

1 measurement across 1 GPU, fastest first.

Operation / workload
Hardware
Latency
Rank
Observed
AMD Instinct MI355X
64.9µs
#282 of 766
2026-03-21

Reported · How evidence levels are derived →

Source and license

sourceavailable
revision digestsha256:ead255c7df745b4646967c903cc166b4ddfc68488f4024964c1ac3f4a79733a7
license declaredunknown
license concludedunknown
authorssamxuality
imported2026-08-26

Kernel source

submission.py145 lines
"""
MLA decode - torch.compile GEMM for small + assembly with PRE-COMPUTED metadata.

Combines:
1. torch.compile GEMM for small configs (proven fast at 19µs for bs=4/kv=1024)
2. Pre-computed metadata for assembly configs (saves ~9µs per call)
3. Pre-allocated kvi, lg, ls, o for all configs
"""

import os
os.environ.setdefault('PYTORCH_TUNABLEOP_ENABLED', '1')
os.environ.setdefault('PYTORCH_TUNABLEOP_TUNING', '1')
os.environ.setdefault('PYTORCH_TUNABLEOP_VERBOSE', '0')
os.environ.setdefault('PYTORCH_TUNABLEOP_MAX_TUNING_ITERATIONS', '100')
os.environ.setdefault('PYTORCH_TUNABLEOP_MAX_WARMUP_DURATION_MS', '50')

import torch
import torch.nn.functional as F
from task import input_t, output_t

import aiter
from aiter import dtypes as aiter_dtypes
from aiter import get_mla_metadata_info_v1, get_mla_metadata_v1
from aiter.ops.triton.quant.quant import dynamic_per_tensor_quant_fp8_i8

FP8_DTYPE = aiter_dtypes.fp8
BF16 = torch.bfloat16
FP32 = torch.float32
NH = 16
NKV = 1
DQ = 576
DV = 512
SM_SCALE = 1.0 / (DQ ** 0.5)


# ============================================================================
# torch.compile GEMM for small configs (proven best at 19µs)
# ============================================================================

def _gemm_attn(q_3d, kv_t, v):
    bs = q_3d.shape[0]
    kv_len = kv_t.shape[2]
    scores = torch.empty(bs, NH, kv_len, dtype=BF16, device=q_3d.device)
    torch.baddbmm(scores, q_3d, kv_t, beta=0, alpha=SM_SCALE, out=scores)
    return torch.bmm(F.softmax(scores, dim=-1, dtype=FP32).to(BF16), v)

_compiled_gemm_short = torch.compile(_gemm_attn)
_compiled_gemm_long = torch.compile(_gemm_attn)


# ============================================================================
# Pre-compute ALL assembly metadata + buffers at module level
# ============================================================================

_KVI = torch.arange(256 * 8192, dtype=torch.int32, device="cuda")

_CONFIGS = {}

def _precompute_config(bs, kv_seq_len, nks, qd, kvd, kvg=32):
    key = (bs, kv_seq_len)
    n = bs * kv_seq_len
    np_ = bs * nks

    qo_indptr = torch.arange(bs + 1, dtype=torch.int32, device="cuda")
    kv_indptr = torch.arange(bs + 1, dtype=torch.int32, device="cuda") * kv_seq_len
    klp = qo_indptr[1:bs+1]

    info = get_mla_metadata_info_v1(
        bs, 1, NH, qd, kvd, is_sparse=False, fast_mode=False,
        num_kv_splits=nks, intra_batch_mode=True)
    wm, wi, wis, ri, rfm, rpm = [torch.empty(s, dtype=t, device="cuda") for s, t in info]

    get_mla_metadata_v1(
        qo_indptr, kv_indptr, klp, NH // NKV, NKV, True,
        wm, wis, wi, ri, rfm, rpm,
        page_size=1, kv_granularity=kvg,
        max_seqlen_qo=1, uni_seqlen_qo=1,
        fast_mode=False, max_split_per_batch=nks,
        intra_batch_mode=True, dtype_q=qd, dtype_kv=kvd)

    _CONFIGS[key] = {
        'wm': wm, 'wi': wi, 'wis': wis,
        'ri': ri, 'rfm': rfm, 'rpm': rpm,
        'klp': klp,
        'lg': torch.empty((np_, 1, NH, DV), dtype=FP32, device="cuda"),
        'ls': torch.empty((np_, 1, NH, 1), dtype=FP32, device="cuda"),
        'o': torch.empty((bs, NH, DV), dtype=BF16, device="cuda"),
        'nks': nks,
        'qd': qd,
    }

# Pre-compute all assembly configs
_precompute_config(32, 8192, 32, FP8_DTYPE, FP8_DTYPE)
_precompute_config(64, 1024, 8, BF16, FP8_DTYPE)
_precompute_config(64, 8192, 32, FP8_DTYPE, FP8_DTYPE)
_precompute_config(256, 1024, 8, BF16, FP8_DTYPE)
_precompute_config(256, 8192, 32, FP8_DTYPE, FP8_DTYPE)


# ============================================================================
# Main kernel
# ============================================================================

@torch.inference_mode()
def custom_kernel(data: input_t) -> output_t:
    q, kv_data, qo_indptr, kv_indptr, cfg = data
    bs = cfg["batch_size"]
    kv_seq_len = cfg.get("kv_seq_len", 1024)

    # Small configs: torch.compile GEMM
    if bs <= 4 or (bs <= 32 and kv_seq_len <= 1024):
        kv = kv_data["bf16"].view(bs, kv_seq_len, DQ)
        q_3d = q.view(bs, NH, DQ)
        v = kv[:, :, :DV]
        kv_t = kv.transpose(-2, -1)
        if kv_seq_len <= 1024:
            return _compiled_gemm_short(q_3d, kv_t, v)
        else:
            return _compiled_gemm_long(q_3d, kv_t, v)

    # Large configs: assembly with pre-computed metadata
    kv_buffer, kv_scale = kv_data["fp8"]
    n = kv_buffer.shape[0]
    c = _CONFIGS[(bs, kv_seq_len)]

    if kv_seq_len <= 1024:
        q_input, q_scale = q, None
    else:
        t2d = q.view(-1, DQ)
        qx = torch.empty_like(t2d, dtype=FP8_DTYPE)
        scale = torch.zeros(1, dtype=FP32, device=q.device)
        dynamic_per_tensor_quant_fp8_i8(qx, t2d, scale)
        q_input, q_scale = qx.view(q.shape), scale

    kvi = _KVI[:n]

    aiter.mla_decode_stage1_asm_fwd(
        q_input.view(-1, NH, DQ),
        kv_buffer.view(n, 1, NKV, DQ),
        qo_indptr, kv_indptr, kvi, c['klp'],
        None, c['wm'], c['wi'], c['wis'], 1, 1, NKV, SM_SCALE,
        c['lg'], c['ls'], c['o'], q_scale, kv_scale)
    aiter.mla_reduce_v1(c['lg'], c['ls'], c['ri'], c['rfm'], c['rpm'], 1, c['o'], None)
    return c['o']
scrolls · 145 lines total

Source code from GPU Mode and the KernelBot dataset · June 9 Researcher Reciprocity License v1.0

Best evidence level for this revision: reported

JSON