简体   繁体   English

OpenCL:从内联函数初始化struct字段不起作用

[英]OpenCL: struct field initialization from inline function does not work

I have an OpenCL kernel code, which does not behave as expected. 我有一个OpenCL内核代码,它的行为不符合预期。 The similar C code compiled with gcc works fine. 用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;
}

Always outputs [0, 0, ..., 0] . 始终输出[0, 0, ..., 0]
If I initialize da in __kernel bar and only assign d->a[0] = 99 in foo it works as expected and outputs [99, 99, ..., 99] 如果我在__kernel bar初始化da并且只在foo指定d->a[0] = 99 ,它按预期工作并输出[99, 99, ..., 99]

Thanks in advance! 提前致谢!

UPDATE: 更新:
I'm using Java and JOCL for the host code. 我正在使用Java和JOCL作为主机代码。

As ScottD suggested I've changed d->a = b; 正如ScottD所说,我改变了d->a = b; in function foo to *d->a = *b; 在函数foo*d->a = *b; .
And it works great in C version. 它在C版本中运行良好。 But causes the following error for OpenCL on MacOS: 但是在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)
...

Or a JVM termination on Windows with AMD CPU: 或者使用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]

I believe the problem is this: Function foo sets a pointer used by the caller to the address of a local variable that goes out of scope when foo returns. 我相信问题是这样的:函数foo将调用者使用的指针设置为当foo返回时超出范围的局部变量的地址。 When the caller accesses that pointer, data in the out of scope variable may or may not still be 99. To demonstrate, make a gcc debug build for this code. 当调用者访问该指针时,超出范围变量的数据可能仍然是99,也可能不是。要演示,请为此代码创建一个gcc调试版本。 It works. 有用。 Now add a printf(hello\\n") after foo(&d) and before val=da[0]. Now it fails. This is because the printf call overites the stack memory containing the out of scope 99 value. 现在在foo(&d)之后和val = da [0]之前添加一个printf(hello \\ n“)。现在它失败。这是因为printf调用覆盖了包含超出范围99值的堆栈内存。

Probably you intended: 可能你打算:

*d->a = *b; * d-> a = * b; in place of d->a = b; 代替d-> a = b;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM