我有一个让我对 OpenCL 发疯的问题。我已将问题缩小到给出问题的特定代码段,并在下面引用它。问题是,当我使用 OpenCL 串行执行此代码并比较结果时,它们并不相同。这里唯一作为内核参数的是单元格变量。
在测试期间,我尝试使用之前计算的特定值(例如 local_density)来设置最后一个循环中的值。然后我得到的结果是正确的。据我了解,问题在于 u 和 d_equ 数组在循环中用于计算时。我不得不提一下,这些数组是双精度类型的,我已经添加了所需的编译指示来启用双精度。
在此代码中是否需要同步或类似的东西,因为它适用于 OpenCL?
local_density = 0.0;
for(kk = 0; kk < 9; kk++)
{
local_density += tmp_cells[pos].speeds[kk];
}
u_x = (tmp_cells[pos].speeds[1] + tmp_cells[pos].speeds[5] +
tmp_cells[pos].speeds[8] - ( tmp_cells[pos].speeds[3] +
tmp_cells[pos].speeds[6] + tmp_cells[pos].speeds[7]))
/ local_density;
u_y = (tmp_cells[pos].speeds[2] + tmp_cells[pos].speeds[5] +
tmp_cells[pos].speeds[6] - ( tmp_cells[pos].speeds[4] +
tmp_cells[pos].speeds[7] + tmp_cells[pos].speeds[8]))
/ local_density;
u_sq = u_x * u_x + u_y * u_y;
u[1] = u_x ;
u[2] = u_y;
u[3] = - u_x ;
u[4] = - u_y;
u[5] = u_x + u_y;
u[6] = - u_x + u_y;
u[7] = - u_x - u_y;
u[8] = u_x - u_y;
t1 = 2.0 * c_sq;
d_equ[0] = w0 * local_density * (1.0 - u_sq / t1);
t3 = w1 * local_density;
t2 = t1 * c_sq;
t1 = u_sq / t1;
d_equ[1] = t3 * (1.0 + u[1] / c_sq + (u[1] * u[1]) / t2 - t1);
d_equ[2] = t3 * (1.0 + u[2] / c_sq + (u[2] * u[2]) / t2 - t1);
d_equ[3] = t3 * (1.0 + u[3] / c_sq + (u[3] * u[3]) / t2 - t1);
d_equ[4] = t3 * (1.0 + u[4] / c_sq + (u[4] * u[4]) / t2 - t1);
t3 = w2 * local_density;
d_equ[5] = t3 * (1.0 + u[5] / c_sq + (u[5] * u[5]) / t2 - t1);
d_equ[6] = t3 * (1.0 + u[6] / c_sq + (u[6] * u[6]) / t2 - t1);
d_equ[7] = t3 * (1.0 + u[7] / c_sq + (u[7] * u[7]) / t2 - t1);
d_equ[8] = t3 * (1.0 + u[8] / c_sq + (u[8] * u[8]) / t2 - t1);
for(kk = 0; kk < 9; kk++)
{
cells[pos].speeds[kk] = (tmp_cells[pos].speeds[kk] + params->omega *
(d_equ[kk] - tmp_cells[pos].speeds[kk]));
}
如果有人想知道它是类型的细胞类型
typedef struct {
double speeds[NSPEEDS];
} t_speed;
编辑
经过几次测试后,问题是当我尝试为每个单元格[pos].speeds[kk] 设置值时。如果我只改变其中一种速度的值,那么我得到的结果会更好(更正确的值)。如果我尝试更改多个,那么结果非常糟糕。
所以问题是,为什么我不能在结构中更改多个值而不会出现问题?
编辑
在尝试在几个循环中执行整个代码后,经过一定数量的步骤后,上述代码会导致分段错误。导致问题的原因当然是更新。
for(kk = 0; kk < 9; kk++)
{
cells[pos].speeds[kk] = (tmp_cells[pos].speeds[kk] + params->omega *
(d_equ[kk] - tmp_cells[pos].speeds[kk]));
}
如果我将此注释掉,则不会出现分段错误。
编辑
当我将 cpu 定位为 OpenCL 的执行设备时,代码可以正常执行而没有问题。为什么会这样?