Skip to content

Commit a041524

Browse files
committed
[GR-52583] Update onnxruntime to 1.17.1
PullRequest: graalpython/3241
2 parents 630b1d6 + e2f42c4 commit a041524

File tree

16 files changed

+487
-114
lines changed

16 files changed

+487
-114
lines changed

graalpython/com.oracle.graal.python.cext/include/pystate.h

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
/* Copyright (c) 2018, 2023, Oracle and/or its affiliates.
1+
/* Copyright (c) 2018, 2024, Oracle and/or its affiliates.
22
* Copyright (C) 1996-2020 Python Software Foundation
33
*
44
* Licensed under the PYTHON SOFTWARE FOUNDATION LICENSE VERSION 2
@@ -39,6 +39,7 @@ PyAPI_FUNC(PyObject *) PyInterpreterState_GetDict(PyInterpreterState *);
3939
#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x03070000
4040
/* New in 3.7 */
4141
PyAPI_FUNC(int64_t) PyInterpreterState_GetID(PyInterpreterState *);
42+
// GraalPy-specific
4243
PyAPI_FUNC(int64_t) PyInterpreterState_GetIDFromThreadState(PyThreadState *);
4344
#endif
4445
#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x03030000
@@ -79,8 +80,9 @@ PyAPI_FUNC(PyFrameObject*) PyThreadState_GetFrame(PyThreadState *tstate);
7980
PyAPI_FUNC(uint64_t) PyThreadState_GetID(PyThreadState *tstate);
8081
#endif
8182

82-
/* GraalVM change: we need more state bits */
83-
typedef int PyGILState_STATE;
83+
typedef
84+
enum {PyGILState_LOCKED, PyGILState_UNLOCKED}
85+
PyGILState_STATE;
8486

8587

8688
/* Ensure that the current thread is ready to call the Python

graalpython/com.oracle.graal.python.cext/src/pystate.c

Lines changed: 41 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -137,29 +137,56 @@ int PyState_RemoveModule(struct PyModuleDef* def) {
137137
return 0;
138138
}
139139

140-
#define _PYGILSTATE_LOCKED 0x1
141-
#define _PYGILSTATE_ATTACHED 0x2
142-
143-
PyAPI_FUNC(PyGILState_STATE) PyGILState_Ensure() {
144-
int result = 0;
140+
int
141+
PyGILState_Check()
142+
{
143+
int attached = 0;
144+
/*
145+
* PyGILState_Check is allowed to be called from a new thread that didn't yet setup the GIL.
146+
* If we don't attach the thread ourselves, the upcall will work because NFI will attach
147+
* the thread automatically, but it won't create the context which would then break
148+
* subsequent PyGILState_Ensure.
149+
*/
145150
if (TRUFFLE_CONTEXT) {
146151
if ((*TRUFFLE_CONTEXT)->getTruffleEnv(TRUFFLE_CONTEXT) == NULL) {
147152
(*TRUFFLE_CONTEXT)->attachCurrentThread(TRUFFLE_CONTEXT);
148-
result |= _PYGILSTATE_ATTACHED;
153+
attached = 1;
149154
}
150155
}
151-
int locked = GraalPyTruffleGILState_Ensure();
152-
if (locked) {
153-
result |= _PYGILSTATE_LOCKED;
156+
int ret = GraalPyTruffleGILState_Check();
157+
if (attached) {
158+
(*TRUFFLE_CONTEXT)->detachCurrentThread(TRUFFLE_CONTEXT);
159+
}
160+
return ret;
161+
}
162+
163+
static THREAD_LOCAL int graalpy_attached_thread = 0;
164+
static THREAD_LOCAL int graalpy_gilstate_counter = 0;
165+
166+
PyGILState_STATE
167+
PyGILState_Ensure(void)
168+
{
169+
if (TRUFFLE_CONTEXT) {
170+
if ((*TRUFFLE_CONTEXT)->getTruffleEnv(TRUFFLE_CONTEXT) == NULL) {
171+
(*TRUFFLE_CONTEXT)->attachCurrentThread(TRUFFLE_CONTEXT);
172+
graalpy_attached_thread = 1;
173+
}
174+
graalpy_gilstate_counter++;
154175
}
155-
return result;
176+
return GraalPyTruffleGILState_Ensure() ? PyGILState_UNLOCKED : PyGILState_LOCKED;
156177
}
157178

