我在openCL程序中遇到了一些异常行为。
在程序的主机部分,我创建了一个double数组,并将所有元素设置为零。使用以下命令将该数组复制到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)!?!
我尝试将double更改为float但结果相似。我使用的是openCL的nvidia实现,版本是1.1。有谁知道这是什么问题?
答案 0 :(得分:0)
我怀疑你的内核代码有问题。如果你只运行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),并在所有这些驱动程序上获得了正确的结果。
答案 1 :(得分:0)
尝试用此替换显示的代码,然后发布错误号码
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);