[PATCH] GPU Exploitation Infrastructure

Ben Walsh ben_walsh at uk.ibm.com
Tue Feb 6 15:32:06 UTC 2018


Hi Paul,

To build OpenJDK with Eclipse OpenJ9 we ...
  Take an OpenJDK level
  Remove the HotSpot compiler code completely
  Apply a set of patches to the OpenJDK level
  Add the OpenJ9 code (https://www.eclipse.org/openj9)

This patch is one of that set of patches.

The motivation is to get the changes we make to OpenJDK to support this 
functionality contributed - 
https://www.ibm.com/support/knowledgecenter/en/SSYKE2_8.0.0/com.ibm.java.lnx.80.doc/diag/understanding/gpu_overview.html

Someone that is able to view the code of a competing compiler 
implementation to HotSpot, can view an example of the JVM side of the 
solution (for OpenJ9) here - 
https://github.com/eclipse/openj9/search?utf8=%E2%9C%93&q=promoteGPUCompile&type=

The additional intention with this patch to OpenJDK is to reduce the 
impact on HotSpot of the "stub" promoteGPUCompile native library method as 
much as possible.
I'm not sure I've placed it in the most optimal location yet or done so in 
the best way - please provide guidance.

All trace of the "stub" promoteGPUCompile native library method needs to 
go, when we remove the HotSpot compiler code, so the implementation in 
OpenJ9 can fully replace it.

Regards,
Ben Walsh




From:   Paul Sandoz <paul.sandoz at oracle.com>
To:     Ben Walsh <ben_walsh at uk.ibm.com>
Cc:     valhalla-dev <valhalla-dev at openjdk.java.net>
Date:   01/02/2018 23:14
Subject:        Re: [PATCH] GPU Exploitation Infrastructure



Hi Ben,

Can you expand a bit on your motivation or goals here, such as to provide 
hooks but no implementation? It?s hard for me to comment without a better 
understanding of your motivations and whether this is a research endeavor 
or something you consider more concrete.

I consider the approach you have taken as a very ad-hoc integration into 
the stream API, which does have a cost both in maintenance and possibly 
performance. The hook is part of a currently undocumented public SPI whose 
behaviour would need to be specified if it would be part of the JDK. 
Further, it is missing what i consider to be the most interesting bit 
which is the GPU offload :-)

I have follow on questions such as what happens if the stream pipeline 
cannot be offloaded because the byte code of a stream operation is not 
translatable to OpenCL or CUDA code, or a pre-cooked snippet of. We have 
discussed this problem a few times, we term it crackable lambdas, and it's 
quite a hard problem. We would like to solve it at some point for the 
Vector API, which supports compiling down vector computations to a 
sequence of vector harder instructions. It might involve something like 
this:

  http://cr.openjdk.java.net/~jrose/panama/token-codes.html

Thanks,
Paul. 

On Feb 1, 2018, at 6:01 AM, Ben Walsh <ben_walsh at uk.ibm.com> wrote:

As per the responses to 
http://mail.openjdk.java.net/pipermail/core-libs-dev/2018-January/051181.html

, I am reposting this patch to this mailing list ...

This patch provides the infrastructure to enable the exploitation of a GPU 

by the compiler to accelerate certain suitable Java constructs.

When enabled, a suitable compiler can attempt to accelerate the following 
Java constructs by launching the corresponding lambda expression on the 
GPU:

  IntStream.range(<range>).parallel().forEach(<lambda>)
  IntStream.rangeClosed(<range>).parallel().forEach(<lambda>)

  where:

     <range> defines upper and lower bounds
     <lambda> is a correctly defined lambda expression

As it stands, with the HotSpot compiler, this patch performs a "no op" in 
the newly added in-built native library method.
This can be extended so that the HotSpot compiler attempts the 
acceleration detailed above instead.

I would like to pair with a sponsor to contribute this patch ...


--------------------------------------------------------------------------------------------------------------

diff -r fd237da7a113 make/hotspot/symbols/symbols-unix
--- a/make/hotspot/symbols/symbols-unix Mon Jan 22 23:06:29 2018 -0800
+++ b/make/hotspot/symbols/symbols-unix Tue Jan 30 10:07:18 2018 +0000
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2016, 2017, Oracle and/or its affiliates. All rights 
reserved.
+# Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights 
reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
@@ -187,3 +187,6 @@
JVM_AddReadsModule
JVM_DefineModule
JVM_SetBootLoaderUnnamedModule
+
+# GPU exploitation support
+Java_java_util_stream_IntPipeline_promoteGPUCompile
diff -r fd237da7a113 src/hotspot/share/include/jvm.h
--- a/src/hotspot/share/include/jvm.h   Mon Jan 22 23:06:29 2018 -0800
+++ b/src/hotspot/share/include/jvm.h   Tue Jan 30 10:07:18 2018 +0000
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights 
reserved.
+ * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights 
reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
@@ -1189,6 +1189,12 @@
JNIEXPORT jstring JNICALL
JVM_GetTemporaryDirectory(JNIEnv *env);

