gpt-5.5-priority · original · l123_single_gpt
correct 43_Max_Pooling_3D.py
model
gpt-5.5-priority
turns / max
1 / 1
tool calls
1
tokens (total)
0
wall clock
—
truncated
no
backend
cuda fp32
variant
original
runtime
6.06 μs
ref runtime
3.93 μs
speedup
0.65x
started
2026-05-05T00:53:28Z
timingkernelbench.timing
kernel runtime
6.06 μs
ref runtime
3.93 μs
speedup
0.65x
kernel mean / median / std
6.06 / — / 0.72 μs
ref mean / median / std
3.93 / — / 0.05 μs
numerical precisioneval_kernel_against_ref
max abs error
0.00
mean abs error
0.00
max rel error
0.00
mean rel error
0.00
gpu memoryextended_metrics.measure_memory
kernel peak
4595.00 MB
ref peak
5525.97 MB
kernel / ref
0.83x
kernel launches / fusiontorch.profiler
kernel launches
1
ref launches
6
fusion ratio (ref / kernel)
6.00x
total cuda time
28 μs
energyNVML (pynvml)
kernel mJ / run
720.56
ref mJ / run
960.70
ratio (ref / kernel)
1.33x
avg power
120.63 W
ref avg power
238.08 W
SOL (speed-of-light)nsight_hardware_counters
SOL score (0–1)
0.309
dram util %
25.1%
compute util %
30.9%
bottleneck
compute-bound
dominant pipe
FP32
arithmetic intensity
—
ridge point
20.00
roofline / occupancynsight_hardware_counters
dram bandwidth
839.16 GB/s
dram util %
25.0%
fp32 tflops
—
fp32 util %
—
fp16 tflops
—
occupancy %
98.4%
bottleneck
compute-bound
dominant pipe %
30.9%
arithmetic intensity
—
ridge point
20.00
L1 hit %
—
L2 hit %
67.6%
ld sectors / req
6.40
st sectors / req
—
regs / thread
28
smem / block
38144 B
block size
512
peak bw
3350.00 GB/s
peak fp32 tflops
67.00
peak fp16 tflops
1979.00
warp stalls (top 5)nsight
long_scoreboard
1160.5%
mio_throttle
387.3%
short_scoreboard
68.4%
reference PyTorch source (the prompt the agent sees)
import torch
import torch.nn as nn

class Model(nn.Module):
    """
    Simple model that performs Max Pooling 3D.
    """
    def __init__(self, kernel_size: int, stride: int = None, padding: int = 0, dilation: int = 1, return_indices: bool = False, ceil_mode: bool = False):
        """
        Initializes the Max Pooling 3D layer.

        Args:
            kernel_size (int): Size of the kernel for the max pooling operation.
            stride (int, optional): Stride of the pooling operation. Defaults to None, which means stride is equal to kernel_size.
            padding (int, optional): Padding applied to the input tensor. Defaults to 0.
            dilation (int, optional): Spacing between kernel elements. Defaults to 1.
            return_indices (bool, optional): Whether to return indices of the maximum values. Defaults to False.
            ceil_mode (bool, optional): When True, the output size is ceil(input_size / stride) instead of floor. Defaults to False.
        """
        super(Model, self).__init__()
        self.maxpool = nn.MaxPool3d(kernel_size=kernel_size, stride=stride, padding=padding, dilation=dilation, return_indices=return_indices, ceil_mode=ceil_mode)

    def forward(self, x: torch.Tensor) -> torch.Tensor:
        """
        Applies Max Pooling 3D to the input tensor.

        Args:
            x (torch.Tensor): Input tensor of shape (batch_size, channels, dim1, dim2, dim3).

        Returns:
            torch.Tensor: Output tensor with Max Pooling 3D applied.
        """
        return self.maxpool(x)

batch_size = 16
channels = 32
dim1 = 128
dim2 = 128
dim3 = 128
kernel_size = 3
stride = 2
padding = 1
dilation = 3

def get_inputs():
    x = torch.rand(batch_size, channels, dim1, dim2, dim3)
    return [x]

def get_init_inputs():
    return [kernel_size, stride, padding, dilation]
