gpt-5.5-priority · original · l3_all_gpt
correct 7_GoogleNetInceptionV1.py
model
gpt-5.5-priority
turns / max
4 / 15
tool calls
4
tokens (total)
0
wall clock
—
truncated
no
backend
cuda fp32
variant
original
runtime
6.52 μs
ref runtime
3.36 μs
speedup
0.52x
started
2026-05-04T16:59:55Z
timingkernelbench.timing
kernel runtime
6.52 μs
ref runtime
3.36 μs
speedup
0.52x
kernel mean / median / std
6.52 / — / 33.70 μs
ref mean / median / std
3.36 / — / 0.39 μ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
329.43 MB
ref peak
330.39 MB
kernel / ref
1.00x
kernel launches / fusiontorch.profiler
kernel launches
433
ref launches
450
fusion ratio (ref / kernel)
1.04x
total cuda time
18459 μs
energyNVML (pynvml)
kernel mJ / run
484.26
ref mJ / run
968.34
ratio (ref / kernel)
2.00x
avg power
155.28 W
ref avg power
292.63 W
SOL (speed-of-light)heuristic_from_speedup
SOL score (0–1)
0.051
dram util %
—
compute util %
—
bottleneck
unknown
dominant pipe
—
arithmetic intensity
—
ridge point
—
roofline / occupancyheuristic
dram bandwidth
—
dram util %
—
fp32 tflops
—
fp32 util %
—
fp16 tflops
—
occupancy %
—
bottleneck
—
dominant pipe %
—
arithmetic intensity
—
ridge point
—
L1 hit %
—
L2 hit %
—
ld sectors / req
—
st sectors / req
—
regs / thread
—
smem / block
—
block size
—
peak bw
—
peak fp32 tflops
—
peak fp16 tflops
—
reference PyTorch source (the prompt the agent sees)
import torch
import torch.nn as nn
import torch.nn.functional as F

class InceptionModule(nn.Module):
    def __init__(self, in_channels, out_1x1, reduce_3x3, out_3x3, reduce_5x5, out_5x5, pool_proj):
        """
        :param in_channels: Number of input channels
        :param out_1x1: Number of output channels for the 1x1 convolution
        :param reduce_3x3: Number of output channels for the 1x1 reduction before 3x3 convolution
        :param out_3x3: Number of output channels for the 3x3 convolution
        :param reduce_5x5: Number of output channels for the 1x1 reduction before 5x5 convolution
        :param out_5x5: Number of output channels for the 5x5 convolution
        :param pool_proj: Number of output channels for the pooling projection
        """
        super(InceptionModule, self).__init__()
        
        # 1x1 convolution branch
        self.branch1x1 = nn.Conv2d(in_channels, out_1x1, kernel_size=1)
        
        # 3x3 convolution branch
        self.branch3x3 = nn.Sequential(
            nn.Conv2d(in_channels, reduce_3x3, kernel_size=1),
            nn.Conv2d(reduce_3x3, out_3x3, kernel_size=3, padding=1)
        )
        
        # 5x5 convolution branch
        self.branch5x5 = nn.Sequential(
            nn.Conv2d(in_channels, reduce_5x5, kernel_size=1),
            nn.Conv2d(reduce_5x5, out_5x5, kernel_size=5, padding=2)
        )
        
        # Max pooling branch
        self.branch_pool = nn.Sequential(
            nn.MaxPool2d(kernel_size=3, stride=1, padding=1),
            nn.Conv2d(in_channels, pool_proj, kernel_size=1)
        )
    
    def forward(self, x):
        """
        :param x: Input tensor, shape (batch_size, in_channels, height, width)
        :return: Output tensor, shape (batch_size, out_channels, height, width)
        """
        branch1x1 = self.branch1x1(x)
        branch3x3 = self.branch3x3(x)
        branch5x5 = self.branch5x5(x)
        branch_pool = self.branch_pool(x)
        
        outputs = [branch1x1, branch3x3, branch5x5, branch_pool]
        return torch.cat(outputs, 1)

