我有以下内核:
#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
并验证该变量实际上包含35
或29
。
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];
我在这里缺少什么?我做错了什么?
答案 0 :(得分:1)
我们弄清楚问题是什么。
鉴于i0
是ulong
,它是未签名的。将其与-6
相乘会导致它向上投射。 ulong
似乎只能向上施放floats
(这似乎是合理的),所以现在我们将i0
作为浮点数乘以-6
。这最终是一个float
类型,我无法索引我的数组,因此我得到一个“分段错误”或在这种情况下“-9999”。
将i0
更改为int
会导致它不能投放,因为-6
和i0
现在可以成倍增加。