turn 0 · FINAL · 1 tool call(s) · 59.0s turn · 59.0s LLM · 11,257 chars (click to expand)
turn 059.0s turn · 59.0s LLM · 0.0s tools · FINAL
reasoning
**Optimizing maxpool3d parameters** I need to craft a complete Python implementation for custom maxpool3d parameters. The constructor will accept specific arguments like fp32 and a fixed input shape. I must calculate the output dimensions using a kernel size of 3, stride of 2, padding of 1, and depth of 3. This results in a heavy load on memory, which seems inefficient. I'll explore a CUDA extension for optimization while handling the return indices appropriately. Each output’s neighboring difference must be considered for improved efficiency. **Analyzing output positions for pooling** I’m looking at how to handle output max values over three w positions, considering overlaps with strides and dilation. It seems there's a possibility of overlap despite the stride of 2 and dilation of 3. I can map threads to output positions for better memory coalescing, but loads are still pretty high. If I can vectorize computations to handle two adjacent outputs, that might help. I also need to check for interleaved loads to see if I can optimize performance further, even if it requires handling larger data structures.
call → submit_kernel
callsubmit_kernel { "kernel_code": "import torch\nimport torch.nn as nn\nfrom torch.utils.cpp_extension import load_inline\n\n_cpp_src = r\"\"\"\n#include <torch/extension.h>\n\ntorch::Tensor maxpool3d_forward(torch::Tensor x,\n int64_t kernel_size,\n int64_t stride,\n int64_t padding,\n int64_t dilation,\n bool ceil_mode);\n\"\"\"\n\n_cuda_src = r\"\"\"\n#include <torch/extension.h>\n#include <ATen/cuda/CUDAContext.h>\n#include <c10/cuda/CUDAGuard.h>\n#include <cfloat>\n\n#define TILE 8\n#define IN_TILE 21\n#define IN_PLANE (IN_TILE * IN_TILE)\n#define SH_SIZE (IN_TILE * IN_TILE * IN_TILE)\n\n__global__ __launch_bounds__(512, 2)\nvoid maxpool3d_ks3_s2_p1_d3_kernel(const float* __restrict__ x,\n float* __restrict__ y,\n int N, int C, int D, int H, int W,\n int OD, int OH, int OW,\n int dBlocks) {\n __shared__ float smem[SH_SIZE];\n\n const int tx = threadIdx.x;\n const int ty = threadIdx.y;\n const int tz = threadIdx.z;\n const int tid = tx + TILE * (ty + TILE * tz);\n\n const int ow0 = blockIdx.x * TILE;\n const int oh0 = blockIdx.y * TILE;\n const int db = blockIdx.z % dBlocks;\n const int nc = blockIdx.z / dBlocks;\n const int od0 = db * TILE;\n\n const int iw_start = ow0 * 2 - 1;\n const int ih_start = oh0 * 2 - 1;\n const int id_start = od0 * 2 - 1;\n\n const bool interior = (iw_start >= 0) && (ih_start >= 0) && (id_start >= 0) &&\n (iw_start + IN_TILE - 1 < W) &&\n (ih_start + IN_TILE - 1 < H) &&\n (id_start + IN_TILE - 1 < D);\n\n const long long base_nc = (long long)nc * D * H * W;\n\n if (interior) {\n #pragma unroll 1\n for (int idx = tid; idx < SH_SIZE; idx += 512) {\n int t = idx;\n const int liw = t % IN_TILE; t /= IN_TILE;\n const int lih = t % IN_TILE;\n const int lid = t / IN_TILE;\n const int gd = id_start + lid;\n const int gh = ih_start + lih;\n const int gw = iw_start + liw;\n smem[idx] = x[base_nc + ((long long)gd * H + gh) * W + gw];\n }\n } else {\n #pragma unroll 1\n for (int idx = tid; idx < SH_SIZE; idx += 512) {\n int t = idx;\n const int liw = t % IN_TILE; t /= IN_TILE;\n const int lih = t % IN_TILE;\n const int lid = t / IN_TILE;\n const int gd = id_start + lid;\n const int gh = ih_start + lih;\n const int gw = iw_start + liw;\n float v = -FLT_MAX;\n if ((unsigned)gd < (unsigned)D && (unsigned)gh < (unsigned)H && (unsigned)gw < (unsigned)W) {\n v = x[base_nc + ((long long)gd * H + gh) * W + gw];\n }\n smem[idx] = v;\n }\n }\n\n __syncthreads();\n\n const int ow = ow0 + tx;\n const int oh = oh0 + ty;\n const int od = od0 + tz;\n\n if (ow < OW && oh < OH && od < OD) {\n const int lbase = (tz * 2) * IN_PLANE + (ty * 2) * IN_TILE + (tx * 2);\n float m = -FLT_MAX;\n\n #pragma unroll\n for (int kd = 0; kd < 3; ++kd) {\n const int doff = lbase + kd * 3 * IN_PLANE;\n #pragma unroll\n for (int kh = 0; kh < 3; ++kh) {\n const int hoff = doff + kh * 3 * IN_TILE;\n float v0 = smem[hoff + 0];\n float v1 = smem[hoff + 3];\n float v2 = smem[hoff + 6];\n m = fmaxf(m, v0);\n m = fmaxf(m, v1);\n m = fmaxf(m, v2);\n }\n }\n\n y[((long long)nc * OD * OH * OW) + ((long long)od * OH + oh) * OW + ow] = m;\n }\n}\n\n// A simple generic kernel is included only for uncommon constructor choices. The benchmarked\n// problem uses the specialized k=3,s=2,p=1,d=3 path above.\n__global__ void maxpool3d_generic_kernel(const float* __restrict__ x,\n float* __restrict__ y,\n long long total,\n int C, int D, int H, int W,\n int OD, int OH, int OW,\n int k, int s, int p, int dil) {\n long long idx = (long long)blockIdx.x * blockDim.x + threadIdx.x;\n if (idx >= total) return;\n\n int ow = idx % OW;\n long long t = idx / OW;\n int oh = t % OH; t /= OH;\n int od = t % OD; t /= OD;\n int nc = (int)t;\n\n int id0 = od * s - p;\n int ih0 = oh * s - p;\n int iw0 = ow * s - p;\n float m = -FLT_MAX;\n const long long base = (long long)nc * D * H * W;\n\n for (int kd = 0; kd < k; ++kd) {\n int gd = id0 + kd * dil;\n if ((unsigned)gd >= (unsigned)D) continue;\n for (int kh = 0; kh < k; ++kh) {\n int gh = ih0 + kh * dil;\n if ((unsigned)gh >= (unsigned)H) continue;\n for (int kw = 0; kw < k; ++kw) {\n int gw = iw0 + kw * dil;\n if ((unsigned)gw < (unsigned)W) {\n float v = x[base + ((long long)gd * H + gh) * W + gw];\n m = fmaxf(m, v);\n }\n }\n }\n }\n y[idx] = m;\n}\n\ntorch::Tensor maxpool3d_forward(torch::Tensor x,\n int64_t kernel_size,\n int64_t stride,\n int64_t padding,\n int64_t dilation,\n bool ceil_mode) {\n const at::cuda::OptionalCUDAGuard device_guard(device_of(x));\n\n const int N = (int)x.size(0);\n const int C = (int)x.size(1);\n const int D = (int)x.size(2);\n const int H = (int)x.size(3);\n const int W = (int)x.size(4);\n const int k = (int)kernel_size;\n const int s = (int)stride;\n const int p = (int)padding;\n const int dil = (int)dilation;\n\n int OD, OH, OW;\n if (!ceil_mode) {\n OD = (D + 2 * p - dil * (k - 1) - 1) / s + 1;\n OH = (H + 2 * p - dil * (k - 1) - 1) / s + 1;\n OW = (W + 2 * p - dil * (k - 1) - 1) / s + 1;\n } else {\n OD = (D + 2 * p - dil * (k - 1) - 1 + s - 1) / s + 1;\n OH = (H + 2 * p - dil * (k - 1) - 1 + s - 1) / s + 1;\n OW = (W + 2 * p - dil * (k - 1) - 1 + s - 1) / s + 1;\n if ((OD - 1) * s >= D + p) --OD;\n if ((OH - 1) * s >= H + p) --OH;\n if ((OW - 1) * s >= W + p) --OW;\n }\n\n auto y = torch::empty({N, C, OD, OH, OW}, x.options());\n cudaStream_t stream = at::cuda::getCurrentCUDAStream();\n\n if (x.scalar_type() == at::kFloat && k == 3 && s == 2 && p == 1 && dil == 3 && !ceil_mode) {\n const int dBlocks = (OD + TILE - 1) / TILE;\n dim3 block(TILE, TILE, TILE);\n dim3 grid((OW + TILE - 1) / TILE, (OH + TILE - 1) / TILE, N * C * dBlocks);\n maxpool3d_ks3_s2_p1_d3_kernel<<<grid, block, 0, stream>>>(\n x.data_ptr<float>(), y.data_ptr<float>(), N, C, D, H, W, OD, OH, OW, dBlocks);\n } else {\n long long total = (long long)N * C * OD * OH * OW;\n int threads = 256;\n int blocks = (int)((total + threads - 1) / threads);\n maxpool3d_generic_kernel<<<blocks, threads, 0, stream>>>(\n x.data_ptr<float>(), y.data_ptr<float>(), total, C, D, H, W, OD, OH, OW, k, s, p, dil);\n }\n\n C10_CUDA_KERNEL_LAUNCH_CHECK();\n return y;\n}\n\"\"\"\n\n_ext = load_inline(\n name=\"maxpool3d_dilated_ext_v1\",\n cpp_sources=[_cpp_src],\n cuda_sources=[_cuda_src],\n functions=[\"maxpool3d_forward\"],\n extra_cflags=[\"-O3\"],\n extra_cuda_cflags=[\"-O3\", \"--use_fast_math\"],\n verbose=False,\n)\n\n\nclass ModelNew(nn.Module):\n def __init__(self, kernel_size: int, stride: int = None, padding: int = 0, dilation: int = 1,\n return_indices: bool = False, ceil_mode: bool = False):\n super(ModelNew, self).__init__()\n self.kernel_size = int(kernel_size)\n self.stride = int(kernel_size if stride is None else stride)\n self.padding = int(padding)\n self.dilation = int(dilation)\n self.return_indices = bool(return_indices)\n self.ceil_mode = bool(ceil_mode)\n\n def forward(self, x: torch.Tensor) -> torch.Tensor:\n # The supplied task uses return_indices=False and fp32 CUDA tensors.\n return _ext.maxpool3d_forward(x, self.kernel_size, self.stride, self.padding, self.dilation, self.ceil_mode)\n" }
result ← submit_kernel (ok)
oksubmit_kernel submit_kernel PASSED: (5 / 5) correctness trials all passed. Kernel runtime: 6.06 μs Runtime stats: mean=6.06μs median=?μs std=0.72μs Numerical precision: max_abs_err=0.00e+00 mean_abs_err=0.00e+00 max_rel_err=0.00e+00 Memory: 4595.0 MB peak (ref: 5525.97 MB, ratio: 0.8315x) Kernel launches: 1 (ref: 6, fusion ratio: 6.0) Energy: 720.56 mJ/run (ref: 960.7 mJ, ratio: 1.3333x) SOL score: 0.309
final submitted kernel (236 lines, 8,496 chars) — full source, untruncated
import torch
import torch.nn as nn
from torch.utils.cpp_extension import load_inline

