我的openCL程序中出现了一些异常的行为。
在程序的主机部分中,我创建了一个双精度数组并将所有元素设置为零。该数组使用以下方法复制到 GPU:
memObjects[4] = clCreateBuffer(context, CL_MEM_READ_WRITE | CL_MEM_COPY_HOST_PTR,
sizeof(double) * I_numel, I, NULL);
在内核内部,根据某些条件,某些元素设置为 1,然后我用以下命令将其读回主机:
errNum = clEnqueueReadBuffer(commandQueue, memObjects[4], CL_TRUE, 0,
I_numel * sizeof(double), I, 0, NULL, NULL);
然而,一些应该为零的元素已经变成了非常小(6.953267903e-310)或非常大的数字(2.0002319483e+161)?!
我尝试将双精度更改为浮动,但结果相似。我正在使用 openCL 的 nvidia 实现,版本是 1.1。有谁知道问题出在哪里?
我怀疑你的内核代码有问题。如果你只执行 clEnqueueRead 而不运行内核,会发生什么,然后你会得到所有的零吗?如果您删除CL_MEM_COPY_HOST_PTR并使用 clEnqueueWrite 清除缓冲区怎么样?
我试图用这个简化的内核重现这个问题,但输出只是交替的零和一,正如预期的那样:
kernel void enqueueReadBuffer(global float* outputValueArray) {
int gid = get_global_id(0);
if (gid % 2 == 0) {
outputValueArray[gid] = 1.0f;
}
}
我在Windows 7上的三个不同的OpenCL驱动程序上运行了这个,包括NVIDIA Quadro FX4800(R307.45),并在所有这些驱动程序上都得到了正确的结果。
尝试用这个替换显示的代码,然后发布错误编号
cl_int err;
memObjects[4] = clCreateBuffer(context, CL_MEM_READ_WRITE | CL_MEM_COPY_HOST_PTR,
sizeof(double) * I_numel, I, &err);
printf("Buffer creation error no = %d", err);
并复制回来
cl_int err2;
err2= clEnqueueReadBuffer(commandQueue, memObjects[4], CL_TRUE, 0,
I_numel * sizeof(double), I, 0, NULL, NULL);
printf("Copy back error no = %d", err2);