Skip to content
KernelIndex
Search⌘K

submission 71033

Jaber · python · License unknown

Use it

Vendorable · source mirrored · license unknownView source →

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

submission.py
curl "https://kernelindex.com/api/v1/implementations/kernelbot-sort-v2-71033?include=source"
interfacepython
Compatibility
measured onNVIDIA A100
declared hardwareNVIDIA A100
architecturessm_80
dtypesfp32

Benchmark evidence

1 measurement across 1 GPU, fastest first.

Operation / workload
Hardware
Latency
Rank
Observed
Sortsuite of 5 cases
NVIDIA A100
16.1ms
#24 of 28
2025-11-11

Reported · How evidence levels are derived →

Source and license

sourceavailable
revision digestsha256:0f0e49cc13db1bf4726be399d4fddbc1a0111b6b1ec664747b51bfd43c5de238
license declaredunknown
license concludedunknown
authorsJaber
imported2026-08-15

Techniques

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

shared-memory__shared__ int local[RADIX];

Kernel source

submission.py181 lines
import torch
from torch.utils.cpp_extension import load_inline

cuda_src = """
#include <torch/extension.h>
#include <cuda_runtime.h>
#include <cooperative_groups.h>

namespace cg = cooperative_groups;

#define WARP_SIZE 32
#define RADIX_BITS 8
#define RADIX 256

__device__ __forceinline__ unsigned int float_flip(float f) {
    unsigned int u = __float_as_uint(f);
    return (u & 0x80000000) ? ~u : u ^ 0x80000000;
}

__device__ __forceinline__ float flip_float(unsigned int u) {
    u = (u & 0x80000000) ? u ^ 0x80000000 : ~u;
    return __uint_as_float(u);
}

__global__ void count_radix(const float* __restrict__ in, int* __restrict__ hist,
                            int n, int shift) {
    __shared__ int local[RADIX];
    int tid = threadIdx.x;

    if (tid < RADIX) local[tid] = 0;
    __syncthreads();

    int idx = blockIdx.x * blockDim.x + tid;
    int stride = blockDim.x * gridDim.x;

    for (int i = idx; i < n; i += stride) {
        unsigned int key = float_flip(in[i]);
        int digit = (key >> shift) & (RADIX - 1);
        atomicAdd(&local[digit], 1);
    }
    __syncthreads();

    if (tid < RADIX) {
        atomicAdd(&hist[blockIdx.x * RADIX + tid], local[tid]);
    }
}

__global__ void scan_radix(int* hist, int num_blocks) {
    __shared__ int temp[RADIX];
    int tid = threadIdx.x;

    if (tid < RADIX) {
        int sum = 0;
        for (int b = 0; b < num_blocks; b++) {
            sum += hist[b * RADIX + tid];
        }
        temp[tid] = sum;
    }
    __syncthreads();

    if (tid == 0) {
        int acc = 0;
        for (int i = 0; i < RADIX; i++) {
            int cnt = temp[i];
            temp[i] = acc;
            acc += cnt;
        }
    }
    __syncthreads();

    if (tid < RADIX) hist[tid] = temp[tid];
}

__global__ void reorder_radix(const float* __restrict__ in, float* __restrict__ out,
                              int* __restrict__ offsets, int n, int shift) {
    __shared__ int local_off[RADIX];
    __shared__ int block_off[RADIX];
    int tid = threadIdx.x;

    if (tid < RADIX) local_off[tid] = 0;
    __syncthreads();

    int block_start = blockIdx.x * blockDim.x;
    int block_end = min(block_start + (int)blockDim.x, n);

    for (int i = block_start + tid; i < block_end; i += blockDim.x) {
        unsigned int key = float_flip(in[i]);
        int digit = (key >> shift) & (RADIX - 1);
        atomicAdd(&local_off[digit], 1);
    }
    __syncthreads();

    if (tid < RADIX && local_off[tid] > 0) {
        block_off[tid] = atomicAdd(&offsets[tid], local_off[tid]);
    }
    __syncthreads();

    __shared__ int write_off[RADIX];
    if (tid < RADIX) write_off[tid] = 0;
    __syncthreads();

    for (int i = block_start + tid; i < block_end; i += blockDim.x) {
        float val = in[i];
        unsigned int key = float_flip(val);
        int digit = (key >> shift) & (RADIX - 1);
        int pos = block_off[digit] + atomicAdd(&write_off[digit], 1);
        out[pos] = val;
    }
}

void radix_sort_impl(const float* in, float* out, float* tmp, int n, cudaStream_t stream) {
    const int threads = 1024;
    const int blocks = min((n + threads - 1) / threads, 128);

    int* d_hist;
    cudaMalloc(&d_hist, blocks * RADIX * sizeof(int));

    const float* src = in;
    float* dst = out;

    for (int pass = 0; pass < 4; pass++) {
        int shift = pass * RADIX_BITS;

        cudaMemsetAsync(d_hist, 0, blocks * RADIX * sizeof(int), stream);
        count_radix<<<blocks, threads, 0, stream>>>(src, d_hist, n, shift);
        scan_radix<<<1, RADIX, 0, stream>>>(d_hist, blocks);
        reorder_radix<<<blocks, threads, 0, stream>>>(src, dst, d_hist, n, shift);

        if (pass < 3) {
            src = dst;
            dst = (dst == out) ? tmp : out;
        }
    }

    if (dst != out) {
        cudaMemcpyAsync(out, dst, n * sizeof(float), cudaMemcpyDeviceToDevice, stream);
    }

    cudaFree(d_hist);
}

torch::Tensor radix_sort(torch::Tensor input, torch::Tensor output) {
    auto tmp = torch::empty_like(input);
    radix_sort_impl(
        input.data_ptr<float>(),
        output.data_ptr<float>(),
        tmp.data_ptr<float>(),
        input.numel(),
        c10::cuda::getCurrentCUDAStream()
    );
    return output;
}

PYBIND11_MODULE(TORCH_EXTENSION_NAME, m) {
    m.def("sort", &radix_sort);
}
"""

