submission 106200
rbyrots · python · License unknown
Use it
Vendorable · source mirrored · license unknownView source →
No package. Vendor the mirrored source: 380 lines, June 9 Researcher Reciprocity License v1.0.
submission_v1.py
curl "https://kernelindex.com/api/v1/implementations/kernelbot-nvfp4-gemv-106200?include=source"interfacepython
Compatibility
measured onNVIDIA B200
declared hardwareNVIDIA B200
architecturessm_100
dtypesfp8_e4m3, nvfp4
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:f493677dd9a6b8a8a64bd9ea19e62a1dbb6c41dc9d1e6ed2c757b0d30e103285
license declaredunknown
license concludedunknown
authorsrbyrots
imported2026-08-26
Techniques
Extracted from the mirrored source by pattern, never inferred. Each row cites its line.
fp4
- Does NOT try to be nvfp4-correct; it just does a float32 GEMVKernel source
submission_v1.py380 lines
from typing import cast
import torch
from task import input_t, output_t
# Try to import CuTe / cutlass – this will fail on macOS CPU wheels
try:
import cutlass
import cutlass.cute as cute
from cutlass.cute.runtime import make_ptr
import cutlass.utils.blockscaled_layout as blockscaled_utils
HAVE_CUTE = True
except Exception:
HAVE_CUTE = False
# -----------------------------
# Shared configuration
# -----------------------------
mma_tiler_mnk = (128, 1, 64) # M, N, K tile
ab_dtype = cutlass.Float4E2M1FN if HAVE_CUTE else None
sf_dtype = cutlass.Float8E4M3FN if HAVE_CUTE else None
c_dtype = cutlass.Float16 if HAVE_CUTE else None
sf_vec_size = 16
threads_per_cta = 128
_compiled_kernel_cache = None # per-process cache
_compiled_kernel_cache_l1 = None # L=1 specialized kernel cache
# -----------------------------
# CuTe kernel path (GPU-only)
# -----------------------------
if HAVE_CUTE:
@cute.kernel
def _kernel(
mA_mkl: cute.Tensor,
mB_nkl: cute.Tensor,
mSFA_mkl: cute.Tensor,
mSFB_nkl: cute.Tensor,
mC_mnl: cute.Tensor,
):
bidx, bidy, bidz = cute.arch.block_idx()
tidx, _, _ = cute.arch.thread_idx()
gA_mkl = cute.local_tile(
mA_mkl, cute.slice_(mma_tiler_mnk, (None, 0, None)), (None, None, None)
)
gSFA_mkl = cute.local_tile(
mSFA_mkl, cute.slice_(mma_tiler_mnk, (None, 0, None)), (None, None, None)
)
gB_nkl = cute.local_tile(
mB_nkl, cute.slice_(mma_tiler_mnk, (0, None, None)), (None, None, None)
)
gSFB_nkl = cute.local_tile(
mSFB_nkl, cute.slice_(mma_tiler_mnk, (0, None, None)), (None, None, None)
)
gC_mnl = cute.local_tile(
mC_mnl, cute.slice_(mma_tiler_mnk, (None, None, 0)), (None, None, None)
)
tCgC = gC_mnl[tidx, None, bidx, bidy, bidz]
tCgC = cute.make_tensor(tCgC.iterator, 1)
res = cute.zeros_like(tCgC, cutlass.Float32)
k_tile_cnt = gA_mkl.layout[3].shape
for k_tile in range(k_tile_cnt):
tAgA = gA_mkl[tidx, None, bidx, k_tile, bidz]
tBgB = gB_nkl[0, None, bidy, k_tile, bidz]
tAgSFA = gSFA_mkl[tidx, None, bidx, k_tile, bidz]
tBgSFB = gSFB_nkl[0, None, bidy, k_tile, bidz]
# Load fragments and convert directly to Float32
a_f32 = tAgA.load().to(cutlass.Float32)
b_f32 = tBgB.load().to(cutlass.Float32)
sfa_f32 = tAgSFA.load().to(cutlass.Float32)
sfb_f32 = tBgSFB.load().to(cutlass.Float32)
# Fuse scale factors: SF = SFA * SFB
sf_f32 = sfa_f32 * sfb_f32
# Inner accumulation: res += a * b * sf
for i in cutlass.range_constexpr(mma_tiler_mnk[2]):
res += a_f32[i] * b_f32[i] * sf_f32[i]
tCgC.store(res.to(cutlass.Float16))
return
@cute.kernel
def _kernel_l1(
mA_mkl: cute.Tensor,
mB_nkl: cute.Tensor,
mSFA_mkl: cute.Tensor,
mSFB_nkl: cute.Tensor,
mC_mnl: cute.Tensor,
):
# Same tiling as _kernel, but no L dimension in the grid
bidx, bidy, bidz = cute.arch.block_idx()
tidx, _, _ = cute.arch.thread_idx()
# Local tiles exactly as before
gA_mkl = cute.local_tile(
mA_mkl, cute.slice_(mma_tiler_mnk, (None, 0, None)), (None, None, None)
)
gSFA_mkl = cute.local_tile(
mSFA_mkl, cute.slice_(mma_tiler_mnk, (None, 0, None)), (None, None, None)
)
gB_nkl = cute.local_tile(
mB_nkl, cute.slice_(mma_tiler_mnk, (0, None, None)), (None, None, None)
)
gSFB_nkl = cute.local_tile(
mSFB_nkl, cute.slice_(mma_tiler_mnk, (0, None, None)), (None, None, None)
)
gC_mnl = cute.local_tile(
mC_mnl, cute.slice_(mma_tiler_mnk, (None, None, 0)), (None, None, None)
)
# For L=1, the only valid "rest_L" index is 0.
# (bidz from arch.block_idx().z will always be 0 because we launch grid.z = 1.)
l_idx = 0
tCgC = gC_mnl[tidx, None, bidx, bidy, l_idx]
tCgC = cute.make_tensor(tCgC.iterator, 1)
res = cute.zeros_like(tCgC, cutlass.Float32)
k_tile_cnt = gA_mkl.layout[3].shape
for k_tile in range(k_tile_cnt):
tAgA = gA_mkl[tidx, None, bidx, k_tile, l_idx]
tBgB = gB_nkl[0, None, bidy, k_tile, l_idx]
tAgSFA = gSFA_mkl[tidx, None, bidx, k_tile, l_idx]
tBgSFB = gSFB_nkl[0, None, bidy, k_tile, l_idx]
# Load fragments and convert directly to Float32
a_f32 = tAgA.load().to(cutlass.Float32)
b_f32 = tBgB.load().to(cutlass.Float32)
sfa_f32 = tAgSFA.load().to(cutlass.Float32)
sfb_f32 = tBgSFB.load().to(cutlass.Float32)
# Fuse scale factors for this fragment
sf_f32 = sfa_f32 * sfb_f32
# Inner accumulation: res += a * b * sf
for i in cutlass.range_constexpr(mma_tiler_mnk[2]):
res += a_f32[i] * b_f32[i] * sf_f32[i]
tCgC.store(res.to(cutlass.Float16))
return
@cute.jit
def _my_kernel(
a_ptr: cute.Pointer,
b_ptr: cute.Pointer,
sfa_ptr: cute.Pointer,
sfb_ptr: cute.Pointer,
c_ptr: cute.Pointer,
problem_size: tuple,
):
m, _, k, l = problem_size
a_tensor = cute.make_tensor(
a_ptr,
cute.make_layout(
(m, cute.assume(k, 32), l),
stride=(cute.assume(k, 32), 1, cute.assume(m * k, 32)),
),
)
n_padded_128 = 128
b_tensor = cute.make_tensor(
b_ptr,
cute.make_layout(
(n_padded_128, cute.assume(k, 32), l),
stride=(cute.assume(k, 32), 1, cute.assume(n_padded_128 * k, 32)),
),
)
c_tensor = cute.make_tensor(
c_ptr,
cute.make_layout((cute.assume(m, 32), 1, l), stride=(1, 1, m)),
)
sfa_layout = blockscaled_utils.tile_atom_to_shape_SF(
a_tensor.shape, sf_vec_size
)
sfa_tensor = cute.make_tensor(sfa_ptr, sfa_layout)
sfb_layout = blockscaled_utils.tile_atom_to_shape_SF(
b_tensor.shape, sf_vec_size
)
sfb_tensor = cute.make_tensor(sfb_ptr, sfb_layout)
grid = (
cute.ceil_div(c_tensor.shape[0], 128),
1,
c_tensor.shape[2],
)
_kernel(a_tensor, b_tensor, sfa_tensor, sfb_tensor, c_tensor).launch(
grid=grid,
block=[threads_per_cta, 1, 1],
cluster=(1, 1, 1),
)
return
@cute.jit
def _my_kernel_l1(
a_ptr: cute.Pointer,
b_ptr: cute.Pointer,
sfa_ptr: cute.Pointer,
sfb_ptr: cute.Pointer,
c_ptr: cute.Pointer,
problem_size: tuple,
):
# For L=1 we still pass (m, n, k, l) but know l == 1
m, _, k, l = problem_size
a_tensor = cute.make_tensor(
a_ptr,
cute.make_layout(
(m, cute.assume(k, 32), l),
stride=(cute.assume(k, 32), 1, cute.assume(m * k, 32)),
),
)
n_padded_128 = 128
b_tensor = cute.make_tensor(
b_ptr,
cute.make_layout(
(n_padded_128, cute.assume(k, 32), l),
stride=(cute.assume(k, 32), 1, cute.assume(n_padded_128 * k, 32)),
),
)
c_tensor = cute.make_tensor(
c_ptr,
cute.make_layout((cute.assume(m, 32), 1, l), stride=(1, 1, m)),
)
sfa_layout = blockscaled_utils.tile_atom_to_shape_SF(
a_tensor.shape, sf_vec_size
)
sfa_tensor = cute.make_tensor(sfa_ptr, sfa_layout)
sfb_layout = blockscaled_utils.tile_atom_to_shape_SF(
b_tensor.shape, sf_vec_size
)
sfb_tensor = cute.make_tensor(sfb_ptr, sfb_layout)
# L=1 -> grid.z = 1
grid = (
cute.ceil_div(c_tensor.shape[0], 128),
1,
1,
)
_kernel_l1(a_tensor, b_tensor, sfa_tensor, sfb_tensor, c_tensor).launch(
grid=grid,
block=[threads_per_cta, 1, 1],
cluster=(1, 1, 1),
)
return
def _compile_kernel():
global _compiled_kernel_cache
if _compiled_kernel_cache is not None:
return _compiled_kernel_cache
a_ptr = make_ptr(ab_dtype, 0, cute.AddressSpace.gmem, assumed_align=16)
b_ptr = make_ptr(ab_dtype, 0, cute.AddressSpace.gmem, assumed_align=16)
c_ptr = make_ptr(c_dtype, 0, cute.AddressSpace.gmem, assumed_align=16)
sfa_ptr = make_ptr(sf_dtype, 0, cute.AddressSpace.gmem, assumed_align=32)
sfb_ptr = make_ptr(sf_dtype, 0, cute.AddressSpace.gmem, assumed_align=32)
_compiled_kernel_cache = cute.compile(
_my_kernel, a_ptr, b_ptr, sfa_ptr, sfb_ptr, c_ptr, (0, 0, 0, 0)
)
return _compiled_kernel_cache
def _compile_kernel_l1():
global _compiled_kernel_cache_l1
if _compiled_kernel_cache_l1 is not None:
return _compiled_kernel_cache_l1
a_ptr = make_ptr(ab_dtype, 0, cute.AddressSpace.gmem, assumed_align=16)
b_ptr = make_ptr(ab_dtype, 0, cute.AddressSpace.gmem, assumed_align=16)
c_ptr = make_ptr(c_dtype, 0, cute.AddressSpace.gmem, assumed_align=16)
sfa_ptr = make_ptr(sf_dtype, 0, cute.AddressSpace.gmem, assumed_align=32)
sfb_ptr = make_ptr(sf_dtype, 0, cute.AddressSpace.gmem, assumed_align=32)
_compiled_kernel_cache_l1 = cute.compile(
_my_kernel_l1, a_ptr, b_ptr, sfa_ptr, sfb_ptr, c_ptr, (0, 0, 0, 1)
)
return _compiled_kernel_cache_l1
def _nvfp4_blockscaled_gemv_gpu(data: input_t) -> output_t:
"""
Real CuTe path – only called when cutlass + CUDA are available.
"""
assert HAVE_CUTE, "CuTe path requested on a system without cutlass/CUDA."
a, b, _sfa, _sfb, sfa_perm, sfb_perm, c = data
m, k_half, l = a.shape # a: [m, k/2, l] in float4_e2m1fn_x2
k = k_half * 2
n = 1
if l == 1:
compiled = _compile_kernel_l1()
else:
compiled = _compile_kernel()
a_ptr = make_ptr(ab_dtype, a.data_ptr(), cute.AddressSpace.gmem, assumed_align=16)
b_ptr = make_ptr(ab_dtype, b.data_ptr(), cute.AddressSpace.gmem, assumed_align=16)
c_ptr = make_ptr(c_dtype, c.data_ptr(), cute.AddressSpace.gmem, assumed_align=16)
sfa_ptr = make_ptr(
sf_dtype, sfa_perm.data_ptr(), cute.AddressSpace.gmem, assumed_align=32
)
sfb_ptr = make_ptr(
sf_dtype, sfb_perm.data_ptr(), cute.AddressSpace.gmem, assumed_align=32
)
compiled(a_ptr, b_ptr, sfa_ptr, sfb_ptr, c_ptr, (m, n, k, l))
return c
# -----------------------------
# CPU-only fallback for macOS dev
# -----------------------------
def _fallback_gemv_cpu(data: input_t) -> output_t:
"""
Extremely simplified fallback so you can at least run shape/syntax checks on CPU.
IMPORTANT:
- Only meant for local dev.
- Does NOT try to be nvfp4-correct; it just does a float32 GEMV
with the same outer shapes.
"""
a, b, _sfa, _sfb, _sfa_perm, _sfb_perm, c = data
# Interpret a,b as regular float tensors on CPU
# For local fake tests you'll construct them as float32/float16 anyway.
# Shapes (for fake data): a: [m, k, l], b: [1, k, l], c: [m, 1, l]
m, k_like, l = a.shape
out = c
out.zero_()
for li in range(l):
# [m, k] @ [k] -> [m]
a_slice = a[:, :, li].to(torch.float32)
b_slice = b[0, :, li].to(torch.float32)
y = a_slice @ b_slice
out[:, 0, li] = y.to(out.dtype)
return cast(output_t, out)
# -----------------------------
# Public entrypoint
# -----------------------------
def custom_kernel(data: input_t) -> output_t:
"""
Entry point used by the evaluation framework.
On GPU box with CuTe: runs the high-performance kernel.
On macOS/CPU: runs a dumb fallback so you can at least import and smoke-test.
"""
if HAVE_CUTE and torch.cuda.is_available():
return _nvfp4_blockscaled_gemv_gpu(data)
else:
# local dev / CPU-only environment
return _fallback_gemv_cpu(data)
scrolls · 380 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