2015-06-15 3 views
2

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

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

+0

Пытались ли вы что-нибудь? Какой-то код? – jabujavi

ответ

1

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

struct point2d { 
    double x; 
    double y; 
}; 

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

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

Вы также должны убедиться, что каждое генерироваться ядро ​​знает о вашей структуре. Это может быть достигнуто с vex::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]); 
    } 
} 
+0

Ничего себе, спасибо, это именно то, что я искал. Я попробую завтра. – Frodo

Смежные вопросы