1

我有几个关于 OpenCL 的问题(总菜鸟),但我认为如果我设法解决这个问题,我将能够解决其他一些问题。我有以下内核,我想将由结构数据计算出的数字存储在双精度数组中。我传递给内核的参数是一个结构数组并且被初始化并且值非零(我测试过它)。

执行内核时,虽然我得到一个“浮点异常”。如果我做对了,这意味着 local_density 变量为零并且除法会导致错误。我不明白为什么它为零,因为在主机中的值非零。我在内核中做错了吗?

#pragma OPENCL EXTENSION cl_khr_fp64 : enable
typedef struct
{
double speeds[9];
} t_speed;

__kernel void prepare(__global const t_speed* cells,
                  __global const int*     obstacles,
                  __global       double*  results,
                           const unsigned int count)
{
  int pos = get_global_id(0);
  if(pos >= count) return;
  if(obstacles[pos] == 1) results[pos] = 0.00;
  else
  {
    double local_density = 0.00;
    for(int kk = 0; kk < 9; kk++)
      local_density += cells[pos].speeds[kk];
    results[pos] = (cells[pos].speeds[1] + cells[pos].speeds[5] +
                    cells[pos].speeds[8] - (cells[pos].speeds[3] +
                    cells[pos].speeds[6] + cells[pos].speeds[7])) /
                    local_density;
  }
}

这也是我作为参数传递的变量的初始化。params->ny/nx 有正确的值。

cells = (t_speed*) malloc(sizeof(t_speed) * (params->ny * params->nx));

我还引用了单元格变量的内核参数设置。

m_cells = clCreateBuffer(context, CL_MEM_READ_ONLY, sizeof(t_speed) * count, NULL, NULL);
err  = clEnqueueWriteBuffer(commands, m_cells, CL_TRUE, 0, sizeof(t_speed) * count, cells, 0, NULL, NULL);
err |= clSetKernelArg(av_velocity_prepare_kernel,  0, sizeof(cl_mem), &m_cells);

- - - - - - - - - - - - - - - - - - - - - 编辑 - - - - ----------------------------------

好的,真正奇怪的是,即使使用非常简单的以下内核,我也会遇到相同的错误(浮点异常)。有人有线索吗?

#pragma OPENCL EXTENSION cl_khr_fp64 : enable
__kernel void test(__global float*  result, const unsigned int n)
{
  int i = get_global_id(0);
  if(i >= n) return;
  result[i] += 1.0f;
}
4

2 回答 2

2

我注意到您将缓冲区声明为CL_MEM_READ_ONLY,但您正在内核内部对其进行写入。根据 OpenCL 规范,这是未定义的。尝试CL_MEM_READ_WRITE改用。

于 2012-04-07T08:48:58.673 回答
1

好的,所以这与我想象的完全不同。问题是当我打电话时

clEnqueueNDRangeKernel (command_queue, kernel, work_dim, *global_work_offset,     
                        *global_work_size, *local_work_size, num_events_in_wait_list,
                        *event_wait_list, *event)

不能被global_work_size整除local_work_size。这导致了浮点异常。

于 2012-04-07T09:16:25.317 回答