Daniel Dekkers
Daniel Dekkers

Reputation: 269

clSetKernelArg, size parameter

Do I have to understand the description of the arg_size parameter in the OpenCL documentation of clSetKernelArg() or could I safely just type: clSetKernelArg([parameter index], sizeof(A), (void*) &A)? ...independent of what A is? In my case A might be a struct, I'm not sure if there could be padding problems.

Thanks, Daniel Dekkers

Upvotes: 1

Views: 9444

Answers (1)

DarkZeros
DarkZeros

Reputation: 8410

You have to pass this:

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

Where:

  • Kernel: The kernel you want to set up an argument
  • Arg_index: The index (0 for first, 1 for second, and so on), sometimes you just want to change 1 arg
  • Arg: The argument you want to set up. Typically is just a cl_mem buffer object that hold a larg array of data, but it might also be a constant value.

NOTE: If it is a constant value, it must not exceed the constant memory of your device. Typically only single integers/char/floats or simple struct are used here.

Example: For this kernel:

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

You would set the arguments like:

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);

Regarding your question of structs you cannot use struct that..:

  • Are not using standard cl data types (cl_int -> OK, int -> unsafe!).
  • Use any kind of pointers.
  • Use nested structs.
  • Have any other class inside (ie: std::vector<>)
  • They need some kind of special alignment.

This struct would be valid:

//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;
}

Upvotes: 8

Related Questions