#pragma once // Stage 03: one work item is a fixed (x,z). Its private axis terms are computed // once, then reused for every seed. No host table or global coordinate table. template __device__ __forceinline__ bool solidAxes(uint64_t seed,const uint64_t (&xs)[N], const uint64_t (&zs)[N]) { #pragma unroll for(int dx=0;dx __global__ void coordinateKernel(DeviceArgs a,show::Hit* hits,unsigned long long* count) { const uint64_t area=a.width*a.height; const uint64_t stride=uint64_t(gridDim.x)*blockDim.x; for(uint64_t p=uint64_t(blockIdx.x)*blockDim.x+threadIdx.x;p(a.seed+s,xs,zs)) emit(a,hits,count,a.seed+s,x,z); } } // Compile-time sizes let the compiler scalarize/unroll the private axis arrays. // Dispatch once on the host, outside the kernel's timed seed loop. void launchCoordinate(int blocks,int threads,DeviceArgs a,show::Hit* hits, unsigned long long* count) { switch(a.n) { case 1: coordinateKernel<1><<>>(a,hits,count); break; case 2: coordinateKernel<2><<>>(a,hits,count); break; case 3: coordinateKernel<3><<>>(a,hits,count); break; case 4: coordinateKernel<4><<>>(a,hits,count); break; case 5: coordinateKernel<5><<>>(a,hits,count); break; case 6: coordinateKernel<6><<>>(a,hits,count); break; case 7: coordinateKernel<7><<>>(a,hits,count); break; case 8: coordinateKernel<8><<>>(a,hits,count); break; default: throw std::runtime_error("invalid pattern size"); } }