call → run_correctness
callrun_correctness
{
"kernel_code": "import math\nimport 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 netvlad_cuda_forward(torch::Tensor x, torch::Tensor clusters, torch::Tensor bn_weight, torch::Tensor bn_bias, torch::Tensor running_mean, torch::Tensor running_var, torch::Tensor clusters2, double eps, bool training);\ntorch::Tensor netvlad_forward(torch::Tensor x, torch::Tensor clusters, torch::Tensor bn_weight, torch::Tensor bn_bias, torch::Tensor running_mean, torch::Tensor running_var, torch::Tensor clusters2, double eps, bool training){return netvlad_cuda_forward(x,clusters,bn_weight,bn_bias,running_mean,running_var,clusters2,eps,training);}'''\n_cuda_src=r'''\n#include <torch/extension.h>\n#include <cuda.h>\n#include <cuda_runtime.h>\n#include <math.h>\n#define D 512\n#define K 32\n#define N 100\n#define INV_SQRT_K 0.17677669529663687f\n__global__ void score_kernel4(const float* __restrict__ x,const float* __restrict__ clusters,float* __restrict__ scores,int rows){\n int lt=threadIdx.x&127; int sub=threadIdx.x>>7; int row=blockIdx.x*4+sub; if(row>=rows) return; int kk=lt>>2,lane=lt&3; float sum=0.0f; const float* xr=x+(size_t)row*D;\n for(int d=lane;d<D;d+=4) sum=fmaf(xr[d],clusters[d*K+kk],sum); sum+=__shfl_xor_sync(0xffffffff,sum,1,4); sum+=__shfl_xor_sync(0xffffffff,sum,2,4); if(lane==0) scores[(size_t)row*K+kk]=sum;\n}\n__global__ void stats_kernel(const float* __restrict__ scores,float* __restrict__ mean,float* __restrict__ invstd,int rows){int k=blockIdx.x,tid=threadIdx.x; float s=0,ss=0; for(int r=tid;r<rows;r+=256){float v=scores[(size_t)r*K+k]; s+=v; ss=fmaf(v,v,ss);} __shared__ float sm[256],sv[256]; sm[tid]=s; sv[tid]=ss; __syncthreads(); for(int off=128;off>0;off>>=1){if(tid<off){sm[tid]+=sm[tid+off]; sv[tid]+=sv[tid+off];} __syncthreads();} if(tid==0){float m=sm[0]/(float)rows; float var=sv[0]/(float)rows-m*m; if(var<0)var=0; mean[k]=m; invstd[k]=rsqrtf(var+1.0e-5f);}}\n__global__ void bn_softmax_kernel8(float* __restrict__ scores,const float* __restrict__ bw,const float* __restrict__ bb,const float* __restrict__ mean,const float* __restrict__ invstd,int rows){int lane=threadIdx.x&31,wrp=threadIdx.x>>5,row=blockIdx.x*8+wrp; if(row>=rows) return; float v=(scores[(size_t)row*K+lane]-mean[lane])*invstd[lane]; v=v*bw[lane]+bb[lane]; float mx=v; for(int off=16;off>0;off>>=1) mx=fmaxf(mx,__shfl_down_sync(0xffffffff,mx,off)); mx=__shfl_sync(0xffffffff,mx,0); float e=expf(v-mx),s=e; for(int off=16;off>0;off>>=1) s+=__shfl_down_sync(0xffffffff,s,off); s=__shfl_sync(0xffffffff,s,0); scores[(size_t)row*K+lane]=e/s;}\n__global__ void score_softmax_eval_kernel(const float* __restrict__ x,const float* __restrict__ clusters,const float* __restrict__ bw,const float* __restrict__ bb,const float* __restrict__ rm,const float* __restrict__ rv,float eps,float* __restrict__ assign,int rows){int row=blockIdx.x,tid=threadIdx.x,kk=tid>>2,lane=tid&3; float sum=0; const float* xr=x+(size_t)row*D; for(int d=lane;d<D;d+=4) sum=fmaf(xr[d],clusters[d*K+kk],sum); sum+=__shfl_xor_sync(0xffffffff,sum,1,4); sum+=__shfl_xor_sync(0xffffffff,sum,2,4); __shared__ float logits[K]; if(lane==0) logits[kk]=((sum-rm[kk])*rsqrtf(rv[kk]+eps))*bw[kk]+bb[kk]; __syncthreads(); if(tid<K){float v=logits[tid]; float mx=v; for(int off=16;off>0;off>>=1) mx=fmaxf(mx,__shfl_down_sync(0xffffffff,mx,off)); mx=__shfl_sync(0xffffffff,mx,0); float e=expf(v-mx),s=e; for(int off=16;off>0;off>>=1) s+=__shfl_down_sync(0xffffffff,s,off); s=__shfl_sync(0xffffffff,s,0); assign[(size_t)row*K+tid]=e/s;}}\n__global__ void vlad_kernel(const float* __restrict__ x,const float* __restrict__ assign,const float* __restrict__ c2,float* __restrict__ out,int B){size_t idx=(size_t)blockIdx.x*blockDim.x+threadIdx.x,total=(size_t)B*D*K; if(idx>=total)return; int k=idx%K,tmp=idx/K,d=tmp%D,b=tmp/D; float acc=0,center=c2[d*K+k]; const float* xb=x+(size_t)b*N*D+d; const float* ab=assign+(size_t)b*N*K+k; #pragma unroll 4\n for(int n=0;n<N;++n) acc=fmaf(ab[n*K],xb[(size_t)n*D]-center,acc); out[idx]=acc;}\n__global__ void intra_norm_kernel(float* __restrict__ out,int B){int bid=blockIdx.x,b=bid/K,k=bid-b*K,tid=threadIdx.x; float ss=0; for(int d=tid;d<D;d+=256){float v=out[((size_t)b*D+d)*K+k]; ss=fmaf(v,v,ss);} __shared__ float smem[256]; smem[tid]=ss; __syncthreads(); for(int s=128;s>0;s>>=1){if(tid<s) smem[tid]+=smem[tid+s]; __syncthreads();} float inv=rsqrtf(smem[0]+1e-12f)*INV_SQRT_K; for(int d=tid;d<D;d+=256) out[((size_t)b*D+d)*K+k]*=inv;}\ntorch::Tensor netvlad_cuda_forward(torch::Tensor x,torch::Tensor clusters,torch::Tensor bn_weight,torch::Tensor bn_bias,torch::Tensor running_mean,torch::Tensor running_var,torch::Tensor clusters2,double eps,bool training){x=x.contiguous(); int64_t B=x.size(0); int rows=(int)(B*N); auto opts=x.options(); auto assign=torch::empty({rows,K},opts); if(training){score_kernel4<<<(rows+3)/4,512>>>(x.data_ptr<float>(),clusters.data_ptr<float>(),assign.data_ptr<float>(),rows); auto stats=torch::empty({2,K},opts); stats_kernel<<<K,256>>>(assign.data_ptr<float>(),stats.data_ptr<float>(),stats.data_ptr<float>()+K,rows); bn_softmax_kernel8<<<(rows+7)/8,256>>>(assign.data_ptr<float>(),bn_weight.data_ptr<float>(),bn_bias.data_ptr<float>(),stats.data_ptr<float>(),stats.data_ptr<float>()+K,rows);} else {score_softmax_eval_kernel<<<rows,128>>>(x.data_ptr<float>(),clusters.data_ptr<float>(),bn_weight.data_ptr<float>(),bn_bias.data_ptr<float>(),running_mean.data_ptr<float>(),running_var.data_ptr<float>(),(float)eps,assign.data_ptr<float>(),rows);} auto out3=torch::empty({B,D,K},opts); size_t total=(size_t)B*D*K; vlad_kernel<<<(int)((total+255)/256),256>>>(x.data_ptr<float>(),assign.data_ptr<float>(),clusters2.data_ptr<float>(),out3.data_ptr<float>(),(int)B); intra_norm_kernel<<<(int)B*K,256>>>(out3.data_ptr<float>(),(int)B); return out3.view({B,D*K});}\n'''\n_ext=load_inline(name='netvlad_ext_v5',cpp_sources=[_cpp_src],cuda_sources=[_cuda_src],functions=['netvlad_forward'],extra_cuda_cflags=['-O3','--use_fast_math'],extra_cflags=['-O3'],verbose=False)\nclass ModelNew(nn.Module):\n def __init__(self,cluster_size,feature_size,ghost_clusters):\n super(ModelNew,self).__init__(); self.feature_size=feature_size; self.cluster_size=cluster_size; self.ghost_clusters=ghost_clusters; init_sc=(1/math.sqrt(feature_size)); clusters=cluster_size+ghost_clusters; self.clusters=nn.Parameter(init_sc*torch.randn(feature_size,clusters)); self.batch_norm=nn.BatchNorm1d(clusters); self.clusters2=nn.Parameter(init_sc*torch.randn(1,feature_size,cluster_size)); self.out_dim=self.cluster_size*feature_size\n def forward(self,x,mask=None):\n return _ext.netvlad_forward(x,self.clusters,self.batch_norm.weight,self.batch_norm.bias,self.batch_norm.running_mean,self.batch_norm.running_var,self.clusters2,self.batch_norm.eps,self.training)\n"
}