OpenCL 1.2 使用有效内核给出 -9999 错误

OpenCL 1.2 gives -9999 error with valid kernel

我有以下内核:

#pragma OPENCL EXTENSION cl_khr_fp64 : enable
#include <kernel_dependencies/complex_operations.h>
#include <kernel_dependencies/integer_operations.h>

__kernel void execute(__global long *a0, __global long *a1, ulong vo0, ulong vs0_0, ulong vo1, ulong vs1_0) {
    const ulong i0 = get_global_id(0); 

    if (i0 >= 2) {
        return;
    }

    long s1_1; 
    s1_1 = a1[35+i0*-6]; // <-- PROBLEM IS HERE
    const ulong idx0= (vo0 +i0*vs0_0);
    a0[idx0] = s1_1 + s1_1;
}

运行 我的 Telsa P100-PCIE-16GB 和 OpenCL C 1.2 在 clWaitForEvents 上给我一个 -9999 错误。我已将错误缩小到 a1 的索引。我尝试过:

s1_1 = a1[35];

相反,它工作得很好(尽管它给出了错误的结果)。我也尝试过使用 29,这是表达式 35+i0*-6 的唯一其他结果。我还尝试了表达式的各种其他配置,即以下都给出了这个 -9999 错误:

a1[(35 + i0 * -6)];
a1[35 + (i0 * -6)];
a1[35 + -(i0 * 6)];
a1[(-6 * i0) + 35];

如果我将表达式放入变量中,例如ulong t = 35+i0*-6; s1_1 = a1[t]; 我仍然遇到同样的错误。我可以在两者之间放置一个 printf 并验证该变量实际上包含 3529.

long s1_1; 
ulong t = 35+i0*-6; 
printf("%lu\n", t); // <-- This prints '35' first time and '29' second time.
s1_1 = a1[t];

我在这里错过了什么?我做错了什么?

我们找出问题所在。

鉴于 i0 是一个 ulong,它是无符号的。将它与 -6 相乘将导致它向上投射。 ulongs 似乎只能向上转换为 floats(这似乎是合理的),所以现在我们将 i0 作为浮点数乘以 -6 作为浮点数。这最终是一个 float 类型,我无法用它来索引我的数组,因此我得到一个 "segmentation fault" 或在这种情况下为“-9999”。

i0 更改为 int 将导致它不会施放它,因为 -6i0 现在可以相乘了。