Не все рабочие элементы используются opencl
Поэтому я могу скомпилировать и запустить свое ядро, проблема в том, что используются только два рабочих элемента. Я в основном пытаюсь заполнить массив с плавающей точкой [8] с помощью {0,1,2,3,4,5,6,7}. Так что это очень простое приложение Hello World. Сильфон это мое ядро.
// Highly simplified to demonstrate
__kernel void rnd_float32_matrix (
__global float * res
) {
uint idx = get_global_id(0);
res[idx] = idx;
}
Затем я создаю и запускаю ядро со следующим кодом...
// Some more code
cl::Program program(context, sources, &err);
program.build(devices, NULL, NULL, NULL);
cl::Kernel kernel(program, "rnd_float32_matrix", &err);
kernel.setArg(0, src_d);
cl::CommandQueue queue(context, devices[0], 0, &err);
cl::Event event;
err = queue.enqueueNDRangeKernel(
kernel,
cl::NullRange,
cl::NDRange(8),
// I've tried cl::NDRange(8) as well
cl::NDRange(1),
NULL,
&event
);
event.wait();
err = queue.enqueueReadBuffer(
// This is:
// cl::Buffer src_d(
// context,
// CL_MEM_READ_ONLY | CL_MEM_COPY_HOST_PTR,
// mem_size,
// src_h,
// &err);
src_d,
CL_TRUE,
0,
8,
// This is float * src_h = new float[8];
src_h);
for(int i = 0; i < 8; i ++) {
std::cout << src_h[i] << std::endl;
}
Я не могу показать его в коде, но я также выбираю устройство GPU и с помощью context.getInfo (..) он показывает, что я использую мою карту NVidia GTX 770M, которая показывает 1024, 1024, 64 рабочих элемента, доступных в измерениях 0, 1 и 2. Когда этот массив печатается, я продолжаю получать... 0, 1, 0, 0, 0, 0, 0, 0. Я также попытался установить res[idx] = 5, и я получаю.. 5, 5, 0, 0, 0, 0, 0, 0. Таким образом, кажется, что фактически используются только два заданных рабочих элемента. Что я делаю неправильно?
1 ответ
Ваша команда для чтения данных с устройства читает только 8 байтов, что составляет два числа с плавающей запятой:
err = queue.enqueueReadBuffer(
src_d,
CL_TRUE,
0,
8, // <- This is the number of bytes, not the number of elements!
// This is float * src_h = new float[8];
src_h);
Чтобы прочитать 8 поплавков, вам нужно сделать это:
err = queue.enqueueReadBuffer(
src_d,
CL_TRUE,
0,
8 * sizeof(cl_float),
// This is float * src_h = new float[8];
src_h);