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>\ntorch::Tensor matmul_forward(torch::Tensor A, torch::Tensor B);\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 <cuda.h>\n#include <cuda_runtime.h>\n\n// Specialized SGEMM for C[M,N] = A[M,64] * B[64,N].\n// Tile: 128 rows x 64 cols per CTA, 16x16 threads; each thread computes 8x4 outputs.\n__global__ __launch_bounds__(256, 2)\nvoid matmul_128x64_k64_kernel(const float* __restrict__ A,\n const float* __restrict__ B,\n float* __restrict__ C,\n int M, int N) {\n __shared__ float As[128][64];\n __shared__ float Bs[64][64];\n\n const int tx = threadIdx.x; // 0..15\n const int ty = threadIdx.y; // 0..15\n const int tid = ty * 16 + tx;\n\n const int row_base = blockIdx.y * 128;\n const int col_base = blockIdx.x * 64;\n\n // Load A tile: 128 x 64, coalesced along K.\n #pragma unroll\n for (int idx = tid; idx < 8192; idx += 256) {\n int r = idx >> 6; // /64\n int k = idx & 63; // %64\n As[r][k] = A[(row_base + r) * 64 + k];\n }\n\n // Load B tile: 64 x 64, coalesced along N.\n #pragma unroll\n for (int idx = tid; idx < 4096; idx += 256) {\n int k = idx >> 6;\n int c = idx & 63;\n Bs[k][c] = B[k * N + (col_base + c)];\n }\n\n __syncthreads();\n\n const int local_row = ty * 8;\n const int local_col = tx * 4;\n\n float acc00=0.f, acc01=0.f, acc02=0.f, acc03=0.f;\n float acc10=0.f, acc11=0.f, acc12=0.f, acc13=0.f;\n float acc20=0.f, acc21=0.f, acc22=0.f, acc23=0.f;\n float acc30=0.f, acc31=0.f, acc32=0.f, acc33=0.f;\n float acc40=0.f, acc41=0.f, acc42=0.f, acc43=0.f;\n float acc50=0.f, acc51=0.f, acc52=0.f, acc53=0.f;\n float acc60=0.f, acc61=0.f, acc62=0.f, acc63=0.f;\n float acc70=0.f, acc71=0.f, acc72=0.f, acc73=0.f;\n\n #pragma unroll\n for (int k = 0; k < 64; ++k) {\n float b0 = Bs[k][local_col + 0];\n float b1 = Bs[k][local_col + 1];\n float b2 = Bs[k][local_col + 2];\n float b3 = Bs[k][local_col + 3];\n\n float a0 = As[local_row + 0][k];\n acc00 = fmaf(a0, b0, acc00); acc01 = fmaf(a0, b1, acc01); acc02 = fmaf(a0, b2, acc02); acc03 = fmaf(a0, b3, acc03);\n float a1 = As[local_row + 1][k];\n acc10 = fmaf(a1, b0, acc10); acc11 = fmaf(a1, b1, acc11); acc12 = fmaf(a1, b2, acc12); acc13 = fmaf(a1, b3, acc13);\n float a2 = As[local_row + 2][k];\n acc20 = fmaf(a2, b0, acc20); acc21 = fmaf(a2, b1, acc21); acc22 = fmaf(a2, b2, acc22); acc23 = fmaf(a2, b3, acc23);\n float a3 = As[local_row + 3][k];\n acc30 = fmaf(a3, b0, acc30); acc31 = fmaf(a3, b1, acc31); acc32 = fmaf(a3, b2, acc32); acc33 = fmaf(a3, b3, acc33);\n float a4 = As[local_row + 4][k];\n acc40 = fmaf(a4, b0, acc40); acc41 = fmaf(a4, b1, acc41); acc42 = fmaf(a4, b2, acc42); acc43 = fmaf(a4, b3, acc43);\n float a5 = As[local_row + 5][k];\n acc50 = fmaf(a5, b0, acc50); acc51 = fmaf(a5, b1, acc51); acc52 = fmaf(a5, b2, acc52); acc53 = fmaf(a5, b3, acc53);\n float a6 = As[local_row + 6][k];\n acc60 = fmaf(a6, b0, acc60); acc61 = fmaf(a6, b1, acc61); acc62 = fmaf(a6, b2, acc62); acc63 = fmaf(a6, b3, acc63);\n float a7 = As[local_row + 7][k];\n acc70 = fmaf(a7, b0, acc70); acc71 = fmaf(a7, b1, acc71); acc72 = fmaf(a7, b2, acc72); acc73 = fmaf(a7, b3, acc73);\n }\n\n const int global_row = row_base + local_row;\n const int global_col = col_base + local_col;\n\n float4* out;\n out = reinterpret_cast<float4*>(C + (global_row + 0) * N + global_col); *out = make_float4(acc00, acc01, acc02, acc03);\n out = reinterpret_cast<float4*>(C + (global_row + 1) * N + global_col); *out = make_float4(acc10, acc11, acc12, acc13);\n out = reinterpret_cast<float4*>(C + (global_row + 2) * N + global_col); *out = make_float4(acc20, acc21, acc22, acc23);\n out = reinterpret_cast<float4*>(C + (global_row + 3) * N + global_col); *out = make_float4(acc30, acc31, acc32, acc33);\n out = reinterpret_cast<float4*>(C + (global_row + 4) * N + global_col); *out = make_float4(acc40, acc41, acc42, acc43);\n out = reinterpret_cast<float4*>(C + (global_row + 5) * N + global_col); *out = make_float4(acc50, acc51, acc52, acc53);\n out = reinterpret_cast<float4*>(C + (global_row + 6) * N + global_col); *out = make_float4(acc60, acc61, acc62, acc63);\n out = reinterpret_cast<float4*>(C + (global_row + 7) * N + global_col); *out = make_float4(acc70, acc71, acc72, acc73);\n}\n\ntorch::Tensor matmul_forward(torch::Tensor A, torch::Tensor B) {\n const at::cuda::OptionalCUDAGuard device_guard(device_of(A));\n const int M = (int)A.size(0);\n const int N = (int)B.size(1);\n auto C = torch::empty({M, N}, A.options());\n\n dim3 block(16, 16);\n dim3 grid((unsigned)(N / 64), (unsigned)(M / 128));\n cudaStream_t stream = at::cuda::getCurrentCUDAStream();\n matmul_128x64_k64_kernel<<<grid, block, 0, stream>>>(\n A.data_ptr<float>(), B.data_ptr<float>(), C.data_ptr<float>(), M, N);\n return C;\n}\n\"\"\"\n\n_ext = load_inline(\n name=\"smallk_matmul_128x64_ext\",\n cpp_sources=_cpp_src,\n cuda_sources=_cuda_src,\n functions=[\"matmul_forward\"],\n extra_cflags=[\"-O3\"],\n extra_cuda_cflags=[\"-O3\"],\n verbose=False,\n)\n\nclass ModelNew(nn.Module):\n def __init__(self):\n super(ModelNew, self).__init__()\n\n def forward(self, A: torch.Tensor, B: torch.Tensor) -> torch.Tensor:\n return _ext.matmul_forward(A, B)\n"
}