call → run_correctness
callrun_correctness
{
"kernel_code": "import math\nimport torch\nimport torch.nn as nn\nimport torch as th\nfrom torch.utils.cpp_extension import load_inline\n_cpp_src=r'''\n#include <torch/extension.h>\ntorch::Tensor vlad_forward_cuda(torch::Tensor x, torch::Tensor logits, torch::Tensor clusters2, int64_t B, int64_t N, int64_t D, int64_t K, int64_t C);\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 <math.h>\n#define D_TILE 32\n#define K_TILE 8\n#define WARPS_PER_BLOCK 4\n__inline__ __device__ float warp_sum0(float v){ for(int o=16;o>0;o>>=1) v += __shfl_down_sync(0xffffffff,v,o); return v; }\n__inline__ __device__ float warp_max0(float v){ for(int o=16;o>0;o>>=1) v = fmaxf(v,__shfl_down_sync(0xffffffff,v,o)); return v; }\n__global__ void softmax_keep_kernel(const float* __restrict__ logits,float* __restrict__ probs,int rows,int C,int K){\n int tid=threadIdx.x; int lane=tid&31; int wid=tid>>5; int row=blockIdx.x*WARPS_PER_BLOCK+wid; if(row>=rows) return;\n const float* in=logits+(long long)row*C; float m=-INFINITY; for(int c=lane;c<C;c+=32) m=fmaxf(m,in[c]); m=warp_max0(m); m=__shfl_sync(0xffffffff,m,0);\n float s=0.f; for(int c=lane;c<C;c+=32) s+=expf(in[c]-m); s=warp_sum0(s); s=__shfl_sync(0xffffffff,s,0); float inv=1.f/s;\n if(lane<K) probs[(long long)row*K+lane]=expf(in[lane]-m)*inv;\n}\n__global__ void raw_vlad_kernel(const float* __restrict__ x,const float* __restrict__ probs,const float* __restrict__ c2,float* __restrict__ raw,float* __restrict__ partial,int B,int N,int D,int K,int num_dtiles){\n int tx=threadIdx.x, ty=threadIdx.y; int d=blockIdx.x*D_TILE+tx; int k=blockIdx.y*K_TILE+ty; int b=blockIdx.z; float val=0.f;\n if(d<D && k<K){ float acc=0.f, ps=0.f; const float* xb=x+(long long)b*N*D+d; const float* pb=probs+(long long)b*N*K+k;\n #pragma unroll 4\n for(int n=0;n<N;++n){ float p=pb[(long long)n*K]; ps+=p; acc+=p*xb[(long long)n*D]; }\n val=acc-ps*c2[d*K+k]; raw[((long long)b*D+d)*K+k]=val; }\n float ss=warp_sum0(val*val); if(tx==0 && k<K) partial[((long long)b*K+k)*num_dtiles+blockIdx.x]=ss;\n}\n__global__ void invnorm_kernel(const float* __restrict__ partial,float* __restrict__ invs,int B,int K,int num_dtiles){\n int tid=threadIdx.x; int k=blockIdx.x; int b=blockIdx.y; float s=0.f; if(tid<num_dtiles) s=partial[((long long)b*K+k)*num_dtiles+tid]; s=warp_sum0(s); if(tid==0) invs[(long long)b*K+k]=(s>1.e-24f)?(rsqrtf(s)*rsqrtf((float)K)):0.f;\n}\n__global__ void apply_kernel(const float* __restrict__ raw,const float* __restrict__ invs,float* __restrict__ out,long long total,int D,int K){\n long long idx=(long long)blockIdx.x*blockDim.x+threadIdx.x; if(idx>=total) return; int k=idx%K; long long bd=idx/K; int b=bd/D; out[idx]=raw[idx]*invs[(long long)b*K+k];\n}\ntorch::Tensor vlad_forward_cuda(torch::Tensor x,torch::Tensor logits,torch::Tensor clusters2,int64_t B,int64_t N,int64_t D,int64_t K,int64_t C){\n auto opts=x.options(); auto probs=torch::empty({B*N,K},opts); auto raw=torch::empty({B,D,K},opts); int64_t nd=(D+D_TILE-1)/D_TILE; auto partial=torch::empty({B,K,nd},opts); auto invs=torch::empty({B,K},opts); auto out=torch::empty({B,D*K},opts); cudaStream_t stream=at::cuda::getCurrentCUDAStream();\n softmax_keep_kernel<<<(int)((B*N+WARPS_PER_BLOCK-1)/WARPS_PER_BLOCK), WARPS_PER_BLOCK*32,0,stream>>>(logits.data_ptr<float>(),probs.data_ptr<float>(),(int)(B*N),(int)C,(int)K);\n dim3 block(D_TILE,K_TILE); dim3 grid((unsigned)nd,(unsigned)((K+K_TILE-1)/K_TILE),(unsigned)B); raw_vlad_kernel<<<grid,block,0,stream>>>(x.data_ptr<float>(),probs.data_ptr<float>(),clusters2.data_ptr<float>(),raw.data_ptr<float>(),partial.data_ptr<float>(),(int)B,(int)N,(int)D,(int)K,(int)nd);\n dim3 gridn((unsigned)K,(unsigned)B); invnorm_kernel<<<gridn,32,0,stream>>>(partial.data_ptr<float>(),invs.data_ptr<float>(),(int)B,(int)K,(int)nd);\n long long total=B*D*K; apply_kernel<<<(unsigned)((total+255)/256),256,0,stream>>>(raw.data_ptr<float>(),invs.data_ptr<float>(),out.data_ptr<float>(),total,(int)D,(int)K); return out;\n}\n'''\n_ext=load_inline(name='netvlad_ext_v4',cpp_sources=_cpp_src,cuda_sources=_cuda_src,functions=['vlad_forward_cuda'],extra_cuda_cflags=['-O3'],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*th.randn(feature_size,clusters)); self.batch_norm=nn.BatchNorm1d(clusters); self.clusters2=nn.Parameter(init_sc*th.randn(1,feature_size,cluster_size)); self.out_dim=self.cluster_size*feature_size\n def forward(self,x,mask=None):\n B=x.size(0); N=x.size(1); D=self.feature_size; K=self.cluster_size; C=K+self.ghost_clusters; xc=x.contiguous(); assignment=th.matmul(xc.view(-1,D),self.clusters); assignment=self.batch_norm(assignment); return _ext.vlad_forward_cuda(xc,assignment.contiguous(),self.clusters2.contiguous(),B,N,D,K,C)\n"
}