Skip to content
KernelIndex
Search⌘K

submission 779808

ajay_a · python · License unknown

Use it

Vendorable · source mirrored · license unknownView source →

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

submission.py
curl "https://kernelindex.com/api/v1/implementations/kernelbot-conv2d-v2-779808?include=source"
interfacepython
Compatibility
measured onNVIDIA B200
declared hardwareNVIDIA B200
architecturessm_100
dtypesfp32

Benchmark evidence

1 measurement across 1 GPU, fastest first.

Operation / workload
Hardware
Latency
Rank
Observed
2D convolutionsuite of 5 cases
NVIDIA B200
6.45ms
#1 of 28
2026-04-23

Reported · How evidence levels are derived →

Source and license

sourceavailable
revision digestsha256:1126804b21d5f74cd74de3672ab0538d5a5e59553874edc6282474b96b4b58eb
license declaredunknown
license concludedunknown
authorsajay_a
imported2026-08-15

Kernel source

submission.py53 lines
#!POPCORN leaderboard conv2d_v2
#!POPCORN gpu B200

# cuDNN-backed conv2d via ATen in C++. Forces TF32 off + deterministic math
# to exactly match the reference (which the bot computes without TF32).
from task import input_t, output_t
import torch

# Disable TF32 globally so cuDNN picks the fp32-exact algo family.
# Must be set BEFORE any conv call and BEFORE the C++ extension compiles.
torch.backends.cudnn.allow_tf32 = False
torch.backends.cudnn.deterministic = True
torch.backends.cudnn.benchmark = True
torch.backends.cuda.matmul.allow_tf32 = False

from torch.utils.cpp_extension import load_inline


_CUDA_SRC = r"""
#include <ATen/ATen.h>
#include <torch/torch.h>

// cuDNN conv via ATen. Bias=None, stride=1, padding=0, dilation=1, groups=1.
void conv2d_fwd(const torch::Tensor& x,
                const torch::Tensor& w,
                torch::Tensor& out) {
    auto y = at::conv2d(x, w, at::Tensor(),
                        at::IntArrayRef({1, 1}),
                        at::IntArrayRef({0, 0}),
                        at::IntArrayRef({1, 1}),
                        1);
    out.copy_(y);
}
"""

_CPP_SRC = "void conv2d_fwd(const torch::Tensor&, const torch::Tensor&, torch::Tensor&);"

_mod = load_inline(
    name="conv2d_cudnn_wrap_v2",
    cpp_sources=_CPP_SRC,
    cuda_sources=_CUDA_SRC,
    functions=["conv2d_fwd"],
    extra_cuda_cflags=["-O3", "-arch=sm_100"],
    extra_cflags=["-O3"],
    verbose=False,
)


def custom_kernel(data: input_t) -> output_t:
    x, w, out = data
    _mod.conv2d_fwd(x, w, out)
    return out
scrolls · 53 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 779801.

