-
Notifications
You must be signed in to change notification settings - Fork 19
CallingOpenCLKernelsFromJava
Olivier Chafik edited this page Nov 10, 2022
·
3 revisions
Let's assume you wrote the following kernel in file com/mypackage/MyProgram.cl
:
__kernel void myKernel(__global const float* input, __global float* output, float multFactor) {
int i = get_global_id(0);
output[i] = input[i] * multFactor;
}
Then you have two ways to call it from JavaCL : a generic dynamic way, which is loosely typed, and a hard-typed precompiled way.
CLContext context = ... ; // e.g. JavaCL.createBestContext()
CLQueue queue = ... ; // e.g. context.createDefaultQueue()
int dataSize = 128;
CLBuffer<Float> input = context.createFloatBuffer(CLMem.Usage.Input, dataSize);
CLBuffer<Float> output = context.createFloatBuffer(CLMem.Usage.Output, dataSize);
float multFactor = 0.5f;
Setup the kernel :
String sources = ... ; // read the source file from resources / from a file
CLProgram program = context.createProgram(sources).build();
CLKernel kernel = program.createKernel("myKernel");
Then call it :
CLEvent kernelCompletion;
// The same kernel can be safely used by different threads, as long as setArgs + enqueueNDRange are in a synchronized block
synchronized (kernel) {
// setArgs will throw an exception at runtime if the types / sizes of the arguments are incorrect
kernel.setArgs(input, output, multFactor);
// Ask for 1-dimensional execution of length dataSize, with auto choice of local workgroup size :
kernelCompletion = kernel.enqueueNDRange(queue, new int[] { dataSize }, null);
}
kernelCompletion.waitFor(); // better not to wait for it but to pass it as a dependent event to some other queuable operation (CLBuffer.read, for instance)
Read [UnderstandOpenCLKernelArguments] to know which JavaCL type is appropriate for a given OpenCL C type.
This documentation only covers the wrapper autogeneration from within the Maven build system, but a standalone utility is also available and can be documented on demand.
Start by adding the following required repositories to your project's pom.xml file :
<repositories>
<repository>
<id>nativelibs4java</id>
<url>https://nativelibs4java.sourceforge.net/maven</url>
</repository>
<repository>
<id>jnaerator</id>
<url>https://jnaerator.sourceforge.net/maven</url>
</repository>
</repositories>
Setup the JavaCL Generator Maven Plugin :
<plugin>
<groupId>com.nativelibs4java</groupId>
<artifactId>javacl-generator</artifactId>
<version>1.0-SNAPSHOT</version>
<executions>
<execution>
<phase>generate-sources</phase>
<goals>
<goal>compile</goal>
</goals>
</execution>
</executions>
</plugin>
Start by setting up the kernel :
// The JavaCL Generator Maven Plugin will autogenerate a MyProgram class out of the MyProgram.cl file :
import com.mypackage.MyProgram;
...
MyProgram myProgram = new MyProgram(context);
Then call it :
// This call is statically typed and thread-safe :
CLEvent kernelCompletion = myProgram.myKernel(queue, input, output, multFactor, new int[] { dataSize }, null);