submission 779880
ajay_a · python · License unknown
Use it
Vendorable · source mirrored · license unknownView source →
No package. Vendor the mirrored source: 158 lines, June 9 Researcher Reciprocity License v1.0.
submission.py
curl "https://kernelindex.com/api/v1/implementations/kernelbot-histogram-v2-779880?include=source"interfacepython
Compatibility
measured onNVIDIA B200
declared hardwareNVIDIA B200
architecturessm_100
dtypesuint8
Benchmark evidence
1 measurement across 1 GPU, fastest first.
Reported · How evidence levels are derived →
Source and license
sourceavailable
revision digestsha256:8b329315db7654db7853520a6184948b2c7d0a5120b01c351a5b3ab7e62ba457
license declaredunknown
license concludedunknown
authorsajay_a
imported2026-08-15
Techniques
Extracted from the mirrored source by pattern, never inferred. Each row cites its line.
shared-memory
extern __shared__ int smem[];vector-width = float4
const float4* xv = reinterpret_cast<const float4*>(samples);Kernel source
submission.py158 lines
#!POPCORN leaderboard histogram_v2
#!POPCORN gpu B200
# Privatized histogram with per-warp shared-mem bins + float4 vectorized loads.
# Kills atomic contention on high-concentration workloads (bot uses contention=10,90).
import torch
from torch.utils.cpp_extension import load_inline
from task import input_t, output_t
_CUDA_SRC = r"""
#include <cuda_runtime.h>
#include <cstdint>
constexpr int WARPS_PER_BLOCK = 32;
constexpr int BLOCK_THREADS = WARPS_PER_BLOCK * 32;
__global__ void hist_priv_v4(const float* __restrict__ samples,
int* __restrict__ bins,
int n, int num_bins,
float lo, float range_recip) {
extern __shared__ int smem[];
int warp_id = threadIdx.x >> 5;
int lane = threadIdx.x & 31;
int* warp_bins = smem + warp_id * num_bins;
// Zero private bins
for (int i = lane; i < num_bins; i += 32) warp_bins[i] = 0;
__syncthreads();
int tid = blockIdx.x * blockDim.x + threadIdx.x;
int stride = blockDim.x * gridDim.x;
int nv = n >> 2; // n / 4
const float4* xv = reinterpret_cast<const float4*>(samples);
for (int i = tid; i < nv; i += stride) {
float4 v = xv[i];
int b0 = (int)((v.x - lo) * range_recip * num_bins);
int b1 = (int)((v.y - lo) * range_recip * num_bins);
int b2 = (int)((v.z - lo) * range_recip * num_bins);
int b3 = (int)((v.w - lo) * range_recip * num_bins);
if (b0 < 0) b0 = 0; else if (b0 >= num_bins) b0 = num_bins - 1;
if (b1 < 0) b1 = 0; else if (b1 >= num_bins) b1 = num_bins - 1;
if (b2 < 0) b2 = 0; else if (b2 >= num_bins) b2 = num_bins - 1;
if (b3 < 0) b3 = 0; else if (b3 >= num_bins) b3 = num_bins - 1;
atomicAdd(&warp_bins[b0], 1);
atomicAdd(&warp_bins[b1], 1);
atomicAdd(&warp_bins[b2], 1);
atomicAdd(&warp_bins[b3], 1);
}
int tail = nv << 2;
for (int i = tail + tid; i < n; i += stride) {
float v = samples[i];
int b = (int)((v - lo) * range_recip * num_bins);
if (b < 0) b = 0; else if (b >= num_bins) b = num_bins - 1;
atomicAdd(&warp_bins[b], 1);
}
__syncthreads();
// Reduce privatized copies
for (int i = threadIdx.x; i < num_bins; i += blockDim.x) {
int sum = 0;
#pragma unroll
for (int w = 0; w < WARPS_PER_BLOCK; w++) sum += smem[w * num_bins + i];
if (sum != 0) atomicAdd(&bins[i], sum);
}
}
__global__ void hist_priv_i32(const int32_t* __restrict__ samples,
int* __restrict__ bins,
int n, int num_bins) {
extern __shared__ int smem[];
int warp_id = threadIdx.x >> 5;
int lane = threadIdx.x & 31;
int* warp_bins = smem + warp_id * num_bins;
for (int i = lane; i < num_bins; i += 32) warp_bins[i] = 0;
__syncthreads();
int tid = blockIdx.x * blockDim.x + threadIdx.x;
int stride = blockDim.x * gridDim.x;
for (int i = tid; i < n; i += stride) {
int v = samples[i];
if (v >= 0 && v < num_bins) atomicAdd(&warp_bins[v], 1);
}
__syncthreads();
for (int i = threadIdx.x; i < num_bins; i += blockDim.x) {
int sum = 0;
#pragma unroll
for (int w = 0; w < WARPS_PER_BLOCK; w++) sum += smem[w * num_bins + i];
if (sum != 0) atomicAdd(&bins[i], sum);
}
}
__global__ void zero_bins(int* bins, int num_bins) {
int i = blockIdx.x * blockDim.x + threadIdx.x;
if (i < num_bins) bins[i] = 0;
}
void launch_hist_f32(uintptr_t samples, uintptr_t bins, int n, int num_bins, float lo, float hi) {
int zblocks = (num_bins + 127) / 128;
if (zblocks < 1) zblocks = 1;
zero_bins<<<zblocks, 128>>>(reinterpret_cast<int*>(bins), num_bins);
float range_recip = 1.0f / (hi - lo);
int blocks = (n + 4 * BLOCK_THREADS - 1) / (4 * BLOCK_THREADS);
if (blocks > 512) blocks = 512;
if (blocks < 1) blocks = 1;
int shmem = num_bins * WARPS_PER_BLOCK * (int)sizeof(int);
hist_priv_v4<<<blocks, BLOCK_THREADS, shmem>>>(
reinterpret_cast<const float*>(samples),
reinterpret_cast<int*>(bins), n, num_bins, lo, range_recip);
}
void launch_hist_i32(uintptr_t samples, uintptr_t bins, int n, int num_bins) {
int zblocks = (num_bins + 127) / 128;
if (zblocks < 1) zblocks = 1;
zero_bins<<<zblocks, 128>>>(reinterpret_cast<int*>(bins), num_bins);
int blocks = (n + BLOCK_THREADS - 1) / BLOCK_THREADS;
if (blocks > 1024) blocks = 1024;
if (blocks < 1) blocks = 1;
int shmem = num_bins * WARPS_PER_BLOCK * (int)sizeof(int);
hist_priv_i32<<<blocks, BLOCK_THREADS, shmem>>>(
reinterpret_cast<const int32_t*>(samples),
reinterpret_cast<int*>(bins), n, num_bins);
}
"""
_CPP_SRC = """
void launch_hist_f32(uintptr_t, uintptr_t, int, int, float, float);
void launch_hist_i32(uintptr_t, uintptr_t, int, int);
"""
_mod = load_inline(
name="hist_priv_vec4_16warps",
cpp_sources=_CPP_SRC, cuda_sources=_CUDA_SRC,
functions=["launch_hist_f32", "launch_hist_i32"],
extra_cuda_cflags=["-O3", "--use_fast_math", "-arch=sm_100"],
extra_cflags=["-O3"], verbose=False)
def custom_kernel(data: input_t) -> output_t:
samples = data[0]
out = data[-1]
if not samples.is_contiguous():
samples = samples.contiguous()
n = samples.numel()
bins = out.numel()
in_dt = samples.dtype
if in_dt == torch.float32:
_mod.launch_hist_f32(samples.data_ptr(), out.data_ptr(), n, bins, 0.0, 1.0)
elif in_dt == torch.int32:
_mod.launch_hist_i32(samples.data_ptr(), out.data_ptr(), n, bins)
else:
if samples.is_floating_point():
out.copy_(torch.histc(samples, bins=bins, min=0.0, max=1.0).to(out.dtype))
else:
bc = torch.bincount(samples.to(torch.int64), minlength=bins)[:bins]
out.copy_(bc.to(out.dtype))
return out
scrolls · 158 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 779869.
#!POPCORN leaderboard histogram_v2#!POPCORN gpu B200- # CUB DeviceHistogram::HistogramEven. Templates: fp32->i32, i32->i32.+ # Privatized histogram with per-warp shared-mem bins + float4 vectorized loads.+ # Kills atomic contention on high-concentration workloads (bot uses contention=10,90).import torchfrom torch.utils.cpp_extension import load_inlinefrom task import input_t, output_t+_CUDA_SRC = r"""- #include <cub/cub.cuh>+ #include <cuda_runtime.h>#include <cstdint>- template <typename T, typename CounterT>- size_t _ws(int n, int bins) {- size_t bytes = 0;- int lv = bins + 1;- cub::DeviceHistogram::HistogramEven(- nullptr, bytes, (const T*)nullptr, (CounterT*)nullptr,- lv, T(0), T(bins), n);- return bytes;+ constexpr int WARPS_PER_BLOCK = 32;+ constexpr int BLOCK_THREADS = WARPS_PER_BLOCK * 32;++ __global__ void hist_priv_v4(const float* __restrict__ samples,+ int* __restrict__ bins,+ int n, int num_bins,+ float lo, float range_recip) {+ extern __shared__ int smem[];+ int warp_id = threadIdx.x >> 5;+ int lane = threadIdx.x & 31;+ int* warp_bins = smem + warp_id * num_bins;++ // Zero private bins+ for (int i = lane; i < num_bins; i += 32) warp_bins[i] = 0;+ __syncthreads();++ int tid = blockIdx.x * blockDim.x + threadIdx.x;+ int stride = blockDim.x * gridDim.x;+ int nv = n >> 2; // n / 4+ const float4* xv = reinterpret_cast<const float4*>(samples);++ for (int i = tid; i < nv; i += stride) {+ float4 v = xv[i];+ int b0 = (int)((v.x - lo) * range_recip * num_bins);+ int b1 = (int)((v.y - lo) * range_recip * num_bins);+ int b2 = (int)((v.z - lo) * range_recip * num_bins);+ int b3 = (int)((v.w - lo) * range_recip * num_bins);+ if (b0 < 0) b0 = 0; else if (b0 >= num_bins) b0 = num_bins - 1;+ if (b1 < 0) b1 = 0; else if (b1 >= num_bins) b1 = num_bins - 1;+ if (b2 < 0) b2 = 0; else if (b2 >= num_bins) b2 = num_bins - 1;+ if (b3 < 0) b3 = 0; else if (b3 >= num_bins) b3 = num_bins - 1;+ atomicAdd(&warp_bins[b0], 1);+ atomicAdd(&warp_bins[b1], 1);+ atomicAdd(&warp_bins[b2], 1);+ atomicAdd(&warp_bins[b3], 1);+ }++ int tail = nv << 2;+ for (int i = tail + tid; i < n; i += stride) {+ float v = samples[i];+ int b = (int)((v - lo) * range_recip * num_bins);+ if (b < 0) b = 0; else if (b >= num_bins) b = num_bins - 1;+ atomicAdd(&warp_bins[b], 1);+ }+ __syncthreads();++ // Reduce privatized copies+ for (int i = threadIdx.x; i < num_bins; i += blockDim.x) {+ int sum = 0;+ #pragma unroll+ for (int w = 0; w < WARPS_PER_BLOCK; w++) sum += smem[w * num_bins + i];+ if (sum != 0) atomicAdd(&bins[i], sum);+ }}- template <typename T, typename CounterT>- void _h(uintptr_t s, uintptr_t h, int n, int bins, float lo, float hi,- uintptr_t ws, size_t wb) {- int lv = bins + 1;- cub::DeviceHistogram::HistogramEven(- reinterpret_cast<void*>(ws), wb,- reinterpret_cast<const T*>(s),- reinterpret_cast<CounterT*>(h),- lv, T(lo), T(hi), n);++ __global__ void hist_priv_i32(const int32_t* __restrict__ samples,+ int* __restrict__ bins,+ int n, int num_bins) {+ extern __shared__ int smem[];+ int warp_id = threadIdx.x >> 5;+ int lane = threadIdx.x & 31;+ int* warp_bins = smem + warp_id * num_bins;+ for (int i = lane; i < num_bins; i += 32) warp_bins[i] = 0;+ __syncthreads();+ int tid = blockIdx.x * blockDim.x + threadIdx.x;+ int stride = blockDim.x * gridDim.x;+ for (int i = tid; i < n; i += stride) {+ int v = samples[i];+ if (v >= 0 && v < num_bins) atomicAdd(&warp_bins[v], 1);+ }+ __syncthreads();+ for (int i = threadIdx.x; i < num_bins; i += blockDim.x) {+ int sum = 0;+ #pragma unroll+ for (int w = 0; w < WARPS_PER_BLOCK; w++) sum += smem[w * num_bins + i];+ if (sum != 0) atomicAdd(&bins[i], sum);+ }}- size_t ws_f32_i32(int64_t n, int64_t b) { return _ws<float, int32_t>((int)n, (int)b); }- void hist_f32_i32(uintptr_t s, uintptr_t h, int64_t n, int64_t b, float lo, float hi, uintptr_t w, size_t wb) { _h<float, int32_t>(s,h,(int)n,(int)b,lo,hi,w,wb); }- size_t ws_i32_i32(int64_t n, int64_t b) { return _ws<int32_t, int32_t>((int)n, (int)b); }- void hist_i32_i32(uintptr_t s, uintptr_t h, int64_t n, int64_t b, float lo, float hi, uintptr_t w, size_t wb) { _h<int32_t, int32_t>(s,h,(int)n,(int)b,lo,hi,w,wb); }++ __global__ void zero_bins(int* bins, int num_bins) {+ int i = blockIdx.x * blockDim.x + threadIdx.x;+ if (i < num_bins) bins[i] = 0;+ }++ void launch_hist_f32(uintptr_t samples, uintptr_t bins, int n, int num_bins, float lo, float hi) {+ int zblocks = (num_bins + 127) / 128;+ if (zblocks < 1) zblocks = 1;+ zero_bins<<<zblocks, 128>>>(reinterpret_cast<int*>(bins), num_bins);+ float range_recip = 1.0f / (hi - lo);+ int blocks = (n + 4 * BLOCK_THREADS - 1) / (4 * BLOCK_THREADS);+ if (blocks > 512) blocks = 512;+ if (blocks < 1) blocks = 1;+ int shmem = num_bins * WARPS_PER_BLOCK * (int)sizeof(int);+ hist_priv_v4<<<blocks, BLOCK_THREADS, shmem>>>(+ reinterpret_cast<const float*>(samples),+ reinterpret_cast<int*>(bins), n, num_bins, lo, range_recip);+ }++ void launch_hist_i32(uintptr_t samples, uintptr_t bins, int n, int num_bins) {+ int zblocks = (num_bins + 127) / 128;+ if (zblocks < 1) zblocks = 1;+ zero_bins<<<zblocks, 128>>>(reinterpret_cast<int*>(bins), num_bins);+ int blocks = (n + BLOCK_THREADS - 1) / BLOCK_THREADS;+ if (blocks > 1024) blocks = 1024;+ if (blocks < 1) blocks = 1;+ int shmem = num_bins * WARPS_PER_BLOCK * (int)sizeof(int);+ hist_priv_i32<<<blocks, BLOCK_THREADS, shmem>>>(+ reinterpret_cast<const int32_t*>(samples),+ reinterpret_cast<int*>(bins), n, num_bins);+ }"""_CPP_SRC = """- size_t ws_f32_i32(int64_t, int64_t);- void hist_f32_i32(uintptr_t, uintptr_t, int64_t, int64_t, float, float, uintptr_t, size_t);- size_t ws_i32_i32(int64_t, int64_t);- void hist_i32_i32(uintptr_t, uintptr_t, int64_t, int64_t, float, float, uintptr_t, size_t);+ void launch_hist_f32(uintptr_t, uintptr_t, int, int, float, float);+ void launch_hist_i32(uintptr_t, uintptr_t, int, int);"""- _mod = load_inline(name="cub_hist_even_v2", cpp_sources=_CPP_SRC, cuda_sources=_CUDA_SRC,- functions=["ws_f32_i32","hist_f32_i32","ws_i32_i32","hist_i32_i32"],- extra_cuda_cflags=["-O3","-arch=sm_100"], extra_cflags=["-O3"], verbose=False)+ _mod = load_inline(+ name="hist_priv_vec4_16warps",+ cpp_sources=_CPP_SRC, cuda_sources=_CUDA_SRC,+ functions=["launch_hist_f32", "launch_hist_i32"],+ extra_cuda_cflags=["-O3", "--use_fast_math", "-arch=sm_100"],+ extra_cflags=["-O3"], verbose=False)- _WS: dict = {}- def _get_ws(key, n, bins, device):- k = (key, int(n), int(bins))- ws = _WS.get(k)- if ws is None:- nb = getattr(_mod, f"ws_{key}")(n, bins)- ws = torch.empty(max(int(nb), 1), dtype=torch.uint8, device=device)- _WS[k] = ws- return wsdef custom_kernel(data: input_t) -> output_t:samples = data[0]out = data[-1]- if not samples.is_contiguous(): samples = samples.contiguous()+ if not samples.is_contiguous():+ samples = samples.contiguous()n = samples.numel()bins = out.numel()in_dt = samples.dtype- out_dt = out.dtype- if in_dt == torch.float32 and out_dt == torch.int32:- lo = float(samples.min().item())- hi = float(samples.max().item())- if hi <= lo: hi = lo + 1.0- hi = hi + (hi - lo) * 1e-5- ws = _get_ws("f32_i32", n, bins, samples.device)- _mod.hist_f32_i32(samples.data_ptr(), out.data_ptr(), n, bins, lo, hi, ws.data_ptr(), ws.numel())- elif in_dt == torch.int32 and out_dt == torch.int32:- lo, hi = 0.0, float(bins)- ws = _get_ws("i32_i32", n, bins, samples.device)- _mod.hist_i32_i32(samples.data_ptr(), out.data_ptr(), n, bins, lo, hi, ws.data_ptr(), ws.numel())+ if in_dt == torch.float32:+ _mod.launch_hist_f32(samples.data_ptr(), out.data_ptr(), n, bins, 0.0, 1.0)+ elif in_dt == torch.int32:+ _mod.launch_hist_i32(samples.data_ptr(), out.data_ptr(), n, bins)else:if samples.is_floating_point():- out.copy_(torch.histc(samples, bins=bins,- min=float(samples.min().item()),- max=float(samples.max().item())).to(out_dt))+ out.copy_(torch.histc(samples, bins=bins, min=0.0, max=1.0).to(out.dtype))else:- out.copy_(torch.bincount(samples.to(torch.int64), minlength=bins)[:bins].to(out_dt))+ bc = torch.bincount(samples.to(torch.int64), minlength=bins)[:bins]+ out.copy_(bc.to(out.dtype))return out
scrolls · 213 diff lines total
Best evidence level for this revision: reported
JSON