Skip to content
KernelIndex
Search⌘K

submission 68288

Nick · python · License unknown

Use it

Vendorable · source mirrored · license unknownView source →

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

fastadd.py
curl "https://kernelindex.com/api/v1/implementations/kernelbot-vectoradd-v2-68288?include=source"
interfacepython
Compatibility
measured onNVIDIA B200
declared hardwareNVIDIA B200
architecturessm_100
dtypesfp16

Benchmark evidence

1 measurement across 1 GPU, fastest first.

Operation / workload
Hardware
Latency
Rank
Observed
FP16 vector additionsuite of 5 cases
NVIDIA B200
233.7µs
#12 of 66
2025-11-08

Reported · How evidence levels are derived →

Source and license

sourceavailable
revision digestsha256:e582a06a13bc4c2dfb2501a1758c4f460f3f6e383bb64a7a471cd25922991de9
license declaredunknown
license concludedunknown
authorsNick
imported2026-08-15

Techniques

Extracted from the mirrored source by pattern, never inferred. Each row cites its line.

vector-width = uint4const uint4 a_vec = *reinterpret_cast<const uint4*>(A + base);

Kernel source

fastadd.py134 lines
from utils import make_match_reference, DeterministicContext
import torch
from torch.utils.cpp_extension import load_inline
from task import input_t, output_t

vectoradd_source = r"""
#include <cuda_fp16.h>
#include <stdexcept>

__global__ void __launch_bounds__(512, 2)
vectoradd_cuda_fast(
    const half* __restrict__ A,
    const half* __restrict__ B,
    half* __restrict__ C,
    const int N)
{
    const int tid  = blockIdx.x * blockDim.x + threadIdx.x;
    const int base = tid * 8;   // 8 elems per thread

    if (base >= N) return;

    // fast path: we can read 8 halves (16B) safely
    if (base + 7 < N) {
        const uint4 a_vec = *reinterpret_cast<const uint4*>(A + base);
        const uint4 b_vec = *reinterpret_cast<const uint4*>(B + base);

        const half2 a0 = reinterpret_cast<const half2&>(a_vec.x);
        const half2 a1 = reinterpret_cast<const half2&>(a_vec.y);
        const half2 a2 = reinterpret_cast<const half2&>(a_vec.z);
        const half2 a3 = reinterpret_cast<const half2&>(a_vec.w);

        const half2 b0 = reinterpret_cast<const half2&>(b_vec.x);
        const half2 b1 = reinterpret_cast<const half2&>(b_vec.y);
        const half2 b2 = reinterpret_cast<const half2&>(b_vec.z);
        const half2 b3 = reinterpret_cast<const half2&>(b_vec.w);

        const half2 c0 = __hadd2(a0, b0);
        const half2 c1 = __hadd2(a1, b1);
        const half2 c2 = __hadd2(a2, b2);
        const half2 c3 = __hadd2(a3, b3);

        uint4 c_vec;
        reinterpret_cast<half2&>(c_vec.x) = c0;
        reinterpret_cast<half2&>(c_vec.y) = c1;
        reinterpret_cast<half2&>(c_vec.z) = c2;
        reinterpret_cast<half2&>(c_vec.w) = c3;

        *reinterpret_cast<uint4*>(C + base) = c_vec;
    } else {
        // tail: only final partial block hits this
        #pragma unroll
        for (int i = 0; i < 8; ++i) {
            const int idx = base + i;
            if (idx < N) {
                C[idx] = __hadd(A[idx], B[idx]);
            }
        }
    }
}

// this is the function PyTorch calls
torch::Tensor vectoradd_triton_match(torch::Tensor A,
                                     torch::Tensor B,
                                     torch::Tensor C) {
    const int N = A.numel();

    const half* a_ptr = reinterpret_cast<const half*>(A.data_ptr<at::Half>());
    const half* b_ptr = reinterpret_cast<const half*>(B.data_ptr<at::Half>());
    half*       c_ptr = reinterpret_cast<half*>(C.data_ptr<at::Half>());

    const int threads = 512;
    const int elems_per_block = 4096;
    const int blocks = (N + elems_per_block - 1) / elems_per_block;

    // ✅ call the kernel we actually defined
    vectoradd_cuda_fast<<<blocks, threads>>>(a_ptr, b_ptr, c_ptr, N);

    cudaError_t err = cudaGetLastError();
    if (err != cudaSuccess) {
        throw std::runtime_error(cudaGetErrorString(err));
    }

    return C;
}
"""

