Skip to content

Commit 9590bfa

Browse files
committed
Merge branch 'master' into tim/threading
2 parents a5feae9 + 2a89f1b commit 9590bfa

File tree

431 files changed

+19444
-13717
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

431 files changed

+19444
-13717
lines changed

CHANGELOG.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,16 @@ language runtime. The main focus is on user-observable behavior of the engine.
66
## Version 21.1.0
77

88
* Support multi-threading with a global interpreter lock by default.
9+
* Added subclassing of Java classes in JVM mode
10+
* Use native posix functions in the GraalPython Launcher
11+
* Support iterating over Python objects from Java and other languages as well as iterating over foreign objects in Python
12+
* Support catching foreign exceptions in catch-all except clauses
13+
14+
## Version 21.1.0
15+
16+
* Support catching exceptions from other languages or Java with catch-all except blocks
17+
* Support iterating over iterables from other languages, as well as allow other languages to iterate over Python iterables and iterators
18+
* Support isinstance and issubclass with instances and classes of other languages
919

1020
## Version 21.0.0
1121

ci.jsonnet

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
{ "overlay": "9a7664fcc195d1cac261d7faedfedbb10ff1d75d" }
1+
{ "overlay": "d8d57ccfe5a0a2b1ef094be4772d4f01c2dfb2cb" }

graalpython/com.oracle.graal.python.annotations/src/com/oracle/graal/python/annotations/ArgumentClinic.java

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -66,8 +66,9 @@
6666

6767
/**
6868
* The string should contain valid Java constant value expression, for example, {@code true}, or
69-
* {@code \"some string\"}. You may have to update the annotation processor to include import of
70-
* necessary packages or use fully qualified names.
69+
* {@code \"some string\"}. Another supported value is an identifier of a static field inside
70+
* the annotated class. For anything else, you may have to update the annotation processor to
71+
* include import of necessary packages or use fully qualified names.
7172
*/
7273
String defaultValue() default "";
7374

