Передача структур C в ядро ​​OpenCL - PullRequest
0 голосов
/ 24 августа 2018

У меня есть следующая структура в моей хост-программе:

typedef struct  s_figure
{
    cl_float        reflection;
    cl_int          color;
    enum e_figure   type;
    cl_float3       vector1;
    cl_float3       vector2;
    cl_float        param1;
    cl_float        param2;
}                       t_figure;

У меня есть следующая структура в моем ядре:

typedef struct          s_figure
{
    float       reflection;
    int         color;
    enum e_figure   type;
    float3      vector1;
    float3      vector2;
    float       param1;
    float       param2;
}                       t_figure;

Также вы можете увидеть перечисление для обоих:

enum            e_figure
{
    BadFigure = -1,
    InfinitePlane = 0,
    Sphere = 1,
    InfiniteCylinder = 2,
    InfiniteCone = 3
};

При такой передаче данных ядру OpenCL (где figure - это правильный массив разобранных структур):

buf_figures = clCreateBuffer(context, CL_MEM_USE_HOST_PTR, sizeof(t_figure) * figures_count, figures, &err);
clEnqueueWriteBuffer(view->cl->queue, buf_figures, CL_TRUE, 0,sizeof(t_figure) * figures_count, figures, 0, NULL, NULL);

У меня проблемы с искажением данных, например, цвет после передачи данных в ядро ​​OpenCL может быть изменен на очень разные (0xFFFFFF-> 0x007FC2). Также алгоритмы raytrace работают по-разному при каждом выполнении программы. Как я могу это исправить? Я думаю, что компилятор gcc создает структуры не так, как openclc, но как его синхронизировать?

1 Ответ

0 голосов
/ 24 августа 2018

Вам необходимо указать __attribute__ ((packed)) для объявления структуры как для хоста, так и для устройства.В противном случае разные компиляторы (компилятор хоста и компилятор устройства) могут создавать разные структуры памяти для структуры.

РЕДАКТИРОВАТЬ: Учитывая, что sizeof(t_figure) равно 52 на хосте и устройстве, основная причина, вероятно, не связана со структурой.

Поскольку вы создаете буфер с CL_MEM_USE_HOST_PTR, есть некоторыеПредупреждения, которые вы должны учитывать:

  1. figures указатель, который вы указываете с помощью CL_MEM_USE_HOST_PTR, должен указывать на действительную память, пока буфер жив, потому что он фактически используется в качестве основной памятихранилище для объекта cl_mem.

  2. Буфер, созданный с помощью CL_MEM_USE_HOST_PTR, уже использует память (или ее копию), указанную figures, поэтому последующая запись с clEnqueueWriteBuffer является избыточнойВот.Что еще более важно, я даже не уверен, как clEnqueueWriteBuffer ведет себя в этом случае, потому что эта операция по сути является memcpy(figures,figures, size).

...