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