// Isolate the upper-13 optimization on identical supplied lower35 planes. // The full seed pipeline lives in 08_seed_cpu.cpp / 08_seed_cuda.cu. #include "common.hpp" #include "../research/slime_solver_core.hpp" #include #include namespace sr=slime_research; void check(cudaError_t e) { if(e!=cudaSuccess) throw std::runtime_error(cudaGetErrorString(e)); } struct Solution { uint64_t lower35,seed; bool operator<(const Solution& o) const { return std::tie(lower35,seed) __global__ void upperKernel( uint64_t lower35,uint64_t planes,const sr::CellTerm* cells,int n, Solution* out,unsigned long long* count,uint64_t capacity ) { const uint64_t stride=uint64_t(gridDim.x)*blockDim.x; const uint64_t total=analytic?planes:planes*8192; for(uint64_t i=uint64_t(blockIdx.x)*blockDim.x+threadIdx.x;i>17)%10!=0) { candidate=false;break; } } if(candidate && sr::verifyPattern(seed,cells,n)) emit(seed); } } } int main(int argc,char** argv) { try { uint64_t lower=16420645998ULL,planes=4096; int repeats=5; for(int i=1;i=argc) throw std::runtime_error("missing value"); if(key=="--lower35") lower=show::positive(argv[i]); else if(key=="--planes") planes=show::positive(argv[i]); else if(key=="--repeats") repeats=std::stoi(argv[i]); else throw std::runtime_error("unknown option"); } if(!planes || planes>1000000 || repeats<1 || lower>=(1ULL<<35)) throw std::runtime_error("invalid planes/repeats/lower35"); std::array terms; int cell=0; for(int dx=0;dx<5;++dx) for(int dz=0;dz<5;++dz) terms[cell++]={sr::coordinateTerm(51069+dx,419124+dz),sr::kSlime}; sr::CellTerm* deviceTerms=nullptr; Solution* out=nullptr; unsigned long long* count=nullptr; constexpr uint64_t capacity=100000; check(cudaMalloc(&deviceTerms,sizeof(terms))); check(cudaMalloc(&out,capacity*sizeof(Solution))); check(cudaMalloc(&count,sizeof(unsigned long long))); check(cudaMemcpy(deviceTerms,terms.data(),sizeof(terms),cudaMemcpyHostToDevice)); cudaEvent_t begin,end; check(cudaEventCreate(&begin)); check(cudaEventCreate(&end)); std::array,2> times; std::vector expected; bool first=true; int dev=0; cudaDeviceProp prop{}; check(cudaGetDevice(&dev)); check(cudaGetDeviceProperties(&prop,dev)); for(int r=-1;r((work+255)/256,prop.multiProcessorCount*32)); if(mode) upperKernel<<>>(lower,planes,deviceTerms,25,out,count,capacity); else upperKernel<<>>(lower,planes,deviceTerms,25,out,count,capacity); check(cudaGetLastError()); check(cudaEventRecord(end)); check(cudaEventSynchronize(end)); float elapsed=0; check(cudaEventElapsedTime(&elapsed,begin,end)); unsigned long long size=0; check(cudaMemcpy(&size,count,sizeof(size),cudaMemcpyDeviceToHost)); if(size>capacity) throw std::runtime_error("upper results truncated"); std::vector hits(size); if(size) check(cudaMemcpy(hits.data(),out,size*sizeof(Solution),cudaMemcpyDeviceToHost)); std::sort(hits.begin(),hits.end()); if(first) { expected=hits;first=false; } else if(hits!=expected) throw std::runtime_error("enumerated/analytic upper results differ"); if(r>=0) times[mode].push_back(elapsed); } std::cout.precision(10); std::cout << "{\"lower35_start\":" << lower << ",\"planes\":" << planes << ",\"candidate_model\":\"first_draw\",\"comparison_equal\":true,\"rows\":["; for(int m=0;m<2;++m) { if(m) std::cout << ','; std::cout << "{\"mode\":\"" << (m?"analytic_upper13":"enumerate_upper13") << "\",\"kernel_samples_ms\":"; show::array(times[m]); std::cout << ",\"kernel_median_ms\":" << show::median(times[m]) << '}'; } std::cout << "],\"solutions\":["; for(size_t i=0;i