[PATCH] GPU Exploitation Infrastructure

Paul Sandoz paul.sandoz at oracle.com
Thu Feb 1 23:14:01 UTC 2018


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 <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
> 



More information about the valhalla-dev mailing list