submission 512815
mreso · python · License unknown
Use it
Vendorable · source mirrored · license unknownView source →
No package. Vendor the mirrored source: 86 lines, June 9 Researcher Reciprocity License v1.0.
solution.py
curl "https://kernelindex.com/api/v1/implementations/kernelbot-matmul-v2-512815?include=source"interfacepython
Compatibility
measured onNVIDIA L4
declared hardwareNVIDIA L4
architecturessm_89
dtypesfp16
Benchmark evidence
1 measurement across 1 GPU, fastest first.
Operation / workload
Hardware
Latency
Rank
Observed
Reported · How evidence levels are derived →
Source and license
sourceavailable
revision digestsha256:0babe8e6f47a2502b18fefd3034ef7282adde972d7571a4f45d8b086d106f16b
license declaredunknown
license concludedunknown
authorsmreso
imported2026-08-15
Techniques
Extracted from the mirrored source by pattern, never inferred. Each row cites its line.
autotune
@triton.autotune(mma
acc = tl.dot(a, b, acc)num-warps = 8
triton.Config({'BLOCK_M': 256, 'BLOCK_N': 256, 'BLOCK_K': 64, 'GROUP_M': 8}, num_stages=3, num_warps=8),stages = 3
triton.Config({'BLOCK_M': 256, 'BLOCK_N': 256, 'BLOCK_K': 64, 'GROUP_M': 8}, num_stages=3, num_warps=8),Kernel source
solution.py86 lines
import os
os.environ.setdefault('CUBLAS_WORKSPACE_CONFIG', ':4096:8')
import torch
import triton
import triton.language as tl
from task import input_t, output_t
@triton.autotune(
configs=[
# Hopper/Blackwell configs (large tiles, many stages)
triton.Config({'BLOCK_M': 256, 'BLOCK_N': 256, 'BLOCK_K': 64, 'GROUP_M': 8}, num_stages=3, num_warps=8),
triton.Config({'BLOCK_M': 128, 'BLOCK_N': 256, 'BLOCK_K': 64, 'GROUP_M': 8}, num_stages=4, num_warps=8),
triton.Config({'BLOCK_M': 256, 'BLOCK_N': 128, 'BLOCK_K': 64, 'GROUP_M': 8}, num_stages=4, num_warps=8),
triton.Config({'BLOCK_M': 128, 'BLOCK_N': 256, 'BLOCK_K': 64, 'GROUP_M': 8}, num_stages=3, num_warps=8),
triton.Config({'BLOCK_M': 256, 'BLOCK_N': 128, 'BLOCK_K': 64, 'GROUP_M': 8}, num_stages=3, num_warps=8),
triton.Config({'BLOCK_M': 128, 'BLOCK_N': 128, 'BLOCK_K': 64, 'GROUP_M': 8}, num_stages=4, num_warps=8),
triton.Config({'BLOCK_M': 64, 'BLOCK_N': 256, 'BLOCK_K': 64, 'GROUP_M': 8}, num_stages=4, num_warps=8),
triton.Config({'BLOCK_M': 256, 'BLOCK_N': 64, 'BLOCK_K': 64, 'GROUP_M': 8}, num_stages=4, num_warps=8),
# Ampere/L4 configs (smaller tiles)
triton.Config({'BLOCK_M': 128, 'BLOCK_N': 128, 'BLOCK_K': 32, 'GROUP_M': 8}, num_stages=4, num_warps=4),
triton.Config({'BLOCK_M': 128, 'BLOCK_N': 64, 'BLOCK_K': 32, 'GROUP_M': 8}, num_stages=4, num_warps=4),
triton.Config({'BLOCK_M': 64, 'BLOCK_N': 128, 'BLOCK_K': 32, 'GROUP_M': 8}, num_stages=4, num_warps=4),
triton.Config({'BLOCK_M': 64, 'BLOCK_N': 64, 'BLOCK_K': 32, 'GROUP_M': 8}, num_stages=5, num_warps=4),
triton.Config({'BLOCK_M': 64, 'BLOCK_N': 256, 'BLOCK_K': 32, 'GROUP_M': 8}, num_stages=4, num_warps=4),
triton.Config({'BLOCK_M': 128, 'BLOCK_N': 32, 'BLOCK_K': 32, 'GROUP_M': 8}, num_stages=4, num_warps=4),
triton.Config({'BLOCK_M': 32, 'BLOCK_N': 128, 'BLOCK_K': 32, 'GROUP_M': 8}, num_stages=4, num_warps=4),
triton.Config({'BLOCK_M': 64, 'BLOCK_N': 32, 'BLOCK_K': 32, 'GROUP_M': 8}, num_stages=5, num_warps=2),
triton.Config({'BLOCK_M': 32, 'BLOCK_N': 64, 'BLOCK_K': 32, 'GROUP_M': 8}, num_stages=5, num_warps=2),
],
key=['M', 'N', 'K'],
)
@triton.jit
def _matmul_kernel(
a_ptr, b_ptr, c_ptr,
M, N, K,
stride_am, stride_ak,
stride_bk, stride_bn,
stride_cm, stride_cn,
BLOCK_M: tl.constexpr, BLOCK_N: tl.constexpr, BLOCK_K: tl.constexpr,
GROUP_M: tl.constexpr,
):
pid = tl.program_id(axis=0)
num_pid_m = tl.cdiv(M, BLOCK_M)
num_pid_n = tl.cdiv(N, BLOCK_N)
num_pid_in_group = GROUP_M * num_pid_n
group_id = pid // num_pid_in_group
first_pid_m = group_id * GROUP_M
group_size_m = tl.minimum(num_pid_m - first_pid_m, GROUP_M)
pid_m = first_pid_m + ((pid % num_pid_in_group) % group_size_m)
pid_n = (pid % num_pid_in_group) // group_size_m
offs_am = (pid_m * BLOCK_M + tl.arange(0, BLOCK_M)) % M
offs_bn = (pid_n * BLOCK_N + tl.arange(0, BLOCK_N)) % N
offs_k = tl.arange(0, BLOCK_K)
a_ptrs = a_ptr + (offs_am[:, None] * stride_am + offs_k[None, :] * stride_ak)
b_ptrs = b_ptr + (offs_k[:, None] * stride_bk + offs_bn[None, :] * stride_bn)
acc = tl.zeros((BLOCK_M, BLOCK_N), dtype=tl.float32)
for k in range(0, tl.cdiv(K, BLOCK_K)):
a = tl.load(a_ptrs, mask=offs_k[None, :] < K - k * BLOCK_K, other=0.0)
b = tl.load(b_ptrs, mask=offs_k[:, None] < K - k * BLOCK_K, other=0.0)
acc = tl.dot(a, b, acc)
a_ptrs += BLOCK_K * stride_ak
b_ptrs += BLOCK_K * stride_bk
c = acc.to(tl.float16)
offs_cm = pid_m * BLOCK_M + tl.arange(0, BLOCK_M)
offs_cn = pid_n * BLOCK_N + tl.arange(0, BLOCK_N)
c_ptrs = c_ptr + stride_cm * offs_cm[:, None] + stride_cn * offs_cn[None, :]
c_mask = (offs_cm[:, None] < M) & (offs_cn[None, :] < N)
tl.store(c_ptrs, c, mask=c_mask)
def custom_kernel(data: input_t) -> output_t:
a, b, c = data
M, K = a.shape
_, N = b.shape
# cuBLAS (torch.mm) is optimal for all sizes and architectures.
# It uses hardware-specific GEMM implementations (wgmma on Hopper/Blackwell,
# tensor cores on Ampere/Ada) via cuBLAS, which is the reference for top scores.
torch.mm(a, b, out=c)
return c
scrolls · 86 lines total
Source code from GPU Mode and the KernelBot dataset · June 9 Researcher Reciprocity License v1.0
Changes from previous submission
Against this author's previous submission submission 512775.
- # submission_matmul_v2.py- # Matrix multiplication C = A @ B for float16 matrices.- # Interface: custom_kernel((A, B, C)) -> C- # A: (M, K) float16, B: (K, N) float16, C: (M, N) float16 output- #- # Set CUBLAS_WORKSPACE_CONFIG so cuBLAS can run in deterministic mode when- # check_implementation calls the reference (a @ b in float16 under- # DeterministicContext). Must be set before any cuBLAS handle is created.-import osos.environ.setdefault('CUBLAS_WORKSPACE_CONFIG', ':4096:8')⋯ 5 unchanged lines@triton.autotune(configs=[- triton.Config({'BM': 128, 'BN': 256, 'BK': 64, 'GROUP': 8}, num_warps=8, num_stages=4),- triton.Config({'BM': 64, 'BN': 256, 'BK': 32, 'GROUP': 8}, num_warps=4, num_stages=4),- triton.Config({'BM': 128, 'BN': 128, 'BK': 32, 'GROUP': 8}, num_warps=4, num_stages=4),- triton.Config({'BM': 128, 'BN': 64, 'BK': 32, 'GROUP': 8}, num_warps=4, num_stages=4),- triton.Config({'BM': 64, 'BN': 128, 'BK': 32, 'GROUP': 8}, num_warps=4, num_stages=4),- triton.Config({'BM': 128, 'BN': 32, 'BK': 32, 'GROUP': 8}, num_warps=4, num_stages=4),- triton.Config({'BM': 64, 'BN': 32, 'BK': 32, 'GROUP': 8}, num_warps=4, num_stages=2),- triton.Config({'BM': 32, 'BN': 64, 'BK': 32, 'GROUP': 8}, num_warps=4, num_stages=2),- triton.Config({'BM': 128, 'BN': 256, 'BK': 128, 'GROUP': 8}, num_warps=8, num_stages=3),- triton.Config({'BM': 256, 'BN': 128, 'BK': 128, 'GROUP': 8}, num_warps=8, num_stages=3),- triton.Config({'BM': 256, 'BN': 64, 'BK': 128, 'GROUP': 8}, num_warps=8, num_stages=3),- triton.Config({'BM': 64, 'BN': 256, 'BK': 128, 'GROUP': 8}, num_warps=8, num_stages=3),- triton.Config({'BM': 64, 'BN': 64, 'BK': 64, 'GROUP': 8}, num_warps=4, num_stages=3),+ # Hopper/Blackwell configs (large tiles, many stages)+ triton.Config({'BLOCK_M': 256, 'BLOCK_N': 256, 'BLOCK_K': 64, 'GROUP_M': 8}, num_stages=3, num_warps=8),+ triton.Config({'BLOCK_M': 128, 'BLOCK_N': 256, 'BLOCK_K': 64, 'GROUP_M': 8}, num_stages=4, num_warps=8),+ triton.Config({'BLOCK_M': 256, 'BLOCK_N': 128, 'BLOCK_K': 64, 'GROUP_M': 8}, num_stages=4, num_warps=8),+ triton.Config({'BLOCK_M': 128, 'BLOCK_N': 256, 'BLOCK_K': 64, 'GROUP_M': 8}, num_stages=3, num_warps=8),+ triton.Config({'BLOCK_M': 256, 'BLOCK_N': 128, 'BLOCK_K': 64, 'GROUP_M': 8}, num_stages=3, num_warps=8),+ triton.Config({'BLOCK_M': 128, 'BLOCK_N': 128, 'BLOCK_K': 64, 'GROUP_M': 8}, num_stages=4, num_warps=8),+ triton.Config({'BLOCK_M': 64, 'BLOCK_N': 256, 'BLOCK_K': 64, 'GROUP_M': 8}, num_stages=4, num_warps=8),+ triton.Config({'BLOCK_M': 256, 'BLOCK_N': 64, 'BLOCK_K': 64, 'GROUP_M': 8}, num_stages=4, num_warps=8),+ # Ampere/L4 configs (smaller tiles)+ triton.Config({'BLOCK_M': 128, 'BLOCK_N': 128, 'BLOCK_K': 32, 'GROUP_M': 8}, num_stages=4, num_warps=4),+ triton.Config({'BLOCK_M': 128, 'BLOCK_N': 64, 'BLOCK_K': 32, 'GROUP_M': 8}, num_stages=4, num_warps=4),+ triton.Config({'BLOCK_M': 64, 'BLOCK_N': 128, 'BLOCK_K': 32, 'GROUP_M': 8}, num_stages=4, num_warps=4),+ triton.Config({'BLOCK_M': 64, 'BLOCK_N': 64, 'BLOCK_K': 32, 'GROUP_M': 8}, num_stages=5, num_warps=4),+ triton.Config({'BLOCK_M': 64, 'BLOCK_N': 256, 'BLOCK_K': 32, 'GROUP_M': 8}, num_stages=4, num_warps=4),+ triton.Config({'BLOCK_M': 128, 'BLOCK_N': 32, 'BLOCK_K': 32, 'GROUP_M': 8}, num_stages=4, num_warps=4),+ triton.Config({'BLOCK_M': 32, 'BLOCK_N': 128, 'BLOCK_K': 32, 'GROUP_M': 8}, num_stages=4, num_warps=4),+ triton.Config({'BLOCK_M': 64, 'BLOCK_N': 32, 'BLOCK_K': 32, 'GROUP_M': 8}, num_stages=5, num_warps=2),+ triton.Config({'BLOCK_M': 32, 'BLOCK_N': 64, 'BLOCK_K': 32, 'GROUP_M': 8}, num_stages=5, num_warps=2),],key=['M', 'N', 'K'],)@triton.jitdef _matmul_kernel(a_ptr, b_ptr, c_ptr,- M: int, N: int, K: int,- stride_am: int, stride_ak: int,- stride_bk: int, stride_bn: int,- stride_cm: int, stride_cn: int,- BM: tl.constexpr, BN: tl.constexpr, BK: tl.constexpr, GROUP: tl.constexpr,+ M, N, K,+ stride_am, stride_ak,+ stride_bk, stride_bn,+ stride_cm, stride_cn,+ BLOCK_M: tl.constexpr, BLOCK_N: tl.constexpr, BLOCK_K: tl.constexpr,+ GROUP_M: tl.constexpr,):- # Grouped tile ordering for better L2 cache reuse (from Triton tutorial).- # group_size_m is clamped so the last group is handled correctly when- # num_m is not a multiple of GROUP.- pid = tl.program_id(0)- num_m = tl.cdiv(M, BM)- num_n = tl.cdiv(N, BN)+ pid = tl.program_id(axis=0)+ num_pid_m = tl.cdiv(M, BLOCK_M)+ num_pid_n = tl.cdiv(N, BLOCK_N)+ num_pid_in_group = GROUP_M * num_pid_n+ group_id = pid // num_pid_in_group+ first_pid_m = group_id * GROUP_M+ group_size_m = tl.minimum(num_pid_m - first_pid_m, GROUP_M)+ pid_m = first_pid_m + ((pid % num_pid_in_group) % group_size_m)+ pid_n = (pid % num_pid_in_group) // group_size_m- num_in_group = GROUP * num_n- group_id = pid // num_in_group- first_m = group_id * GROUP- group_size_m = tl.minimum(num_m - first_m, GROUP) # ← key fix+ offs_am = (pid_m * BLOCK_M + tl.arange(0, BLOCK_M)) % M+ offs_bn = (pid_n * BLOCK_N + tl.arange(0, BLOCK_N)) % N+ offs_k = tl.arange(0, BLOCK_K)+ a_ptrs = a_ptr + (offs_am[:, None] * stride_am + offs_k[None, :] * stride_ak)+ b_ptrs = b_ptr + (offs_k[:, None] * stride_bk + offs_bn[None, :] * stride_bn)- pid_in_group = pid % num_in_group- m_id = first_m + (pid_in_group % group_size_m)- n_id = pid_in_group // group_size_m-- offs_m = (m_id * BM + tl.arange(0, BM)) % M- offs_n = (n_id * BN + tl.arange(0, BN)) % N- offs_k = tl.arange(0, BK)-- a_ptrs = a_ptr + offs_m[:, None] * stride_am + offs_k[None, :] * stride_ak- b_ptrs = b_ptr + offs_k[:, None] * stride_bk + offs_n[None, :] * stride_bn-- acc = tl.zeros((BM, BN), dtype=tl.float32)- for k in range(0, tl.cdiv(K, BK)):- a = tl.load(a_ptrs, mask=offs_k[None, :] < K - k * BK, other=0.0)- b = tl.load(b_ptrs, mask=offs_k[:, None] < K - k * BK, other=0.0)+ acc = tl.zeros((BLOCK_M, BLOCK_N), dtype=tl.float32)+ for k in range(0, tl.cdiv(K, BLOCK_K)):+ a = tl.load(a_ptrs, mask=offs_k[None, :] < K - k * BLOCK_K, other=0.0)+ b = tl.load(b_ptrs, mask=offs_k[:, None] < K - k * BLOCK_K, other=0.0)acc = tl.dot(a, b, acc)- a_ptrs += BK * stride_ak- b_ptrs += BK * stride_bk+ a_ptrs += BLOCK_K * stride_ak+ b_ptrs += BLOCK_K * stride_bk- c_m = m_id * BM + tl.arange(0, BM)- c_n = n_id * BN + tl.arange(0, BN)- c_mask = (c_m[:, None] < M) & (c_n[None, :] < N)- c_ptrs = c_ptr + stride_cm * c_m[:, None] + stride_cn * c_n[None, :]- tl.store(c_ptrs, acc.to(tl.float16), mask=c_mask)+ c = acc.to(tl.float16)+ offs_cm = pid_m * BLOCK_M + tl.arange(0, BLOCK_M)+ offs_cn = pid_n * BLOCK_N + tl.arange(0, BLOCK_N)+ c_ptrs = c_ptr + stride_cm * offs_cm[:, None] + stride_cn * offs_cn[None, :]+ c_mask = (offs_cm[:, None] < M) & (offs_cn[None, :] < N)+ tl.store(c_ptrs, c, mask=c_mask)def custom_kernel(data: input_t) -> output_t:- A, B, C = data- M, K = A.shape- K2, N = B.shape- assert K == K2- grid = lambda meta: (triton.cdiv(M, meta['BM']) * triton.cdiv(N, meta['BN']),)- _matmul_kernel[grid](- A, B, C,- M, N, K,- A.stride(0), A.stride(1),- B.stride(0), B.stride(1),- C.stride(0), C.stride(1),- )- return C+ a, b, c = data+ M, K = a.shape+ _, N = b.shape++ # cuBLAS (torch.mm) is optimal for all sizes and architectures.+ # It uses hardware-specific GEMM implementations (wgmma on Hopper/Blackwell,+ # tensor cores on Ampere/Ada) via cuBLAS, which is the reference for top scores.+ torch.mm(a, b, out=c)+ return c
scrolls · 153 diff lines total
Best evidence level for this revision: reported
JSON