Я пытаюсь сгенерировать гистограмму на основе изображения в градациях серого. Я использую библиотеку OpenCL в C ++, с библиотекой CImg. До сих пор мне удалось записать образ в буфер и запустить ядро. Однако при попытке прочитать из буфера и скопировать вектор, я получаю clEnqueueReadBuffer, CL_OUT_OF_RESOURCES. Я попытался закомментировать только эту строку кода, чтобы увидеть, работает ли она нормально, и поэтому, поэтому я сузил ее до этой строки кода. Кто-нибудь может мне помочь?
Вот код хоста / устройства:
//Part 3 - host operations
//3.1 Select computing devices
cl::Context context = GetContext(platform_id, device_id);
//display the selected device
std::cout << "Runing on " << GetPlatformName(platform_id) << ", " << GetDeviceName(platform_id, device_id) << std::endl;
//create a queue to which we will push commands for the device
cl::CommandQueue queue(context);
// Get max compute units
//3.2 Load & build the device code
cl::Program::Sources sources;
AddSources(sources, "kernels/kernels.cl");
cl::Program program(context, sources);
//build and debug the kernel code
try {
program.build();
}
catch (const cl::Error& err) {
std::cout << "Build Status: " << program.getBuildInfo<CL_PROGRAM_BUILD_STATUS>(context.getInfo<CL_CONTEXT_DEVICES>()[0]) << std::endl;
std::cout << "Build Options:\t" << program.getBuildInfo<CL_PROGRAM_BUILD_OPTIONS>(context.getInfo<CL_CONTEXT_DEVICES>()[0]) << std::endl;
std::cout << "Build Log:\t " << program.getBuildInfo<CL_PROGRAM_BUILD_LOG>(context.getInfo<CL_CONTEXT_DEVICES>()[0]) << std::endl;
throw err;
}
// Variables
CImg<unsigned char> image_input("test.pgm");
CImgDisplay disp_input(image_input, "input");
vector<unsigned char> output_vector(image_input.size());
// Device buffers
cl::Buffer device_image_input(context, CL_MEM_READ_ONLY, image_input.size());
cl::Buffer device_image_output(context, CL_MEM_READ_WRITE, image_input.size());
std::cout << "Image input size: " << image_input.size() << std::endl;
std::cout << "Output input size: " << output_vector.size() << std::endl;
// Copy image to the buffer
queue.enqueueWriteBuffer(device_image_input, CL_TRUE, 0, image_input.size(), &image_input.data()[0]);
// Trying to implement hist
queue.enqueueFillBuffer(device_image_output, 0, 0, output_vector.size());
// Setup and kernel
cl::Kernel kernel = cl::Kernel(program, "hist_simple");
kernel.setArg(0, device_image_input);
kernel.setArg(1, device_image_output);
// Queue kernel code
queue.enqueueNDRangeKernel(kernel, cl::NullRange, cl::NDRange(image_input.size()), cl::NullRange);
// Read from buffer and copy to output_vector
queue.enqueueReadBuffer(device_image_output, CL_TRUE, 0, output_vector.size(), &output_vector.data()[0]);
// Convert output_vector to a CImg and display output
//CImg<unsigned char> output_image(output_vector.data(), image_input.width(), image_input.height(), image_input.depth(), image_input.spectrum());
//CImgDisplay disp_output(output_image, "output");
А также код ядра
kernel void hist_simple(global const int* A, global int* B) {
int id = get_global_id(0);
//assumes that H has been initialised to 0
int bin_index = A[id];//take value as a bin index
atomic_inc(&B[bin_index]);//serial operation, not very efficient!
}
Кроме того, просто примечание верхняя часть кода использует вспомогательную функцию из отдельного заголовочного файла.