2014-08-27 4 views
1

У меня есть следующее OpenCL ядро:Каков правильный способ обработки буферов OpenCL структур?

//OPENCL KERNEL 
struct MyStruct 
{ 
    float A; 
    float B; 
    float C; 
    float D; 
    float E; 
}; 

__kernel void kernelMain(struct MyStruct* outputBuffer) 
{ 
    size_t idx = get_global_id(0); 

    //Do some stuff here with the outputBuffer 
    outputBuffer[idx].A = 42.0; 
} 

Как вы можете видеть, это определяет пользовательский тип, называемый MyStruct.

На принимающей стороне, у меня есть такое же определение структуры (копия-pasta'd):

//HOST SIDE 
struct MyStruct 
{ 
    float A; 
    float B; 
    float C; 
    float D; 
    float E; 
}; 

И я пытаюсь создать буфер для написания данных ядра, вновь принимать код на стороне :

//HOST SIDE 
cl::Buffer outputBuffer(clContext, CL_MEM_READ_WRITE, (size_t)numElements * sizeof(MyStruct)); 

clKernel.setArg(0, outputBuffer); 

Проблема возникает, когда я вызываю clKernel.setArg. Он выходит из строя с кодом ошибки -51, который, согласно документации OpenCL, является ошибкой размера аргумента ядра.

Я попытался с помощью OpenCL типов данных, переписывание определения хоста структуры быть:

struct MyStruct 
{ 
    cl_float A; 
    cl_float B; 
    cl_float C; 
    cl_float D; 
    cl_float E; 
}; 

Но это также дает ошибку.

Мой вопрос: Что такое правильный способ создания буфера OpenCL для работы с настраиваемыми структурами?

+2

попробовать __kernel аннулированию kernelMain (__ глобальная структура MyStruct * OUTPUTBUFFER) или просто __kernel аннулированию kernelMain (__ глобальной MyStruct * outputBuffer) –

+0

Использовать 'typedef struct {...} MyStruct;' и в ядре args '__kernel void kernelMain (__ global MyStruct * outputBuffer)' – DarkZeros

ответ

1

Если вы можете использовать C++, вы можете использовать макрос BOOST_COMPUTE_ADAPT_STRUCT(), который заботится об упаковке структуры и делает ее доступной для использования в ядрах OpenCL.

После обертывания, вы можете создать буфер памяти OpenCL для коллекции ваших структур с классом boost::compute::vector<T> контейнера:

// adapt "MyStruct" for OpenCL 
BOOST_COMPUTE_ADAPT_STRUCT(MyStruct, MyStruct, (A, B, C, D, E)); 

// create a OpenCL buffer with 100 "MyStruct" objects 
boost::compute::vector<MyStruct> my_structs(100); 

// use "my_structs" with an opencl kernel 
my_kernel.set_arg(0, my_structs); 
1

Если добавление ключевого слова __global не помогает, это звучит так, как будто у вас может быть different struct padding between host and device. Это сделало бы размер структуры или позиций данных внутри структуры разными. Наложение структуры - platform and compiler dependent.

Это то, что вы должны учитывать при использовании тех же структур на хосте и устройстве с OpenCL. Особенно, если вы нацеливаете свое программное обеспечение на несколько платформ.

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

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