_cpp_src = r"""
#include <torch/extension.h>

torch::Tensor maxpool3d_forward(torch::Tensor x,
                                int64_t kernel_size,
                                int64_t stride,
                                int64_t padding,
                                int64_t dilation,
                                bool ceil_mode);
"""

_cuda_src = r"""
#include <torch/extension.h>
#include <ATen/cuda/CUDAContext.h>
#include <c10/cuda/CUDAGuard.h>
#include <cfloat>

#define TILE 8
#define IN_TILE 21
#define IN_PLANE (IN_TILE * IN_TILE)
#define SH_SIZE (IN_TILE * IN_TILE * IN_TILE)

__global__ __launch_bounds__(512, 2)
void maxpool3d_ks3_s2_p1_d3_kernel(const float* __restrict__ x,
                                    float* __restrict__ y,
                                    int N, int C, int D, int H, int W,
                                    int OD, int OH, int OW,
                                    int dBlocks) {
    __shared__ float smem[SH_SIZE];

    const int tx = threadIdx.x;
    const int ty = threadIdx.y;
    const int tz = threadIdx.z;
    const int tid = tx + TILE * (ty + TILE * tz);

    const int ow0 = blockIdx.x * TILE;
    const int oh0 = blockIdx.y * TILE;
    const int db  = blockIdx.z % dBlocks;
    const int nc  = blockIdx.z / dBlocks;
    const int od0 = db * TILE;

    const int iw_start = ow0 * 2 - 1;
    const int ih_start = oh0 * 2 - 1;
    const int id_start = od0 * 2 - 1;

    const bool interior = (iw_start >= 0) && (ih_start >= 0) && (id_start >= 0) &&
                          (iw_start + IN_TILE - 1 < W) &&
                          (ih_start + IN_TILE - 1 < H) &&
                          (id_start + IN_TILE - 1 < D);

    const long long base_nc = (long long)nc * D * H * W;

    if (interior) {
        #pragma unroll 1
        for (int idx = tid; idx < SH_SIZE; idx += 512) {
            int t = idx;
            const int liw = t % IN_TILE; t /= IN_TILE;
            const int lih = t % IN_TILE;
            const int lid = t / IN_TILE;
            const int gd = id_start + lid;
            const int gh = ih_start + lih;
            const int gw = iw_start + liw;
            smem[idx] = x[base_nc + ((long long)gd * H + gh) * W + gw];
        }
    } else {
        #pragma unroll 1
        for (int idx = tid; idx < SH_SIZE; idx += 512) {
            int t = idx;
            const int liw = t % IN_TILE; t /= IN_TILE;
            const int lih = t % IN_TILE;
            const int lid = t / IN_TILE;
            const int gd = id_start + lid;
            const int gh = ih_start + lih;
            const int gw = iw_start + liw;
            float v = -FLT_MAX;
            if ((unsigned)gd < (unsigned)D && (unsigned)gh < (unsigned)H && (unsigned)gw < (unsigned)W) {
                v = x[base_nc + ((long long)gd * H + gh) * W + gw];
            }
            smem[idx] = v;
        }
    }

    __syncthreads();

    const int ow = ow0 + tx;
    const int oh = oh0 + ty;
    const int od = od0 + tz;

    if (ow < OW && oh < OH && od < OD) {
        const int lbase = (tz * 2) * IN_PLANE + (ty * 2) * IN_TILE + (tx * 2);
        float m = -FLT_MAX;

        #pragma unroll
        for (int kd = 0; kd < 3; ++kd) {
            const int doff = lbase + kd * 3 * IN_PLANE;
            #pragma unroll
            for (int kh = 0; kh < 3; ++kh) {
                const int hoff = doff + kh * 3 * IN_TILE;
                float v0 = smem[hoff + 0];
                float v1 = smem[hoff + 3];
                float v2 = smem[hoff + 6];
                m = fmaxf(m, v0);
                m = fmaxf(m, v1);
                m = fmaxf(m, v2);
            }
        }

        y[((long long)nc * OD * OH * OW) + ((long long)od * OH + oh) * OW + ow] = m;
    }
}

// A simple generic kernel is included only for uncommon constructor choices.  The benchmarked
// problem uses the specialized k=3,s=2,p=1,d=3 path above.
__global__ void maxpool3d_generic_kernel(const float* __restrict__ x,
                                         float* __restrict__ y,
                                         long long total,
                                         int C, int D, int H, int W,
                                         int OD, int OH, int OW,
                                         int k, int s, int p, int dil) {
    long long idx = (long long)blockIdx.x * blockDim.x + threadIdx.x;
    if (idx >= total) return;

    int ow = idx % OW;
    long long t = idx / OW;
    int oh = t % OH; t /= OH;
    int od = t % OD; t /= OD;
    int nc = (int)t;

    int id0 = od * s - p;
    int ih0 = oh * s - p;
    int iw0 = ow * s - p;
    float m = -FLT_MAX;
    const long long base = (long long)nc * D * H * W;

    for (int kd = 0; kd < k; ++kd) {
        int gd = id0 + kd * dil;
        if ((unsigned)gd >= (unsigned)D) continue;
        for (int kh = 0; kh < k; ++kh) {
            int gh = ih0 + kh * dil;
            if ((unsigned)gh >= (unsigned)H) continue;
            for (int kw = 0; kw < k; ++kw) {
                int gw = iw0 + kw * dil;
                if ((unsigned)gw < (unsigned)W) {
                    float v = x[base + ((long long)gd * H + gh) * W + gw];
                    m = fmaxf(m, v);
                }
            }
        }
    }
    y[idx] = m;
}

torch::Tensor maxpool3d_forward(torch::Tensor x,
                                int64_t kernel_size,
                                int64_t stride,
                                int64_t padding,
                                int64_t dilation,
                                bool ceil_mode) {
    const at::cuda::OptionalCUDAGuard device_guard(device_of(x));

    const int N = (int)x.size(0);
    const int C = (int)x.size(1);
    const int D = (int)x.size(2);
    const int H = (int)x.size(3);
    const int W = (int)x.size(4);
    const int k = (int)kernel_size;
    const int s = (int)stride;
    const int p = (int)padding;
    const int dil = (int)dilation;

    int OD, OH, OW;
    if (!ceil_mode) {
        OD = (D + 2 * p - dil * (k - 1) - 1) / s + 1;
        OH = (H + 2 * p - dil * (k - 1) - 1) / s + 1;
        OW = (W + 2 * p - dil * (k - 1) - 1) / s + 1;
    } else {
        OD = (D + 2 * p - dil * (k - 1) - 1 + s - 1) / s + 1;
        OH = (H + 2 * p - dil * (k - 1) - 1 + s - 1) / s + 1;
        OW = (W + 2 * p - dil * (k - 1) - 1 + s - 1) / s + 1;
        if ((OD - 1) * s >= D + p) --OD;
        if ((OH - 1) * s >= H + p) --OH;
        if ((OW - 1) * s >= W + p) --OW;
    }

    auto y = torch::empty({N, C, OD, OH, OW}, x.options());
    cudaStream_t stream = at::cuda::getCurrentCUDAStream();

    if (x.scalar_type() == at::kFloat && k == 3 && s == 2 && p == 1 && dil == 3 && !ceil_mode) {
        const int dBlocks = (OD + TILE - 1) / TILE;
        dim3 block(TILE, TILE, TILE);
        dim3 grid((OW + TILE - 1) / TILE, (OH + TILE - 1) / TILE, N * C * dBlocks);
        maxpool3d_ks3_s2_p1_d3_kernel<<<grid, block, 0, stream>>>(
            x.data_ptr<float>(), y.data_ptr<float>(), N, C, D, H, W, OD, OH, OW, dBlocks);
    } else {
        long long total = (long long)N * C * OD * OH * OW;
        int threads = 256;
        int blocks = (int)((total + threads - 1) / threads);
        maxpool3d_generic_kernel<<<blocks, threads, 0, stream>>>(
            x.data_ptr<float>(), y.data_ptr<float>(), total, C, D, H, W, OD, OH, OW, k, s, p, dil);
    }

    C10_CUDA_KERNEL_LAUNCH_CHECK();
    return y;
}
"""

_ext = load_inline(
    name="maxpool3d_dilated_ext_v1",
    cpp_sources=[_cpp_src],
    cuda_sources=[_cuda_src],
    functions=["maxpool3d_forward"],
    extra_cflags=["-O3"],
    extra_cuda_cflags=["-O3", "--use_fast_math"],
    verbose=False,
)


class ModelNew(nn.Module):
    def __init__(self, kernel_size: int, stride: int = None, padding: int = 0, dilation: int = 1,
                 return_indices: bool = False, ceil_mode: bool = False):
        super(ModelNew, self).__init__()
        self.kernel_size = int(kernel_size)
        self.stride = int(kernel_size if stride is None else stride)
        self.padding = int(padding)
        self.dilation = int(dilation)
        self.return_indices = bool(return_indices)
        self.ceil_mode = bool(ceil_mode)

    def forward(self, x: torch.Tensor) -> torch.Tensor:
        # The supplied task uses return_indices=False and fp32 CUDA tensors.
        return _ext.maxpool3d_forward(x, self.kernel_size, self.stride, self.padding, self.dilation, self.ceil_mode)