#include #include "MonteCarloTests.h" #include "Common.h" #include LFG::LFG(size_t _randomNumbers, size_t _threadCount, size_t _randomStateSize, size_t _bucketNum) { randomNumbers = _randomNumbers; threadCount = _threadCount; bucketNum = _bucketNum; randomBuffer = std::vector(threadCount * randomNumbers); seedBuffer = std::vector(threadCount); histoBuffer = std::vector(bucketNum); kernel_name = "randomLFG"; randomStateSize = _randomStateSize; for (int i = 0; i < threadCount; ++i) { seedBuffer[i] = rand(); } } void LFG::collect_results(cl::CommandQueue* queue) { queue->enqueueReadBuffer(clResultBuffer, true, 0, sizeof(float) * threadCount * randomNumbers, randomBuffer.data()); queue->enqueueReadBuffer(clHistoBuffer, true, 0, sizeof(int) * bucketNum, histoBuffer.data()); } void LFG::gpu_compute(cl::Context* context, cl::CommandQueue* queue, cl::Program* program, cl::Event* Event) { cl_int err = CL_SUCCESS; cl::Kernel kernel = cl::Kernel(*program, kernel_name.c_str(), &err); CheckCLError(err); clInputBuffer = cl::Buffer(*context, CL_MEM_READ_ONLY, sizeof(float) * threadCount, NULL, &err); queue->enqueueWriteBuffer(clInputBuffer, true, 0, sizeof(float) * threadCount, seedBuffer.data()); clResultBuffer = cl::Buffer(*context, CL_MEM_WRITE_ONLY, sizeof(float) * threadCount * randomNumbers, NULL, &err); cl::Buffer randomStates(*context, CL_MEM_WRITE_ONLY, sizeof(float) * threadCount * randomStateSize, NULL, &err); // Set the kernel parameters kernel.setArg(0, randomNumbers); kernel.setArg(1, clInputBuffer); kernel.setArg(2, randomStateSize); kernel.setArg(3, randomStates); kernel.setArg(4, clResultBuffer); // Enqueue the kernel: threadCount threads in total, each generating random numbers in [0,1] randomNumbers times queue->enqueueNDRangeKernel(kernel, cl::NullRange, cl::NDRange(threadCount, 1), cl::NullRange, NULL, Event); Event->wait(); cl::Kernel kernel_histo = cl::Kernel(*program, "testUniform1D", &err); CheckCLError(err); clHistoBuffer = cl::Buffer(*context, CL_MEM_WRITE_ONLY, sizeof(int) * bucketNum, NULL, &err); kernel_histo.setArg(0, threadCount * randomNumbers); kernel_histo.setArg(1, clResultBuffer); kernel_histo.setArg(2, bucketNum); kernel_histo.setArg(3, clHistoBuffer); queue->enqueueNDRangeKernel(kernel_histo, cl::NullRange, cl::NDRange(threadCount, 1), cl::NullRange, NULL, Event); } void LFG::cpu_compute() { } bool LFG::validate_results() { float min = 1000.0; float max = -1000.0; std::ofstream ofs(description() + "_randoms.txt", std::ofstream::out); for (int i = 0; i < threadCount; ++i) { for (int j = 0; j < randomNumbers; ++j) { ofs << j << "\t" << randomBuffer[i + j * threadCount] << std::endl; if (randomBuffer[i + j * threadCount] > max) { max = randomBuffer[i + j * threadCount]; } if (randomBuffer[i + j * threadCount] < min) { min = randomBuffer[i + j * threadCount]; } } } ofs.close(); std::ofstream ofsh(description() + "_histo.txt", std::ofstream::out); for (int i = 0; i < bucketNum; ++i) { ofsh << i << "\t" << histoBuffer[i] << std::endl; } ofsh.close(); std::cout << "LFG: Min: " << min << ", max: " << max << std::endl; return true; } std::string LFG::description() { return kernel_name + "(numbers=" + std::to_string(randomNumbers) + ",threads=" + std::to_string(threadCount) + ",state="+std::to_string(randomStateSize) + ")"; }