call → submit_kernel
callsubmit_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>\n#include <vector>\nstd::vector<torch::Tensor> cvae_forward(torch::Tensor x, torch::Tensor y, torch::Tensor enc_wt, torch::Tensor enc_b, torch::Tensor mu_wt, torch::Tensor mu_b, torch::Tensor logvar_wt, torch::Tensor logvar_b, torch::Tensor dec0_wt, torch::Tensor dec0_b, torch::Tensor dec2_wt, torch::Tensor dec2_b);\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 <vector>\n\n#define INPUT_DIM 256\n#define LABEL_DIM 10\n#define HIDDEN_DIM 128\n#define LATENT_DIM 32\n\n__global__ __launch_bounds__(256, 2) void cvae_main_kernel(\n const float* __restrict__ x,\n const float* __restrict__ y,\n const float* __restrict__ eps,\n const float* __restrict__ enc_wt,\n const float* __restrict__ enc_b,\n const float* __restrict__ mu_wt,\n const float* __restrict__ mu_b,\n const float* __restrict__ logvar_wt,\n const float* __restrict__ logvar_b,\n const float* __restrict__ dec0_wt,\n const float* __restrict__ dec0_b,\n const float* __restrict__ dec2_wt,\n const float* __restrict__ dec2_b,\n float* __restrict__ partial,\n int B) {\n\n const int b = blockIdx.x;\n const int tid = threadIdx.x;\n\n __shared__ float h[HIDDEN_DIM];\n __shared__ float z[LATENT_DIM];\n __shared__ float dh[HIDDEN_DIM];\n __shared__ float red[256];\n\n const float* xb = x + b * INPUT_DIM;\n const float* yb = y + b * LABEL_DIM;\n\n if (tid < HIDDEN_DIM) {\n float s = enc_b[tid];\n #pragma unroll 4\n for (int i = 0; i < INPUT_DIM; ++i) {\n s = fmaf(xb[i], enc_wt[i * HIDDEN_DIM + tid], s);\n }\n #pragma unroll\n for (int l = 0; l < LABEL_DIM; ++l) {\n s = fmaf(yb[l], enc_wt[(INPUT_DIM + l) * HIDDEN_DIM + tid], s);\n }\n h[tid] = s > 0.0f ? s : 0.0f;\n }\n __syncthreads();\n\n float kval = 0.0f;\n if (tid < LATENT_DIM) {\n float sm = mu_b[tid];\n float sl = logvar_b[tid];\n #pragma unroll 4\n for (int j = 0; j < HIDDEN_DIM; ++j) {\n float hv = h[j];\n sm = fmaf(hv, mu_wt[j * LATENT_DIM + tid], sm);\n sl = fmaf(hv, logvar_wt[j * LATENT_DIM + tid], sl);\n }\n z[tid] = sm + expf(0.5f * sl) * eps[b * LATENT_DIM + tid];\n kval = -0.5f * (1.0f + sl - sm * sm - expf(sl));\n }\n\n red[tid] = (tid < LATENT_DIM) ? kval : 0.0f;\n __syncthreads();\n for (int off = 128; off > 0; off >>= 1) {\n if (tid < off) red[tid] += red[tid + off];\n __syncthreads();\n }\n if (tid == 0) partial[B + b] = red[0];\n __syncthreads();\n\n if (tid < HIDDEN_DIM) {\n float s = dec0_b[tid];\n #pragma unroll\n for (int k = 0; k < LATENT_DIM; ++k) {\n s = fmaf(z[k], dec0_wt[k * HIDDEN_DIM + tid], s);\n }\n #pragma unroll\n for (int l = 0; l < LABEL_DIM; ++l) {\n s = fmaf(yb[l], dec0_wt[(LATENT_DIM + l) * HIDDEN_DIM + tid], s);\n }\n dh[tid] = s > 0.0f ? s : 0.0f;\n }\n __syncthreads();\n\n float r = 0.0f;\n if (tid < INPUT_DIM) {\n float s = dec2_b[tid];\n #pragma unroll 4\n for (int j = 0; j < HIDDEN_DIM; ++j) {\n s = fmaf(dh[j], dec2_wt[j * INPUT_DIM + tid], s);\n }\n float d = s - xb[tid];\n r = d * d;\n }\n\n red[tid] = r;\n __syncthreads();\n for (int off = 128; off > 0; off >>= 1) {\n if (tid < off) red[tid] += red[tid + off];\n __syncthreads();\n }\n if (tid == 0) partial[b] = red[0];\n}\n\n__global__ void cvae_final_reduce_kernel(const float* __restrict__ partial, float* __restrict__ out, int B) {\n int tid = threadIdx.x;\n __shared__ float red[256];\n\n float s = 0.0f;\n for (int i = tid; i < B; i += blockDim.x) s += partial[i];\n red[tid] = s;\n __syncthreads();\n for (int off = 128; off > 0; off >>= 1) {\n if (tid < off) red[tid] += red[tid + off];\n __syncthreads();\n }\n float recon = red[0] / (float)B;\n\n s = 0.0f;\n for (int i = tid; i < B; i += blockDim.x) s += partial[B + i];\n red[tid] = s;\n __syncthreads();\n for (int off = 128; off > 0; off >>= 1) {\n if (tid < off) red[tid] += red[tid + off];\n __syncthreads();\n }\n\n if (tid == 0) {\n float kl = red[0] / (float)B;\n out[0] = recon + kl;\n out[1] = recon;\n out[2] = kl;\n }\n}\n\nstd::vector<torch::Tensor> cvae_forward(\n torch::Tensor x,\n torch::Tensor y,\n torch::Tensor enc_wt,\n torch::Tensor enc_b,\n torch::Tensor mu_wt,\n torch::Tensor mu_b,\n torch::Tensor logvar_wt,\n torch::Tensor logvar_b,\n torch::Tensor dec0_wt,\n torch::Tensor dec0_b,\n torch::Tensor dec2_wt,\n torch::Tensor dec2_b) {\n\n int B = (int)x.size(0);\n auto opts = x.options();\n auto eps = torch::randn({B, LATENT_DIM}, opts);\n auto partial = torch::empty({2, B}, opts);\n auto out = torch::empty({3}, opts);\n\n cudaStream_t stream = at::cuda::getCurrentCUDAStream();\n cvae_main_kernel<<<B, 256, 0, stream>>>(\n x.data_ptr<float>(), y.data_ptr<float>(), eps.data_ptr<float>(),\n enc_wt.data_ptr<float>(), enc_b.data_ptr<float>(),\n mu_wt.data_ptr<float>(), mu_b.data_ptr<float>(),\n logvar_wt.data_ptr<float>(), logvar_b.data_ptr<float>(),\n dec0_wt.data_ptr<float>(), dec0_b.data_ptr<float>(),\n dec2_wt.data_ptr<float>(), dec2_b.data_ptr<float>(),\n partial.data_ptr<float>(), B);\n\n cvae_final_reduce_kernel<<<1, 256, 0, stream>>>(partial.data_ptr<float>(), out.data_ptr<float>(), B);\n return {out.select(0, 0), out.select(0, 1), out.select(0, 2)};\n}\n'''\n\n_ext = load_inline(\n name='cvae_fused_ext_final',\n cpp_sources=_cpp_src,\n cuda_sources=_cuda_src,\n functions=['cvae_forward'],\n verbose=False,\n extra_cuda_cflags=['-O3', '--use_fast_math'],\n extra_cflags=['-O3'],\n)\n\nclass ModelNew(nn.Module):\n def __init__(self, input_dim, label_dim, hidden_dim, latent_dim):\n super().__init__()\n self.enc = nn.Sequential(nn.Linear(input_dim + label_dim, hidden_dim), nn.ReLU())\n self.enc_mu = nn.Linear(hidden_dim, latent_dim)\n self.enc_logvar = nn.Linear(hidden_dim, latent_dim)\n self.dec = nn.Sequential(\n nn.Linear(latent_dim + label_dim, hidden_dim),\n nn.ReLU(),\n nn.Linear(hidden_dim, input_dim),\n )\n self.register_buffer('_enc_wt', torch.empty(input_dim + label_dim, hidden_dim), persistent=False)\n self.register_buffer('_mu_wt', torch.empty(hidden_dim, latent_dim), persistent=False)\n self.register_buffer('_logvar_wt', torch.empty(hidden_dim, latent_dim), persistent=False)\n self.register_buffer('_dec0_wt', torch.empty(latent_dim + label_dim, hidden_dim), persistent=False)\n self.register_buffer('_dec2_wt', torch.empty(hidden_dim, input_dim), persistent=False)\n self._refresh_cache()\n\n def _refresh_cache(self):\n with torch.no_grad():\n self._enc_wt = self.enc[0].weight.detach().t().contiguous()\n self._mu_wt = self.enc_mu.weight.detach().t().contiguous()\n self._logvar_wt = self.enc_logvar.weight.detach().t().contiguous()\n self._dec0_wt = self.dec[0].weight.detach().t().contiguous()\n self._dec2_wt = self.dec[2].weight.detach().t().contiguous()\n\n def load_state_dict(self, state_dict, strict=True, assign=False):\n result = super().load_state_dict(state_dict, strict=strict, assign=assign)\n self._refresh_cache()\n return result\n\n def forward(self, x: torch.Tensor, y: torch.Tensor) -> tuple:\n return tuple(_ext.cvae_forward(\n x, y,\n self._enc_wt, self.enc[0].bias,\n self._mu_wt, self.enc_mu.bias,\n self._logvar_wt, self.enc_logvar.bias,\n self._dec0_wt, self.dec[0].bias,\n self._dec2_wt, self.dec[2].bias,\n ))\n"
}