VexCL вектор структур?

Так что я знаю, что можно использовать пользовательские типы с OpenCL. Но я не смог использовать их с VexCL. Создание вектора структур устройства работает нормально, но я не могу выполнить никаких операций.

Поскольку я не нашел примеров использования пользовательских типов с VexCL, мой вопрос, возможно ли это? Заранее спасибо.

2

Решение

VexCL не поддерживает операции с векторами структур из коробки. Вам нужно будет немного помочь. Во-первых, вам нужно сказать VexCL, как пишется имя типа структуры. Допустим, у вас есть следующая структура, определенная на стороне хоста:

struct point2d {
double x;
double y;
};

Вы должны предоставить спецификацию досаждать :: type_name_impl структура, которая будет генерировать строку, соответствующую имени типа структуры. Помните, что вы генерируете код C99:

namespace vex {
template <> struct type_name_impl<point2d> {
static std::string get() { return "struct point2d"; }
};
}

Вам также необходимо убедиться, что каждое сгенерированное ядро ​​знает о вашей структуре. Это может быть достигнуто с досаждать :: push_program_header () Функция после инициализации контекста VexCL:

vex::push_program_header(ctx, "struct point2d { double x; double y; };");

Это позволит вам объявлять векторы структуры и передавать векторы в пользовательские функции. Это должно быть достаточно общим. Вот полный пример:

#include <vexcl/vexcl.hpp>

// Host-side definition of the struct.
struct point2d {
double x, y;
};

// We need this for code generation.
namespace vex {
template <>
struct type_name_impl<point2d> {
static std::string get() { return "struct point2d"; }
};
}

int main() {
const size_t n = 16;

vex::Context ctx(vex::Filter::Env);
std::cout << ctx << std::endl;

// After this, every kernel will have the struct declaration in header:
vex::push_program_header(ctx, "struct point2d { double x; double y; };");

// Now we may define vectors of the struct:
vex::vector<point2d> x(ctx, n);
vex::vector<double>  y(ctx, n);

// We won't be able to use the vectors in any expressions except for
// custom functions, but that should be enough:
VEX_FUNCTION(point2d, init, (double, x)(double, y),
struct point2d p = {x, y}; return p;
);

VEX_FUNCTION(double, dist, (point2d, p),
return sqrt(p.x * p.x + p.y * p.y);
);

x = init(3,4);
y = dist(x);

std::cout << y << std::endl;
}

А вот ядро, которое будет сгенерировано для операции присваивания y = dist(x);:

struct point2d { double x; double y; };
double dist
(
struct point2d p
)
{
return sqrt(p.x * p.x + p.y * p.y);
}
kernel void vexcl_vector_kernel
(
ulong n,
global double * prm_1,
global struct point2d * prm_2
)
{
for(ulong idx = get_global_id(0); idx < n; idx += get_global_size(0))
{
prm_1[idx] = dist( prm_2[idx] );
}
}
1

Другие решения


По вопросам рекламы [email protected]