+/*
+ * GPU exploitation support
+ */
+JNIEXPORT void JNICALL
+Java_java_util_stream_IntPipeline_promoteGPUCompile(JNIEnv *env, jobject 
obj);
+
/* Generics reflection support.
 *
 * Returns information about the given class's EnclosingMethod
diff -r fd237da7a113 src/hotspot/share/prims/jvm.cpp
--- a/src/hotspot/share/prims/jvm.cpp   Mon Jan 22 23:06:29 2018 -0800
+++ b/src/hotspot/share/prims/jvm.cpp   Tue Jan 30 10:07:18 2018 +0000
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights 
reserved.
+ * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights 
reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
@@ -3661,3 +3661,11 @@
JVM_ENTRY_NO_ENV(jint, JVM_FindSignal(const char *name))
  return os::get_signal_number(name);
JVM_END
+
+
+// GPU exploitation support stub 
/////////////////////////////////////////////////////////////////////
+
+JVM_ENTRY(void, 
Java_java_util_stream_IntPipeline_promoteGPUCompile(JNIEnv *env, jobject 
thisObj))
+  JVMWrapper("Java_java_util_stream_IntPipeline_promoteGPUCompile");
+  return;
+JVM_END
diff -r fd237da7a113 
src/java.base/share/classes/java/util/stream/AbstractPipeline.java
--- a/src/java.base/share/classes/java/util/stream/AbstractPipeline.java 
Mon Jan 22 23:06:29 2018 -0800
+++ b/src/java.base/share/classes/java/util/stream/AbstractPipeline.java 
Tue Jan 30 10:07:18 2018 +0000
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012, 2016, Oracle and/or its affiliates. All rights 
reserved.
+ * Copyright (c) 2012, 2018, Oracle and/or its affiliates. All rights 
reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
@@ -373,6 +373,14 @@
        return sourceStage.parallel;
    }

+    /**
+     * Returns the sourceSpliterator
+     *
+     * @return the sourceSpliterator
+     */
+    final Spliterator<?> getSourceSpliterator() {
+       return sourceSpliterator;
+    }

    /**
     * Returns the composition of stream flags of the stream source and 
all
diff -r fd237da7a113 
src/java.base/share/classes/java/util/stream/IntPipeline.java
--- a/src/java.base/share/classes/java/util/stream/IntPipeline.java Mon 
Jan 22 23:06:29 2018 -0800
+++ b/src/java.base/share/classes/java/util/stream/IntPipeline.java Tue 
Jan 30 10:07:18 2018 +0000
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012, 2017, Oracle and/or its affiliates. All rights 
reserved.
+ * Copyright (c) 2012, 2018, Oracle and/or its affiliates. All rights 
reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
@@ -433,10 +433,33 @@
    }

    // Terminal ops from IntStream
+    private static boolean tryGPU = false;
+    protected static native void promoteGPUCompile();

    @Override
    public void forEach(IntConsumer action) {
-        evaluate(ForEachOps.makeInt(action, false));
+       boolean instanceOfRangeIntSpliterator = getSourceSpliterator() 
instanceof Streams.RangeIntSpliterator;
+       if (instanceOfRangeIntSpliterator) {
+               Streams.RangeIntSpliterator intRange = 
(Streams.RangeIntSpliterator)getSourceSpliterator();
+               int last = intRange.upTo;
+               if  (intRange.upTo != Integer.MAX_VALUE && intRange.last 
== 1){
+                       last = intRange.upTo + 1;
+               }
+               // tryGPU will be set at runtime using a suitable JVM 
specific method option
+               if (tryGPU) {
+                       for (int i = intRange.from; i < last; i++){
+                               action.accept(i);
+                       }
+                       if (intRange.upTo == Integer.MAX_VALUE && 
intRange.last == 1){
+                               action.accept(Integer.MAX_VALUE);
+                       }
+                       return;
+               }
+       } 
+       evaluate(ForEachOps.makeInt(action, false));
+       if (instanceOfRangeIntSpliterator){
+               promoteGPUCompile();
+       }
    }

    @Override
diff -r fd237da7a113 
src/java.base/share/classes/java/util/stream/Streams.java
--- a/src/java.base/share/classes/java/util/stream/Streams.java Mon Jan 22 

23:06:29 2018 -0800
+++ b/src/java.base/share/classes/java/util/stream/Streams.java Tue Jan 30 

10:07:18 2018 +0000
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights 
reserved.
+ * Copyright (c) 2012, 2018, Oracle and/or its affiliates. All rights 
reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
@@ -55,12 +55,12 @@
        // Can never be greater that upTo, this avoids overflow if upper 
bound
        // is Integer.MAX_VALUE
        // All elements are traversed if from == upTo & last == 0
-        private int from;
-        private final int upTo;
+        int from;
+        final int upTo;
        // 1 if the range is closed and the last element has not been 
traversed
        // Otherwise, 0 if the range is open, or is a closed range and 
all
        // elements have been traversed
-        private int last;
+        int last;

        RangeIntSpliterator(int from, int upTo, boolean closed) {
            this(from, upTo, closed ? 1 : 0);

--------------------------------------------------------------------------------------------------------------


Regards,
Ben Walsh


Unless stated otherwise above:
IBM United Kingdom Limited - Registered in England and Wales with number 
741598. 
Registered office: PO Box 41, North Harbour, Portsmouth, Hampshire PO6 3AU



Unless stated otherwise above:
IBM United Kingdom Limited - Registered in England and Wales with number 
741598. 
Registered office: PO Box 41, North Harbour, Portsmouth, Hampshire PO6 3AU




More information about the valhalla-dev mailing list