class Model(nn.Module):
    def __init__(self, num_classes=1000):
        """
        :param num_classes: Number of output classes
        """
        super(Model, self).__init__()
        
        self.conv1 = nn.Conv2d(3, 64, kernel_size=7, stride=2, padding=3)
        self.maxpool1 = nn.MaxPool2d(3, stride=2, padding=1)
        self.conv2 = nn.Conv2d(64, 64, kernel_size=1)
        self.conv3 = nn.Conv2d(64, 192, kernel_size=3, padding=1)
        self.maxpool2 = nn.MaxPool2d(3, stride=2, padding=1)
        
        self.inception3a = InceptionModule(192, 64, 96, 128, 16, 32, 32)
        self.inception3b = InceptionModule(256, 128, 128, 192, 32, 96, 64)
        self.maxpool3 = nn.MaxPool2d(3, stride=2, padding=1)
        
        self.inception4a = InceptionModule(480, 192, 96, 208, 16, 48, 64)
        self.inception4b = InceptionModule(512, 160, 112, 224, 24, 64, 64)
        self.inception4c = InceptionModule(512, 128, 128, 256, 24, 64, 64)
        self.inception4d = InceptionModule(512, 112, 144, 288, 32, 64, 64)
        self.inception4e = InceptionModule(528, 256, 160, 320, 32, 128, 128)
        self.maxpool4 = nn.MaxPool2d(3, stride=2, padding=1)
        
        self.inception5a = InceptionModule(832, 256, 160, 320, 32, 128, 128)
        self.inception5b = InceptionModule(832, 384, 192, 384, 48, 128, 128)
        
        self.avgpool = nn.AdaptiveAvgPool2d((1, 1))
        self.dropout = nn.Dropout(0.0)
        self.fc = nn.Linear(1024, num_classes)
    
    def forward(self, x):
        """
        :param x: Input tensor, shape (batch_size, 3, height, width)
        :return: Output tensor, shape (batch_size, num_classes)
        """
        x = self.maxpool1(F.relu(self.conv1(x)))
        x = F.relu(self.conv2(x))
        x = self.maxpool2(F.relu(self.conv3(x)))
        
        x = self.inception3a(x)
        x = self.inception3b(x)
        x = self.maxpool3(x)
        
        x = self.inception4a(x)
        x = self.inception4b(x)
        x = self.inception4c(x)
        x = self.inception4d(x)
        x = self.inception4e(x)
        x = self.maxpool4(x)
        
        x = self.inception5a(x)
        x = self.inception5b(x)
        
        x = self.avgpool(x)
        x = torch.flatten(x, 1)
        x = self.dropout(x)
        x = self.fc(x)
        
        return x

# Test code
batch_size = 10
input_channels = 3
height = 224
width = 224
num_classes = 1000

def get_inputs():
    return [torch.rand(batch_size, input_channels, height, width)]

def get_init_inputs():
    return [num_classes]