try:
    radix = load_inline(
        name='radix_sort',
        cpp_sources='',
        cuda_sources=cuda_src,
        functions=['sort'],
        extra_cuda_cflags=['-O3', '--use_fast_math', '-std=c++17'],
        with_cuda=True
    )
    HAS_RADIX = True
except:
    HAS_RADIX = False

def custom_kernel(data):
    input_tensor, output_tensor = data

    if HAS_RADIX:
        radix.sort(input_tensor, output_tensor)
    else:
        torch.sort(input_tensor, out=(output_tensor, torch.empty_like(input_tensor, dtype=torch.long)))

    return output_tensor
scrolls · 181 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 71021.

import torch
+ from torch.utils.cpp_extension import load_inline
+ cuda_src = """
+ #include <torch/extension.h>
+ #include <cuda_runtime.h>
+ #include <cooperative_groups.h>
+
+ namespace cg = cooperative_groups;
+
+ #define WARP_SIZE 32
+ #define RADIX_BITS 8
+ #define RADIX 256
+
+ __device__ __forceinline__ unsigned int float_flip(float f) {
+ unsigned int u = __float_as_uint(f);
+ return (u & 0x80000000) ? ~u : u ^ 0x80000000;
+ }
+
+ __device__ __forceinline__ float flip_float(unsigned int u) {
+ u = (u & 0x80000000) ? u ^ 0x80000000 : ~u;
+ return __uint_as_float(u);
+ }
+
+ __global__ void count_radix(const float* __restrict__ in, int* __restrict__ hist,
+ int n, int shift) {
+ __shared__ int local[RADIX];
+ int tid = threadIdx.x;
+
+ if (tid < RADIX) local[tid] = 0;
+ __syncthreads();
+
+ int idx = blockIdx.x * blockDim.x + tid;
+ int stride = blockDim.x * gridDim.x;
+
+ for (int i = idx; i < n; i += stride) {
+ unsigned int key = float_flip(in[i]);
+ int digit = (key >> shift) & (RADIX - 1);
+ atomicAdd(&local[digit], 1);
+ }
+ __syncthreads();
+
+ if (tid < RADIX) {
+ atomicAdd(&hist[blockIdx.x * RADIX + tid], local[tid]);
+ }
+ }
+
+ __global__ void scan_radix(int* hist, int num_blocks) {
+ __shared__ int temp[RADIX];
+ int tid = threadIdx.x;
+
+ if (tid < RADIX) {
+ int sum = 0;
+ for (int b = 0; b < num_blocks; b++) {
+ sum += hist[b * RADIX + tid];
+ }
+ temp[tid] = sum;
+ }
+ __syncthreads();
+
+ if (tid == 0) {
+ int acc = 0;
+ for (int i = 0; i < RADIX; i++) {
+ int cnt = temp[i];
+ temp[i] = acc;
+ acc += cnt;
+ }
+ }
+ __syncthreads();
+
+ if (tid < RADIX) hist[tid] = temp[tid];
+ }
+
+ __global__ void reorder_radix(const float* __restrict__ in, float* __restrict__ out,
+ int* __restrict__ offsets, int n, int shift) {
+ __shared__ int local_off[RADIX];
+ __shared__ int block_off[RADIX];
+ int tid = threadIdx.x;
+
+ if (tid < RADIX) local_off[tid] = 0;
+ __syncthreads();
+
+ int block_start = blockIdx.x * blockDim.x;
+ int block_end = min(block_start + (int)blockDim.x, n);
+
+ for (int i = block_start + tid; i < block_end; i += blockDim.x) {
+ unsigned int key = float_flip(in[i]);
+ int digit = (key >> shift) & (RADIX - 1);
+ atomicAdd(&local_off[digit], 1);
+ }
+ __syncthreads();
+
+ if (tid < RADIX && local_off[tid] > 0) {
+ block_off[tid] = atomicAdd(&offsets[tid], local_off[tid]);
+ }
+ __syncthreads();
+
+ __shared__ int write_off[RADIX];
+ if (tid < RADIX) write_off[tid] = 0;
+ __syncthreads();
+
+ for (int i = block_start + tid; i < block_end; i += blockDim.x) {
+ float val = in[i];
+ unsigned int key = float_flip(val);
+ int digit = (key >> shift) & (RADIX - 1);
+ int pos = block_off[digit] + atomicAdd(&write_off[digit], 1);
+ out[pos] = val;
+ }
+ }
+
+ void radix_sort_impl(const float* in, float* out, float* tmp, int n, cudaStream_t stream) {
+ const int threads = 1024;
+ const int blocks = min((n + threads - 1) / threads, 128);
+
+ int* d_hist;
+ cudaMalloc(&d_hist, blocks * RADIX * sizeof(int));
+
+ const float* src = in;
+ float* dst = out;
+
+ for (int pass = 0; pass < 4; pass++) {
+ int shift = pass * RADIX_BITS;
+
+ cudaMemsetAsync(d_hist, 0, blocks * RADIX * sizeof(int), stream);
+ count_radix<<<blocks, threads, 0, stream>>>(src, d_hist, n, shift);
+ scan_radix<<<1, RADIX, 0, stream>>>(d_hist, blocks);
+ reorder_radix<<<blocks, threads, 0, stream>>>(src, dst, d_hist, n, shift);
+
+ if (pass < 3) {
+ src = dst;
+ dst = (dst == out) ? tmp : out;
+ }
+ }
+
+ if (dst != out) {
+ cudaMemcpyAsync(out, dst, n * sizeof(float), cudaMemcpyDeviceToDevice, stream);
+ }
+
+ cudaFree(d_hist);
+ }
+
+ torch::Tensor radix_sort(torch::Tensor input, torch::Tensor output) {
+ auto tmp = torch::empty_like(input);
+ radix_sort_impl(
+ input.data_ptr<float>(),
+ output.data_ptr<float>(),
+ tmp.data_ptr<float>(),
+ input.numel(),
+ c10::cuda::getCurrentCUDAStream()
+ );
+ return output;
+ }
+
+ PYBIND11_MODULE(TORCH_EXTENSION_NAME, m) {
+ m.def("sort", &radix_sort);
+ }
+ """
+
+ try:
+ radix = load_inline(
+ name='radix_sort',
+ cpp_sources='',
+ cuda_sources=cuda_src,
+ functions=['sort'],
+ extra_cuda_cflags=['-O3', '--use_fast_math', '-std=c++17'],
+ with_cuda=True
+ )
+ HAS_RADIX = True
+ except:
+ HAS_RADIX = False
+
def custom_kernel(data):
input_tensor, output_tensor = data
- torch.sort(input_tensor, out=(output_tensor, torch.empty_like(input_tensor, dtype=torch.long)))
+
+ if HAS_RADIX:
+ radix.sort(input_tensor, output_tensor)
+ else:
+ torch.sort(input_tensor, out=(output_tensor, torch.empty_like(input_tensor, dtype=torch.long)))
+
return output_tensor
scrolls · 181 diff lines total

Best evidence level for this revision: reported

JSON