clSetKernelArg,size参数

时间:2014-02-28 16:08:28

标签: opencl

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

谢谢, Daniel Dekkers

1 个答案:

答案 0 :(得分:5)

你必须通过这个:

clSetKernelArg(kernel, Arg_index, sizeof(Arg), &Arg)

其中:

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

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

示例:对于此内核:

__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数据类型(cl_int -> OKint -> 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;
}