vectoradd_cpp_source = r"""
#include <torch/extension.h>
torch::Tensor vectoradd_triton_match(torch::Tensor A,
                                     torch::Tensor B,
                                     torch::Tensor C);
"""

vectoradd_module = load_inline(
    name='vectoradd_triton_match',
    cpp_sources=vectoradd_cpp_source,
    cuda_sources=vectoradd_source,
    functions=['vectoradd_triton_match'],
    verbose=False,
    extra_cuda_cflags=[
        '-O3',
        '--use_fast_math',
        '-gencode=arch=compute_100,code=sm_100',
        '-Xptxas=-O3',
    ],
)


def ref_kernel(data: input_t) -> output_t:
    with DeterministicContext():
        A, B, output = data
        output[...] = A + B
        return output


def generate_input(size: int, seed: int) -> input_t:
    gen = torch.Generator(device="cuda")
    gen.manual_seed(seed)
    A = torch.randn(size, size, device="cuda", dtype=torch.float16,
                    generator=gen).contiguous()
    B = torch.randn(size, size, device="cuda", dtype=torch.float16,
                    generator=gen).contiguous()
    C = torch.empty(size, size, device="cuda", dtype=torch.float16).contiguous()
    return A, B, C


def custom_kernel(data: input_t) -> output_t:
    with DeterministicContext():
        A, B, C = data
        return vectoradd_module.vectoradd_triton_match(A, B, C)


check_implementation = make_match_reference(ref_kernel)
scrolls · 134 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 67581.