158-
PyAPI_FUNC(void) PyGILState_Release(PyGILState_STATE state) {
159-
if (state & _PYGILSTATE_LOCKED) {
179+
void
180+
PyGILState_Release(PyGILState_STATE oldstate)
181+
{
182+
if (oldstate == PyGILState_UNLOCKED) {
160183
GraalPyTruffleGILState_Release();
161184
}
162-
if (TRUFFLE_CONTEXT && (state & _PYGILSTATE_ATTACHED)) {
163-
(*TRUFFLE_CONTEXT)->detachCurrentThread(TRUFFLE_CONTEXT);
185+
if (TRUFFLE_CONTEXT) {
186+
graalpy_gilstate_counter--;
187+
if (graalpy_gilstate_counter == 0 && graalpy_attached_thread) {
188+
(*TRUFFLE_CONTEXT)->detachCurrentThread(TRUFFLE_CONTEXT);
189+
graalpy_attached_thread = 0;
190+
}
164191
}
165192
}

graalpython/com.oracle.graal.python.test/src/tests/cpyext/test_thread.py

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,16 +89,33 @@ def test_register_new_thread(self):
8989
includes="#include <pthread.h>",
9090
code=r'''
9191
void* thread_entrypoint(void* arg) {
92+
// This check is important not just to check that the function works without the thread attached,
93+
// but also because the thread attaching logic in it can break the following PyGILState_Ensure call
94+
if (PyGILState_Check()) {
95+
PyErr_SetString(PyExc_RuntimeError, "Thread shouldn't be holding the GIL at this point");
96+
PyErr_WriteUnraisable(NULL);
97+
return NULL;
98+
}
9299
PyObject* callable = (PyObject*)arg;
93100
PyGILState_STATE gstate;
94101
gstate = PyGILState_Ensure();
102+
if (!PyGILState_Check()) {
103+
PyErr_SetString(PyExc_RuntimeError, "GIL not acquired");
104+
PyErr_WriteUnraisable(NULL);
105+
return NULL;
106+
}
95107
if (!PyObject_CallNoArgs(callable)) {
96108
PyErr_WriteUnraisable(callable);
97109
}
98110
if (PyThreadState_Get() == NULL || PyThreadState_Get() == NULL) {
99111
PyErr_WriteUnraisable(callable);
100112
}
101113
PyGILState_Release(gstate);
114+
if (PyGILState_Check()) {
115+
PyErr_SetString(PyExc_RuntimeError, "GIL not released");
116+
PyErr_WriteUnraisable(NULL);
117+
return NULL;
118+
}
102119
return NULL;
103120
}
104121
PyObject* run_in_thread(PyObject* self, PyObject* callable) {

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/cext/PythonCextPyStateBuiltins.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@
7171
public final class PythonCextPyStateBuiltins {
7272

7373
@CApiBuiltin(ret = Int, args = {}, acquiresGIL = false, call = Direct)
74-
abstract static class PyGILState_Check extends CApiNullaryBuiltinNode {
74+
abstract static class PyTruffleGILState_Check extends CApiNullaryBuiltinNode {
7575

7676
@Specialization
7777
Object check() {

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/capi/CApiFunction.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -186,6 +186,7 @@ public final class CApiFunction {
186186
/*
187187
* Functions that are implemented as C code that can be executed both in native and in Sulong:
188188
*/
189+
@CApiBuiltin(name = "PyGILState_Check", ret = Int, args = {}, acquiresGIL = false, call = CImpl)
189190
@CApiBuiltin(name = "PyArg_Parse", ret = Int, args = {PyObject, ConstCharPtrAsTruffleString, VARARGS}, call = CImpl)
190191
@CApiBuiltin(name = "PyArg_ParseTuple", ret = Int, args = {PyObject, ConstCharPtrAsTruffleString, VARARGS}, call = CImpl)
191192
@CApiBuiltin(name = "PyArg_ParseTupleAndKeywords", ret = Int, args = {PyObject, PyObject, ConstCharPtrAsTruffleString, CHAR_PTR_LIST, VARARGS}, call = CImpl)

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/complex/ComplexBuiltins.java

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,7 @@
113113
import com.oracle.graal.python.runtime.object.PythonObjectFactory;
114114
import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
115115
import com.oracle.truffle.api.CompilerDirectives.ValueType;
116+
import com.oracle.truffle.api.HostCompilerDirectives.InliningCutoff;
116117
import com.oracle.truffle.api.dsl.Bind;
117118
import com.oracle.truffle.api.dsl.Cached;
118119
import com.oracle.truffle.api.dsl.Cached.Exclusive;
@@ -168,6 +169,7 @@ static ComplexValue doComplex(PComplex v) {
168169
}
169170

170171
@Specialization(guards = "check.execute(inliningTarget, v)", limit = "1")
172+
@InliningCutoff
171173
static ComplexValue doNative(@SuppressWarnings("unused") Node inliningTarget, PythonAbstractNativeObject v,
172174
@SuppressWarnings("unused") @Cached PyComplexCheckNode check,
173175
@Cached(inline = false) CStructAccess.ReadDoubleNode read) {
@@ -187,13 +189,15 @@ static ComplexValue doDouble(double v) {
187189
}
188190

189191
@Specialization(guards = "check.execute(inliningTarget, v)", limit = "1")
192+
@InliningCutoff
190193
static ComplexValue doIntGeneric(Node inliningTarget, Object v,
191194
@SuppressWarnings("unused") @Cached PyLongCheckNode check,
192195
@Cached PyLongAsDoubleNode longAsDoubleNode) {
193196
return new ComplexValue(longAsDoubleNode.execute(inliningTarget, v), 0);
194197
}
195198

196199
@Specialization(guards = "check.execute(inliningTarget, v)", limit = "1")
200+
@InliningCutoff
197201
static ComplexValue doFloatGeneric(Node inliningTarget, Object v,
198202
@SuppressWarnings("unused") @Cached PyFloatCheckNode check,
199203
@Cached PyFloatAsDoubleNode floatAsDoubleNode) {
@@ -232,6 +236,7 @@ public abstract static class AbsNode extends PythonUnaryBuiltinNode {
232236
public abstract double executeDouble(Object arg);
233237

234238
@Specialization
239+
@InliningCutoff
235240
static double abs(Object self,
236241
@Bind("this") Node inliningTarget,
237242
@Cached ToComplexValueNode toComplexValueNode,
@@ -380,19 +385,19 @@ public static AbsNode create() {
380385
@GenerateNodeFactory
381386
abstract static class AddNode extends PythonBinaryBuiltinNode {
382387
@Specialization
383-
static PComplex doComplex(PComplex left, int right,
388+
static PComplex doInt(PComplex left, int right,
384389
@Shared @Cached PythonObjectFactory factory) {
385390
return factory.createComplex(left.getReal() + right, left.getImag());
386391
}
387392

388393
@Specialization
389-
static PComplex doComplex(PComplex left, double right,
394+
static PComplex doDouble(PComplex left, double right,
390395
@Shared @Cached PythonObjectFactory factory) {
391396
return factory.createComplex(left.getReal() + right, left.getImag());
392397
}
393398

394399
@Specialization
395-
static Object doComplex(Object leftObj, Object rightObj,
400+
static Object doGeneric(Object leftObj, Object rightObj,
396401
@Bind("this") Node inliningTarget,
397402
@Cached ToComplexValueNode toComplexLeft,
398403
@Cached ToComplexValueNode toComplexRight,
@@ -533,6 +538,7 @@ static Object doComplex(Object leftObj, Object rightObj,
533538
abstract static class PowerNode extends PythonTernaryBuiltinNode {
534539

535540
@Specialization
541+
@InliningCutoff
536542
static Object doGeneric(Object leftObj, Object rightObj, @SuppressWarnings("unused") PNone mod,
537543
@Bind("this") Node inliningTarget,
538544
@Cached ToComplexValueNode toComplexLeft,
@@ -579,8 +585,9 @@ static Object doGeneric(Object leftObj, Object rightObj, @SuppressWarnings("unus
579585
}
580586

581587
@Specialization(guards = "!isPNone(mod)")
588+
@InliningCutoff
582589
@SuppressWarnings("unused")
583-
static Object doGeneric(Object left, Object right, Object mod,
590+
static Object error(Object left, Object right, Object mod,
584591
@Cached PRaiseNode raiseNode) {
585592
throw raiseNode.raise(ValueError, ErrorMessages.COMPLEX_MODULO);
586593
}
@@ -660,7 +667,7 @@ static boolean doComplexInt(Node inliningTarget, Object leftObj, PInt right,
660667

661668
@SuppressWarnings("unused")
662669
@Fallback
663-
static PNotImplemented doGeneric(Object left, Object right) {
670+
static PNotImplemented doNotImplemented(Object left, Object right) {
664671
return PNotImplemented.NOT_IMPLEMENTED;
665672
}
666673
}
@@ -735,6 +742,7 @@ static PNotImplemented doGeneric(Object left, Object right) {
735742
@Builtin(name = J___REPR__, minNumOfPositionalArgs = 1)
736743
abstract static class ReprNode extends PythonUnaryBuiltinNode {
737744
@Specialization
745+
@InliningCutoff
738746
static TruffleString repr(Object self,
739747
@Bind("this") Node inliningTarget,
740748
@Cached ToComplexValueNode toComplexValueNode) {
@@ -760,6 +768,7 @@ protected ArgumentClinicProvider getArgumentClinic() {
760768
}
761769

762770
@Specialization
771+
@InliningCutoff
763772
static TruffleString format(Object self, TruffleString formatString,
764773
@Bind("this") Node inliningTarget,
765774
@Cached ToComplexValueNode toComplexValueNode,
@@ -849,6 +858,7 @@ static double get(PComplex self) {
849858
}
850859

851860
@Specialization
861+
@InliningCutoff
852862
static double getNative(PythonAbstractNativeObject self,
853863
@Cached CStructAccess.ReadDoubleNode read) {
854864
return read.readFromObj(self, PyComplexObject__cval__real);
@@ -864,6 +874,7 @@ static double get(PComplex self) {
864874
}
865875

866876
@Specialization
877+
@InliningCutoff
867878
static double getNative(PythonAbstractNativeObject self,
868879
@Cached CStructAccess.ReadDoubleNode read) {
869880
return read.readFromObj(self, PyComplexObject__cval__imag);

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyLongAsDoubleNode.java

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -40,12 +40,17 @@
4040
*/
4141
package com.oracle.graal.python.lib;
4242

43+
import static com.oracle.graal.python.builtins.PythonBuiltinClassType.NotImplementedError;
4344
import static com.oracle.graal.python.builtins.PythonBuiltinClassType.TypeError;
4445

46+
import com.oracle.graal.python.builtins.objects.cext.PythonAbstractNativeObject;
4547
import com.oracle.graal.python.builtins.objects.ints.PInt;
4648
import com.oracle.graal.python.nodes.ErrorMessages;
4749
import com.oracle.graal.python.nodes.PNodeWithContext;
4850
import com.oracle.graal.python.nodes.PRaiseNode;
51+
import com.oracle.truffle.api.CompilerDirectives;
52+
import com.oracle.truffle.api.HostCompilerDirectives.InliningCutoff;
53+
import com.oracle.truffle.api.dsl.Cached;
4954
import com.oracle.truffle.api.dsl.Fallback;
5055
import com.oracle.truffle.api.dsl.GenerateCached;
5156
import com.oracle.truffle.api.dsl.GenerateInline;
@@ -83,12 +88,23 @@ static double doLong(long self) {
8388
}
8489

8590
@Specialization
86-
double doPInt(PInt self) {
87-
return self.doubleValueWithOverflow(this);
91+
static double doPInt(Node inliningTarget, PInt self) {
92+
return self.doubleValueWithOverflow(inliningTarget);
93+
}
94+
95+
@Specialization(guards = "check.execute(inliningTarget, self)", limit = "1")
96+
@InliningCutoff
97+
static double doNative(Node inliningTarget, @SuppressWarnings("unused") PythonAbstractNativeObject self,
98+
@SuppressWarnings("unused") @Cached PyLongCheckNode check) {
99+
CompilerDirectives.transferToInterpreterAndInvalidate();
100+
throw PRaiseNode.raiseUncached(inliningTarget, NotImplementedError, ErrorMessages.CASTING_A_NATIVE_INT_OBJECT_IS_NOT_IMPLEMENTED_YET);
88101
}
89102

90103
@Fallback
91-
double fallback(@SuppressWarnings("unused") Object object) {
92-
throw PRaiseNode.getUncached().raise(TypeError, ErrorMessages.INTEGER_REQUIRED);
104+
@InliningCutoff
105+
@SuppressWarnings("unused")
106+
static double fallback(Node inliningTarget, Object object,
107+
@Cached(inline = false) PRaiseNode raiseNode) {
108+
throw raiseNode.raise(TypeError, ErrorMessages.INTEGER_REQUIRED);
93109
}
94110
}

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyLongCheckNode.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2021, 2023, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2021, 2024, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* The Universal Permissive License (UPL), Version 1.0
@@ -46,6 +46,7 @@
4646
import com.oracle.graal.python.nodes.SpecialMethodNames;
4747
import com.oracle.graal.python.nodes.classes.IsSubtypeNode;
4848
import com.oracle.graal.python.nodes.object.GetClassNode;
49+
import com.oracle.truffle.api.HostCompilerDirectives.InliningCutoff;
4950
import com.oracle.truffle.api.dsl.Cached;
5051
import com.oracle.truffle.api.dsl.GenerateCached;
5152
import com.oracle.truffle.api.dsl.GenerateInline;
@@ -91,6 +92,7 @@ static boolean doPInt(@SuppressWarnings("unused") PInt object) {
9192
}
9293

9394
@Specialization
95+
@InliningCutoff
9496
static boolean doGeneric(Node inliningTarget, Object object,
9597
@Cached GetClassNode getClassNode,
9698
@Cached(inline = false) IsSubtypeNode isSubtypeNode,

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/ErrorMessages.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -970,6 +970,7 @@ public abstract class ErrorMessages {
970970
public static final TruffleString SEMAPHORE_RELEASED_TOO_MANY_TIMES = tsLiteral("semaphore or lock released too many times");
971971
public static final TruffleString N_SLOTNAMES_SHOULD_BE_A_LIST_OR_NONE_NOT_P = tsLiteral("%N.__slotnames__ should be a list or None, not %p");
972972
public static final TruffleString COPYREG_SLOTNAMES_DIDN_T_RETURN_A_LIST_OR_NONE = tsLiteral("copyreg._slotnames didn't return a list or None");
973+
public static final TruffleString CASTING_A_NATIVE_INT_OBJECT_IS_NOT_IMPLEMENTED_YET = tsLiteral("casting a native int object is not implemented yet");
973974

974975
// SSL errors
975976
public static final TruffleString SSL_SESSION_CLOSED = tsLiteral("SSL/TLS session closed cleanly.");

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/util/CastToJavaBooleanNode.java

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2018, 2023, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2018, 2024, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* The Universal Permissive License (UPL), Version 1.0
@@ -40,14 +40,19 @@
4040
*/
4141
package com.oracle.graal.python.nodes.util;
4242

43+
import static com.oracle.graal.python.builtins.PythonBuiltinClassType.NotImplementedError;
44+
4345
import com.oracle.graal.python.builtins.PythonBuiltinClassType;
4446
import com.oracle.graal.python.builtins.objects.cext.PythonNativeObject;
4547
import com.oracle.graal.python.builtins.objects.ints.PInt;
48+
import com.oracle.graal.python.nodes.ErrorMessages;
4649
import com.oracle.graal.python.nodes.PGuards;
4750
import com.oracle.graal.python.nodes.PNodeWithContext;
51+
import com.oracle.graal.python.nodes.PRaiseNode;
4852
import com.oracle.graal.python.nodes.classes.IsSubtypeNode;
4953
import com.oracle.graal.python.nodes.object.GetClassNode;
5054
import com.oracle.truffle.api.CompilerDirectives;
55+
import com.oracle.truffle.api.HostCompilerDirectives;
5156
import com.oracle.truffle.api.dsl.Cached;
5257
import com.oracle.truffle.api.dsl.Cached.Shared;
5358
import com.oracle.truffle.api.dsl.Fallback;
@@ -94,13 +99,14 @@ static boolean doPInt(Node inliningTarget, PInt x,
9499
}
95100

96101
@Specialization
102+
@HostCompilerDirectives.InliningCutoff
97103
static boolean doNativeObject(Node inliningTarget, PythonNativeObject x,
98104
@SuppressWarnings("unused") @Shared("dummy") @Cached InlinedConditionProfile isBoolean,
99105
@Shared @Cached GetClassNode getClassNode,
100106
@Shared @Cached(inline = false) IsSubtypeNode isSubtypeNode) {
101107
if (isSubtypeNode.execute(getClassNode.execute(inliningTarget, x), PythonBuiltinClassType.Boolean)) {
102108
CompilerDirectives.transferToInterpreterAndInvalidate();
103-
throw new RuntimeException("casting a native long object to a Java boolean is not implemented yet");
109+
throw PRaiseNode.raiseUncached(inliningTarget, NotImplementedError, ErrorMessages.CASTING_A_NATIVE_INT_OBJECT_IS_NOT_IMPLEMENTED_YET);
104110
}
105111
// the object's type is not a subclass of 'int'
106112
throw CannotCastException.INSTANCE;

0 commit comments

Comments
 (0)