call → compile_kernel
callcompile_kernel
{
"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>\ntorch::Tensor tri_forward_cuda(torch::Tensor pair_repr, torch::Tensor pair_mask, torch::Tensor ln_in_w, torch::Tensor ln_in_b, torch::Tensor proj_a_w, torch::Tensor proj_a_b, torch::Tensor gate_a_w, torch::Tensor gate_a_b, torch::Tensor proj_b_w, torch::Tensor proj_b_b, torch::Tensor gate_b_w, torch::Tensor gate_b_b, torch::Tensor ln_out_w, torch::Tensor ln_out_b, torch::Tensor out_proj_w, torch::Tensor out_proj_b, torch::Tensor out_gate_w, torch::Tensor out_gate_b);\n'''\n\ncuda_src = r'''\n#include <torch/extension.h>\n#include <cuda.h>\n#include <cuda_runtime.h>\n#define C_DIM 64\n#define H_DIM 32\n#define EPS 1.0e-5f\n__device__ __forceinline__ float sigmoidf_fast(float x) { return 1.0f / (1.0f + expf(-x)); }\n\n__global__ void ln_proj_kernel(const float* __restrict__ x, const float* __restrict__ mask, const float* __restrict__ ln_w, const float* __restrict__ ln_b, const float* __restrict__ pa_w, const float* __restrict__ pa_b, const float* __restrict__ ga_w, const float* __restrict__ ga_b, const float* __restrict__ pb_w, const float* __restrict__ pb_b, const float* __restrict__ gb_w, const float* __restrict__ gb_b, float* __restrict__ a, float* __restrict__ b) {\n int row = blockIdx.x, tid = threadIdx.x;\n __shared__ float red[64]; __shared__ float xn[C_DIM]; __shared__ float mean_s, rstd_s;\n float val = x[row*C_DIM + tid]; red[tid] = val; __syncthreads();\n for (int off=32; off>0; off>>=1) { if (tid < off) red[tid] += red[tid+off]; __syncthreads(); }\n if (tid == 0) mean_s = red[0] * (1.0f/C_DIM); __syncthreads();\n float d0 = val - mean_s; red[tid] = d0*d0; __syncthreads();\n for (int off=32; off>0; off>>=1) { if (tid < off) red[tid] += red[tid+off]; __syncthreads(); }\n if (tid == 0) rstd_s = rsqrtf(red[0] * (1.0f/C_DIM) + EPS); __syncthreads();\n xn[tid] = d0 * rstd_s * ln_w[tid] + ln_b[tid]; __syncthreads();\n if (tid < H_DIM) {\n int h = tid; float pa=pa_b[h], ga=ga_b[h], pb=pb_b[h], gb=gb_b[h];\n #pragma unroll\n for (int d=0; d<C_DIM; ++d) { float xv=xn[d]; pa=fmaf(xv,pa_w[h*C_DIM+d],pa); ga=fmaf(xv,ga_w[h*C_DIM+d],ga); pb=fmaf(xv,pb_w[h*C_DIM+d],pb); gb=fmaf(xv,gb_w[h*C_DIM+d],gb); }\n float m = mask[row];\n a[row*H_DIM+h] = pa * sigmoidf_fast(ga) * m; b[row*H_DIM+h] = pb * sigmoidf_fast(gb) * m;\n }\n}\n\n__global__ void tri_einsum_kernel(const float* __restrict__ a, const float* __restrict__ b, float* __restrict__ out, int B, int N) {\n int idx=blockIdx.x*blockDim.x+threadIdx.x; int total=B*N*N*H_DIM; if(idx>=total) return;\n int h=idx & 31; int t=idx>>5; int j=t%N; t/=N; int i=t%N; int batch=t/N;\n int base_i=(batch*N+i)*N, base_j=(batch*N+j)*N; float sum=0.0f;\n #pragma unroll\n for(int k=0;k<32;++k) sum=fmaf(a[(base_i+k)*H_DIM+h], b[(base_j+k)*H_DIM+h], sum);\n out[idx]=sum;\n}\n\n__global__ void out_kernel(const float* __restrict__ inter, const float* __restrict__ pair, const float* __restrict__ ln_w, const float* __restrict__ ln_b, const float* __restrict__ op_w, const float* __restrict__ op_b, const float* __restrict__ og_w, const float* __restrict__ og_b, float* __restrict__ y) {\n int row=blockIdx.x, tid=threadIdx.x;\n __shared__ float red[64]; __shared__ float xn[H_DIM]; __shared__ float mean_s, rstd_s;\n float v = (tid < H_DIM) ? inter[row*H_DIM+tid] : 0.0f; red[tid]=v; __syncthreads();\n for(int off=32; off>0; off>>=1){ if(tid<off) red[tid]+=red[tid+off]; __syncthreads(); }\n if(tid==0) mean_s=red[0]*(1.0f/H_DIM); __syncthreads();\n float dv = (tid < H_DIM) ? (inter[row*H_DIM+tid]-mean_s) : 0.0f; red[tid]=dv*dv; __syncthreads();\n for(int off=32; off>0; off>>=1){ if(tid<off) red[tid]+=red[tid+off]; __syncthreads(); }\n if(tid==0) rstd_s=rsqrtf(red[0]*(1.0f/H_DIM)+EPS); __syncthreads();\n if(tid < H_DIM) xn[tid]=dv*rstd_s*ln_w[tid]+ln_b[tid]; __syncthreads();\n int c=tid; float op=op_b[c];\n #pragma unroll\n for(int h=0; h<H_DIM; ++h) op=fmaf(xn[h], op_w[c*H_DIM+h], op);\n float og=og_b[c];\n #pragma unroll\n for(int d=0; d<C_DIM; ++d) og=fmaf(pair[row*C_DIM+d], og_w[c*C_DIM+d], og);\n y[row*C_DIM+c]=sigmoidf_fast(og)*op;\n}\n\ntorch::Tensor tri_forward_cuda(torch::Tensor pair_repr, torch::Tensor pair_mask, torch::Tensor ln_in_w, torch::Tensor ln_in_b, torch::Tensor proj_a_w, torch::Tensor proj_a_b, torch::Tensor gate_a_w, torch::Tensor gate_a_b, torch::Tensor proj_b_w, torch::Tensor proj_b_b, torch::Tensor gate_b_w, torch::Tensor gate_b_b, torch::Tensor ln_out_w, torch::Tensor ln_out_b, torch::Tensor out_proj_w, torch::Tensor out_proj_b, torch::Tensor out_gate_w, torch::Tensor out_gate_b) {\n int B=pair_repr.size(0), N=pair_repr.size(1), rows=B*N*N; auto opts=pair_repr.options();\n auto a=torch::empty({B,N,N,H_DIM}, opts); auto b=torch::empty({B,N,N,H_DIM}, opts); auto inter=torch::empty({B,N,N,H_DIM}, opts); auto y=torch::empty_like(pair_repr);\n ln_proj_kernel<<<rows,64>>>(pair_repr.data_ptr<float>(), pair_mask.data_ptr<float>(), ln_in_w.data_ptr<float>(), ln_in_b.data_ptr<float>(), proj_a_w.data_ptr<float>(), proj_a_b.data_ptr<float>(), gate_a_w.data_ptr<float>(), gate_a_b.data_ptr<float>(), proj_b_w.data_ptr<float>(), proj_b_b.data_ptr<float>(), gate_b_w.data_ptr<float>(), gate_b_b.data_ptr<float>(), a.data_ptr<float>(), b.data_ptr<float>());\n int total=B*N*N*H_DIM; tri_einsum_kernel<<<(total+255)/256,256>>>(a.data_ptr<float>(), b.data_ptr<float>(), inter.data_ptr<float>(), B, N);\n out_kernel<<<rows,64>>>(inter.data_ptr<float>(), pair_repr.data_ptr<float>(), ln_out_w.data_ptr<float>(), ln_out_b.data_ptr<float>(), out_proj_w.data_ptr<float>(), out_proj_b.data_ptr<float>(), out_gate_w.data_ptr<float>(), out_gate_b.data_ptr<float>(), y.data_ptr<float>());\n return y;\n}\n'''\n_tri_ext = load_inline(name='tri_mul_outgoing_ext_v2', cpp_sources=cpp_src, cuda_sources=cuda_src, functions=['tri_forward_cuda'], verbose=False, extra_cuda_cflags=['-O3','--use_fast_math'])\nclass ModelNew(nn.Module):\n def __init__(self, pair_dim, hidden_dim):\n super().__init__(); self.layer_norm_in=nn.LayerNorm(pair_dim); self.proj_a=nn.Linear(pair_dim, hidden_dim); self.gate_a=nn.Linear(pair_dim, hidden_dim); self.proj_b=nn.Linear(pair_dim, hidden_dim); self.gate_b=nn.Linear(pair_dim, hidden_dim); self.layer_norm_out=nn.LayerNorm(hidden_dim); self.out_proj=nn.Linear(hidden_dim, pair_dim); self.out_gate=nn.Linear(pair_dim, pair_dim)\n def forward(self, pair_repr: torch.Tensor, pair_mask: torch.Tensor) -> torch.Tensor:\n return _tri_ext.tri_forward_cuda(pair_repr, pair_mask, self.layer_norm_in.weight, self.layer_norm_in.bias, self.proj_a.weight, self.proj_a.bias, self.gate_a.weight, self.gate_a.bias, self.proj_b.weight, self.proj_b.bias, self.gate_b.weight, self.gate_b.bias, self.layer_norm_out.weight, self.layer_norm_out.bias, self.out_proj.weight, self.out_proj.bias, self.out_gate.weight, self.out_gate.bias)\n"
}