@@ -122,10 +123,21 @@ enum ClinicConversion {
122123
*/
123124
Int,
124125
/**
125-
* Corresponds to CPython's {@code Py_ssize_t} converter. Supports {@link #defaultValue()},
126-
* and {@link #useDefaultForNone()}.
126+
* Corresponds to CPython's {@code long} converter ("L"/"l" for old style conversions).
127+
* Supports {@link #defaultValue()}, and {@link #useDefaultForNone()}.
128+
*/
129+
Long,
130+
/**
131+
* Corresponds to CPython's {@code Py_ssize_t} converter, except that it converts the result
132+
* into Java integer. Supports {@link #defaultValue()}, and {@link #useDefaultForNone()}.
127133
*/
128134
Index,
135+
/**
136+
* Roughly corresponds to CPython's legacy "n" converter: calls the __index__ and then
137+
* converts it to Java long. Supports {@link #defaultValue()}, and
138+
* {@link #useDefaultForNone()}.
139+
*/
140+
LongIndex,
129141
/**
130142
* Corresponds to CPython's {@code slice_index} converter. Supports {@link #defaultValue()},
131143
* and {@link #useDefaultForNone()}.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,277 @@
1+
/*
2+
* Copyright (c) 2021, 2021, Oracle and/or its affiliates. All rights reserved.
3+
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4+
*
5+
* The Universal Permissive License (UPL), Version 1.0
6+
*
7+
* Subject to the condition set forth below, permission is hereby granted to any
8+
* person obtaining a copy of this software, associated documentation and/or
9+
* data (collectively the "Software"), free of charge and under any and all
10+
* copyright rights in the Software, and any and all patent rights owned or
11+
* freely licensable by each licensor hereunder covering either (i) the
12+
* unmodified Software as contributed to or provided by such licensor, or (ii)
13+
* the Larger Works (as defined below), to deal in both
14+
*
15+
* (a) the Software, and
16+
*
17+
* (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if
18+
* one is included with the Software each a "Larger Work" to which the Software
19+
* is contributed by such licensors),
20+
*
21+
* without restriction, including without limitation the rights to copy, create
22+
* derivative works of, display, perform, and distribute the Software and make,
23+
* use, sell, offer for sale, import, export, have made, and have sold the
24+
* Software and the Larger Work(s), and to sublicense the foregoing rights on
25+
* either these or other terms.
26+
*
27+
* This license is subject to the following condition:
28+
*
29+
* The above copyright notice and either this complete permission notice or at a
30+
* minimum a reference to the UPL must be included in all copies or substantial
31+
* portions of the Software.
32+
*
33+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
34+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
35+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
36+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
37+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
38+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
39+
* SOFTWARE.
40+
*/
41+
package com.oracle.graal.python.benchmarks;
42+
43+
import java.io.IOException;
44+
import java.nio.file.Path;
45+
import java.nio.file.Paths;
46+
import java.util.ArrayList;
47+
import java.util.Arrays;
48+
import java.util.HashMap;
49+
import java.util.List;
50+
import java.util.Map;
51+
import java.util.stream.Collectors;
52+
53+
import org.graalvm.launcher.AbstractLanguageLauncher;
54+
import org.graalvm.options.OptionCategory;
55+
import org.graalvm.polyglot.Context;
56+
import org.graalvm.polyglot.Context.Builder;
57+
import org.graalvm.polyglot.Engine;
58+
import org.graalvm.polyglot.Source;
59+
import org.graalvm.polyglot.Value;
60+
61+
public class JavaBenchmarkDriver extends AbstractLanguageLauncher {
62+
private static final String LINE = "-------------------------------------------------------------------------------";
63+
private static final String BENCHMARK_ENTRY_POINT = "java_embedded_bench_entrypoint";
64+
65+
public static class BenchmarkOptions {
66+
public boolean sharedEngine;
67+
public boolean multiContext;
68+
public int iterations = 10;
69+
public int warmupIterations = 10;
70+
public String benchmarksPath;
71+
private String benchmarkName;
72+
private String[] benchmarkArgs = new String[0];
73+
}
74+
75+
private final Map<String, String> engineOptions = new HashMap<>();
76+
private final BenchmarkOptions options = new BenchmarkOptions();
77+
78+
public static void main(String[] args) {
79+
new JavaBenchmarkDriver().launch(args);
80+
}
81+
82+
@Override
83+
protected List<String> preprocessArguments(List<String> arguments, Map<String, String> polyglotOptions) {
84+
ArrayList<String> unrecognized = new ArrayList<>();
85+
int i = 0;
86+
optionsLoop: while (i < arguments.size()) {
87+
String arg = arguments.get(i);
88+
switch (arg) {
89+
case "-interpreter":
90+
engineOptions.put("engine.Compilation", "false");
91+
break;
92+
case "-shared-engine":
93+
options.sharedEngine = true;
94+
break;
95+
case "-multi-context":
96+
options.multiContext = true;
97+
break;
98+
case "-path":
99+
if (i + 1 >= arguments.size()) {
100+
System.err.println("Option -path is not followed by anything");
101+
System.exit(1);
102+
}
103+
options.benchmarksPath = arguments.get(i + 1);
104+
i += 1;
105+
break;
106+
case "-i":
107+
options.iterations = getIntOption(arguments, i);
108+
i += 1;
109+
break;
110+
case "-w":
111+
options.warmupIterations = getIntOption(arguments, i);
112+
i += 1;
113+
break;
114+
case "--":
115+
options.benchmarkArgs = arguments.subList(i + 1, arguments.size()).toArray(new String[0]);
116+
break optionsLoop;
117+
default:
118+
if (!arg.startsWith("-") && options.benchmarkName == null) {
119+
options.benchmarkName = arg;
120+
break;
121+
}
122+
unrecognized.add(arg);
123+
}
124+
i++;
125+
}
126+
return unrecognized;
127+
}
128+
129+
private static int getIntOption(List<String> arguments, int index) {
130+
if (index + 1 >= arguments.size()) {
131+
System.err.println("Option -i is not followed by anything");
132+
System.exit(1);
133+
}
134+
try {
135+
return Integer.parseInt(arguments.get(index + 1));
136+
} catch (NumberFormatException ex) {
137+
System.err.println("Option -i is not followed by a number");
138+
System.exit(1);
139+
}
140+
throw new AssertionError();
141+
}
142+
143+
@Override
144+
protected void launch(Builder contextBuilder) {
145+
contextBuilder.allowExperimentalOptions(true);
146+
contextBuilder.arguments("python", new String[]{"java_embedding_bench"});
147+
if (options.sharedEngine) {
148+
contextBuilder.engine(Engine.newBuilder().allowExperimentalOptions(true).options(engineOptions).build());
149+
} else {
150+
contextBuilder.options(engineOptions);
151+
}
152+
153+
System.out.println(LINE);
154+
System.out.printf("### %s, %d warmup iterations, %d bench iterations%n", options.benchmarkName, options.warmupIterations, options.iterations);
155+
System.out.printf("### args = %s%n", Arrays.toString(options.benchmarkArgs));
156+
157+
System.out.println(LINE);
158+
System.out.println("### setup ... ");
159+
Source source;
160+
Path path = Paths.get(options.benchmarksPath, options.benchmarkName + ".py");
161+
try {
162+
source = Source.newBuilder("python", path.toFile()).build();
163+
} catch (IOException e) {
164+
System.err.println("Cannot open the file: " + path);
165+
System.exit(1);
166+
return;
167+
}
168+
169+
System.out.println("### start benchmark ... ");
170+
if (options.multiContext) {
171+
runBenchmarkMultiContext(contextBuilder, source);
172+
} else {
173+
runBenchmarkSingleContext(contextBuilder, source);
174+
}
175+
}
176+
177+
private void runBenchmarkMultiContext(Builder contextBuilder, Source source) {
178+
System.out.println();
179+
System.out.printf("### (pre)warming up for %d iterations ... %n", options.warmupIterations);
180+
repeatBenchmarkMultiContext(contextBuilder, source, options.warmupIterations, true);
181+
182+
System.out.println();
183+
System.out.printf("### measure phase for %d iterations ... %n", options.iterations);
184+
long[] durations = repeatBenchmarkMultiContext(contextBuilder, source, options.iterations, false);
185+
186+
System.out.println(LINE);
187+
System.out.println("### benchmark complete");
188+
189+
System.out.println(LINE);
190+
System.out.printf("### BEST duration: %.4f%n", Arrays.stream(durations).min().getAsLong() / 1000_000_000.0);
191+
System.out.printf("### WORST duration: %.4f%n", Arrays.stream(durations).max().getAsLong() / 1000_000_000.0);
192+
System.out.printf("### AVG (no warmup) duration: %.4f%n", Arrays.stream(durations).average().getAsDouble() / 1000_000_000.0);
193+
194+
System.out.println(LINE);
195+
System.out.printf("### RAW DURATIONS: [%s]%n", Arrays.stream(durations).mapToObj(x -> String.format("%.4f", x / 1000_000_000.0)).collect(Collectors.joining(",")));
196+
}
197+
198+
private long[] repeatBenchmarkMultiContext(Builder contextBuilder, Source source, int iterations, boolean warmup) {
199+
long[] durations = new long[iterations];
200+
for (int i = 0; i < iterations; i++) {
201+
Context context = contextBuilder.build();
202+
Value benchmark = getBenchmark(source, context);
203+
204+
long start = System.nanoTime();
205+
benchmark.executeVoid((Object[]) options.benchmarkArgs);
206+
long end = System.nanoTime();
207+
durations[i] = end - start;
208+
reportIteration(i, durations[i], warmup);
209+
}
210+
return durations;
211+
}
212+
213+
private void runBenchmarkSingleContext(Builder contextBuilder, Source source) {
214+
Context context = contextBuilder.build();
215+
Value benchmark = getBenchmark(source, context);
216+
217+
System.out.println();
218+
System.out.printf("### (pre)warming up for %d iterations ... %n", options.warmupIterations);
219+
repeatBenchmarkSingleContext(benchmark, options.warmupIterations, true);
220+
221+
System.out.println();
222+
System.out.printf("### measure phase for %d iterations ... %n", options.iterations);
223+
repeatBenchmarkSingleContext(benchmark, options.iterations, false);
224+
}
225+
226+
private void repeatBenchmarkSingleContext(Value benchmark, int iterations, boolean warmup) {
227+
for (int i = 0; i < iterations; i++) {
228+
long start = System.nanoTime();
229+
benchmark.executeVoid((Object[]) options.benchmarkArgs);
230+
long end = System.nanoTime();
231+
long time = end - start;
232+
reportIteration(i, time, warmup);
233+
}
234+
}
235+
236+
private Value getBenchmark(Source source, Context context) {
237+
try {
238+
context.eval(source);
239+
Value result = context.getBindings("python").getMember(BENCHMARK_ENTRY_POINT);
240+
if (result == null) {
241+
throw new UnsupportedOperationException();
242+
}
243+
return result;
244+
} catch (UnsupportedOperationException ex) {
245+
System.err.printf("Benchmark in file '%s' does not define method named '%s'.%n", options.benchmarkName, BENCHMARK_ENTRY_POINT);
246+
System.exit(1);
247+
return null;
248+
}
249+
}
250+
251+
private void reportIteration(int iter, long nanoTime, boolean warmup) {
252+
System.out.printf("### %siteration=%d, name=%s, duration=%.4f%n", warmup ? "warmup " : "", iter, options.benchmarkName, nanoTime / 1_000_000_000.0);
253+
}
254+
255+
@Override
256+
protected String getLanguageId() {
257+
return "python";
258+
}
259+
260+
@Override
261+
protected void printHelp(OptionCategory maxCategory) {
262+
System.out.println("Python Java benchmarks driver");
263+
System.out.println();
264+
System.out.println("usage: java ... JavaBenchmarkDriver [options] benchmarkName -- [benchmark arguments]");
265+
System.out.println();
266+
System.out.println("Supported options:");
267+
System.out.println("-i Number of benchmark iterations");
268+
System.out.println("-w Number of warmup iterations");
269+
System.out.println("-interpreter Turn off Truffle compilations to benchmark interpreter performance");
270+
System.out.println("-shared-engine Use shared engine");
271+
System.out.println("-multi-context Run each iteration in a new context");
272+
System.out.println("-path /some/path Where to look for the Python scripts with the benchmarks");
273+
System.out.println();
274+
System.out.printf("The Python benchmark script must define function named '%s'.%n", BENCHMARK_ENTRY_POINT);
275+
System.out.println("The values from [benchmark arguments] will be passed to it as arguments, always as strings.");
276+
}
277+
}

graalpython/com.oracle.graal.python.benchmarks/python/meso/chaos.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -275,3 +275,7 @@ def main(iterations=10, w=1000, h=1200):
275275

276276
def __benchmark__(iterations=10):
277277
main(iterations)
278+
279+
def java_embedded_bench_entrypoint(iterations=2):
280+
__setup__(int(iterations))
281+
main(int(iterations))

graalpython/com.oracle.graal.python.benchmarks/python/meso/image-magix.py

Lines changed: 15 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -125,15 +125,20 @@ def __benchmark__(num=10000):
125125
return measure(num)
126126

127127

128+
def java_embedded_bench_entrypoint(num=10000):
129+
measure(int(num))
130+
131+
128132
if __name__ == '__main__':
129133
import sys
130-
import time
131-
SZ = 5
132-
start = time.time()
133-
if len(sys.argv) >= 2:
134-
num = int(sys.argv[1])
135-
img = __benchmark__(num)
136-
else:
137-
img = __benchmark__(2)
138-
print(img.data)
139-
print("%s took %s s" % (__file__, time.time() - start))
134+
if not (len(sys.argv) == 1 and sys.argv[0] == 'java_embedding_bench'):
135+
import time
136+
SZ = 5
137+
start = time.time()
138+
if len(sys.argv) >= 2:
139+
num = int(sys.argv[1])
140+
img = __benchmark__(num)
141+
else:
142+
img = __benchmark__(2)
143+
print(img.data)
144+
print("%s took %s s" % (__file__, time.time() - start))

graalpython/com.oracle.graal.python.benchmarks/python/meso/raytrace-simple.py

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -365,5 +365,8 @@ def _main(width=400, height=400):
365365
s.addObject(Halfspace(Point(0,0,0), Vector.UP), CheckerboardSurface())
366366
s.render(c)
367367

368-
def __benchmark__():
369-
_main()
368+
def __benchmark__(*args):
369+
_main(*args)
370+
371+
def java_embedded_bench_entrypoint(width=400, height=400):
372+
_main(int(width), int(height))

0 commit comments

Comments
 (0)