clSetKernelArg,size参数

Dan*_*ers 1 opencl

我是否必须理解clSetKernelArg()的OpenCL文档中arg_size参数的描述,或者我可以安全地输入:clSetKernelArg([parameter index],sizeof(A),(void*)&A)?...独立于A是什么?在我的情况下,A可能是一个结构,我不确定是否存在填充问题.

谢谢Daniel Dekkers

Dar*_*ros 6

你必须通过这个:

clSetKernelArg(kernel, Arg_index, sizeof(Arg), &Arg)
Run Code Online (Sandbox Code Playgroud)

哪里:

  • 内核:您要设置参数的内核
  • Arg_index:索引(第一个为0,第二个为1,依此类推),有时您只想更改1个参数
  • Arg:你要设置的参数.通常只是一个cl_mem缓冲对象,它包含大量数据,但它也可能是一个常量值.

注意:如果是常量值,则不得超过设备的常量内存.通常,此处仅使用单个整数/字符/浮点数或简单结构.

示例:对于此内核:

__kernel void mykernel (__global float *inout, int num){
     inout[get_global_id(0)] = num;
}
Run Code Online (Sandbox Code Playgroud)

您可以设置如下参数:

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);
Run Code Online (Sandbox Code Playgroud)

关于结构的问题,你不能使用结构...:

  • 不使用标准cl数据类型(cl_int -> OK,int -> unsafe!).
  • 使用任何类型的指针.
  • 使用嵌套结构.
  • 里面有任何其他类(即:std :: vector <>)
  • 他们需要某种特殊的对齐方式.

这个结构是有效的:

//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;
}
Run Code Online (Sandbox Code Playgroud)