call → submit_kernel
callsubmit_kernel
{
"kernel_code": "import math\nimport torch\nimport torch.nn as nn\nfrom torch.utils.cpp_extension import load_inline\n\n_cpp_src = r\"\"\"\n#include <torch/extension.h>\n\nat::Tensor gf_forward(\n at::Tensor nodes,\n at::Tensor pair_feats,\n at::Tensor edge_mask,\n at::Tensor norm_w,\n at::Tensor norm_b,\n at::Tensor q_w,\n at::Tensor k_w,\n at::Tensor v_w,\n at::Tensor rel1_w,\n at::Tensor rel1_b,\n at::Tensor rel2_w,\n at::Tensor rel2_b,\n at::Tensor out_w,\n double eps,\n double scale);\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 <cmath>\n\n#define D 96\n#define N 24\n#define H 4\n#define HD 24\n#define P 16\n\n__global__ void ln_qkv_kernel(\n const float* __restrict__ nodes,\n const float* __restrict__ gamma,\n const float* __restrict__ beta,\n const float* __restrict__ qw,\n const float* __restrict__ kw,\n const float* __restrict__ vw,\n float* __restrict__ q,\n float* __restrict__ k,\n float* __restrict__ v,\n int B,\n float eps) {\n\n int idx = blockIdx.x; // B*N\n int b = idx / N;\n int n = idx - b * N;\n int tid = threadIdx.x;\n __shared__ float hbuf[D];\n __shared__ float mean_s;\n __shared__ float invstd_s;\n\n const float* x = nodes + (b * N + n) * D;\n if (tid == 0) {\n float m = 0.0f;\n #pragma unroll\n for (int i = 0; i < D; ++i) m += x[i];\n m *= (1.0f / (float)D);\n float var = 0.0f;\n #pragma unroll\n for (int i = 0; i < D; ++i) {\n float d = x[i] - m;\n var += d * d;\n }\n var *= (1.0f / (float)D);\n mean_s = m;\n invstd_s = rsqrtf(var + eps);\n }\n __syncthreads();\n\n if (tid < D) {\n hbuf[tid] = (x[tid] - mean_s) * invstd_s * gamma[tid] + beta[tid];\n }\n __syncthreads();\n\n if (tid < D) {\n float sq = 0.0f, sk = 0.0f, sv = 0.0f;\n const float* wq = qw + tid * D;\n const float* wk = kw + tid * D;\n const float* wv = vw + tid * D;\n #pragma unroll\n for (int e = 0; e < D; ++e) {\n float hv = hbuf[e];\n sq += hv * wq[e];\n sk += hv * wk[e];\n sv += hv * wv[e];\n }\n int hh = tid / HD;\n int dd = tid - hh * HD;\n int o = ((b * H + hh) * N + n) * HD + dd;\n q[o] = sq;\n k[o] = sk;\n v[o] = sv;\n }\n}\n\n__global__ void attn_kernel(\n const float* __restrict__ q,\n const float* __restrict__ k,\n const float* __restrict__ v,\n const float* __restrict__ pair_feats,\n const float* __restrict__ edge_mask,\n const float* __restrict__ r1w,\n const float* __restrict__ r1b,\n const float* __restrict__ r2w,\n const float* __restrict__ r2b,\n float* __restrict__ ctx,\n int B,\n float scale) {\n\n int b = blockIdx.x;\n int h = blockIdx.y;\n int i = blockIdx.z;\n int tid = threadIdx.x;\n\n __shared__ float logits[N];\n __shared__ float denom_s;\n\n if (tid < N) {\n int j = tid;\n float logit;\n float mask = edge_mask[(b * N + i) * N + j];\n if (mask < 0.5f) {\n logit = -INFINITY;\n } else {\n const float* qv = q + ((b * H + h) * N + i) * HD;\n const float* kv = k + ((b * H + h) * N + j) * HD;\n float dot = 0.0f;\n #pragma unroll\n for (int d = 0; d < HD; ++d) dot += qv[d] * kv[d];\n\n const float* pf = pair_feats + ((b * N + i) * N + j) * P;\n float hidden[P];\n #pragma unroll\n for (int r = 0; r < P; ++r) {\n float z = r1b[r];\n const float* wr = r1w + r * P;\n #pragma unroll\n for (int p = 0; p < P; ++p) z += pf[p] * wr[p];\n hidden[r] = z / (1.0f + expf(-z));\n }\n float rb = r2b[h];\n const float* w2 = r2w + h * P;\n #pragma unroll\n for (int r = 0; r < P; ++r) rb += hidden[r] * w2[r];\n logit = dot * scale + rb;\n }\n logits[j] = logit;\n }\n __syncthreads();\n\n if (tid == 0) {\n float m = logits[0];\n #pragma unroll\n for (int j = 1; j < N; ++j) m = fmaxf(m, logits[j]);\n float s = 0.0f;\n #pragma unroll\n for (int j = 0; j < N; ++j) {\n float a = expf(logits[j] - m);\n logits[j] = a;\n s += a;\n }\n denom_s = 1.0f / s;\n }\n __syncthreads();\n\n if (tid < HD) {\n float val = 0.0f;\n #pragma unroll\n for (int j = 0; j < N; ++j) {\n float a = logits[j] * denom_s;\n val += a * v[((b * H + h) * N + j) * HD + tid];\n }\n ctx[(b * N + i) * D + h * HD + tid] = val;\n }\n}\n\n__global__ void out_kernel(\n const float* __restrict__ nodes,\n const float* __restrict__ ctx,\n const float* __restrict__ ow,\n float* __restrict__ out,\n int B) {\n int idx = blockIdx.x;\n int b = idx / N;\n int n = idx - b * N;\n int tid = threadIdx.x;\n if (tid < D) {\n const float* c = ctx + (b * N + n) * D;\n const float* w = ow + tid * D;\n float sum = 0.0f;\n #pragma unroll\n for (int e = 0; e < D; ++e) sum += c[e] * w[e];\n int o = (b * N + n) * D + tid;\n out[o] = nodes[o] + sum;\n }\n}\n\nat::Tensor gf_forward(\n at::Tensor nodes,\n at::Tensor pair_feats,\n at::Tensor edge_mask,\n at::Tensor norm_w,\n at::Tensor norm_b,\n at::Tensor q_w,\n at::Tensor k_w,\n at::Tensor v_w,\n at::Tensor rel1_w,\n at::Tensor rel1_b,\n at::Tensor rel2_w,\n at::Tensor rel2_b,\n at::Tensor out_w,\n double eps,\n double scale) {\n\n const int B = (int)nodes.size(0);\n auto opts = nodes.options();\n auto q = at::empty({B, H, N, HD}, opts);\n auto k = at::empty({B, H, N, HD}, opts);\n auto v = at::empty({B, H, N, HD}, opts);\n auto ctx = at::empty({B, N, D}, opts);\n auto out = at::empty({B, N, D}, opts);\n\n at::cuda::CUDAGuard device_guard(nodes.device());\n cudaStream_t stream = at::cuda::getCurrentCUDAStream();\n\n ln_qkv_kernel<<<B * N, 128, 0, stream>>>(\n nodes.data_ptr<float>(), norm_w.data_ptr<float>(), norm_b.data_ptr<float>(),\n q_w.data_ptr<float>(), k_w.data_ptr<float>(), v_w.data_ptr<float>(),\n q.data_ptr<float>(), k.data_ptr<float>(), v.data_ptr<float>(), B, (float)eps);\n\n dim3 grid(B, H, N);\n attn_kernel<<<grid, 32, 0, stream>>>(\n q.data_ptr<float>(), k.data_ptr<float>(), v.data_ptr<float>(),\n pair_feats.data_ptr<float>(), edge_mask.data_ptr<float>(),\n rel1_w.data_ptr<float>(), rel1_b.data_ptr<float>(),\n rel2_w.data_ptr<float>(), rel2_b.data_ptr<float>(),\n ctx.data_ptr<float>(), B, (float)scale);\n\n out_kernel<<<B * N, 128, 0, stream>>>(\n nodes.data_ptr<float>(), ctx.data_ptr<float>(), out_w.data_ptr<float>(), out.data_ptr<float>(), B);\n\n return out;\n}\n\"\"\"\n\n_ext = load_inline(\n name=\"gf_vla_fused_ext\",\n cpp_sources=_cpp_src,\n cuda_sources=_cuda_src,\n functions=[\"gf_forward\"],\n extra_cflags=[\"-O3\"],\n extra_cuda_cflags=[\"-O3\"],\n with_cuda=True,\n verbose=False,\n)\n\n\nclass ModelNew(nn.Module):\n def __init__(self, dim: int, pair_dim: int, num_heads: int):\n super().__init__()\n assert dim % num_heads == 0\n self.dim = dim\n self.pair_dim = pair_dim\n self.num_heads = num_heads\n self.head_dim = dim // num_heads\n self.scale = 1.0 / math.sqrt(self.head_dim)\n self.norm = nn.LayerNorm(dim)\n self.q_proj = nn.Linear(dim, dim, bias=False)\n self.k_proj = nn.Linear(dim, dim, bias=False)\n self.v_proj = nn.Linear(dim, dim, bias=False)\n self.rel_mlp = nn.Sequential(\n nn.Linear(pair_dim, pair_dim),\n nn.SiLU(),\n nn.Linear(pair_dim, num_heads),\n )\n self.out_proj = nn.Linear(dim, dim, bias=False)\n\n def forward(self, nodes: torch.Tensor, pair_feats: torch.Tensor, edge_mask: torch.Tensor) -> torch.Tensor:\n return _ext.gf_forward(\n nodes,\n pair_feats,\n edge_mask,\n self.norm.weight,\n self.norm.bias,\n self.q_proj.weight,\n self.k_proj.weight,\n self.v_proj.weight,\n self.rel_mlp[0].weight,\n self.rel_mlp[0].bias,\n self.rel_mlp[2].weight,\n self.rel_mlp[2].bias,\n self.out_proj.weight,\n self.norm.eps,\n self.scale,\n )\n"
}