call → compile_kernel
callcompile_kernel
{
"kernel_code": "import torch\nimport torch.nn as nn\nfrom torch.utils.cpp_extension import load_inline\n_cpp_src = '#include <torch/extension.h>\\ntorch::Tensor linear_div_gelu(torch::Tensor x, torch::Tensor weight, torch::Tensor bias, double divisor);\\n'\n_cuda_src = r'''\n#include <torch/extension.h>\n#include <ATen/cuda/CUDAContext.h>\n#include <cuda_runtime.h>\n#include <cublasLt.h>\n#define CHECK_CUBLAS(expr) do { cublasStatus_t _s = (expr); TORCH_CHECK(_s == CUBLAS_STATUS_SUCCESS, \"cuBLASLt error: \", (int)_s); } while(0)\n__global__ void scale_bias_kernel(const float* b, float* out, int n, float inv){int i=blockIdx.x*blockDim.x+threadIdx.x; if(i<n) out[i]=b[i]*inv;}\nstatic cublasLtHandle_t get_lt_handle(){static cublasLtHandle_t h=nullptr; if(!h) CHECK_CUBLAS(cublasLtCreate(&h)); return h;}\ntorch::Tensor linear_div_gelu(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=m64,n=n64,k=k64; auto y=torch::empty({m64,n64},x.options()); auto bs=torch::empty({n64},bias.options()); float inv=1.0f/(float)divisor; scale_bias_kernel<<<(n+255)/256,256,0,at::cuda::getCurrentCUDAStream()>>>(bias.data_ptr<float>(),bs.data_ptr<float>(),n,inv);\n cublasLtHandle_t lt=get_lt_handle(); cublasLtMatmulDesc_t op; cublasLtMatrixLayout_t ad,bd,cd,dd; CHECK_CUBLAS(cublasLtMatmulDescCreate(&op,CUBLAS_COMPUTE_32F,CUDA_R_32F)); cublasOperation_t ta=CUBLAS_OP_N,tb=CUBLAS_OP_T; CHECK_CUBLAS(cublasLtMatmulDescSetAttribute(op,CUBLASLT_MATMUL_DESC_TRANSA,&ta,sizeof(ta))); CHECK_CUBLAS(cublasLtMatmulDescSetAttribute(op,CUBLASLT_MATMUL_DESC_TRANSB,&tb,sizeof(tb))); cublasLtEpilogue_t epi=CUBLASLT_EPILOGUE_GELU_BIAS; CHECK_CUBLAS(cublasLtMatmulDescSetAttribute(op,CUBLASLT_MATMUL_DESC_EPILOGUE,&epi,sizeof(epi))); const void* bp=bs.data_ptr<float>(); CHECK_CUBLAS(cublasLtMatmulDescSetAttribute(op,CUBLASLT_MATMUL_DESC_BIAS_POINTER,&bp,sizeof(bp)));\n CHECK_CUBLAS(cublasLtMatrixLayoutCreate(&ad,CUDA_R_32F,m,k,k)); CHECK_CUBLAS(cublasLtMatrixLayoutCreate(&bd,CUDA_R_32F,n,k,k)); CHECK_CUBLAS(cublasLtMatrixLayoutCreate(&cd,CUDA_R_32F,m,n,n)); CHECK_CUBLAS(cublasLtMatrixLayoutCreate(&dd,CUDA_R_32F,m,n,n)); cublasLtOrder_t ord=CUBLASLT_ORDER_ROW; CHECK_CUBLAS(cublasLtMatrixLayoutSetAttribute(ad,CUBLASLT_MATRIX_LAYOUT_ORDER,&ord,sizeof(ord))); CHECK_CUBLAS(cublasLtMatrixLayoutSetAttribute(bd,CUBLASLT_MATRIX_LAYOUT_ORDER,&ord,sizeof(ord))); CHECK_CUBLAS(cublasLtMatrixLayoutSetAttribute(cd,CUBLASLT_MATRIX_LAYOUT_ORDER,&ord,sizeof(ord))); CHECK_CUBLAS(cublasLtMatrixLayoutSetAttribute(dd,CUBLASLT_MATRIX_LAYOUT_ORDER,&ord,sizeof(ord)));\n const size_t wsSize=32*1024*1024; auto workspace=torch::empty({(long)wsSize}, x.options().dtype(torch::kUInt8)); cublasLtMatmulPreference_t pref; CHECK_CUBLAS(cublasLtMatmulPreferenceCreate(&pref)); 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)); TORCH_CHECK(ret>0,\"no algo\");\n float alpha=inv,beta=0.0f; CHECK_CUBLAS(cublasLtMatmul(lt,op,&alpha,x.data_ptr<float>(),ad,weight.data_ptr<float>(),bd,&beta,y.data_ptr<float>(),cd,y.data_ptr<float>(),dd,&heur.algo,workspace.data_ptr(),wsSize,at::cuda::getCurrentCUDAStream())); cublasLtMatmulPreferenceDestroy(pref); cublasLtMatrixLayoutDestroy(ad); cublasLtMatrixLayoutDestroy(bd); cublasLtMatrixLayoutDestroy(cd); cublasLtMatrixLayoutDestroy(dd); cublasLtMatmulDescDestroy(op); return y;}\n'''\n_ext=load_inline(name='lt_try2', cpp_sources=[_cpp_src], cuda_sources=[_cuda_src], functions=['linear_div_gelu'], extra_cuda_cflags=['-O3'], extra_cflags=['-O3'], extra_ldflags=['-lcublasLt','-lcublas'], verbose=False)\nclass ModelNew(nn.Module):\n def __init__(self,input_size,output_size,divisor): super().__init__(); self.linear=nn.Linear(input_size,output_size); self.divisor=float(divisor)\n def forward(self,x): return _ext.linear_div_gelu(x,self.linear.weight,self.linear.bias,self.divisor)\n"
}