turn 012.8s turn · 12.8s LLM · 0.0s tools
reasoning
**Considering model optimization** I need to think about crafting a full model similar to GoogLeNet. It might be a good idea to use the same weights, perhaps by copying the state in the ModelNew constructor. I wonder if we need to define the same parameter names. If I subclass nn.Module, I could create identical layers to match the state_dict. Additionally, should I optimize using custom kernels or leverage PyTorch’s capabilities for convolution? I'll also need to think about the overall architecture and its efficiency. **Exploring fusions and layers** I need to consider how there’s no ReLU after inception layers, meaning the network operates post-max pooling. Max pooling adds nonlinearity, and I wonder if I can fuse 1x1 and 3x3 convolutions into a single 3x3 conv with combined weights, perhaps even for 5x5. I also think about using PyTorch to lazily fuse weights during each forward call to reduce conv calls, but the costs of fused direct convolutions seem significant. Maybe I should explore using custom kernels or specific configurations for better performance. **Analyzing convolution outputs** I'm considering the convolution output sizes starting with conv1, which shapes to B10 64 112x112, then goes through ReLU and max pooling to reduce to 56. I wonder if fusing operations could save memory and reduce the overhead from PyTorch's max pooling. In my evaluation, it seems that implementing custom maxpool kernels might expedite the process. However, I recognize that the overall convolution operations could still be dominating the performance, so I need to assess if the custom maxpool would be enough.
call → get_gpu_specs
callget_gpu_specs {}
result ← get_gpu_specs (ok)
okget_gpu_specs GPU specs for NVIDIA H100 80GB HBM3: total memory (runtime): 79.1 GB spec entry: H100 GPU Architecture: Hopper GPU Memory: 80GB Memory Bandwidth: 3.35 TB/s FP64 TFLOPS: 34 FP64 Tensor Core TFLOPS: 67 FP32 TFLOPS: 67 TF32 Tensor Core TFLOPS: 989 with sparsity BFLOAT16 Tensore Core TFLOPS: 1979 with sparsity FP16 Tensor Core TFLOPS: 1979 with sparsity FP8 Tensor Core TFLOPS: 3958 with sparsity INT8 Tensor Core TOPS: 3958 with sparsity Register File Size: 64K 32-bit registers per SM Maximum number of registers per thread: 255 Maximum number of thread blocks per SM: 32 Shared memory capacity per SM: 228 KB Maximum shared memory per thread block: 227 KB
turn 1 · 1 tool call(s) · 27.8s turn · 27.8s LLM · 6,289 chars (click to expand)
turn 127.8s turn · 27.8s LLM · 0.0s tools
call → compile_kernel
callcompile_kernel { "kernel_code": "import torch\nimport torch.nn as nn\nimport torch.nn.functional as F\nfrom torch.utils.cpp_extension import load_inline\n\n_cpp = r'''\n#include <torch/extension.h>\ntorch::Tensor maxpool3x3_forward(torch::Tensor x, int stride, bool relu);\n'''\n\n_cuda = r'''\n#include <torch/extension.h>\n#include <cuda.h>\n#include <cuda_runtime.h>\n#include <float.h>\n\n__global__ void maxpool3x3_kernel(const float* __restrict__ x, float* __restrict__ y,\n int total, int N, int C, int H, int W, int OH, int OW,\n int stride, bool relu) {\n int idx = blockIdx.x * blockDim.x + threadIdx.x;\n if (idx >= total) return;\n int ow = idx % OW;\n int t = idx / OW;\n int oh = t % OH;\n t /= OH;\n int c = t % C;\n int n = t / C;\n int ih0 = oh * stride - 1;\n int iw0 = ow * stride - 1;\n const float* base = x + ((n * C + c) * H) * W;\n float m = relu ? 0.0f : -FLT_MAX;\n #pragma unroll\n for (int kh=0; kh<3; ++kh) {\n int ih = ih0 + kh;\n if ((unsigned)ih < (unsigned)H) {\n #pragma unroll\n for (int kw=0; kw<3; ++kw) {\n int iw = iw0 + kw;\n if ((unsigned)iw < (unsigned)W) {\n float v = base[ih * W + iw];\n if (relu && v < 0.0f) v = 0.0f;\n m = fmaxf(m, v);\n }\n }\n }\n }\n y[idx] = m;\n}\n\ntorch::Tensor maxpool3x3_forward(torch::Tensor x, int stride, bool relu) {\n TORCH_CHECK(x.is_cuda(), \"x must be CUDA\");\n TORCH_CHECK(x.scalar_type() == torch::kFloat32, \"float32 only\");\n x = x.contiguous();\n int N = x.size(0), C = x.size(1), H = x.size(2), W = x.size(3);\n int OH = (H + 2 - 3) / stride + 1;\n int OW = (W + 2 - 3) / stride + 1;\n auto y = torch::empty({N, C, OH, OW}, x.options());\n int total = N*C*OH*OW;\n int threads = 256;\n int blocks = (total + threads - 1) / threads;\n maxpool3x3_kernel<<<blocks, threads>>>(x.data_ptr<float>(), y.data_ptr<float>(), total, N, C, H, W, OH, OW, stride, relu);\n return y;\n}\n'''\n\n_ext = load_inline(name='googlenet_pool_ext_v1', cpp_sources=_cpp, cuda_sources=_cuda,\n functions=['maxpool3x3_forward'], extra_cuda_cflags=['-O3'], verbose=False)\n\nclass InceptionModule(nn.Module):\n def __init__(self, in_channels, out_1x1, reduce_3x3, out_3x3, reduce_5x5, out_5x5, pool_proj):\n super(InceptionModule, self).__init__()\n self.branch1x1 = nn.Conv2d(in_channels, out_1x1, kernel_size=1)\n self.branch3x3 = nn.Sequential(\n nn.Conv2d(in_channels, reduce_3x3, kernel_size=1),\n nn.Conv2d(reduce_3x3, out_3x3, kernel_size=3, padding=1)\n )\n self.branch5x5 = nn.Sequential(\n nn.Conv2d(in_channels, reduce_5x5, kernel_size=1),\n nn.Conv2d(reduce_5x5, out_5x5, kernel_size=5, padding=2)\n )\n self.branch_pool = nn.Sequential(\n nn.MaxPool2d(kernel_size=3, stride=1, padding=1),\n nn.Conv2d(in_channels, pool_proj, kernel_size=1)\n )\n def forward(self, x):\n branch1x1 = self.branch1x1(x)\n branch3x3 = self.branch3x3(x)\n branch5x5 = self.branch5x5(x)\n p = _ext.maxpool3x3_forward(x, 1, False)\n branch_pool = self.branch_pool[1](p)\n return torch.cat([branch1x1, branch3x3, branch5x5, branch_pool], 1)\n\nclass ModelNew(nn.Module):\n def __init__(self, num_classes=1000):\n super(ModelNew, self).__init__()\n self.conv1 = nn.Conv2d(3, 64, kernel_size=7, stride=2, padding=3)\n self.maxpool1 = nn.MaxPool2d(3, stride=2, padding=1)\n self.conv2 = nn.Conv2d(64, 64, kernel_size=1)\n self.conv3 = nn.Conv2d(64, 192, kernel_size=3, padding=1)\n self.maxpool2 = nn.MaxPool2d(3, stride=2, padding=1)\n self.inception3a = InceptionModule(192, 64, 96, 128, 16, 32, 32)\n self.inception3b = InceptionModule(256, 128, 128, 192, 32, 96, 64)\n self.maxpool3 = nn.MaxPool2d(3, stride=2, padding=1)\n self.inception4a = InceptionModule(480, 192, 96, 208, 16, 48, 64)\n self.inception4b = InceptionModule(512, 160, 112, 224, 24, 64, 64)\n self.inception4c = InceptionModule(512, 128, 128, 256, 24, 64, 64)\n self.inception4d = InceptionModule(512, 112, 144, 288, 32, 64, 64)\n self.inception4e = InceptionModule(528, 256, 160, 320, 32, 128, 128)\n self.maxpool4 = nn.MaxPool2d(3, stride=2, padding=1)\n self.inception5a = InceptionModule(832, 256, 160, 320, 32, 128, 128)\n self.inception5b = InceptionModule(832, 384, 192, 384, 48, 128, 128)\n self.avgpool = nn.AdaptiveAvgPool2d((1, 1))\n self.dropout = nn.Dropout(0.0)\n self.fc = nn.Linear(1024, num_classes)\n def forward(self, x):\n x = _ext.maxpool3x3_forward(self.conv1(x), 2, True)\n x = F.relu(self.conv2(x))\n x = _ext.maxpool3x3_forward(self.conv3(x), 2, True)\n x = self.inception3a(x)\n x = self.inception3b(x)\n x = _ext.maxpool3x3_forward(x, 2, False)\n x = self.inception4a(x)\n x = self.inception4b(x)\n x = self.inception4c(x)\n x = self.inception4d(x)\n x = self.inception4e(x)\n x = _ext.maxpool3x3_forward(x, 2, False)\n x = self.inception5a(x)\n x = self.inception5b(x)\n x = self.avgpool(x)\n x = torch.flatten(x, 1)\n x = self.dropout(x)\n x = self.fc(x)\n return x\n" }
result ← compile_kernel (ok)
okcompile_kernel compile_kernel PASSED: kernel compiled without errors.
turn 2 · 1 tool call(s) · 11.2s turn · 11.2s LLM · 6,391 chars (click to expand)
turn 211.2s turn · 11.2s LLM · 0.0s tools
call → run_correctness
callrun_correctness { "kernel_code": "import torch\nimport torch.nn as nn\nimport torch.nn.functional as F\nfrom torch.utils.cpp_extension import load_inline\n\n_cpp = r'''\n#include <torch/extension.h>\ntorch::Tensor maxpool3x3_forward(torch::Tensor x, int stride, bool relu);\n'''\n\n_cuda = r'''\n#include <torch/extension.h>\n#include <cuda.h>\n#include <cuda_runtime.h>\n#include <float.h>\n\n__global__ void maxpool3x3_kernel(const float* __restrict__ x, float* __restrict__ y,\n int total, int N, int C, int H, int W, int OH, int OW,\n int stride, bool relu) {\n int idx = blockIdx.x * blockDim.x + threadIdx.x;\n if (idx >= total) return;\n int ow = idx % OW;\n int t = idx / OW;\n int oh = t % OH;\n t /= OH;\n int c = t % C;\n int n = t / C;\n int ih0 = oh * stride - 1;\n int iw0 = ow * stride - 1;\n const float* base = x + ((n * C + c) * H) * W;\n float m = relu ? 0.0f : -FLT_MAX;\n #pragma unroll\n for (int kh=0; kh<3; ++kh) {\n int ih = ih0 + kh;\n if ((unsigned)ih < (unsigned)H) {\n #pragma unroll\n for (int kw=0; kw<3; ++kw) {\n int iw = iw0 + kw;\n if ((unsigned)iw < (unsigned)W) {\n float v = base[ih * W + iw];\n if (relu && v < 0.0f) v = 0.0f;\n m = fmaxf(m, v);\n }\n }\n }\n }\n y[idx] = m;\n}\n\ntorch::Tensor maxpool3x3_forward(torch::Tensor x, int stride, bool relu) {\n TORCH_CHECK(x.is_cuda(), \"x must be CUDA\");\n TORCH_CHECK(x.scalar_type() == torch::kFloat32, \"float32 only\");\n x = x.contiguous();\n int N = x.size(0), C = x.size(1), H = x.size(2), W = x.size(3);\n int OH = (H + 2 - 3) / stride + 1;\n int OW = (W + 2 - 3) / stride + 1;\n auto y = torch::empty({N, C, OH, OW}, x.options());\n int total = N*C*OH*OW;\n int threads = 256;\n int blocks = (total + threads - 1) / threads;\n maxpool3x3_kernel<<<blocks, threads>>>(x.data_ptr<float>(), y.data_ptr<float>(), total, N, C, H, W, OH, OW, stride, relu);\n return y;\n}\n'''\n\n_ext = load_inline(name='googlenet_pool_ext_v1', cpp_sources=_cpp, cuda_sources=_cuda,\n functions=['maxpool3x3_forward'], extra_cuda_cflags=['-O3'], verbose=False)\n\nclass InceptionModule(nn.Module):\n def __init__(self, in_channels, out_1x1, reduce_3x3, out_3x3, reduce_5x5, out_5x5, pool_proj):\n super(InceptionModule, self).__init__()\n self.branch1x1 = nn.Conv2d(in_channels, out_1x1, kernel_size=1)\n self.branch3x3 = nn.Sequential(\n nn.Conv2d(in_channels, reduce_3x3, kernel_size=1),\n nn.Conv2d(reduce_3x3, out_3x3, kernel_size=3, padding=1)\n )\n self.branch5x5 = nn.Sequential(\n nn.Conv2d(in_channels, reduce_5x5, kernel_size=1),\n nn.Conv2d(reduce_5x5, out_5x5, kernel_size=5, padding=2)\n )\n self.branch_pool = nn.Sequential(\n nn.MaxPool2d(kernel_size=3, stride=1, padding=1),\n nn.Conv2d(in_channels, pool_proj, kernel_size=1)\n )\n def forward(self, x):\n branch1x1 = self.branch1x1(x)\n branch3x3 = self.branch3x3(x)\n branch5x5 = self.branch5x5(x)\n p = _ext.maxpool3x3_forward(x, 1, False)\n branch_pool = self.branch_pool[1](p)\n return torch.cat([branch1x1, branch3x3, branch5x5, branch_pool], 1)\n\nclass ModelNew(nn.Module):\n def __init__(self, num_classes=1000):\n super(ModelNew, self).__init__()\n self.conv1 = nn.Conv2d(3, 64, kernel_size=7, stride=2, padding=3)\n self.maxpool1 = nn.MaxPool2d(3, stride=2, padding=1)\n self.conv2 = nn.Conv2d(64, 64, kernel_size=1)\n self.conv3 = nn.Conv2d(64, 192, kernel_size=3, padding=1)\n self.maxpool2 = nn.MaxPool2d(3, stride=2, padding=1)\n self.inception3a = InceptionModule(192, 64, 96, 128, 16, 32, 32)\n self.inception3b = InceptionModule(256, 128, 128, 192, 32, 96, 64)\n self.maxpool3 = nn.MaxPool2d(3, stride=2, padding=1)\n self.inception4a = InceptionModule(480, 192, 96, 208, 16, 48, 64)\n self.inception4b = InceptionModule(512, 160, 112, 224, 24, 64, 64)\n self.inception4c = InceptionModule(512, 128, 128, 256, 24, 64, 64)\n self.inception4d = InceptionModule(512, 112, 144, 288, 32, 64, 64)\n self.inception4e = InceptionModule(528, 256, 160, 320, 32, 128, 128)\n self.maxpool4 = nn.MaxPool2d(3, stride=2, padding=1)\n self.inception5a = InceptionModule(832, 256, 160, 320, 32, 128, 128)\n self.inception5b = InceptionModule(832, 384, 192, 384, 48, 128, 128)\n self.avgpool = nn.AdaptiveAvgPool2d((1, 1))\n self.dropout = nn.Dropout(0.0)\n self.fc = nn.Linear(1024, num_classes)\n def forward(self, x):\n x = _ext.maxpool3x3_forward(self.conv1(x), 2, True)\n x = F.relu(self.conv2(x))\n x = _ext.maxpool3x3_forward(self.conv3(x), 2, True)\n x = self.inception3a(x)\n x = self.inception3b(x)\n x = _ext.maxpool3x3_forward(x, 2, False)\n x = self.inception4a(x)\n x = self.inception4b(x)\n x = self.inception4c(x)\n x = self.inception4d(x)\n x = self.inception4e(x)\n x = _ext.maxpool3x3_forward(x, 2, False)\n x = self.inception5a(x)\n x = self.inception5b(x)\n x = self.avgpool(x)\n x = torch.flatten(x, 1)\n x = self.dropout(x)\n x = self.fc(x)\n return x\n" }
result ← run_correctness (ok)
okrun_correctness run_correctness PASSED: (5 / 5) trials all matched the reference. Numerical precision: max_abs_err=0.00e+00 mean_abs_err=0.00e+00 max_rel_err=0.00e+00
turn 3 · FINAL · 1 tool call(s) · 12.6s turn · 12.6s LLM · 6,652 chars (click to expand)
turn 312.6s turn · 12.6s LLM · 0.0s tools · FINAL
call → submit_kernel
callsubmit_kernel { "kernel_code": "import torch\nimport torch.nn as nn\nimport torch.nn.functional as F\nfrom torch.utils.cpp_extension import load_inline\n\n_cpp = r'''\n#include <torch/extension.h>\ntorch::Tensor maxpool3x3_forward(torch::Tensor x, int stride, bool relu);\n'''\n\n_cuda = r'''\n#include <torch/extension.h>\n#include <cuda.h>\n#include <cuda_runtime.h>\n#include <float.h>\n\n__global__ void maxpool3x3_kernel(const float* __restrict__ x, float* __restrict__ y,\n int total, int N, int C, int H, int W, int OH, int OW,\n int stride, bool relu) {\n int idx = blockIdx.x * blockDim.x + threadIdx.x;\n if (idx >= total) return;\n int ow = idx % OW;\n int t = idx / OW;\n int oh = t % OH;\n t /= OH;\n int c = t % C;\n int n = t / C;\n int ih0 = oh * stride - 1;\n int iw0 = ow * stride - 1;\n const float* base = x + ((n * C + c) * H) * W;\n float m = relu ? 0.0f : -FLT_MAX;\n #pragma unroll\n for (int kh=0; kh<3; ++kh) {\n int ih = ih0 + kh;\n if ((unsigned)ih < (unsigned)H) {\n #pragma unroll\n for (int kw=0; kw<3; ++kw) {\n int iw = iw0 + kw;\n if ((unsigned)iw < (unsigned)W) {\n float v = base[ih * W + iw];\n if (relu && v < 0.0f) v = 0.0f;\n m = fmaxf(m, v);\n }\n }\n }\n }\n y[idx] = m;\n}\n\ntorch::Tensor maxpool3x3_forward(torch::Tensor x, int stride, bool relu) {\n TORCH_CHECK(x.is_cuda(), \"x must be CUDA\");\n TORCH_CHECK(x.scalar_type() == torch::kFloat32, \"float32 only\");\n x = x.contiguous();\n int N = x.size(0), C = x.size(1), H = x.size(2), W = x.size(3);\n int OH = (H + 2 - 3) / stride + 1;\n int OW = (W + 2 - 3) / stride + 1;\n auto y = torch::empty({N, C, OH, OW}, x.options());\n int total = N*C*OH*OW;\n int threads = 256;\n int blocks = (total + threads - 1) / threads;\n maxpool3x3_kernel<<<blocks, threads>>>(x.data_ptr<float>(), y.data_ptr<float>(), total, N, C, H, W, OH, OW, stride, relu);\n return y;\n}\n'''\n\n_ext = load_inline(name='googlenet_pool_ext_v1', cpp_sources=_cpp, cuda_sources=_cuda,\n functions=['maxpool3x3_forward'], extra_cuda_cflags=['-O3'], verbose=False)\n\nclass InceptionModule(nn.Module):\n def __init__(self, in_channels, out_1x1, reduce_3x3, out_3x3, reduce_5x5, out_5x5, pool_proj):\n super(InceptionModule, self).__init__()\n self.branch1x1 = nn.Conv2d(in_channels, out_1x1, kernel_size=1)\n self.branch3x3 = nn.Sequential(\n nn.Conv2d(in_channels, reduce_3x3, kernel_size=1),\n nn.Conv2d(reduce_3x3, out_3x3, kernel_size=3, padding=1)\n )\n self.branch5x5 = nn.Sequential(\n nn.Conv2d(in_channels, reduce_5x5, kernel_size=1),\n nn.Conv2d(reduce_5x5, out_5x5, kernel_size=5, padding=2)\n )\n self.branch_pool = nn.Sequential(\n nn.MaxPool2d(kernel_size=3, stride=1, padding=1),\n nn.Conv2d(in_channels, pool_proj, kernel_size=1)\n )\n def forward(self, x):\n branch1x1 = self.branch1x1(x)\n branch3x3 = self.branch3x3(x)\n branch5x5 = self.branch5x5(x)\n p = _ext.maxpool3x3_forward(x, 1, False)\n branch_pool = self.branch_pool[1](p)\n return torch.cat([branch1x1, branch3x3, branch5x5, branch_pool], 1)\n\nclass ModelNew(nn.Module):\n def __init__(self, num_classes=1000):\n super(ModelNew, self).__init__()\n self.conv1 = nn.Conv2d(3, 64, kernel_size=7, stride=2, padding=3)\n self.maxpool1 = nn.MaxPool2d(3, stride=2, padding=1)\n self.conv2 = nn.Conv2d(64, 64, kernel_size=1)\n self.conv3 = nn.Conv2d(64, 192, kernel_size=3, padding=1)\n self.maxpool2 = nn.MaxPool2d(3, stride=2, padding=1)\n self.inception3a = InceptionModule(192, 64, 96, 128, 16, 32, 32)\n self.inception3b = InceptionModule(256, 128, 128, 192, 32, 96, 64)\n self.maxpool3 = nn.MaxPool2d(3, stride=2, padding=1)\n self.inception4a = InceptionModule(480, 192, 96, 208, 16, 48, 64)\n self.inception4b = InceptionModule(512, 160, 112, 224, 24, 64, 64)\n self.inception4c = InceptionModule(512, 128, 128, 256, 24, 64, 64)\n self.inception4d = InceptionModule(512, 112, 144, 288, 32, 64, 64)\n self.inception4e = InceptionModule(528, 256, 160, 320, 32, 128, 128)\n self.maxpool4 = nn.MaxPool2d(3, stride=2, padding=1)\n self.inception5a = InceptionModule(832, 256, 160, 320, 32, 128, 128)\n self.inception5b = InceptionModule(832, 384, 192, 384, 48, 128, 128)\n self.avgpool = nn.AdaptiveAvgPool2d((1, 1))\n self.dropout = nn.Dropout(0.0)\n self.fc = nn.Linear(1024, num_classes)\n def forward(self, x):\n x = _ext.maxpool3x3_forward(self.conv1(x), 2, True)\n x = F.relu(self.conv2(x))\n x = _ext.maxpool3x3_forward(self.conv3(x), 2, True)\n x = self.inception3a(x)\n x = self.inception3b(x)\n x = _ext.maxpool3x3_forward(x, 2, False)\n x = self.inception4a(x)\n x = self.inception4b(x)\n x = self.inception4c(x)\n x = self.inception4d(x)\n x = self.inception4e(x)\n x = _ext.maxpool3x3_forward(x, 2, False)\n x = self.inception5a(x)\n x = self.inception5b(x)\n x = self.avgpool(x)\n x = torch.flatten(x, 1)\n x = self.dropout(x)\n x = self.fc(x)\n return x\n" }
result ← submit_kernel (ok)
oksubmit_kernel submit_kernel PASSED: (5 / 5) correctness trials all passed. Kernel runtime: 6.52 μs Runtime stats: mean=6.52μs median=?μs std=33.70μs Numerical precision: max_abs_err=0.00e+00 mean_abs_err=0.00e+00 max_rel_err=0.00e+00 Memory: 329.43 MB peak (ref: 330.39 MB, ratio: 0.9971x) Kernel launches: 433 (ref: 450, fusion ratio: 1.0393) Energy: 484.26 mJ/run (ref: 968.34 mJ, ratio: 1.9996x) SOL score: 0.0515
final submitted kernel (135 lines, 5,418 chars) — full source, untruncated
import torch
import torch.nn as nn
import torch.nn.functional as F
from torch.utils.cpp_extension import load_inline

