call → compile_kernel
callcompile_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 lstm_forward_cuda(torch::Tensor x, torch::Tensor wih0, torch::Tensor whh0, torch::Tensor bih0, torch::Tensor bhh0, torch::Tensor wih1, torch::Tensor whh1, torch::Tensor bih1, torch::Tensor bhh1, torch::Tensor wih2, torch::Tensor whh2, torch::Tensor bih2, torch::Tensor bhh2, torch::Tensor wih3, torch::Tensor whh3, torch::Tensor bih3, torch::Tensor bhh3, torch::Tensor wih4, torch::Tensor whh4, torch::Tensor bih4, torch::Tensor bhh4, torch::Tensor wih5, torch::Tensor whh5, torch::Tensor bih5, torch::Tensor bhh5, torch::Tensor fcw, torch::Tensor fcb, torch::Tensor h0, torch::Tensor c0);\ntorch::Tensor lstm_forward(torch::Tensor x, torch::Tensor wih0, torch::Tensor whh0, torch::Tensor bih0, torch::Tensor bhh0, torch::Tensor wih1, torch::Tensor whh1, torch::Tensor bih1, torch::Tensor bhh1, torch::Tensor wih2, torch::Tensor whh2, torch::Tensor bih2, torch::Tensor bhh2, torch::Tensor wih3, torch::Tensor whh3, torch::Tensor bih3, torch::Tensor bhh3, torch::Tensor wih4, torch::Tensor whh4, torch::Tensor bih4, torch::Tensor bhh4, torch::Tensor wih5, torch::Tensor whh5, torch::Tensor bih5, torch::Tensor bhh5, torch::Tensor fcw, torch::Tensor fcb, torch::Tensor h0, torch::Tensor c0) {\n return lstm_forward_cuda(x,wih0,whh0,bih0,bhh0,wih1,whh1,bih1,bhh1,wih2,whh2,bih2,bhh2,wih3,whh3,bih3,bhh3,wih4,whh4,bih4,bhh4,wih5,whh5,bih5,bhh5,fcw,fcb,h0,c0);\n}\n'''\n\n_cuda_src = r'''\n#include <torch/extension.h>\n#include <ATen/cuda/CUDAContext.h>\n#include <cuda.h>\n#include <cuda_runtime.h>\n#include <cooperative_groups.h>\nnamespace cg = cooperative_groups;\n#define B 10\n#define T 512\n#define IN 128\n#define H 256\n#define O 10\n__device__ __forceinline__ float sigm(float x){return 1.0f/(1.0f+expf(-x));}\n__device__ __forceinline__ float wrsum(float v){for(int o=16;o;o>>=1)v+=__shfl_down_sync(0xffffffff,v,o);return v;}\n__device__ __forceinline__ void sel(int l,const float* wih0,const float* whh0,const float* bih0,const float* bhh0,const float* wih1,const float* whh1,const float* bih1,const float* bhh1,const float* wih2,const float* whh2,const float* bih2,const float* bhh2,const float* wih3,const float* whh3,const float* bih3,const float* bhh3,const float* wih4,const float* whh4,const float* bih4,const float* bhh4,const float* wih5,const float* whh5,const float* bih5,const float* bhh5,const float*& wih,const float*& whh,const float*& bih,const float*& bhh){\n if(l==0){wih=wih0;whh=whh0;bih=bih0;bhh=bhh0;} else if(l==1){wih=wih1;whh=whh1;bih=bih1;bhh=bhh1;} else if(l==2){wih=wih2;whh=whh2;bih=bih2;bhh=bhh2;} else if(l==3){wih=wih3;whh=whh3;bih=bih3;bhh=bhh3;} else if(l==4){wih=wih4;whh=whh4;bih=bih4;bhh=bhh4;} else {wih=wih5;whh=whh5;bih=bih5;bhh=bhh5;}}\n__global__ void kern(const float* __restrict__ x,const float* __restrict__ wih0,const float* __restrict__ whh0,const float* __restrict__ bih0,const float* __restrict__ bhh0,const float* __restrict__ wih1,const float* __restrict__ whh1,const float* __restrict__ bih1,const float* __restrict__ bhh1,const float* __restrict__ wih2,const float* __restrict__ whh2,const float* __restrict__ bih2,const float* __restrict__ bhh2,const float* __restrict__ wih3,const float* __restrict__ whh3,const float* __restrict__ bih3,const float* __restrict__ bhh3,const float* __restrict__ wih4,const float* __restrict__ whh4,const float* __restrict__ bih4,const float* __restrict__ bhh4,const float* __restrict__ wih5,const float* __restrict__ whh5,const float* __restrict__ bih5,const float* __restrict__ bhh5,const float* __restrict__ fcw,const float* __restrict__ fcb,const float* __restrict__ h0,const float* __restrict__ c0,int has,float* __restrict__ buf1,float* __restrict__ buf2,float* __restrict__ gates,float* __restrict__ hs,float* __restrict__ cs,float* __restrict__ out){\n cg::grid_group grid=cg::this_grid(); int tid=blockIdx.x*blockDim.x+threadIdx.x, nt=gridDim.x*blockDim.x, lane=threadIdx.x&31, warp=tid>>5, nw=nt>>5;\n for(int l=0;l<6;l++){\n for(int idx=tid;idx<B*H;idx+=nt){int b=idx/H,j=idx-b*H; if(has){hs[idx]=h0[(l*B+b)*H+j]; cs[idx]=c0[(l*B+b)*H+j];}else{hs[idx]=0.0f; cs[idx]=0.0f;}}\n grid.sync(); const float *wih,*whh,*bih,*bhh; sel(l,wih0,whh0,bih0,bhh0,wih1,whh1,bih1,bhh1,wih2,whh2,bih2,bhh2,wih3,whh3,bih3,bhh3,wih4,whh4,bih4,bhh4,wih5,whh5,bih5,bhh5,wih,whh,bih,bhh);\n for(int t=0;t<T;t++){\n for(int idx=warp;idx<B*4*H;idx+=nw){int b=idx/(4*H), gh=idx-b*(4*H); float sum=(lane==0?(bih[gh]+bhh[gh]):0.0f); if(l==0){const float* inp=x+(b*T+t)*IN; for(int k=lane;k<IN;k+=32) sum+=inp[k]*wih[gh*IN+k];} else {const float* prev=((l&1)?buf1:buf2)+(t*B+b)*H; for(int k=lane;k<H;k+=32) sum+=prev[k]*wih[gh*H+k];} const float* hp=hs+b*H; for(int k=lane;k<H;k+=32) sum+=hp[k]*whh[gh*H+k]; sum=wrsum(sum); if(lane==0) gates[idx]=sum;}\n grid.sync();\n for(int idx=tid;idx<B*H;idx+=nt){int b=idx/H,j=idx-b*H; const float* g=gates+b*4*H+j; float i=sigm(g[0]), f=sigm(g[H]), gg=tanhf(g[2*H]), o=sigm(g[3*H]); float c=f*cs[idx]+i*gg; float h=o*tanhf(c); cs[idx]=c; hs[idx]=h; float* dst=((l&1)==0?buf1:buf2)+(t*B+b)*H; dst[j]=h;}\n grid.sync();\n }\n }\n for(int idx=warp;idx<B*O;idx+=nw){int b=idx/O,o=idx-b*O; const float* hv=buf2+((T-1)*B+b)*H; float sum=(lane==0?fcb[o]:0.0f); for(int k=lane;k<H;k+=32) sum+=hv[k]*fcw[o*H+k]; sum=wrsum(sum); if(lane==0) out[idx]=sum;}\n}\n\ntorch::Tensor lstm_forward_cuda(torch::Tensor x, torch::Tensor wih0, torch::Tensor whh0, torch::Tensor bih0, torch::Tensor bhh0, torch::Tensor wih1, torch::Tensor whh1, torch::Tensor bih1, torch::Tensor bhh1, torch::Tensor wih2, torch::Tensor whh2, torch::Tensor bih2, torch::Tensor bhh2, torch::Tensor wih3, torch::Tensor whh3, torch::Tensor bih3, torch::Tensor bhh3, torch::Tensor wih4, torch::Tensor whh4, torch::Tensor bih4, torch::Tensor bhh4, torch::Tensor wih5, torch::Tensor whh5, torch::Tensor bih5, torch::Tensor bhh5, torch::Tensor fcw, torch::Tensor fcb, torch::Tensor h0, torch::Tensor c0){\n auto opts=x.options(); auto buf1=torch::empty({T,B,H},opts), buf2=torch::empty({T,B,H},opts), gates=torch::empty({B,4*H},opts), hs=torch::empty({B,H},opts), cs=torch::empty({B,H},opts), out=torch::empty({B,O},opts); int has=(h0.numel()!=0 && c0.numel()!=0);\n const float *xp=x.data_ptr<float>(), *p_wih0=wih0.data_ptr<float>(), *p_whh0=whh0.data_ptr<float>(), *p_bih0=bih0.data_ptr<float>(), *p_bhh0=bhh0.data_ptr<float>(), *p_wih1=wih1.data_ptr<float>(), *p_whh1=whh1.data_ptr<float>(), *p_bih1=bih1.data_ptr<float>(), *p_bhh1=bhh1.data_ptr<float>(), *p_wih2=wih2.data_ptr<float>(), *p_whh2=whh2.data_ptr<float>(), *p_bih2=bih2.data_ptr<float>(), *p_bhh2=bhh2.data_ptr<float>(), *p_wih3=wih3.data_ptr<float>(), *p_whh3=whh3.data_ptr<float>(), *p_bih3=bih3.data_ptr<float>(), *p_bhh3=bhh3.data_ptr<float>(), *p_wih4=wih4.data_ptr<float>(), *p_whh4=whh4.data_ptr<float>(), *p_bih4=bih4.data_ptr<float>(), *p_bhh4=bhh4.data_ptr<float>(), *p_wih5=wih5.data_ptr<float>(), *p_whh5=whh5.data_ptr<float>(), *p_bih5=bih5.data_ptr<float>(), *p_bhh5=bhh5.data_ptr<float>(), *p_fcw=fcw.data_ptr<float>(), *p_fcb=fcb.data_ptr<float>(), *p_h0=(has?h0.data_ptr<float>():nullptr), *p_c0=(has?c0.data_ptr<float>():nullptr); float *p_buf1=buf1.data_ptr<float>(), *p_buf2=buf2.data_ptr<float>(), *p_g=gates.data_ptr<float>(), *p_hs=hs.data_ptr<float>(), *p_cs=cs.data_ptr<float>(), *p_out=out.data_ptr<float>();\n void* args[]={&xp,&p_wih0,&p_whh0,&p_bih0,&p_bhh0,&p_wih1,&p_whh1,&p_bih1,&p_bhh1,&p_wih2,&p_whh2,&p_bih2,&p_bhh2,&p_wih3,&p_whh3,&p_bih3,&p_bhh3,&p_wih4,&p_whh4,&p_bih4,&p_bhh4,&p_wih5,&p_whh5,&p_bih5,&p_bhh5,&p_fcw,&p_fcb,&p_h0,&p_c0,&has,&p_buf1,&p_buf2,&p_g,&p_hs,&p_cs,&p_out};\n cudaLaunchCooperativeKernel((void*)kern, dim3(240), dim3(256), args, 0, at::cuda::getCurrentCUDAStream()); return out;\n}\n'''\n_ext = load_inline(name='lstm_custom_ext_v2', cpp_sources=_cpp_src, cuda_sources=_cuda_src, functions=['lstm_forward'], extra_cflags=['-O3'], extra_cuda_cflags=['-O3'], verbose=False)\nclass ModelNew(nn.Module):\n def __init__(self, input_size, hidden_size, num_layers, output_size, dropout=0.0):\n super(ModelNew,self).__init__(); self.hidden_size=hidden_size; self.num_layers=num_layers\n self.lstm=nn.LSTM(input_size,hidden_size,num_layers,batch_first=True,dropout=dropout,bidirectional=False); self.fc=nn.Linear(hidden_size,output_size); self._empty=None\n def forward(self,x,h0=None,c0=None):\n if self._empty is None or self._empty.device!=x.device: self._empty=torch.empty(0,device=x.device,dtype=x.dtype)\n if h0 is None: h0=self._empty\n if c0 is None: c0=self._empty\n return _ext.lstm_forward(x,self.lstm.weight_ih_l0,self.lstm.weight_hh_l0,self.lstm.bias_ih_l0,self.lstm.bias_hh_l0,self.lstm.weight_ih_l1,self.lstm.weight_hh_l1,self.lstm.bias_ih_l1,self.lstm.bias_hh_l1,self.lstm.weight_ih_l2,self.lstm.weight_hh_l2,self.lstm.bias_ih_l2,self.lstm.bias_hh_l2,self.lstm.weight_ih_l3,self.lstm.weight_hh_l3,self.lstm.bias_ih_l3,self.lstm.bias_hh_l3,self.lstm.weight_ih_l4,self.lstm.weight_hh_l4,self.lstm.bias_ih_l4,self.lstm.bias_hh_l4,self.lstm.weight_ih_l5,self.lstm.weight_hh_l5,self.lstm.bias_ih_l5,self.lstm.bias_hh_l5,self.fc.weight,self.fc.bias,h0,c0)\n"
}