#!POPCORN leaderboard conv2d_v2
#!POPCORN gpu B200
- # Tensor-core implicit GEMM with L2 swizzle. Linear 1D grid, pid→tile via
- # GROUP_SIZE_M swizzle for L2 cache reuse across tiles.
+ # cuDNN-backed conv2d via ATen in C++. Forces TF32 off + deterministic math
+ # to exactly match the reference (which the bot computes without TF32).
from task import input_t, output_t
- import triton
- import triton.language as tl
+ import torch
+ # Disable TF32 globally so cuDNN picks the fp32-exact algo family.
+ # Must be set BEFORE any conv call and BEFORE the C++ extension compiles.
+ torch.backends.cudnn.allow_tf32 = False
+ torch.backends.cudnn.deterministic = True
+ torch.backends.cudnn.benchmark = True
+ torch.backends.cuda.matmul.allow_tf32 = False
- @triton.jit
- def conv2d_tc_kernel(
- x_ptr, w_ptr, y_ptr,
- N, C_in, H_in, W_in,
- C_out, KH, KW,
- H_out, W_out,
- x_sn, x_sc, x_sh, x_sw,
- w_so, w_sc, w_sh, w_sw,
- y_sn, y_sc, y_sh, y_sw,
- BM: tl.constexpr, BN: tl.constexpr, BK: tl.constexpr,
- GROUP_M: tl.constexpr,
- ):
- pid = tl.program_id(0)
- HW_out = H_out * W_out
- M = N * HW_out
- num_pid_m = tl.cdiv(M, BM)
- num_pid_n = tl.cdiv(C_out, BN)
+ from torch.utils.cpp_extension import load_inline
- # GROUP_SIZE_M swizzle
- 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 = min(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_m = pid_m * BM + tl.arange(0, BM)
- offs_n = pid_n * BN + tl.arange(0, BN)
+ _CUDA_SRC = r"""
+ #include <ATen/ATen.h>
+ #include <torch/torch.h>
- n_idx = offs_m // HW_out
- hw = offs_m % HW_out
- oh = hw // W_out
- ow = hw % W_out
+ // cuDNN conv via ATen. Bias=None, stride=1, padding=0, dilation=1, groups=1.
+ void conv2d_fwd(const torch::Tensor& x,
+ const torch::Tensor& w,
+ torch::Tensor& out) {
+ auto y = at::conv2d(x, w, at::Tensor(),
+ at::IntArrayRef({1, 1}),
+ at::IntArrayRef({0, 0}),
+ at::IntArrayRef({1, 1}),
+ 1);
+ out.copy_(y);
+ }
+ """
- KHKW = KH * KW
- K = C_in * KHKW
+ _CPP_SRC = "void conv2d_fwd(const torch::Tensor&, const torch::Tensor&, torch::Tensor&);"
- acc = tl.zeros((BM, BN), dtype=tl.float32)
+ _mod = load_inline(
+ name="conv2d_cudnn_wrap_v2",
+ cpp_sources=_CPP_SRC,
+ cuda_sources=_CUDA_SRC,
+ functions=["conv2d_fwd"],
+ extra_cuda_cflags=["-O3", "-arch=sm_100"],
+ extra_cflags=["-O3"],
+ verbose=False,
+ )
- for k0 in range(0, K, BK):
- offs_k = k0 + tl.arange(0, BK)
- ic = offs_k // KHKW
- rem = offs_k % KHKW
- kh = rem // KW
- kw_ = rem % KW
- ih = oh[:, None] + kh[None, :]
- iw = ow[:, None] + kw_[None, :]
-
- x_offs = (n_idx[:, None] * x_sn
- + ic[None, :] * x_sc
- + ih * x_sh
- + iw * x_sw)
- x_mask = (offs_m[:, None] < M) & (offs_k[None, :] < K)
- x = tl.load(x_ptr + x_offs, mask=x_mask, other=0.0)
-
- w_offs = (offs_n[None, :] * w_so
- + ic[:, None] * w_sc
- + kh[:, None] * w_sh
- + kw_[:, None] * w_sw)
- w_mask = (offs_k[:, None] < K) & (offs_n[None, :] < C_out)
- w_val = tl.load(w_ptr + w_offs, mask=w_mask, other=0.0)
-
- acc = tl.dot(x, w_val, acc=acc, input_precision="ieee")
-
- y_offs = (n_idx[:, None] * y_sn
- + offs_n[None, :] * y_sc
- + oh[:, None] * y_sh
- + ow[:, None] * y_sw)
- y_mask = (offs_m[:, None] < M) & (offs_n[None, :] < C_out)
- tl.store(y_ptr + y_offs, acc.to(y_ptr.dtype.element_ty), mask=y_mask)
-
-
def custom_kernel(data: input_t) -> output_t:
- input_tensor, kernel, output = data
- N, C_in, H_in, W_in = input_tensor.shape
- C_out, _, KH, KW = kernel.shape
- H_out = H_in - KH + 1
- W_out = W_in - KW + 1
-
- BM, BN, BK = 128, 128, 64
- GROUP_M = 8
- M = N * H_out * W_out
- grid = (triton.cdiv(M, BM) * triton.cdiv(C_out, BN),)
-
- conv2d_tc_kernel[grid](
- input_tensor, kernel, output,
- N, C_in, H_in, W_in, C_out, KH, KW, H_out, W_out,
- input_tensor.stride(0), input_tensor.stride(1), input_tensor.stride(2), input_tensor.stride(3),
- kernel.stride(0), kernel.stride(1), kernel.stride(2), kernel.stride(3),
- output.stride(0), output.stride(1), output.stride(2), output.stride(3),
- BM=BM, BN=BN, BK=BK, GROUP_M=GROUP_M,
- num_warps=8, num_stages=3,
- )
- return output
+ x, w, out = data
+ _mod.conv2d_fwd(x, w, out)
+ return out
scrolls · 143 diff lines total

Best evidence level for this revision: reported

JSON