Hello,
I'm currently in the process of updating my code to make use of the new OpenCL 2.0 features. At the moment I'm implementing a kernel that enqueues some of my existing kernels from the device. In order to enqueue a kernel from the device, this kernel needs to be wrapped in a block, which is then passed to enqueue_kernel(). What this essentially does is that it creates a new anonymous kernel in which the actual kernel is called as a function.
However, this fails when the kernel defines some local variables. This is because OpenCL C requires local variables to be defined at kernel-scope and the kernel is actually treated as a function in the block.
You can find a minimal example of this here: device_enqueue.cl
What I wonder is if there is any other way to make use of device-side enqueue without having to rip out all local definitions out of a kernel and having to pass them as arguments. I'd like to avoid this, because I want to keep calling the kernels from the host if necessary. Exposing all internal local variables would also mess with encapsulation.
PS: Is there any way to get a linker output log from a failed call to clLinkProgram()? I thought I'd use clGetProgramBuildInfo(), but since clLinkProgram() doesn't return a valid program on error, I don't know what to pass as argument.
Solved! Go to Solution.
Hi,
What I wonder is if there is any other way to make use of device-side enqueue without having to rip out all local definitions out of a kernel and having to pass them as arguments.
Unfortunately, I don't think there is a work-around other than passing the local memory dynamically as kernel arguments that are a pointer type to local address space. As per spec, you can not pass blocks having global variables or stack variables local to the enclosing lexical scope that are a pointer type in the local or private address space. I guess, this is also valid for local memory variables declared inside a kernel.
Is there any way to get a linker output log from a failed call to clLinkProgram()? I thought I'd use clGetProgramBuildInfo(), but since clLinkProgram() doesn't return a valid program on error, I don't know what to pass as argument.
I guess, you can use clGetProgramBuildInfo on that unsuccessful program object to check the linking error. Whereas, if the clLinkProgram returns a NULL program object, it passes an appropriate error code using errcode_ret.
Regards,
Hi,
What I wonder is if there is any other way to make use of device-side enqueue without having to rip out all local definitions out of a kernel and having to pass them as arguments.
Unfortunately, I don't think there is a work-around other than passing the local memory dynamically as kernel arguments that are a pointer type to local address space. As per spec, you can not pass blocks having global variables or stack variables local to the enclosing lexical scope that are a pointer type in the local or private address space. I guess, this is also valid for local memory variables declared inside a kernel.
Is there any way to get a linker output log from a failed call to clLinkProgram()? I thought I'd use clGetProgramBuildInfo(), but since clLinkProgram() doesn't return a valid program on error, I don't know what to pass as argument.
I guess, you can use clGetProgramBuildInfo on that unsuccessful program object to check the linking error. Whereas, if the clLinkProgram returns a NULL program object, it passes an appropriate error code using errcode_ret.
Regards,
Yeah, my solution in the end was to wrap the concrete kernel implementation in another function, that takes pointers to the local variables as arguments. I then defined and passed those in the block and kernel: device_enqueue_fix.cl
I will try checking the program objects for linker errors, thanks.