我有一个OpenCL内核代码,它的行为不符合预期。用gcc编译的类似C代码工作正常。
struct data {
short* a;
};
typedef struct data Data;
inline void foo(Data* d) {
short b[1] = {99};
d->a = b;
}
__kernel void bar(__global short* output) {
Data d;
foo(&d);
short val = d.a[0];
int id = get_global_id(0);
output[id] = val;
}
始终输出[0, 0, ..., 0]
如果我在d.a
中初始化__kernel bar
并仅在d->a[0] = 99
中指定foo
,则按预期工作并输出[99, 99, ..., 99]
提前致谢!
更新
我正在使用Java和JOCL作为主机代码。
正如ScottD建议我已将d->a = b;
中的foo
更改为*d->a = *b;
。
它在C版本中效果很好。但是在MacOS上导致OpenCL出现以下错误:
Exception in thread "main" org.jocl.CLException:
CL_BUILD_PROGRAM_FAILURE Build log for device 0:
CVMS_ERROR_COMPILER_FAILURE: CVMS compiler has crashed or hung building an element.
at org.jocl.CL.clBuildProgram(CL.java:9368)
...
或使用AMD CPU的Windows上的JVM终止:
# A fatal error has been detected by the Java Runtime Environment:
# EXCEPTION_ACCESS_VIOLATION (0xc0000005) at pc=0x000007fedfeb007a, pid=3816, tid=4124
# JRE version: 7.0-b147
# Java VM: Java HotSpot(TM) 64-Bit Server VM (21.0-b17 mixed mode windows-amd64 compressed oops)
# Problematic frame:
# C [amdocl64.dll+0x60007a]
答案 0 :(得分:2)
我认为问题是:函数foo将调用者使用的指针设置为当foo返回时超出范围的局部变量的地址。当调用者访问该指针时,超出范围变量的数据可能仍然是99,也可能不是。要演示,请为此代码创建一个gcc调试版本。有用。现在在foo(& d)之后和val = da [0]之前添加一个printf(hello \ n“)。现在它失败了。这是因为printf调用覆盖了包含超出范围99值的堆栈内存。
可能你打算:
* d-> a = * b;代替d-> a = b;