在 OpenCL 中错误地复制内存



我的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);

最新更新