- from utils import make_match_reference, DeterministicContext
- import torch
- from torch.utils.cpp_extension import load_inline
- from task import input_t, output_t
-
- # CUDA: no-tail, assumes N % 4096 == 0
- vectoradd_source = r"""
- #include <cuda_fp16.h>
- #include <stdexcept>
-
- // 512 threads, 8 fp16 elements per thread = 4096 elements per block
- // we assume N is divisible by 4096, so no tail / no bounds
- __global__ void __launch_bounds__(1024, 2)
- vectoradd_cuda_fast_nt(
- const half* __restrict__ A,
- const half* __restrict__ B,
- half* __restrict__ C,
- const int N)
- {
- const int tid = blockIdx.x * blockDim.x + threadIdx.x;
- const int base = tid * 8; // 8 halves = 16 bytes
-
- // no bounds checks — N is multiple of 4096
-
- // 16B load from A and B
- const uint4 a = *reinterpret_cast<const uint4*>(A + base);
- const uint4 b = *reinterpret_cast<const uint4*>(B + base);
-
- // unpack as half2
- const half2 a0 = reinterpret_cast<const half2&>(a.x);
- const half2 a1 = reinterpret_cast<const half2&>(a.y);
- const half2 a2 = reinterpret_cast<const half2&>(a.z);
- const half2 a3 = reinterpret_cast<const half2&>(a.w);
-
- const half2 b0 = reinterpret_cast<const half2&>(b.x);
- const half2 b1 = reinterpret_cast<const half2&>(b.y);
- const half2 b2 = reinterpret_cast<const half2&>(b.z);
- const half2 b3 = reinterpret_cast<const half2&>(b.w);
-
- // add
- uint4 c;
- reinterpret_cast<half2&>(c.x) = __hadd2(a0, b0);
- reinterpret_cast<half2&>(c.y) = __hadd2(a1, b1);
- reinterpret_cast<half2&>(c.z) = __hadd2(a2, b2);
- reinterpret_cast<half2&>(c.w) = __hadd2(a3, b3);
-
- // store
- *reinterpret_cast<uint4*>(C + base) = c;
- }
-
- // C++ binding that PyTorch calls
- torch::Tensor vectoradd_triton_match(torch::Tensor A,
- torch::Tensor B,
- torch::Tensor C) {
- const int N = A.numel();
-
- const half* a_ptr = reinterpret_cast<const half*>(A.data_ptr<at::Half>());
- const half* b_ptr = reinterpret_cast<const half*>(B.data_ptr<at::Half>());
- half* c_ptr = reinterpret_cast<half*>(C.data_ptr<at::Half>());
-
- const int threads = 512;
- const int elems_per_block = 4096; // 512 * 8
- const int blocks = (N + elems_per_block - 1) / elems_per_block;
-
- // straight launch, no error check
- vectoradd_cuda_fast_nt<<<blocks, threads>>>(a_ptr, b_ptr, c_ptr, N);
- return C;
- }
- """
-
- vectoradd_cpp_source = r"""
- #include <torch/extension.h>
- torch::Tensor vectoradd_triton_match(torch::Tensor A,
- torch::Tensor B,
- torch::Tensor C);
- """
-
- vectoradd_module = load_inline(
- name='vectoradd_triton_match',
- cpp_sources=vectoradd_cpp_source,
- cuda_sources=vectoradd_source,
- functions=['vectoradd_triton_match'],
- verbose=False,
- extra_cuda_cflags=[
- '-O3',
- '--use_fast_math',
- # H100 / Hopper
- '-gencode=arch=compute_90,code=sm_90',
- # B200 / Blackwell
- '-gencode=arch=compute_100,code=sm_100',
- # stream through L2, don't clutter L1
- '-Xptxas=-O3,-dlcm=cg',
- ],
- )
-
-
- def ref_kernel(data: input_t) -> output_t:
- # pure PyTorch reference
- with DeterministicContext():
- A, B, output = data
- output[...] = A + B
- return output
-
-
- def generate_input(size: int, seed: int) -> input_t:
- # assuming square, e.g. 16384
- gen = torch.Generator(device="cuda")
- gen.manual_seed(seed)
- A = torch.randn(size, size, device="cuda", dtype=torch.float16,
- generator=gen).contiguous()
- B = torch.randn(size, size, device="cuda", dtype=torch.float16,
- generator=gen).contiguous()
- C = torch.empty(size, size, device="cuda", dtype=torch.float16).contiguous()
- return A, B, C
-
-
- def custom_kernel(data: input_t) -> output_t:
- with DeterministicContext():
- A, B, C = data
- return vectoradd_module.vectoradd_triton_match(A, B, C)
-
-
- check_implementation = make_match_reference(ref_kernel)
+ from utils import make_match_reference, DeterministicContext
+ import torch
+ from torch.utils.cpp_extension import load_inline
+ from task import input_t, output_t
+
+ vectoradd_source = r"""
+ #include <cuda_fp16.h>
+ #include <stdexcept>
+
+ __global__ void __launch_bounds__(512, 2)
+ vectoradd_cuda_fast(
+ const half* __restrict__ A,
+ const half* __restrict__ B,
+ half* __restrict__ C,
+ const int N)
+ {
+ const int tid = blockIdx.x * blockDim.x + threadIdx.x;
+ const int base = tid * 8; // 8 elems per thread
+
+ if (base >= N) return;
+
+ // fast path: we can read 8 halves (16B) safely
+ if (base + 7 < N) {
+ const uint4 a_vec = *reinterpret_cast<const uint4*>(A + base);
+ const uint4 b_vec = *reinterpret_cast<const uint4*>(B + base);
+
+ const half2 a0 = reinterpret_cast<const half2&>(a_vec.x);
+ const half2 a1 = reinterpret_cast<const half2&>(a_vec.y);
+ const half2 a2 = reinterpret_cast<const half2&>(a_vec.z);
+ const half2 a3 = reinterpret_cast<const half2&>(a_vec.w);
+
+ const half2 b0 = reinterpret_cast<const half2&>(b_vec.x);
+ const half2 b1 = reinterpret_cast<const half2&>(b_vec.y);
+ const half2 b2 = reinterpret_cast<const half2&>(b_vec.z);
+ const half2 b3 = reinterpret_cast<const half2&>(b_vec.w);
+
+ const half2 c0 = __hadd2(a0, b0);
+ const half2 c1 = __hadd2(a1, b1);
+ const half2 c2 = __hadd2(a2, b2);
+ const half2 c3 = __hadd2(a3, b3);
+
+ uint4 c_vec;
+ reinterpret_cast<half2&>(c_vec.x) = c0;
+ reinterpret_cast<half2&>(c_vec.y) = c1;
+ reinterpret_cast<half2&>(c_vec.z) = c2;
+ reinterpret_cast<half2&>(c_vec.w) = c3;
+
+ *reinterpret_cast<uint4*>(C + base) = c_vec;
+ } else {
+ // tail: only final partial block hits this
+ #pragma unroll
+ for (int i = 0; i < 8; ++i) {
+ const int idx = base + i;
+ if (idx < N) {
+ C[idx] = __hadd(A[idx], B[idx]);
+ }
+ }
+ }
+ }
+
+ // this is the function PyTorch calls
+ torch::Tensor vectoradd_triton_match(torch::Tensor A,
+ torch::Tensor B,
+ torch::Tensor C) {
+ const int N = A.numel();
+
+ const half* a_ptr = reinterpret_cast<const half*>(A.data_ptr<at::Half>());
+ const half* b_ptr = reinterpret_cast<const half*>(B.data_ptr<at::Half>());
+ half* c_ptr = reinterpret_cast<half*>(C.data_ptr<at::Half>());
+
+ const int threads = 512;
+ const int elems_per_block = 4096;
+ const int blocks = (N + elems_per_block - 1) / elems_per_block;
+
+ // ✅ call the kernel we actually defined
+ vectoradd_cuda_fast<<<blocks, threads>>>(a_ptr, b_ptr, c_ptr, N);
+
+ cudaError_t err = cudaGetLastError();
+ if (err != cudaSuccess) {
+ throw std::runtime_error(cudaGetErrorString(err));
+ }
+
+ return C;
+ }
+ """
+
+ vectoradd_cpp_source = r"""
+ #include <torch/extension.h>
+ torch::Tensor vectoradd_triton_match(torch::Tensor A,
+ torch::Tensor B,
+ torch::Tensor C);
+ """
+
+ vectoradd_module = load_inline(
+ name='vectoradd_triton_match',
+ cpp_sources=vectoradd_cpp_source,
+ cuda_sources=vectoradd_source,
+ functions=['vectoradd_triton_match'],
+ verbose=False,
+ extra_cuda_cflags=[
+ '-O3',
+ '--use_fast_math',
+ '-gencode=arch=compute_100,code=sm_100',
+ '-Xptxas=-O3',
+ ],
+ )
+
+
+ def ref_kernel(data: input_t) -> output_t:
+ with DeterministicContext():
+ A, B, output = data
+ output[...] = A + B
+ return output
+
+
+ def generate_input(size: int, seed: int) -> input_t:
+ gen = torch.Generator(device="cuda")
+ gen.manual_seed(seed)
+ A = torch.randn(size, size, device="cuda", dtype=torch.float16,
+ generator=gen).contiguous()
+ B = torch.randn(size, size, device="cuda", dtype=torch.float16,
+ generator=gen).contiguous()
+ C = torch.empty(size, size, device="cuda", dtype=torch.float16).contiguous()
+ return A, B, C
+
+
+ def custom_kernel(data: input_t) -> output_t:
+ with DeterministicContext():
+ A, B, C = data
+ return vectoradd_module.vectoradd_triton_match(A, B, C)
+
+
+ check_implementation = make_match_reference(ref_kernel)
scrolls · 256 diff lines total

Best evidence level for this revision: reported

JSON