OpenCL内核参数struct的值为零

时间:2012-04-06 11:50:40

标签: c struct opencl

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

执行内核时虽然出现“浮点异常”。如果我做对了,则意味着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-&gt; ny / nx具有正确的值。

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

我还引用了cell变量的内核参数设置。

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;
}

2 个答案:

答案 0 :(得分:2)

我注意到你将缓冲区声明为CL_MEM_READ_ONLY,但是你正在内核中写入它。根据OpenCL规范,这是未定义的。请尝试使用CL_MEM_READ_WRITE

答案 1 :(得分: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整除。这导致浮点异常。