Aparapi: OpenCL in Java

Edit: Aparapi has been open sourced and many issues have already been fixed and improved.

If you have an AMD GPU/APU, you should try Aparapi. This software lets you write OpenCL-code in Java pretty high-level. The idea is that is sort of that it processes the Java intermediate code to search for loops and then create optimised OpenCL-kernels. Just download Aparapi and try the two examples. As the current version is still in alpha, it is not flawless yet. What I think is important when having worked with Aparapi is that you learn how to keep it simple – like you know that you can gain most speed on straight roads and turns slow down.

The Aparapi-team tries to avoid explicit defining of local memory, but it is still possible by using the @Local annotation. Such decisions show the team wants Aparapi to be high-level. It also integrates well with JavaCL and JOCL, so for the kernels you already have created, you can mix. You can also check out a video introducing Aprapi (it is video 15, if #-linking doesn’t work).

Time to create your own project. As not all errors are documented or are solved in the upcoming version, below you will find a list of common errors and how to easily solve them.

Aparapi errors and how to solve them

As it is still in alpha, so there are (still) some restrictions. Long story short: only use primitives, 1-dimensional arrays and for/while-loops. So if you used specialised objects, threads, recursion and such, it’s time to find that unoptimised code again you based your code on. Input and output are specified with the final keyword. If initiated, then it’s input, if not, then it’s output. If you force Aparapi to use the GPU, you get feedback (ClassParseExceptions) about how to fix your program. Else it will fall back to threads automatically.

System.out.println(kernel.getExecutionMode()); // print the selected mode
kernel.setExecutionMode(Kernel.EXECUTION_MODE.GPU); // force GPU-mode

Then we can get back to work and try to find the reasons in the documentation and FAQ. Here are the ClassParseExceptions I could find and how I fixed them.

java.lang.UnsatisfiedLinkError: com.amd.aparapi.KernelRunner.initJNI(Lcom/amd/aparapi/Kernel;ZJ)J

Make sure LD_LIBRARY_PATH is set to include the directory where the native Aparapi-libary resides. See the run-files in the two provided projects.

global size can’t be 0

When starting an empty batch, it complaints. So do a check, before launching.

Found an array local variable which assumes that we will alias a field array

Within the run() function, no array-instantiations are allowed. Make them final and initiate them in the class.

We don’t support putfield instructions

The manual says: “Primitive array elements can be read or written. However, primitive scalar fields can only be read.” I thought it was cryptic. Te results of each kernel needed to be written into an array and cannot be summed (read: shared). Summing can easily be done on the CPU. Rule of thumb: if it is input or output and it cannot be set as final, then it won’t work.

Detected an non-reducable operand consumer/producer mismatch

Edit: I’m working on a new article, but while it is not released, report if you get this error.

Not allowed is “var1 = var2 = var3 = X“. As the manual says: “Generally code should be as simple as possible”. “bitfield = ((1 << ((board_size+1) >> 1)) – 1) << ((board_size) >> 1);” is allowed luckily.

NullPointerException in ExpressionList.foldComposite

Another cryptic one. We must explicitly initialize variables, so no lazy initialization. That means also no temporary variables in loops. I found that “if – else if” also gave this error.

CodeGenException: composite COMPOSITE_IF

This happens when the if-statements have more conditions in it. Removing all instances of “else” could help here, so the conditions for all the if-statements get somewhat longer. See the next error too. Another situation is when to many if-statements are in a while-loop. Another method is to put an assignment

CodeGenException: ifeq -> 0193, if_icmpne -> 0194

Cryptic isn’t it? I make “if equal” and “if inverse compare not equal” of it. It seems that if you have two if-statements checking for the same, it fails. The solution is to make an if-statement into an if-statement – which seems more complex to me, but not to Aparapi.

java.lang.ClassFormatError: Unknown constant tag 117 in class file com/amd/aparapi/classtools/ClassModel$AttributePool$SignatureEntry

You don’t have an AMD GPU. Aparapi might be supporting NVidia in the future, but not now.

Need more?

Try the Aparapi-forum first. Please let me know also in the comments, so I can complete the list. This is also a good moment to give the Aparapi-team some feedback before the next version arrives.

This is what I like: OpenCL as a base and a clever layer on top of that – here is where the competition should be instead of generating low-level alternatives. I therefore wish Gary Frost and hist team all the best with this product.

2 thoughts on “Aparapi: OpenCL in Java

  1. MySchizoBuddy

    It would be nice if they atleast build linear algebra package on top of Aparapi.

Comments are closed.