Reputation: 279
Can I use struct as OpenCL kernel argument?
I want to use struct type as OpenCL kernel argument in NVIDIA OpenCL 1.2 (NVIDIA driver 352.39)
I tried, but it makes CL_OUT_OF_RESOURCE error.
What is wrong in my code??
[for struct definition]
/* struct type definition */
typedef struct _st_foo
{
int aaa;
int bbb;
.....
int zzz;
}st_foo; // st_foo doesn't have any pointer members
[Host code]
/* OpenCL initalize... */
st_foo stVar;
cl_mem cm_buffer;
cm_buffer = clCreateBuffer(cxContext, CL_MEM_READ_ONLY, sizeof(st_foo), NULL, NULL);
clSetKernelArg(ckKernel, 0, sizeof(cl_mem), (void*)&cm_buffer);
clEnqueueWriteBuffer(cqueue, cm_buffer, CL_TRUE, 0, sizeof(st_foo), &stVar, 0, NULL, NULL);
[Kernel code]
__kernel void testfunction(__global const st_foo *stVar)
{
printf("stVar->aaa=%d\n", stVar->aaa);
}
Upvotes: 1
Views: 9956
Reputation: 8420
It is not safe to declare structs in OpenCL if you are not using the OpenCL datatypes. And also, alignment may be an issue, force a packet alignment in the Host/Device compiler.
You should declare your structs as:
[Host]
typedef struct __attribute__ ((packed)) _st_foo
{
cl_int aaa;
cl_int bbb;
.....
cl_int zzz;
}st_foo;
[Device]
typedef struct __attribute__ ((packed)) _st_foo
{
int aaa;
int bbb;
.....
int zzz;
};
Aditionally, if you just want a single parameter, not an array of structs, then just pass it in as:
clSetKernelArg(ckKernel, 0, sizeof(mystruct), mystruct);
Upvotes: 6