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#include <ATen/cuda/CUDAContext.h>\n#include <cuda_runtime.h>\n#include <cublasLt.h>\n#include <mutex>\n#include <stdexcept>\nvoid div_launcher(torch::Tensor y, double divisor);\nstatic cublasLtHandle_t get_lt_handle(){ static cublasLtHandle_t h=nullptr; static std::once_flag f; std::call_once(f, [](){cublasLtCreate(&h);}); return h; }\n#define CHECK_CUBLAS(call) do { cublasStatus_t _s=(call); if(_s!=CUBLAS_STATUS_SUCCESS) throw std::runtime_error(\"cublasLt error\"); } while(0)\ntorch::Tensor linear_relu_div(torch::Tensor x, torch::Tensor weight, torch::Tensor bias, double divisor){\n int64_t M64=x.size(0),K64=x.size(1),N64=weight.size(0); int M=(int)M64,N=(int)N64,K=(int)K64; auto y=torch::empty({M64,N64},x.options());\n cublasLtHandle_t lt=get_lt_handle(); cudaStream_t stream=at::cuda::getCurrentCUDAStream(); cublasLtMatmulDesc_t op; cublasLtMatrixLayout_t ad,bd,cd,dd;\n CHECK_CUBLAS(cublasLtMatmulDescCreate(&op, CUBLAS_COMPUTE_32F, CUDA_R_32F)); cublasOperation_t ta=CUBLAS_OP_T,tb=CUBLAS_OP_N;\n CHECK_CUBLAS(cublasLtMatmulDescSetAttribute(op,CUBLASLT_MATMUL_DESC_TRANSA,&ta,sizeof(ta))); CHECK_CUBLAS(cublasLtMatmulDescSetAttribute(op,CUBLASLT_MATMUL_DESC_TRANSB,&tb,sizeof(tb)));\n cublasLtEpilogue_t epi=CUBLASLT_EPILOGUE_RELU_BIAS; CHECK_CUBLAS(cublasLtMatmulDescSetAttribute(op,CUBLASLT_MATMUL_DESC_EPILOGUE,&epi,sizeof(epi))); const void* bp=bias.data_ptr<float>(); CHECK_CUBLAS(cublasLtMatmulDescSetAttribute(op,CUBLASLT_MATMUL_DESC_BIAS_POINTER,&bp,sizeof(bp)));\n CHECK_CUBLAS(cublasLtMatrixLayoutCreate(&ad,CUDA_R_32F,K,N,K)); CHECK_CUBLAS(cublasLtMatrixLayoutCreate(&bd,CUDA_R_32F,K,M,K)); CHECK_CUBLAS(cublasLtMatrixLayoutCreate(&cd,CUDA_R_32F,N,M,N)); CHECK_CUBLAS(cublasLtMatrixLayoutCreate(&dd,CUDA_R_32F,N,M,N));\n cublasLtMatmulPreference_t pref; CHECK_CUBLAS(cublasLtMatmulPreferenceCreate(&pref)); size_t wsSize=32*1024*1024; CHECK_CUBLAS(cublasLtMatmulPreferenceSetAttribute(pref,CUBLASLT_MATMUL_PREF_MAX_WORKSPACE_BYTES,&wsSize,sizeof(wsSize))); cublasLtMatmulHeuristicResult_t heur; int ret=0; CHECK_CUBLAS(cublasLtMatmulAlgoGetHeuristic(lt,op,ad,bd,cd,dd,pref,1,&heur,&ret)); if(!ret) throw std::runtime_error(\"no algo\");\n auto ws=torch::empty({(long long)wsSize},x.options().dtype(torch::kUInt8)); float alpha=1.0f,beta=0.0f; CHECK_CUBLAS(cublasLtMatmul(lt,op,&alpha,weight.data_ptr<float>(),ad,x.data_ptr<float>(),bd,&beta,y.data_ptr<float>(),cd,y.data_ptr<float>(),dd,&heur.algo,ws.data_ptr(),wsSize,stream));\n cublasLtMatmulPreferenceDestroy(pref); cublasLtMatrixLayoutDestroy(ad); cublasLtMatrixLayoutDestroy(bd); cublasLtMatrixLayoutDestroy(cd); cublasLtMatrixLayoutDestroy(dd); cublasLtMatmulDescDestroy(op); div_launcher(y,divisor); return y; }\n'''\ncuda_src = r'''\n#include <torch/extension.h>\n#include <ATen/cuda/CUDAContext.h>\n__global__ void div_kernel(float* y,long long n,float inv){long long i=blockIdx.x*blockDim.x+threadIdx.x,s=(long long)blockDim.x*gridDim.x; for(;i<n;i+=s) y[i]*=inv;}\nvoid div_launcher(torch::Tensor y,double divisor){long long n=y.numel(); int th=256,bl=(int)((n+th-1)/th); if(bl>4096) bl=4096; div_kernel<<<bl,th,0,at::cuda::getCurrentCUDAStream()>>>(y.data_ptr<float>(),n,1.0f/(float)divisor);}\n'''\n_ext=load_inline(name='linear_relu_div_lt_v3', cpp_sources=cpp_src, cuda_sources=cuda_src, functions=['linear_relu_div'], extra_cuda_cflags=['-O3'], extra_cflags=['-O3'], extra_ldflags=['-lcublas','-lcublasLt'], verbose=False)\nclass ModelNew(nn.Module):\n def __init__(self,in_features,out_features,divisor): super(ModelNew,self).__init__(); self.linear=nn.Linear(in_features,out_features); self.divisor=divisor\n def forward(self,x): return _ext.linear_relu_div(x,self.linear.weight,self.linear.bias,float(self.divisor))\n"
}