call → compile_kernel
callcompile_kernel
{
"kernel_code": "import torch\nimport torch.nn as nn\nimport torch.nn.functional as F\nfrom torch.utils.cpp_extension import load_inline\n\ncuda_source = \"\"\"\n#include <torch/extension.h>\n#include <cuda.h>\n#include <cuda_runtime.h>\n#include <curand_kernel.h>\n\n__global__ void linear_relu_kernel(const float* x, const float* w, const float* b, float* h, int batch, int in_dim, int out_dim) {\n int row = blockIdx.x * blockDim.x + threadIdx.x;\n int col = blockIdx.y * blockDim.y + threadIdx.y;\n if (row < batch && col < out_dim) {\n float sum = b[col];\n for (int i = 0; i < in_dim; i++) {\n sum += x[row * in_dim + i] * w[col * in_dim + i];\n }\n h[row * out_dim + col] = fmaxf(sum, 0.0f);\n }\n}\n\n__global__ void linear_kernel(const float* x, const float* w, const float* b, float* out, int batch, int in_dim, int out_dim) {\n int row = blockIdx.x * blockDim.x + threadIdx.x;\n int col = blockIdx.y * blockDim.y + threadIdx.y;\n if (row < batch && col < out_dim) {\n float sum = b[col];\n for (int i = 0; i < in_dim; i++) {\n sum += x[row * in_dim + i] * w[col * in_dim + i];\n }\n out[row * out_dim + col] = sum;\n }\n}\n\n__global__ void sample_and_kl_recon_prep(const float* mu, const float* logvar, float* z, float* kl, int batch, int latent) {\n int idx = blockIdx.x * blockDim.x + threadIdx.x;\n if (idx < batch * latent) {\n int b = idx / latent;\n float m = mu[idx];\n float lv = logvar[idx];\n float std = expf(0.5f * lv);\n curandState state;\n curand_init(42, idx, 0, &state);\n float eps = curand_normal(&state);\n z[idx] = m + std * eps;\n // partial for kl\n atomicAdd(&kl[b], -0.5f * (1.0f + lv - m*m - expf(lv)));\n }\n}\n\n__global__ void sigmoid_bce_sum(const float* logits, const float* target, float* recon, int batch, int dim) {\n int b = blockIdx.x * blockDim.x + threadIdx.x;\n if (b < batch) {\n float sum = 0.0f;\n for (int i = 0; i < dim; i++) {\n float lg = logits[b * dim + i];\n float xr = 1.0f / (1.0f + expf(-lg));\n float t = target[b * dim + i];\n sum += -t * logf(xr + 1e-12f) - (1-t) * logf(1 - xr + 1e-12f);\n }\n recon[b] = sum;\n }\n}\n\ntorch::Tensor vae_forward(torch::Tensor x, torch::Tensor w_enc, torch::Tensor b_enc,\n torch::Tensor w_mu, torch::Tensor b_mu, torch::Tensor w_logvar, torch::Tensor b_logvar,\n torch::Tensor w_dec1, torch::Tensor b_dec1, torch::Tensor w_dec2, torch::Tensor b_dec2) {\n int batch = x.size(0);\n int input_dim = x.size(1);\n int hidden = w_enc.size(0);\n int latent = w_mu.size(0);\n \n auto options = torch::TensorOptions().device(x.device()).dtype(torch::kFloat32);\n auto h = torch::empty({batch, hidden}, options);\n auto mu = torch::empty({batch, latent}, options);\n auto logvar = torch::empty({batch, latent}, options);\n auto z = torch::empty({batch, latent}, options);\n auto kl = torch::zeros({batch}, options);\n auto h2 = torch::empty({batch, hidden}, options);\n auto logits = torch::empty({batch, input_dim}, options);\n auto recon = torch::empty({batch}, options);\n auto elbo = torch::empty({batch}, options);\n \n dim3 block(16, 16);\n dim3 grid_enc((batch + 15)/16, (hidden + 15)/16);\n linear_relu_kernel<<<grid_enc, block>>>(x.data_ptr<float>(), w_enc.data_ptr<float>(), b_enc.data_ptr<float>(), h.data_ptr<float>(), batch, input_dim, hidden);\n \n dim3 grid_mu((batch + 15)/16, (latent + 15)/16);\n linear_kernel<<<grid_mu, block>>>(h.data_ptr<float>(), w_mu.data_ptr<float>(), b_mu.data_ptr<float>(), mu.data_ptr<float>(), batch, hidden, latent);\n linear_kernel<<<grid_mu, block>>>(h.data_ptr<float>(), w_logvar.data_ptr<float>(), b_logvar.data_ptr<float>(), logvar.data_ptr<float>(), batch, hidden, latent);\n \n sample_and_kl_recon_prep<<<(batch*latent + 255)/256, 256>>>(mu.data_ptr<float>(), logvar.data_ptr<float>(), z.data_ptr<float>(), kl.data_ptr<float>(), batch, latent);\n \n dim3 grid_dec((batch + 15)/16, (hidden + 15)/16);\n linear_relu_kernel<<<grid_dec, block>>>(z.data_ptr<float>(), w_dec1.data_ptr<float>(), b_dec1.data_ptr<float>(), h2.data_ptr<float>(), batch, latent, hidden);\n \n dim3 grid_out((batch + 15)/16, (input_dim + 15)/16);\n linear_kernel<<<grid_out, block>>>(h2.data_ptr<float>(), w_dec2.data_ptr<float>(), b_dec2.data_ptr<float>(), logits.data_ptr<float>(), batch, hidden, input_dim);\n \n sigmoid_bce_sum<<<(batch + 255)/256, 256>>>(logits.data_ptr<float>(), x.data_ptr<float>(), recon.data_ptr<float>(), batch, input_dim);\n \n // compute elbo\n auto kl_sum = kl; // already summed per batch? wait fix later\n // for simplicity return placeholder\n return torch::stack({-(recon + kl), recon, kl}, 0);\n}\n\"\"\"\n\ncpp_source = \"\"\"\ntorch::Tensor vae_forward(torch::Tensor x, torch::Tensor w_enc, torch::Tensor b_enc,\n torch::Tensor w_mu, torch::Tensor b_mu, torch::Tensor w_logvar, torch::Tensor b_logvar,\n torch::Tensor w_dec1, torch::Tensor b_dec1, torch::Tensor w_dec2, torch::Tensor b_dec2);\n\"\"\"\n\nmodule = load_inline(\n name=\"vae_cuda\",\n cpp_sources=cpp_source,\n cuda_sources=cuda_source,\n functions=[\"vae_forward\"],\n verbose=True,\n extra_cuda_cflags=[\"-O3\"]\n)\n\nclass ModelNew(nn.Module):\n def __init__(self, input_dim, hidden_dim, latent_dim):\n super().__init__()\n self.encoder = nn.Sequential(\n nn.Linear(input_dim, hidden_dim),\n nn.ReLU(),\n )\n self.fc_mu = nn.Linear(hidden_dim, latent_dim)\n self.fc_logvar = nn.Linear(hidden_dim, latent_dim)\n\n self.decoder = nn.Sequential(\n nn.Linear(latent_dim, hidden_dim),\n nn.ReLU(),\n nn.Linear(hidden_dim, input_dim),\n nn.Sigmoid(),\n )\n self.input_dim = input_dim\n self.hidden_dim = hidden_dim\n self.latent_dim = latent_dim\n\n def forward(self, x):\n w_enc = self.encoder[0].weight\n b_enc = self.encoder[0].bias\n w_mu = self.fc_mu.weight\n b_mu = self.fc_mu.bias\n w_logvar = self.fc_logvar.weight\n b_logvar = self.fc_logvar.bias\n w_dec1 = self.decoder[0].weight\n b_dec1 = self.decoder[0].bias\n w_dec2 = self.decoder[2].weight\n b_dec2 = self.decoder[2].bias\n out = module.vae_forward(x, w_enc, b_enc, w_mu, b_mu, w_logvar, b_logvar, w_dec1, b_dec1, w_dec2, b_dec2)\n # out is stacked, need to split\n elbo = out[0]\n recon = out[1]\n kl = out[2]\n return elbo, recon, kl\n"
}