0

我有一个 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] = 99foo预期工作并输出[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]
4

1 回答 1

2

我相信问题是这样的:函数 foo 将调用者使用的指针设置为指向 foo 返回时超出范围的局部变量的地址。当调用者访问该指针时,超出范围的变量中的数据可能仍然是 99,也可能不是。为了演示,为此代码进行 gcc 调试构建。有用。现在在 foo(&d) 之后和 val=da[0] 之前添加一个 printf(hello\n")。现在它失败了。这是因为 printf 调用覆盖了包含超出范围 99 值的堆栈内存。

可能你打算:

*d->a = *b; 代替 d->a = b;

于 2013-05-08T02:41:29.913 回答