call → submit_kernel
callsubmit_kernel
{
"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>\ntorch::Tensor mlp_forward(torch::Tensor x,\n torch::Tensor w0, torch::Tensor b0,\n torch::Tensor w1, torch::Tensor b1,\n torch::Tensor w2, torch::Tensor b2);\n'''\n\ncuda_src = r'''\n#include <torch/extension.h>\n#include <ATen/cuda/CUDAContext.h>\n#include <c10/cuda/CUDAGuard.h>\n#include <cuda_runtime.h>\n#include <cublasLt.h>\n#include <stdexcept>\n\nstatic cublasLtHandle_t lt_handle = nullptr;\nstatic inline void ck(cublasStatus_t s, const char* m) {\n if (s != CUBLAS_STATUS_SUCCESS) throw std::runtime_error(m);\n}\n\n__global__ void add_bias_kernel(float* __restrict__ y,\n const float* __restrict__ b,\n long long total, int N) {\n long long i = blockIdx.x * (long long)blockDim.x + threadIdx.x;\n if (i < total) y[i] += b[i & (N - 1)];\n}\n\nstatic torch::Tensor linear_impl(torch::Tensor x, torch::Tensor w, torch::Tensor bias,\n bool relu, cudaStream_t stream) {\n const int64_t M64 = x.size(0), K64 = x.size(1), N64 = w.size(0);\n const int M = (int)M64, N = (int)N64, K = (int)K64;\n auto y = torch::empty({M64, N64}, x.options());\n\n cublasLtMatmulDesc_t op;\n cublasLtMatrixLayout_t ad, bd, cd;\n ck(cublasLtMatmulDescCreate(&op, CUBLAS_COMPUTE_32F, CUDA_R_32F), \"op\");\n\n cublasOperation_t ta = CUBLAS_OP_T, tb = CUBLAS_OP_N;\n ck(cublasLtMatmulDescSetAttribute(op, CUBLASLT_MATMUL_DESC_TRANSA, &ta, sizeof(ta)), \"ta\");\n ck(cublasLtMatmulDescSetAttribute(op, CUBLASLT_MATMUL_DESC_TRANSB, &tb, sizeof(tb)), \"tb\");\n\n cublasLtEpilogue_t epi = relu ? CUBLASLT_EPILOGUE_RELU_BIAS : CUBLASLT_EPILOGUE_DEFAULT;\n ck(cublasLtMatmulDescSetAttribute(op, CUBLASLT_MATMUL_DESC_EPILOGUE, &epi, sizeof(epi)), \"epi\");\n if (relu) {\n const void* bp = bias.data_ptr<float>();\n ck(cublasLtMatmulDescSetAttribute(op, CUBLASLT_MATMUL_DESC_BIAS_POINTER, &bp, sizeof(bp)), \"bias\");\n }\n\n // Row-major y[M,N] == column-major view [N,M].\n // Row-major w[N,K] == column-major view [K,N], transposed in GEMM.\n // Row-major x[M,K] == column-major view [K,M].\n ck(cublasLtMatrixLayoutCreate(&ad, CUDA_R_32F, K, N, K), \"ad\");\n ck(cublasLtMatrixLayoutCreate(&bd, CUDA_R_32F, K, M, K), \"bd\");\n ck(cublasLtMatrixLayoutCreate(&cd, CUDA_R_32F, N, M, N), \"cd\");\n\n float alpha = 1.0f, beta = 0.0f;\n cublasStatus_t st = cublasLtMatmul(lt_handle, op, &alpha,\n w.data_ptr<float>(), ad,\n x.data_ptr<float>(), bd,\n &beta,\n y.data_ptr<float>(), cd,\n y.data_ptr<float>(), cd,\n nullptr, nullptr, 0, stream);\n\n cublasLtMatrixLayoutDestroy(ad);\n cublasLtMatrixLayoutDestroy(bd);\n cublasLtMatrixLayoutDestroy(cd);\n cublasLtMatmulDescDestroy(op);\n ck(st, \"matmul\");\n\n if (!relu) {\n long long total = M64 * N64;\n int block = 256;\n int grid = (int)((total + block - 1) / block);\n add_bias_kernel<<<grid, block, 0, stream>>>(y.data_ptr<float>(), bias.data_ptr<float>(), total, N);\n }\n return y;\n}\n\ntorch::Tensor mlp_forward(torch::Tensor x,\n torch::Tensor w0, torch::Tensor b0,\n torch::Tensor w1, torch::Tensor b1,\n torch::Tensor w2, torch::Tensor b2) {\n TORCH_CHECK(x.is_cuda() && w0.is_cuda() && b0.is_cuda() && w1.is_cuda() && b1.is_cuda() && w2.is_cuda() && b2.is_cuda(), \"CUDA tensors required\");\n TORCH_CHECK(x.is_contiguous() && w0.is_contiguous() && b0.is_contiguous() && w1.is_contiguous() && b1.is_contiguous() && w2.is_contiguous() && b2.is_contiguous(), \"contiguous tensors required\");\n\n c10::cuda::CUDAGuard guard(x.device());\n if (!lt_handle) ck(cublasLtCreate(<_handle), \"create\");\n cudaStream_t stream = at::cuda::getCurrentCUDAStream().stream();\n\n auto y0 = linear_impl(x, w0, b0, true, stream);\n auto y1 = linear_impl(y0, w1, b1, true, stream);\n auto y2 = linear_impl(y1, w2, b2, false, stream);\n return y2;\n}\n'''\n\n_ext = load_inline(\n name='mlp_cublaslt_fused_submit',\n cpp_sources=cpp_src,\n cuda_sources=cuda_src,\n functions=['mlp_forward'],\n extra_cflags=['-O3'],\n extra_cuda_cflags=['-O3'],\n extra_ldflags=['-lcublasLt', '-lcublas'],\n verbose=False,\n)\n\nclass ModelNew(nn.Module):\n def __init__(self, input_size, hidden_layer_sizes, output_size):\n super(ModelNew, self).__init__()\n layers = []\n current_input_size = input_size\n for hidden_size in hidden_layer_sizes:\n layers.append(nn.Linear(current_input_size, hidden_size))\n layers.append(nn.ReLU())\n current_input_size = hidden_size\n layers.append(nn.Linear(current_input_size, output_size))\n self.network = nn.Sequential(*layers)\n\n def forward(self, x):\n return _ext.mlp_forward(\n x,\n self.network[0].weight, self.network[0].bias,\n self.network[2].weight, self.network[2].bias,\n self.network[4].weight, self.network[4].bias,\n )\n"
}