我必須瞭解clSetKernelArg()的OpenCL文檔中arg_size參數的描述,或者我可以安全地輸入: clSetKernelArg([parameter index],sizeof(A),(void *) A)? ...獨立於A是什麼? 在我的情況下,A可能是一個結構體,我不確定是否可能存在填充問題。clSetKernelArg,size參數
感謝, 丹尼爾Dekkers的
我必須瞭解clSetKernelArg()的OpenCL文檔中arg_size參數的描述,或者我可以安全地輸入: clSetKernelArg([parameter index],sizeof(A),(void *) A)? ...獨立於A是什麼? 在我的情況下,A可能是一個結構體,我不確定是否可能存在填充問題。clSetKernelArg,size參數
感謝, 丹尼爾Dekkers的
你要通過這樣的:
clSetKernelArg(kernel, Arg_index, sizeof(Arg), &Arg)
其中:
cl_mem
緩衝區對象,它擁有大量的數據,但它也可能是一個常數值。注:如果它是一個恆定值,它不能超出設備的不斷內存。這裏通常只使用單個整數/字符/浮點數或簡單結構。
例:對於這個內核:
__kernel void mykernel (__global float *inout, int num){
inout[get_global_id(0)] = num;
}
你會設置的參數,如:
cl_mem my_buffer = clCreateBuffer(...);
clSetKernelArg(kernel, 0, sizeof(my_buffer), &my_buffer);
int my_int = 50;
clSetKernelArg(kernel, 1, sizeof(my_int), &my_int);
關於你的,你不能結構使用結構的問題..:
cl_int -> OK
,int -> unsafe!
)。這個結構是有效的:
//Host side
struct my_struct{
cl_int objectid;
cl_float3 speed;
cl_float3 direction;
};
//Kernel arg
my_struct a; a.objectid = 100; ...
clSetKernelArg(kernel, 1, sizeof(my_struct), &a);
//Kernel side
typedef struct {
int objectid;
float3 speed;
float3 direction;
} my_struct;
//Kernel declaration
__kernel void mykernel (__global float *inout, my_struct data){
inout[get_global_id(0)] = (float)data.objectid;
}
感謝您的詳細解答。但仍然不確定,因爲你仍然寫「sizeof(cl_mem),&my_buffer」而不是「sizeof(my_buffer),&mybuffer」。如果我要爲OpenCL內核編寫一個封裝器,我不能只傳遞一個(void *)數據並取該變量的sizeof()。不向包裝的用戶顯示大小? –
你甚至可以傳遞一個結構作爲參數嗎?我從來沒有見過一個顯示它正在工作的例子。內核arg會是什麼樣子?它不能是一個指針。另一方面,我用float16傳遞了一堆相似類型的參數。這工作正常。 – Dithermaster
@Dithermaster是的,你可以使用一個結構作爲參數。內核代碼定義將是結構類型。我不知道的是編譯器將接受的結構體的最大尺寸。 – DarkZeros
不是一個答案,只是暗示:你必須確保在結構和它的各個元素的排列必須等於主機和裝置。這可能很困難。事實上,一個曾經真正知道它的人說:「這可能需要反覆試驗才能弄清楚它」。您可以先看看https://www.khronos.org/registry/cl/sdk/1.1/docs/man/xhtml/attributes-types。html,但可能要考慮單獨將值傳遞給內核(這不應被視爲建議 - 我只是想提到這個選項是安全的) – Marco13
是的,謝謝。我在結構中只使用單獨的浮點數和整數。過去,我有一些填充問題,即使使用float3。 –
對齊問題很棘手,因爲OpenCL和C編譯器的行爲可能會有所不同。您將不得不使用編譯器標誌來確保這些情況下的一致性。 – DarkZeros