_cpp = r'''
#include <torch/extension.h>
torch::Tensor maxpool3x3_forward(torch::Tensor x, int stride, bool relu);
'''

_cuda = r'''
#include <torch/extension.h>
#include <cuda.h>
#include <cuda_runtime.h>
#include <float.h>

__global__ void maxpool3x3_kernel(const float* __restrict__ x, float* __restrict__ y,
                                  int total, int N, int C, int H, int W, int OH, int OW,
                                  int stride, bool relu) {
    int idx = blockIdx.x * blockDim.x + threadIdx.x;
    if (idx >= total) return;
    int ow = idx % OW;
    int t = idx / OW;
    int oh = t % OH;
    t /= OH;
    int c = t % C;
    int n = t / C;
    int ih0 = oh * stride - 1;
    int iw0 = ow * stride - 1;
    const float* base = x + ((n * C + c) * H) * W;
    float m = relu ? 0.0f : -FLT_MAX;
    #pragma unroll
    for (int kh=0; kh<3; ++kh) {
        int ih = ih0 + kh;
        if ((unsigned)ih < (unsigned)H) {
            #pragma unroll
            for (int kw=0; kw<3; ++kw) {
                int iw = iw0 + kw;
                if ((unsigned)iw < (unsigned)W) {
                    float v = base[ih * W + iw];
                    if (relu && v < 0.0f) v = 0.0f;
                    m = fmaxf(m, v);
                }
            }
        }
    }
    y[idx] = m;
}

torch::Tensor maxpool3x3_forward(torch::Tensor x, int stride, bool relu) {
    TORCH_CHECK(x.is_cuda(), "x must be CUDA");
    TORCH_CHECK(x.scalar_type() == torch::kFloat32, "float32 only");
    x = x.contiguous();
    int N = x.size(0), C = x.size(1), H = x.size(2), W = x.size(3);
    int OH = (H + 2 - 3) / stride + 1;
    int OW = (W + 2 - 3) / stride + 1;
    auto y = torch::empty({N, C, OH, OW}, x.options());
    int total = N*C*OH*OW;
    int threads = 256;
    int blocks = (total + threads - 1) / threads;
    maxpool3x3_kernel<<<blocks, threads>>>(x.data_ptr<float>(), y.data_ptr<float>(), total, N, C, H, W, OH, OW, stride, relu);
    return y;
}
'''

