cancel
Showing results for 
Search instead for 
Did you mean: 

Archives Discussions

ginquo
Adept II

Device-side enqueue, block syntax, and local kernel variables

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.

0 Likes
1 Solution
dipak
Big Boss

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,

View solution in original post

0 Likes
2 Replies
dipak
Big Boss

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,

0 Likes

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.