0

我的 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 )!?!

我尝试将 double 更改为 float,但结果相似。我正在使用 openCL 的 nvidia 实现,版本是 1.1。有谁知道是什么问题?

4

2 回答 2

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),并在所有驱动程序上都得到了正确的结果。

于 2012-12-12T13:58:47.323 回答
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);
于 2012-12-12T17:23:41.920 回答