call → run_correctness
callrun_correctness
{
"kernel_code": "import torch\nimport torch.nn as nn\nfrom torch.utils.cpp_extension import load_inline\ncpp_src=r'''\n#include <torch/extension.h>\ntorch::Tensor linear_relu(torch::Tensor x, torch::Tensor weight, torch::Tensor bias);\n'''\ncuda_src=r'''\n#include <torch/extension.h>\n#include <ATen/cuda/CUDAContext.h>\n#include <cuda_runtime.h>\n#include <cublasLt.h>\n#include <mutex>\n#define CHECK_CUDA(x) TORCH_CHECK(x.is_cuda(), #x \" must be CUDA\")\n#define CHECK_CONTIGUOUS(x) TORCH_CHECK(x.is_contiguous(), #x \" must be contiguous\")\n#define CHECK_FLOAT(x) TORCH_CHECK(x.scalar_type()==at::kFloat, #x \" must be float\")\n#define CUBLAS_CHECK(x) do{cublasStatus_t s=(x); TORCH_CHECK(s==CUBLAS_STATUS_SUCCESS,\"cuBLASLt error: \",(int)s);}while(0)\nstatic cublasLtHandle_t h=nullptr; static std::once_flag once; static void init(){CUBLAS_CHECK(cublasLtCreate(&h));}\ntorch::Tensor linear_relu(torch::Tensor x, torch::Tensor weight, torch::Tensor bias){\n CHECK_CUDA(x);CHECK_CUDA(weight);CHECK_CUDA(bias);CHECK_CONTIGUOUS(x);CHECK_CONTIGUOUS(weight);CHECK_CONTIGUOUS(bias);CHECK_FLOAT(x);CHECK_FLOAT(weight);CHECK_FLOAT(bias);\n int64_t M64=x.size(0),K64=x.size(1),N64=weight.size(0); TORCH_CHECK(weight.size(1)==K64 && bias.size(0)==N64,\"shape\"); int M=(int)M64,N=(int)N64,K=(int)K64; auto y=torch::empty({M64,N64},x.options()); std::call_once(once,init);\n cublasLtMatmulDesc_t op; cublasLtMatrixLayout_t a,b,d; cublasOperation_t ta=CUBLAS_OP_N,tb=CUBLAS_OP_T; cublasLtOrder_t row=CUBLASLT_ORDER_ROW,col=CUBLASLT_ORDER_COL; cublasLtEpilogue_t epi=CUBLASLT_EPILOGUE_RELU_BIAS;\n CUBLAS_CHECK(cublasLtMatmulDescCreate(&op,CUBLAS_COMPUTE_32F,CUDA_R_32F)); CUBLAS_CHECK(cublasLtMatmulDescSetAttribute(op,CUBLASLT_MATMUL_DESC_TRANSA,&ta,sizeof(ta))); CUBLAS_CHECK(cublasLtMatmulDescSetAttribute(op,CUBLASLT_MATMUL_DESC_TRANSB,&tb,sizeof(tb))); CUBLAS_CHECK(cublasLtMatmulDescSetAttribute(op,CUBLASLT_MATMUL_DESC_EPILOGUE,&epi,sizeof(epi))); const void* bp=bias.data_ptr<float>(); CUBLAS_CHECK(cublasLtMatmulDescSetAttribute(op,CUBLASLT_MATMUL_DESC_BIAS_POINTER,&bp,sizeof(bp)));\n // compute D_col(N,M) = weight(N,K) * x(M,K)^T, stored as y row-major(M,N)\n CUBLAS_CHECK(cublasLtMatrixLayoutCreate(&a,CUDA_R_32F,N,K,K)); CUBLAS_CHECK(cublasLtMatrixLayoutSetAttribute(a,CUBLASLT_MATRIX_LAYOUT_ORDER,&row,sizeof(row)));\n CUBLAS_CHECK(cublasLtMatrixLayoutCreate(&b,CUDA_R_32F,M,K,K)); CUBLAS_CHECK(cublasLtMatrixLayoutSetAttribute(b,CUBLASLT_MATRIX_LAYOUT_ORDER,&row,sizeof(row)));\n CUBLAS_CHECK(cublasLtMatrixLayoutCreate(&d,CUDA_R_32F,N,M,N)); CUBLAS_CHECK(cublasLtMatrixLayoutSetAttribute(d,CUBLASLT_MATRIX_LAYOUT_ORDER,&col,sizeof(col)));\n float alpha=1.f,beta=0.f; size_t wsSize=32ULL*1024ULL*1024ULL; auto ws=torch::empty({(long)wsSize},x.options().dtype(torch::kUInt8)); cublasLtMatmulPreference_t pref; CUBLAS_CHECK(cublasLtMatmulPreferenceCreate(&pref)); CUBLAS_CHECK(cublasLtMatmulPreferenceSetAttribute(pref,CUBLASLT_MATMUL_PREF_MAX_WORKSPACE_BYTES,&wsSize,sizeof(wsSize))); cublasLtMatmulHeuristicResult_t heur; int ret=0; CUBLAS_CHECK(cublasLtMatmulAlgoGetHeuristic(h,op,a,b,d,d,pref,1,&heur,&ret)); TORCH_CHECK(ret>0,\"no algo\"); auto stream=at::cuda::getCurrentCUDAStream();\n CUBLAS_CHECK(cublasLtMatmul(h,op,&alpha,weight.data_ptr<float>(),a,x.data_ptr<float>(),b,&beta,y.data_ptr<float>(),d,y.data_ptr<float>(),d,&heur.algo,ws.data_ptr(),wsSize,stream));\n CUBLAS_CHECK(cublasLtMatmulPreferenceDestroy(pref)); CUBLAS_CHECK(cublasLtMatrixLayoutDestroy(a)); CUBLAS_CHECK(cublasLtMatrixLayoutDestroy(b)); CUBLAS_CHECK(cublasLtMatrixLayoutDestroy(d)); CUBLAS_CHECK(cublasLtMatmulDescDestroy(op)); return y;\n}\n'''\n_ext=load_inline(name='linear_relu_lt_ext_v5c',cpp_sources=cpp_src,cuda_sources=cuda_src,functions=['linear_relu'],extra_ldflags=['-lcublasLt','-lcublas'],verbose=False)\nclass ModelNew(nn.Module):\n def __init__(self,in_features,out_features,bias_shape):\n super(ModelNew,self).__init__(); self.gemm=nn.Linear(in_features,out_features,bias=False); self.bias=nn.Parameter(torch.randn(bias_shape))\n def forward(self,x): return _ext.linear_relu(x,self.gemm.weight,self.bias)\n"
}