[PATCH] GPU Exploitation Infrastructure

Paul Sandoz paul.sandoz at oracle.com
Fri Feb 16 19:23:41 UTC 2018


Hi Ben,

Thanks for the information i realize such changes can make it easier to support integration with a downstream third party but, to be very honest, i cannot support such changes in OpenJDK for two reasons:

1) In general such unspecified changes add complexity and increases maintenance for OpenJDK reviewers/developers/testers only for the benefit of code outside of OpenJDK; and

2) Specifically for streams this is an ad-hoc unspecified interface. We have rejected two previous approaches of this nature (one proposed by Project Sumatra, and another proposed by to integrate SPARC DAX co-processor). This approach does not scale and is maintenance burden, and possible a performance burden too. Our recommendation is create your own Stream-like API that supports compilation to GPUs rather than trying to co-opt a small subset IntStream pipelines. This is a very hard problem to solve, we need to consider more general approaches for stream-like support for GPU offload.

—

Where possible I would encourage you to consider a more formal approach to Eclipse OpenJ9 integration with OpenJDK perhaps focusing on the same mechanisms that the Graal compiler integrates with OpenJDK through the JVMCI interface. 

—

Separately your patch for the reachability fence for direct buffers is an appropriate and good contribution to OpenJDK, and analysis by Peter and Vladimir indicate we should be able to achieve the required performance (pending benchmark results).

Thanks,
Paul.

> On Feb 6, 2018, at 7:32 AM, Ben Walsh <ben_walsh at uk.ibm.com> wrote:
> 
> 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