Я пытаюсь понять простой пример OpenCL, который является добавлением вектора. Ядро:Open global_work_size недоразумение
__kernel void addVec(__global double* a, __global double* b, __global double* c)
{
size_t id = get_global_id(0);
c[id] = a[id] + b[id];
}
Например, мои входные массивы имеют размер 1 миллион элементов каждый.
В моей программе-хоста я установил global_work_size
как размер векторов входных массивов (1 миллион).
Но когда я устанавливаю его на меньшее значение, например 1000, он также работает с этим ядром!
Я не понимаю, почему global_work_size
может быть меньше размерности задачи, и все же программа OpenCL вычисляет все элементы входных массивов.
Не могли бы прояснить это?
EDIT: Вот код, где я копирую данные:
size_t arraySize = 1000000;
const size_t global_work_size[1] = {512};
double *host_a = malloc(arraySize*sizeof(double));
double *host_b = malloc(arraySize*sizeof(double));
double *host_c = calloc(arraySize, sizeof(double));
...
// Create the input and output arrays in device memory for our calculation
device_a = clCreateBuffer(context, CL_MEM_READ_ONLY, arraySize*sizeof(double), NULL, NULL);
device_b = clCreateBuffer(context, CL_MEM_READ_ONLY, arraySize*sizeof(double), NULL, NULL);
device_c = clCreateBuffer(context, CL_MEM_WRITE_ONLY, arraySize*sizeof(double), NULL, NULL);
...
// Copy data set into the input array in device memory. [host --> device]
status = clEnqueueWriteBuffer(command_queue, device_a, CL_TRUE, 0, arraySize*sizeof(double), host_a, 0, NULL, NULL);
status |= clEnqueueWriteBuffer(command_queue, device_b, CL_TRUE, 0, arraySize*sizeof(double), host_b, 0, NULL, NULL);
...
// Copy-back the results from the device [host <-- device]
clEnqueueReadBuffer(command_queue, device_c, CL_TRUE, 0, arraySize*sizeof(double), host_c, 0, NULL, NULL);
...
printf("checking result validity ...\n");
for (size_t i=0; i<arraySize; ++i)
if(host_c[i] - 1 > 1e-6) // the array is supposed to be 1 everywhere
{
printf("*** ERROR! Invalid results ! host_c[%zi]=%.9lf\n", i, host_c[i]);
break;
}
Благодарности
Предоставление global_work_Size = 1000 для 1 миллиона элементов и чтение результатов из 1 миллиона элементов, которые вы получаете правильные результаты. Если это так, вы должны очистить свой буфер C, т. Е. Установить c [0 - (Миллион -1)] = 0, направить данные на gpu и затем прочитать. (это происходит потому, что в разных прогонах память сопоставляется с тем же адресом, где результаты были вычислены во время предыдущих прогонов, и когда вы читаете назад, вы получаете результаты предыдущего запуска) – Meluha
@Meluha Спасибо, на самом деле мой хост-буфер уже инициализирован с помощью ' calloc'. Кажется, что каждая вещь тоже очищается. – carmellose
, чтобы убедиться, что вы копируете буфер c в GPU. – Meluha