2014-08-27 103 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主機和設備上使用相同結構時應考慮的問題。特別是如果您將軟件定位到多個平臺。

一種解決方法是使用浮點數組在主機和設備之間移動數據。

相關問題