我有几个关于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;
}
答案 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
整除。这导致浮点异常。