2014-08-27 63 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) – 2014-08-28 00:09:30

+0

使用'typedef struct {...} MyStruct;'和内核参数'__kernel void kernelMain(__ global MyStruct * outputBuffer)' – DarkZeros 2014-08-28 08:33:06

回答

1

如果您能够使用C++,则可以使用BOOST_COMPUTE_ADAPT_STRUCT()宏,该宏负责封装结构并使其可用于OpenCL内核。

包装后,你可以为你的结构与boost::compute::vector<T>容器类集合创建的OpenCL内存缓冲区:

// 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主机和设备上使用相同结构时应考虑的问题。特别是如果您将软件定位到多个平台。

一种解决方法是使用浮点数组在主机和设备之间移动数据。

相关问题