Skip to content
KernelIndex
Search⌘K

submission 610921

bigpeach · python · License unknown

Use it

Vendorable · source mirrored · license unknownView source →

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

submission_cuda_inline.py
curl "https://kernelindex.com/api/v1/implementations/kernelbot-vectoradd-v2-610921?include=source"
interfacepython
Compatibility
measured onNVIDIA A100
declared hardwareNVIDIA A100
architecturessm_80
dtypesfp16

Benchmark evidence

1 measurement across 1 GPU, fastest first.

Operation / workload
Hardware
Latency
Rank
Observed
FP16 vector additionsuite of 5 cases
NVIDIA A100
951.3µs
#29 of 87
2026-03-22

Reported · How evidence levels are derived →

Source and license

sourceavailable
revision digestsha256:0975d0f0a4a42d7d94ca64aac30d82468c5f2e8eed895372f159136081320309
license declaredunknown
license concludedunknown
authorsbigpeach
imported2026-08-15

Techniques

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

vector-width = float4float4 a = *reinterpret_cast<const float4*>(A + base);

Kernel source

submission_cuda_inline.py91 lines
import torch
from torch.utils.cpp_extension import load_inline
from typing import List
from task import input_t, output_t

add_cuda_source = """
#include <cuda_fp16.h>

__global__ void add_kernel(const half* __restrict__ A, 
                           const half* __restrict__ B, 
                           half* __restrict__ C, 
                           int N) {
    int idx = blockIdx.x * blockDim.x + threadIdx.x;

    // Each thread handles 8 fp16 elements via one float4 (16 bytes) load
    const int elems_per_thread = 8;
    int base = idx * elems_per_thread;

    if (base + elems_per_thread <= N) {
        float4 a = *reinterpret_cast<const float4*>(A + base);
        float4 b = *reinterpret_cast<const float4*>(B + base);

        half2* a_h = reinterpret_cast<half2*>(&a);
        half2* b_h = reinterpret_cast<half2*>(&b);
        half2 c_h[4];

        #pragma unroll
        for (int i = 0; i < 4; i++) {
            c_h[i] = __hadd2(a_h[i], b_h[i]);
        }

        *reinterpret_cast<float4*>(C + base) = *reinterpret_cast<float4*>(c_h);
    } else {
        // Tail: handle remaining elements one by one
        for (int i = base; i < N; i++) {
            C[i] = __hadd(A[i], B[i]);
        }
    }
}

torch::Tensor add_cuda(torch::Tensor A, torch::Tensor B, torch::Tensor C) {
    TORCH_CHECK(A.device().is_cuda(), "Tensor A must be a CUDA tensor");
    TORCH_CHECK(B.device().is_cuda(), "Tensor B must be a CUDA tensor");
    TORCH_CHECK(C.device().is_cuda(), "Tensor C must be a CUDA tensor");
    TORCH_CHECK(A.sizes() == B.sizes(), "Input tensors must have the same size");
    
    int N = A.numel();  

    const int threads = 256; 
    const int elems_per_thread = 8;
    const int blocks = (N + threads * elems_per_thread - 1) / (threads * elems_per_thread);  
    
    add_kernel<<<blocks, threads>>>(
        reinterpret_cast<const half*>(A.data_ptr<at::Half>()),
        reinterpret_cast<const half*>(B.data_ptr<at::Half>()),
        reinterpret_cast<half*>(C.data_ptr<at::Half>()),
        N
    );

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

    return C;
}
"""

add_cpp_source = """
#include <torch/extension.h>

torch::Tensor add_cuda(torch::Tensor A, torch::Tensor B, torch::Tensor C);
"""

add_module = load_inline(
    name='add_cuda',
    cpp_sources=add_cpp_source,
    cuda_sources=add_cuda_source,
    functions=['add_cuda'],
    verbose=True,
)

def custom_kernel(data: input_t) -> output_t:
    A, B, C = data

    assert A.is_cuda and B.is_cuda, "Input tensors must be on GPU"
    assert A.shape == B.shape, "Input tensors must have the same shape"
    assert A.dtype == torch.float16 and B.dtype == torch.float16, "Input tensors must be float16"

    return add_module.add_cuda(A, B, C)
scrolls · 91 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 607485.

⋯ 3 unchanged lines
from task import input_t, output_t
add_cuda_source = """
- template <typename scalar_t>
- __global__ void add_kernel(const scalar_t* __restrict__ A,
- const scalar_t* __restrict__ B,
- scalar_t* __restrict__ C,
+ #include <cuda_fp16.h>
+
+ __global__ void add_kernel(const half* __restrict__ A,
+ const half* __restrict__ B,
+ half* __restrict__ C,
int N) {
int idx = blockIdx.x * blockDim.x + threadIdx.x;
- if (idx < N) {
- C[idx] = A[idx] + B[idx];
+ // Each thread handles 8 fp16 elements via one float4 (16 bytes) load
+ const int elems_per_thread = 8;
+ int base = idx * elems_per_thread;
+
+ if (base + elems_per_thread <= N) {
+ float4 a = *reinterpret_cast<const float4*>(A + base);
+ float4 b = *reinterpret_cast<const float4*>(B + base);
+
+ half2* a_h = reinterpret_cast<half2*>(&a);
+ half2* b_h = reinterpret_cast<half2*>(&b);
+ half2 c_h[4];
+
+ #pragma unroll
+ for (int i = 0; i < 4; i++) {
+ c_h[i] = __hadd2(a_h[i], b_h[i]);
+ }
+
+ *reinterpret_cast<float4*>(C + base) = *reinterpret_cast<float4*>(c_h);
+ } else {
+ // Tail: handle remaining elements one by one
+ for (int i = base; i < N; i++) {
+ C[i] = __hadd(A[i], B[i]);
+ }
}
}
⋯ 5 unchanged lines
int N = A.numel();
- const int threads = 1024;
- const int blocks = (N + threads - 1) / threads;
+ const int threads = 256;
+ const int elems_per_thread = 8;
+ const int blocks = (N + threads * elems_per_thread - 1) / (threads * elems_per_thread);
- AT_DISPATCH_FLOATING_TYPES_AND_HALF(A.scalar_type(), "add_kernel", ([&] {
- add_kernel<scalar_t><<<blocks, threads>>>(
- A.data_ptr<scalar_t>(),
- B.data_ptr<scalar_t>(),
- C.data_ptr<scalar_t>(),
- N
- );
- }));
+ add_kernel<<<blocks, threads>>>(
+ reinterpret_cast<const half*>(A.data_ptr<at::Half>()),
+ reinterpret_cast<const half*>(B.data_ptr<at::Half>()),
+ reinterpret_cast<half*>(C.data_ptr<at::Half>()),
+ N
+ );
cudaError_t err = cudaGetLastError();
if (err != cudaSuccess) {
scrolls · 71 diff lines total

Best evidence level for this revision: reported

JSON