call → run_correctness
callrun_correctness
{
"kernel_code": "import torch\nimport torch.nn as nn\nfrom torch.utils.cpp_extension import load_inline\n\ncpp_src = r'''\n#include <torch/extension.h>\n\ntorch::Tensor conv2d_tf32_forward(torch::Tensor x, torch::Tensor weight, torch::Tensor bias,\n int stride, int pad_h, int pad_w, int dil_h, int dil_w);\n'''\n\ncuda_src = r'''\n#include <torch/extension.h>\n#include <ATen/cuda/CUDAContext.h>\n#include <cuda.h>\n#include <cuda_runtime.h>\n#include <mma.h>\nusing namespace nvcuda;\n\n__global__ void conv2d_wmma_tf32_kernel(const float* __restrict__ x,\n const float* __restrict__ w,\n const float* __restrict__ bias,\n float* __restrict__ y,\n int N, int C, int H, int W,\n int Kout, int KH, int KW,\n int Ho, int Wo,\n int stride, int pad_h, int pad_w,\n int dil_h, int dil_w,\n int has_bias) {\n int mtile = blockIdx.x;\n int cotile = blockIdx.y;\n int lane = threadIdx.x;\n __shared__ float As[16*8];\n __shared__ float Bs[8*16];\n wmma::fragment<wmma::matrix_a, 16, 16, 8, wmma::precision::tf32, wmma::row_major> a_frag;\n wmma::fragment<wmma::matrix_b, 16, 16, 8, wmma::precision::tf32, wmma::row_major> b_frag;\n wmma::fragment<wmma::accumulator, 16, 16, 8, float> c_frag;\n wmma::fill_fragment(c_frag, 0.0f);\n const int co_base = cotile * 16;\n const int m_base = mtile * 16;\n const int HWo = Ho * Wo;\n const int totalK = C * KH * KW;\n for (int k0 = 0; k0 < totalK; k0 += 8) {\n for (int idx = lane; idx < 16*8; idx += 32) {\n int r = idx >> 3;\n int kk = idx & 7;\n int kval = k0 + kk;\n int co = co_base + r;\n int t = kval;\n int kw = t % KW; t /= KW;\n int kh = t % KH; t /= KH;\n int ci = t;\n float val = w[((co * C + ci) * KH + kh) * KW + kw];\n As[idx] = val;\n }\n for (int idx = lane; idx < 8*16; idx += 32) {\n int kk = idx >> 4;\n int ccol = idx & 15;\n int kval = k0 + kk;\n int m = m_base + ccol;\n int t = kval;\n int kw = t % KW; t /= KW;\n int kh = t % KH; t /= KH;\n int ci = t;\n int n = m / HWo;\n int rem = m - n * HWo;\n int oh = rem / Wo;\n int ow = rem - oh * Wo;\n int ih = oh * stride + kh * dil_h - pad_h;\n int iw = ow * stride + kw * dil_w - pad_w;\n float val = 0.0f;\n if ((unsigned)ih < (unsigned)H && (unsigned)iw < (unsigned)W) {\n val = x[((n * C + ci) * H + ih) * W + iw];\n }\n Bs[idx] = val;\n }\n __syncthreads();\n wmma::load_matrix_sync(a_frag, As, 8);\n wmma::load_matrix_sync(b_frag, Bs, 16);\n wmma::mma_sync(c_frag, a_frag, b_frag, c_frag);\n __syncthreads();\n }\n __shared__ float Cs[16*16];\n wmma::store_matrix_sync(Cs, c_frag, 16, wmma::mem_row_major);\n __syncthreads();\n for (int idx = lane; idx < 16*16; idx += 32) {\n int r = idx >> 4;\n int ccol = idx & 15;\n int co = co_base + r;\n int m = m_base + ccol;\n int n = m / HWo;\n int rem = m - n * HWo;\n float val = Cs[idx];\n if (has_bias) val += bias[co];\n y[((n * Kout + co) * HWo) + rem] = val;\n }\n}\n\ntorch::Tensor conv2d_tf32_forward(torch::Tensor x, torch::Tensor weight, torch::Tensor bias,\n int stride, int pad_h, int pad_w, int dil_h, int dil_w) {\n const int N = x.size(0), C = x.size(1), H = x.size(2), W = x.size(3);\n const int Kout = weight.size(0), KH = weight.size(2), KW = weight.size(3);\n const int Ho = (H + 2*pad_h - dil_h*(KH-1) - 1) / stride + 1;\n const int Wo = (W + 2*pad_w - dil_w*(KW-1) - 1) / stride + 1;\n auto y = torch::empty({N, Kout, Ho, Wo}, x.options());\n dim3 grid((N * Ho * Wo + 15) / 16, (Kout + 15) / 16);\n int has_bias = (bias.numel() == Kout) ? 1 : 0;\n conv2d_wmma_tf32_kernel<<<grid, 32, 0, at::cuda::getCurrentCUDAStream()>>>(x.data_ptr<float>(), weight.data_ptr<float>(), bias.data_ptr<float>(), y.data_ptr<float>(), N, C, H, W, Kout, KH, KW, Ho, Wo, stride, pad_h, pad_w, dil_h, dil_w, has_bias);\n return y;\n}\n'''\n\n_ext = load_inline(name='conv2d_wmma_tf32_ext2', cpp_sources=cpp_src, cuda_sources=cuda_src,\n functions=['conv2d_tf32_forward'], extra_cuda_cflags=['-O3', '--use_fast_math'], extra_cflags=['-O3'], verbose=False)\n\nclass ModelNew(nn.Module):\n def __init__(self, in_channels: int, out_channels: int, kernel_size: tuple, stride: int = 1, padding: tuple = (0, 0), dilation: tuple = (1, 1), bias: bool = False):\n super(ModelNew, self).__init__()\n self.conv2d = nn.Conv2d(in_channels, out_channels, kernel_size, stride=stride, padding=padding, dilation=dilation, bias=bias)\n self.stride = stride; self.padding = padding; self.dilation = dilation\n self.register_buffer('_empty_bias', torch.empty(0, device='cuda'))\n def forward(self, x: torch.Tensor) -> torch.Tensor:\n b = self.conv2d.bias if self.conv2d.bias is not None else self._empty_bias\n return _ext.conv2d_tf32_forward(x.contiguous(), self.conv2d.weight.contiguous(), b, self.stride, self.padding[0], self.padding[1], self.dilation[0], self.dilation[1])\n"
}