OutputIterator inclusive_scan(InputIterator first, InputIterator last, OutputIterator result, BinaryOperation bOp) { if (first != last) { typename std::iterator_traits<InputIterator>::value_type init = *first; *result++ = init; if (++first != last) return inclusive_scan(first, last, result, bOp, init); } return result; }
cl::Buffer inclusive_scan(cl::Buffer input, size_t input_size) { if (block_size >= input_size) { return small_array_scan(input, input_size); } else { cl::Buffer subblocks; cl::Buffer last_elements; std::tie(subblocks, last_elements) = subblock_scan(input, input_size); cl::Buffer last_elements_scaned = inclusive_scan(last_elements, input_size / block_size); return merge(subblocks, last_elements_scaned, input_size); } }
OutputIterator inclusive_scan(InputIterator first, InputIterator last, OutputIterator result) { typedef typename std::iterator_traits<InputIterator>::value_type VT; return inclusive_scan(first, last, result, std::plus<VT>()); }
int main() { try { std::vector<cl::Device> devices; // select platform cl::Platform platform = selectPlatform(); // select device platform.getDevices(CL_DEVICE_TYPE_ALL, &devices); cl::Device device = selectDevice(devices); // create context context = cl::Context(devices); // create command queue queue = cl::CommandQueue(context, device, CL_QUEUE_PROFILING_ENABLE); // load opencl source std::ifstream cl_file("inclusive_scan.cl"); std::string cl_string{std::istreambuf_iterator<char>(cl_file), std::istreambuf_iterator<char>()}; cl::Program::Sources source(1, std::make_pair(cl_string.c_str(), cl_string.length() + 1)); // create programm program = cl::Program(context, source); // compile opencl source try { program.build(devices); size_t input_size; std::ifstream input_file("input.txt"); input_file >> input_size; std::vector<float> input(input_size); // for (size_t i = 0; i < input_size; ++i) { // input[i] = i % 10; // } for (int i = 0; i < input_size; i++) { input_file >> input[i]; } std::vector<float> output(input_size, 0); cl::Buffer dev_input (context, CL_MEM_READ_ONLY, sizeof(float) * input_size); queue.enqueueWriteBuffer(dev_input, CL_TRUE, 0, sizeof(float) * input_size, &input[0]); cl::Buffer dev_output = inclusive_scan(dev_input, input_size); queue.enqueueReadBuffer(dev_output, CL_TRUE, 0, sizeof(float) * input_size, &output[0]); queue.finish(); cpu_check(input, output); std::ofstream output_file("output.txt"); for (int i = 0; i < input_size; i++) { output_file << output[i] << " "; } } catch (cl::Error const & e) { std::string log_str = program.getBuildInfo<CL_PROGRAM_BUILD_LOG>(device); std::cout << std::endl << e.what() << " : " << e.err() << std::endl; std::cout << log_str; return 0; } } catch (cl::Error const & e) { std::cout << "Error: " << e.what() << " #" << e.err() << std::endl; } return 0; }