6

I recently got in touch with Java 8 and I'm trying to learn Lambda expressions. I want to do some graphics calculations, my code so far:

    IntStream.range(0, (screenSize.width * screenSize.height)).parallel().forEach(id -> { 
        int x = id % screenSize.width;
        int y = ((id-x) / screenSize.width);
        /*look up what color this pixel is.*/
    });

Now all this Code is for graphics, everything is basic Math (plus, minus, multiply, modulo), except for bufferedImage.getRGB(x, y) and operations with java.awt.Color, and it can be done for each pixel seperately.

Now the question: Is it possible to run this on the GPU? Or is this even automatically GPU-based? (I remember reading this somewhere, but I'm not sure)

Bart Kiers
  • 166,582
  • 36
  • 299
  • 288
Erik Brendel
  • 683
  • 9
  • 23
  • 3
    I don't think so. There is a project on OpenJDK that (hopes) supports such a thing though: https://wiki.openjdk.java.net/display/Sumatra/Main – Bart Kiers May 31 '15 at 09:15
  • possible similarity: http://stackoverflow.com/questions/22866901/using-java-with-nvidia-gpus-cuda (Also read about Sumatra http://openjdk.java.net/projects/sumatra/ ) – coolharsh55 May 31 '15 at 09:15
  • 1
    In fact, there already **is** a solution for this: https://github.com/aparapi/aparapi . It can be considered as a "predecessor" of project Sumatra (or, as they called in the mailing lis: Aparapi is a "tracing bullet" of what is done in Sumatra). It's also mentioned in the list at the end of the question that kicker86 linked to in the above comment. – Marco13 May 31 '15 at 10:46
  • But, if I got it correctly, aparapi only works with arrays of primitive data types. This would be much work, to convert everything into arrays of int or double. Sumatra sounded like it would be able to take nearly every java code. Am I right? – Erik Brendel May 31 '15 at 10:51
  • 1
    Sure, Aparapi can not automatically convert *all* Java constructs to GPU code. There are approaches for this, like Sumatra or [rootbeer](https://github.com/pcpratts/rootbeer1), but it's complex (particularly, the interdependencies with the JIT, and the different memories that are involved!), and I doubt that there will be a generic solution for this soon. – Marco13 May 31 '15 at 11:07
  • not GPU, but hotspot may auto-vectorize (SIMD instructions) some loops. Although the support for that is not as advanced as, for example, GCC's autovectorization – the8472 May 31 '15 at 12:37
  • I feel dumb to ask this, but as a nonnative English speaker and a beginner in java programming: what means vectorization? – Erik Brendel Jun 02 '15 at 16:17

3 Answers3

10

The JavaVM implementation is free to implement the Java bytecode interpretation however it wants as long as the results are correct. It is free to run anything on the GPU when it wants to. However, I don't know of any Java implementation which does this currently. There is a project to add GPU acceleration to OpenJDK (Project Sumatra), and you guessed correctly: It focuses on the stream API because it was designed to write code which can be parallelized. But this is currently far from production-ready and currently it doesn't seem like there is anyone working on it.

When you want to run computations on the GPU from a Java program today, you will need a library which wraps a GPU computing API like OpenCL using the Java Native Interface (for OpenCL there is JOCL). Be prepared to learn a new programming language, because every GPU computing API takes instructions in a different language and none of them is very similar to Java.

Philipp
  • 67,764
  • 9
  • 118
  • 153
1

It depends on what you are doing. If those really are general parallel computations, connecting GPGPU things like OpenCL may have its benefits, even though integrating it won't be easy.

However, you are doing graphics computatuons, as you said. It's what shaders are designed for. A vertex shader is run once per vertex, then unseen elements are cut, then the scene is split into fragments (size of a pixel each) and each of them is then run through a fragment shader.

I've worked with GLSL a bit, so I can tell your code looks quite simple in shaders. X and Y for each fragment are calculated in between vertex and a fragment shaders by interpolating vertex coordinates (that's how varying variables work), texture sampling is done via texture2d function.

D-side
  • 9,150
  • 3
  • 28
  • 44
0

There is a research project [1] to do exactly this. It is an extension of the JVM (Graal VM actually) to generate C OpenCL code from the byte-codes at run-time.

[1] http://dl.acm.org/citation.cfm?id=2627381

snatverk
  • 661
  • 1
  • 7
  • 11