Тип вектора доступа OpenCL - PullRequest
8 голосов
/ 20 марта 2012

У меня есть переменная в ядре, например:

int16 element;

Я хотел бы знать, есть ли способ адресации третьего int в элементе, например

element[2], чтобыя был бы так же, как написание 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]);

Я знаю, что это ужасно, но это работает,; -)

Ответы [ 6 ]

13 голосов
/ 21 марта 2012

Ну, есть еще более грязный путь :), я надеюсь, OpenCL предоставляет лучший способ прохождения векторных элементов.

Вот мой способ сделать это.

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

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

Кстати, функция rand () недоступна в ядре OpenCL, как вы это сделали ??

9 голосов
/ 19 июля 2012

AMD рекомендует получать компоненты вектора следующим образом:

Поместить массив масок в постоянный буфер 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);
}
8 голосов
/ 14 августа 2012

Использование указателей - очень простое решение

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

int gid = get_global_id(0);


float *p = &f4;

result[gid]=p[3];
4 голосов
/ 27 марта 2012

Я использую этот обходной путь, надеясь, что компиляторы достаточно умны, чтобы понять, что я имею в виду (я думаю, что доступ к элементам является серьезным упущением в стандарте):

int16 vec;
// access i-th element:
((int*)vec)[i]=...;
4 голосов
/ 27 марта 2012

Это возможно , но это не так эффективно, как прямой доступ к массиву.

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;
}

Но, конечно, если вам нужен компонентный доступ таким образом, есть вероятность, что вам лучше не использовать векторы.

2 голосов
/ 21 марта 2012

Нет, это невозможно.По крайней мере, не динамически во время выполнения.Но вы можете использовать индекс времени компиляции для доступа к компоненту:

float4 v;
v.s0 == v.x; // is true
v.s01 == v.xy // also true

См. http://www.khronos.org/registry/cl/specs/opencl-1.1.pdf Раздел 6.1.7

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...