2012-03-20 50 views
7

我有whithin变量的内核,如:访问向量类型的OpenCL

int16 element; 

我想知道如果有ADRESS的元素像

element[2],这样我就第三INT方式像写作作为同一element.s2

所以,我怎样才能做这样的事情:

int16 element; 
int vector[100] = rand() % 16; 

for (int i=0; i<100; i++) 
    element[ vector[i] ]++; 

我做的方法是:

int temp[16] = {0}; 
int16 element; 
int vector[100] = rand() % 16; 

for (int i=0; i<100; i++) 
    temp[ vector[i] ]++; 


element = (int16)(temp[0],temp[1],temp[2],temp[3],temp[4],temp[5],temp[6],temp[7],temp[8],temp[9],temp[10],temp[11],temp[12],temp[13],temp[14],temp[15]); 

我知道这是可怕的,但它的工作原理,;-)

+0

您可以使用结构和数组就像在C:'INT16元素[3];'或许我不明白的问题.. 。 – pezcode 2012-03-20 18:47:07

+4

他不问载体的阵列。他询问使用数组符号访问矢量的组件。 – vocaro 2012-03-20 21:16:20

回答

11

那么还有肮脏的方式:),我希望的OpenCL提供了更好的方法遍历矢量元素。

这是我做这件事的方式。

union 
    { 
     int elarray[16]; 
     int16 elvector; 
    } element; 

//traverse the elements 
for (i = 0; i < 16; i++) 
element.elarray[i] = temp[vector[i]]++; 

在OpenCL内核中,rand函数不可用,你是如何使它工作的?

+1

大声笑...很好!好多了,我忘了工会! 关于兰特,这只是一个例子,我的矢量充满以外的设备。 谢谢 – Caslu 2012-03-21 12:33:16

4

可能的,但它不是那样有效的直接阵列访问。

float index(float4 v, int i) { 
    if (i==0) return v.x; 
    if (i==1) return v.y; 
    if (i==2) return v.z; 
    if (i==3) return v.w; 
} 

但是,当然,如果您需要以这种方式进行组件式访问,那么您可能最好不要使用向量。

4

我使用此解决方法,希望编译器非常聪明,明白我的意思(我觉得元素访问是一个严重的失误形成的标准):

int16 vec; 
// access i-th element: 
((int*)vec)[i]=...; 
8

AMD recommends越来越矢量分量是这样的:

把口罩的阵列到OpenCL的常量缓冲区:

cl_uint const_masks[4][4] = 
{ 
    {0xffffffff, 0, 0, 0}, 
    {0, 0xffffffff, 0, 0}, 
    {0, 0, 0xffffffff, 0}, 
    {0, 0, 0, 0xffffffff}, 
} 

内核里面写这样的事情:

uint getComponent(uint4 a, int index, __constant uint4 * const_masks) 
{ 
    uint b; 
    uint4 masked_a = a & const_masks[index]; 
    b = masked_a.s0 + masked_a.s1 + masked_a.s2 + masked_a.s3; 
    return (b); 
} 

__kernel void foo(…, __constant uint4 * const_masks, …) 
{ 
    uint4 a = ….; 
    int index = …; 
    uint b = getComponent(a, index, const_masks); 
} 
+0

是否从一个不同的存储库加载一个常量缓冲区而不是全局缓冲区?或者他们都共享相同的记忆线? – 2014-10-03 13:45:26

+1

这是独家前GCN?你知道它是否符合标准,或者至少在更新的AMD中仍然推荐和支持它? – Michele 2017-03-03 09:40:54

6

使用指针是一个非常简单的解决方案

float4 f4 = (float4)(1.0f, 2.0f, 3.0f, 4.0f); 

int gid = get_global_id(0); 


float *p = &f4; 

result[gid]=p[3];