_ext = load_inline(name='googlenet_pool_ext_v1', cpp_sources=_cpp, cuda_sources=_cuda,
                   functions=['maxpool3x3_forward'], extra_cuda_cflags=['-O3'], verbose=False)

class InceptionModule(nn.Module):
    def __init__(self, in_channels, out_1x1, reduce_3x3, out_3x3, reduce_5x5, out_5x5, pool_proj):
        super(InceptionModule, self).__init__()
        self.branch1x1 = nn.Conv2d(in_channels, out_1x1, kernel_size=1)
        self.branch3x3 = nn.Sequential(
            nn.Conv2d(in_channels, reduce_3x3, kernel_size=1),
            nn.Conv2d(reduce_3x3, out_3x3, kernel_size=3, padding=1)
        )
        self.branch5x5 = nn.Sequential(
            nn.Conv2d(in_channels, reduce_5x5, kernel_size=1),
            nn.Conv2d(reduce_5x5, out_5x5, kernel_size=5, padding=2)
        )
        self.branch_pool = nn.Sequential(
            nn.MaxPool2d(kernel_size=3, stride=1, padding=1),
            nn.Conv2d(in_channels, pool_proj, kernel_size=1)
        )
    def forward(self, x):
        branch1x1 = self.branch1x1(x)
        branch3x3 = self.branch3x3(x)
        branch5x5 = self.branch5x5(x)
        p = _ext.maxpool3x3_forward(x, 1, False)
        branch_pool = self.branch_pool[1](p)
        return torch.cat([branch1x1, branch3x3, branch5x5, branch_pool], 1)

