call → run_correctness
callrun_correctness
{
"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>\ntorch::Tensor mse_forward(torch::Tensor predictions, torch::Tensor targets);\n\"\"\"\n\n_cuda_src = r\"\"\"\n#include <torch/extension.h>\n#include <ATen/cuda/CUDAContext.h>\n#include <cuda.h>\n#include <cuda_runtime.h>\n#include <cstdint>\n\n#define CHECK_CUDA(x) TORCH_CHECK(x.is_cuda(), #x \" must be a CUDA tensor\")\n\nstatic __device__ __forceinline__ float warp_reduce_sum(float v) {\n #pragma unroll\n for (int offset = 16; offset > 0; offset >>= 1) v += __shfl_down_sync(0xffffffff, v, offset);\n return v;\n}\n\ntemplate<int BLOCK>\n__device__ __forceinline__ void store_block_sum(float sum, float* __restrict__ partial) {\n int tid = threadIdx.x;\n sum = warp_reduce_sum(sum);\n __shared__ float warp_sums[BLOCK / 32];\n if ((tid & 31) == 0) warp_sums[tid >> 5] = sum;\n __syncthreads();\n float block_sum = (tid < (BLOCK / 32)) ? warp_sums[tid] : 0.0f;\n if (tid < 32) {\n block_sum = warp_reduce_sum(block_sum);\n if (tid == 0) partial[blockIdx.x] = block_sum;\n }\n}\n\nstatic __device__ __forceinline__ float4 load4(const float4* __restrict__ p, int64_t i) { return p[i]; }\n\ntemplate<int BLOCK>\n__global__ void mse_stage1_vec4_kernel(const float4* __restrict__ p4,\n const float4* __restrict__ t4,\n float* __restrict__ partial,\n int64_t n4) {\n int tid = threadIdx.x;\n int64_t stride = (int64_t)gridDim.x * BLOCK;\n int64_t idx = (int64_t)blockIdx.x * BLOCK + tid;\n float s0 = 0.0f, s1 = 0.0f, s2 = 0.0f, s3 = 0.0f;\n int64_t stride4 = stride << 2;\n for (; idx + 3 * stride < n4; idx += stride4) {\n float4 a0 = load4(p4, idx); float4 b0 = load4(t4, idx);\n float4 a1 = load4(p4, idx + stride); float4 b1 = load4(t4, idx + stride);\n float4 a2 = load4(p4, idx + 2*stride); float4 b2 = load4(t4, idx + 2*stride);\n float4 a3 = load4(p4, idx + 3*stride); float4 b3 = load4(t4, idx + 3*stride);\n float d;\n d = a0.x - b0.x; s0 = fmaf(d,d,s0); d = a0.y - b0.y; s0 = fmaf(d,d,s0); d = a0.z - b0.z; s0 = fmaf(d,d,s0); d = a0.w - b0.w; s0 = fmaf(d,d,s0);\n d = a1.x - b1.x; s1 = fmaf(d,d,s1); d = a1.y - b1.y; s1 = fmaf(d,d,s1); d = a1.z - b1.z; s1 = fmaf(d,d,s1); d = a1.w - b1.w; s1 = fmaf(d,d,s1);\n d = a2.x - b2.x; s2 = fmaf(d,d,s2); d = a2.y - b2.y; s2 = fmaf(d,d,s2); d = a2.z - b2.z; s2 = fmaf(d,d,s2); d = a2.w - b2.w; s2 = fmaf(d,d,s2);\n d = a3.x - b3.x; s3 = fmaf(d,d,s3); d = a3.y - b3.y; s3 = fmaf(d,d,s3); d = a3.z - b3.z; s3 = fmaf(d,d,s3); d = a3.w - b3.w; s3 = fmaf(d,d,s3);\n }\n float sum = (s0 + s1) + (s2 + s3);\n for (; idx < n4; idx += stride) {\n float4 a = p4[idx]; float4 b = t4[idx];\n float d = a.x - b.x; sum = fmaf(d,d,sum);\n d = a.y - b.y; sum = fmaf(d,d,sum);\n d = a.z - b.z; sum = fmaf(d,d,sum);\n d = a.w - b.w; sum = fmaf(d,d,sum);\n }\n store_block_sum<BLOCK>(sum, partial);\n}\n\ntemplate<int BLOCK>\n__global__ void mse_stage1_scalar_kernel(const float* __restrict__ p,\n const float* __restrict__ t,\n float* __restrict__ partial,\n int64_t n) {\n int tid = threadIdx.x;\n int64_t idx = (int64_t)blockIdx.x * BLOCK + tid;\n int64_t stride = (int64_t)gridDim.x * BLOCK;\n float sum = 0.0f;\n for (; idx < n; idx += stride) {\n float d = p[idx] - t[idx];\n sum = fmaf(d, d, sum);\n }\n store_block_sum<BLOCK>(sum, partial);\n}\n\ntemplate<int BLOCK>\n__global__ void mse_stage2_kernel(const float* __restrict__ partial,\n float* __restrict__ out,\n int blocks,\n int64_t n) {\n int tid = threadIdx.x;\n float sum = 0.0f;\n for (int i = tid; i < blocks; i += BLOCK) sum += partial[i];\n sum = warp_reduce_sum(sum);\n __shared__ float warp_sums[BLOCK / 32];\n if ((tid & 31) == 0) warp_sums[tid >> 5] = sum;\n __syncthreads();\n float total = (tid < (BLOCK / 32)) ? warp_sums[tid] : 0.0f;\n if (tid < 32) {\n total = warp_reduce_sum(total);\n if (tid == 0) out[0] = total / (float)n;\n }\n}\n\ntorch::Tensor mse_forward(torch::Tensor predictions, torch::Tensor targets) {\n CHECK_CUDA(predictions); CHECK_CUDA(targets);\n TORCH_CHECK(predictions.scalar_type() == torch::kFloat32, \"predictions must be float32\");\n TORCH_CHECK(targets.scalar_type() == torch::kFloat32, \"targets must be float32\");\n TORCH_CHECK(predictions.numel() == targets.numel(), \"size mismatch\");\n TORCH_CHECK(predictions.is_contiguous(), \"predictions must be contiguous\");\n TORCH_CHECK(targets.is_contiguous(), \"targets must be contiguous\");\n const int64_t n = predictions.numel();\n auto out = torch::empty({}, predictions.options());\n if (n == 0) return out;\n constexpr int BLOCK = 256;\n const float* p = predictions.data_ptr<float>();\n const float* t = targets.data_ptr<float>();\n uintptr_t addr = reinterpret_cast<uintptr_t>(p) | reinterpret_cast<uintptr_t>(t);\n bool use_vec4 = ((addr & 15) == 0) && ((n & 3LL) == 0);\n int64_t items = use_vec4 ? (n >> 2) : n;\n int blocks = (int)((items + BLOCK - 1) / BLOCK);\n if (blocks > 2048) blocks = 2048;\n auto partial = torch::empty({blocks}, predictions.options());\n cudaStream_t stream = at::cuda::getCurrentCUDAStream();\n if (use_vec4) {\n mse_stage1_vec4_kernel<BLOCK><<<blocks, BLOCK, 0, stream>>>(reinterpret_cast<const float4*>(p), reinterpret_cast<const float4*>(t), partial.data_ptr<float>(), n >> 2);\n } else {\n mse_stage1_scalar_kernel<BLOCK><<<blocks, BLOCK, 0, stream>>>(p, t, partial.data_ptr<float>(), n);\n }\n mse_stage2_kernel<BLOCK><<<1, BLOCK, 0, stream>>>(partial.data_ptr<float>(), out.data_ptr<float>(), blocks, n);\n return out;\n}\n\"\"\"\n\n_ext = load_inline(name=\"mse_mean_ext_v3\", cpp_sources=_cpp_src, cuda_sources=_cuda_src,\n functions=[\"mse_forward\"], verbose=False,\n extra_cuda_cflags=[\"-O3\", \"--use_fast_math\"],\n extra_cflags=[\"-O3\"])\n\nclass ModelNew(nn.Module):\n def __init__(self):\n super(ModelNew, self).__init__()\n def forward(self, predictions, targets):\n return _ext.mse_forward(predictions, targets)\n"
}