call → run_correctness
callrun_correctness
{
"kernel_code": "import torch\nimport torch.nn as nn\nfrom torch.utils.cpp_extension import load_inline\n_cpp_src = r'''\n#include <torch/extension.h>\ntorch::Tensor lstm_forward(torch::Tensor x, torch::Tensor h0, torch::Tensor c0,\n torch::Tensor wih0, torch::Tensor whh0, torch::Tensor bih0, torch::Tensor bhh0,\n torch::Tensor wih1, torch::Tensor whh1, torch::Tensor bih1, torch::Tensor bhh1,\n torch::Tensor wih2, torch::Tensor whh2, torch::Tensor bih2, torch::Tensor bhh2,\n torch::Tensor wih3, torch::Tensor whh3, torch::Tensor bih3, torch::Tensor bhh3,\n torch::Tensor wih4, torch::Tensor whh4, torch::Tensor bih4, torch::Tensor bhh4,\n torch::Tensor wih5, torch::Tensor whh5, torch::Tensor bih5, torch::Tensor bhh5);\n'''\n_cuda_src = r'''\n#include <torch/extension.h>\n#include <ATen/cuda/CUDAContext.h>\n#include <cuda_runtime.h>\n#include <cooperative_groups.h>\n#include <math.h>\nnamespace cg = cooperative_groups;\n#define HSIZE 256\n#define BSIZE 10\n#define TSIZE 512\n#define LAYERS 6\n#define THREADS 64\n#define HGRP 4\n__device__ __forceinline__ float sigm(float x) { return 1.0f/(1.0f+expf(-x)); }\n__device__ __forceinline__ float warp_sum(float v){\n v += __shfl_down_sync(0xffffffff, v, 16);\n v += __shfl_down_sync(0xffffffff, v, 8);\n v += __shfl_down_sync(0xffffffff, v, 4);\n v += __shfl_down_sync(0xffffffff, v, 2);\n v += __shfl_down_sync(0xffffffff, v, 1);\n return v;\n}\n__global__ void lstm_kernel(const float* __restrict__ x, const float* __restrict__ h0, const float* __restrict__ c0,\n const float* __restrict__ wih0,const float* __restrict__ whh0,const float* __restrict__ bih0,const float* __restrict__ bhh0,\n const float* __restrict__ wih1,const float* __restrict__ whh1,const float* __restrict__ bih1,const float* __restrict__ bhh1,\n const float* __restrict__ wih2,const float* __restrict__ whh2,const float* __restrict__ bih2,const float* __restrict__ bhh2,\n const float* __restrict__ wih3,const float* __restrict__ whh3,const float* __restrict__ bih3,const float* __restrict__ bhh3,\n const float* __restrict__ wih4,const float* __restrict__ whh4,const float* __restrict__ bih4,const float* __restrict__ bhh4,\n const float* __restrict__ wih5,const float* __restrict__ whh5,const float* __restrict__ bih5,const float* __restrict__ bhh5,\n float* __restrict__ workspace, float* __restrict__ hbuf, float* __restrict__ hn) {\n cg::grid_group grid = cg::this_grid();\n int groups = HSIZE/HGRP;\n int b = blockIdx.x / groups;\n int hbase = (blockIdx.x - b*groups) * HGRP;\n int tid = threadIdx.x, lane=tid&31, warp=tid>>5;\n __shared__ float sh[4][2];\n float cval[HGRP];\n for(int layer=0; layer<LAYERS; ++layer){\n const float *wih,*whh,*bih,*bhh; int K;\n if(layer==0){wih=wih0;whh=whh0;bih=bih0;bhh=bhh0;K=128;}\n else if(layer==1){wih=wih1;whh=whh1;bih=bih1;bhh=bhh1;K=HSIZE;}\n else if(layer==2){wih=wih2;whh=whh2;bih=bih2;bhh=bhh2;K=HSIZE;}\n else if(layer==3){wih=wih3;whh=whh3;bih=bih3;bhh=bhh3;K=HSIZE;}\n else if(layer==4){wih=wih4;whh=whh4;bih=bih4;bhh=bhh4;K=HSIZE;}\n else {wih=wih5;whh=whh5;bih=bih5;bhh=bhh5;K=HSIZE;}\n int hcur=layer&1, hnxt=hcur^1;\n if(tid==0){\n #pragma unroll\n for(int q=0;q<HGRP;++q){ int h=hbase+q; hbuf[(hcur*BSIZE+b)*HSIZE+h]=h0[(layer*BSIZE+b)*HSIZE+h]; cval[q]=c0[(layer*BSIZE+b)*HSIZE+h]; }\n }\n grid.sync();\n int inbuf=(layer-1)&1, outbuf=layer&1;\n for(int t=0;t<TSIZE;++t){\n #pragma unroll\n for(int q=0;q<HGRP;++q){\n int h=hbase+q;\n float si=0.f,sf=0.f,sg=0.f,so=0.f;\n for(int k=tid;k<K;k+=THREADS){\n float xv = (layer==0) ? x[(b*TSIZE+t)*128+k] : workspace[((inbuf*TSIZE+t)*BSIZE+b)*HSIZE+k];\n si += xv*wih[h*K+k]; sf += xv*wih[(HSIZE+h)*K+k];\n sg += xv*wih[(2*HSIZE+h)*K+k]; so += xv*wih[(3*HSIZE+h)*K+k];\n }\n for(int k=tid;k<HSIZE;k+=THREADS){\n float hv=hbuf[(hcur*BSIZE+b)*HSIZE+k];\n si += hv*whh[h*HSIZE+k]; sf += hv*whh[(HSIZE+h)*HSIZE+k];\n sg += hv*whh[(2*HSIZE+h)*HSIZE+k]; so += hv*whh[(3*HSIZE+h)*HSIZE+k];\n }\n si=warp_sum(si); sf=warp_sum(sf); sg=warp_sum(sg); so=warp_sum(so);\n if(lane==0){ sh[0][warp]=si; sh[1][warp]=sf; sh[2][warp]=sg; sh[3][warp]=so; }\n __syncthreads();\n if(tid==0){\n float ai=sh[0][0]+sh[0][1], af=sh[1][0]+sh[1][1], ag=sh[2][0]+sh[2][1], ao=sh[3][0]+sh[3][1];\n ai += bih[h]+bhh[h]; af += bih[HSIZE+h]+bhh[HSIZE+h]; ag += bih[2*HSIZE+h]+bhh[2*HSIZE+h]; ao += bih[3*HSIZE+h]+bhh[3*HSIZE+h];\n float ig=sigm(ai), fg=sigm(af), gg=tanhf(ag), og=sigm(ao);\n cval[q]=fg*cval[q]+ig*gg; float hnew=og*tanhf(cval[q]);\n hbuf[(hnxt*BSIZE+b)*HSIZE+h]=hnew; workspace[((outbuf*TSIZE+t)*BSIZE+b)*HSIZE+h]=hnew;\n }\n __syncthreads();\n }\n grid.sync(); int tmp=hcur; hcur=hnxt; hnxt=tmp;\n }\n if(tid==0){\n #pragma unroll\n for(int q=0;q<HGRP;++q){ int h=hbase+q; hn[(layer*BSIZE+b)*HSIZE+h]=hbuf[(hcur*BSIZE+b)*HSIZE+h]; }\n }\n grid.sync();\n }\n}\n\ntorch::Tensor lstm_forward(torch::Tensor x, torch::Tensor h0, torch::Tensor c0,\n torch::Tensor wih0, torch::Tensor whh0, torch::Tensor bih0, torch::Tensor bhh0,\n torch::Tensor wih1, torch::Tensor whh1, torch::Tensor bih1, torch::Tensor bhh1,\n torch::Tensor wih2, torch::Tensor whh2, torch::Tensor bih2, torch::Tensor bhh2,\n torch::Tensor wih3, torch::Tensor whh3, torch::Tensor bih3, torch::Tensor bhh3,\n torch::Tensor wih4, torch::Tensor whh4, torch::Tensor bih4, torch::Tensor bhh4,\n torch::Tensor wih5, torch::Tensor whh5, torch::Tensor bih5, torch::Tensor bhh5){\n auto hn=torch::empty({LAYERS,BSIZE,HSIZE}, x.options());\n auto workspace=torch::empty({2,TSIZE,BSIZE,HSIZE}, x.options());\n auto hbuf=torch::empty({2,BSIZE,HSIZE}, x.options());\n const float *xp=x.data_ptr<float>(), *h0p=h0.data_ptr<float>(), *c0p=c0.data_ptr<float>();\n const float *pwih0=wih0.data_ptr<float>(),*pwhh0=whh0.data_ptr<float>(),*pbih0=bih0.data_ptr<float>(),*pbhh0=bhh0.data_ptr<float>();\n const float *pwih1=wih1.data_ptr<float>(),*pwhh1=whh1.data_ptr<float>(),*pbih1=bih1.data_ptr<float>(),*pbhh1=bhh1.data_ptr<float>();\n const float *pwih2=wih2.data_ptr<float>(),*pwhh2=whh2.data_ptr<float>(),*pbih2=bih2.data_ptr<float>(),*pbhh2=bhh2.data_ptr<float>();\n const float *pwih3=wih3.data_ptr<float>(),*pwhh3=whh3.data_ptr<float>(),*pbih3=bih3.data_ptr<float>(),*pbhh3=bhh3.data_ptr<float>();\n const float *pwih4=wih4.data_ptr<float>(),*pwhh4=whh4.data_ptr<float>(),*pbih4=bih4.data_ptr<float>(),*pbhh4=bhh4.data_ptr<float>();\n const float *pwih5=wih5.data_ptr<float>(),*pwhh5=whh5.data_ptr<float>(),*pbih5=bih5.data_ptr<float>(),*pbhh5=bhh5.data_ptr<float>();\n float *wsp=workspace.data_ptr<float>(), *hbp=hbuf.data_ptr<float>(), *hnp=hn.data_ptr<float>();\n void* args[]={&xp,&h0p,&c0p,&pwih0,&pwhh0,&pbih0,&pbhh0,&pwih1,&pwhh1,&pbih1,&pbhh1,&pwih2,&pwhh2,&pbih2,&pbhh2,&pwih3,&pwhh3,&pbih3,&pbhh3,&pwih4,&pwhh4,&pbih4,&pbhh4,&pwih5,&pwhh5,&pbih5,&pbhh5,&wsp,&hbp,&hnp};\n cudaLaunchCooperativeKernel((void*)lstm_kernel, dim3(BSIZE*(HSIZE/HGRP)), dim3(THREADS), args, 0, at::cuda::getCurrentCUDAStream());\n C10_CUDA_KERNEL_LAUNCH_CHECK(); return hn;\n}\n'''\n_ext = load_inline(name='lstm_coop_ext_v3', cpp_sources=[_cpp_src], cuda_sources=[_cuda_src], functions=['lstm_forward'], extra_cuda_cflags=['-O3'], extra_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().__init__(); 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)\n def forward(self,x,h0,c0):\n return _ext.lstm_forward(x.contiguous(),h0.contiguous(),c0.contiguous(),\n self.lstm.weight_ih_l0.contiguous(),self.lstm.weight_hh_l0.contiguous(),self.lstm.bias_ih_l0.contiguous(),self.lstm.bias_hh_l0.contiguous(),\n self.lstm.weight_ih_l1.contiguous(),self.lstm.weight_hh_l1.contiguous(),self.lstm.bias_ih_l1.contiguous(),self.lstm.bias_hh_l1.contiguous(),\n self.lstm.weight_ih_l2.contiguous(),self.lstm.weight_hh_l2.contiguous(),self.lstm.bias_ih_l2.contiguous(),self.lstm.bias_hh_l2.contiguous(),\n self.lstm.weight_ih_l3.contiguous(),self.lstm.weight_hh_l3.contiguous(),self.lstm.bias_ih_l3.contiguous(),self.lstm.bias_hh_l3.contiguous(),\n self.lstm.weight_ih_l4.contiguous(),self.lstm.weight_hh_l4.contiguous(),self.lstm.bias_ih_l4.contiguous(),self.lstm.bias_hh_l4.contiguous(),\n self.lstm.weight_ih_l5.contiguous(),self.lstm.weight_hh_l5.contiguous(),self.lstm.bias_ih_l5.contiguous(),self.lstm.bias_hh_l5.contiguous())\n"
}