class ModelNew(nn.Module):
    def __init__(self, num_classes=1000):
        super(ModelNew, self).__init__()
        self.conv1 = nn.Conv2d(3, 64, kernel_size=7, stride=2, padding=3)
        self.maxpool1 = nn.MaxPool2d(3, stride=2, padding=1)
        self.conv2 = nn.Conv2d(64, 64, kernel_size=1)
        self.conv3 = nn.Conv2d(64, 192, kernel_size=3, padding=1)
        self.maxpool2 = nn.MaxPool2d(3, stride=2, padding=1)
        self.inception3a = InceptionModule(192, 64, 96, 128, 16, 32, 32)
        self.inception3b = InceptionModule(256, 128, 128, 192, 32, 96, 64)
        self.maxpool3 = nn.MaxPool2d(3, stride=2, padding=1)
        self.inception4a = InceptionModule(480, 192, 96, 208, 16, 48, 64)
        self.inception4b = InceptionModule(512, 160, 112, 224, 24, 64, 64)
        self.inception4c = InceptionModule(512, 128, 128, 256, 24, 64, 64)
        self.inception4d = InceptionModule(512, 112, 144, 288, 32, 64, 64)
        self.inception4e = InceptionModule(528, 256, 160, 320, 32, 128, 128)
        self.maxpool4 = nn.MaxPool2d(3, stride=2, padding=1)
        self.inception5a = InceptionModule(832, 256, 160, 320, 32, 128, 128)
        self.inception5b = InceptionModule(832, 384, 192, 384, 48, 128, 128)
        self.avgpool = nn.AdaptiveAvgPool2d((1, 1))
        self.dropout = nn.Dropout(0.0)
        self.fc = nn.Linear(1024, num_classes)
    def forward(self, x):
        x = _ext.maxpool3x3_forward(self.conv1(x), 2, True)
        x = F.relu(self.conv2(x))
        x = _ext.maxpool3x3_forward(self.conv3(x), 2, True)
        x = self.inception3a(x)
        x = self.inception3b(x)
        x = _ext.maxpool3x3_forward(x, 2, False)
        x = self.inception4a(x)
        x = self.inception4b(x)
        x = self.inception4c(x)
        x = self.inception4d(x)
        x = self.inception4e(x)
        x = _ext.maxpool3x3_forward(x, 2, False)
        x = self.inception5a(x)
        x = self.inception5b(x)
        x = self.avgpool(x)
        x = torch.flatten(x, 1)
        x = self.dropout(x)
        x = self.fc(x)
        return x