OpenCL 1.2在有效内核时出现-9999错误

时间:2017-05-10 09:02:45

标签: c opencl gpu nvidia gpgpu

我有以下内核:

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

使用OpenCL C 1.2在我的Telsa P100-PCIE-16GB上运行此操作会在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];

我在这里缺少什么?我做错了什么?

1 个答案:

答案 0 :(得分:1)

我们弄清楚问题是什么。

鉴于i0ulong,它是未签名的。将其与-6相乘会导致它向上投射。 ulong似乎只能向上施放floats(这似乎是合理的),所以现在我们将i0作为浮点数乘以-6。这最终是一个float类型,我无法索引我的数组,因此我得到一个“分段错误”或在这种情况下“-9999”。

i0更改为int会导致它不能投放,因为-6i0现在可以成倍增加。