奇怪的行为OpenCL使用Union里面的Register

时间:2012-06-11 19:14:28

标签: ubuntu union opencl

我在opencl中使用变量union(private)获得了一个奇怪的行为。代码:

v = { 0, 1, 2, ... } // Defined in host and load to Device

typedef union svec8{
    int  word[8];
    int8 word8;
} vec8;

__kernel
void red( global vec8 *v, global int *out ){
    uint sizeBin = 8;
    vec8 binning = {0}; // Every Thread has a 8-space bin, initialized with 0
    uint gID     = get_global_id(0);
    int temp;

    binning.word8 = v[ dID ].word8;

    #ifdef CONDITION
        temp = 0;
        for ( uint i = 0; i < sizeBin; i++ ){
            temp += binning.word[ i ];
        }
    #endif

    if ( dID == 0 ){
        *out = binning.word[n]; // n belongs to [0, 7]
    }
}

问题在于,对于每个选择的n,当定义CONDITION时,* out总是等于1,但是如果我unf CONDITION,* out得到正确的值,即0,1,..,或7,当然取决于哪个ni选择。

我还注意到,如果我停止使用联合并只使用int8,它就可以解决问题。

提前致谢,

平台:Ubuntu 12.04 - 3.2.0-24-generic-pae - 驱动程序OpenCL 1.2 AMD-APP(923.1)

1 个答案:

答案 0 :(得分:2)

AMD有联盟协调的错误,可能是原因?见my report。我建议你尝试使用英特尔SDK运行相同的代码,看它是否有所作为。

编辑:在我自己的代码(许多不同的联盟)中,我使用这个解决方案,直到上游修复:

#define AMD_UNION_ALIGN_BUG_WORKAROUND() __attribute__((aligned(32)))
//            this is the biggest alignment value in the union ^^^^^
// in your case sizeof(int)*8=32 (in bytes)

// define unions like this
union svec8 { /*...*/ } AMD_UNION_ALIGN_BUG_WORKAROUND() vec8;