diff --git a/mlir/lib/Bindings/Python/IRAttributes.cpp b/mlir/lib/Bindings/Python/IRAttributes.cpp index 8f79caf08a6d0..db84ee1fcbce9 100644 --- a/mlir/lib/Bindings/Python/IRAttributes.cpp +++ b/mlir/lib/Bindings/Python/IRAttributes.cpp @@ -16,8 +16,8 @@ #include "NanobindUtils.h" #include "mlir-c/BuiltinAttributes.h" #include "mlir-c/BuiltinTypes.h" -#include "mlir/Bindings/Python/NanobindAdaptors.h" #include "mlir/Bindings/Python/Nanobind.h" +#include "mlir/Bindings/Python/NanobindAdaptors.h" #include "llvm/ADT/ScopeExit.h" #include "llvm/Support/raw_ostream.h" @@ -1428,6 +1428,12 @@ class PyDenseIntElementsAttribute } }; +// Check if the python version is less than 3.13. Py_IsFinalizing is a part +// of stable ABI since 3.13 and before it was available as _Py_IsFinalizing. +#if PY_VERSION_HEX < 0x030d0000 +#define Py_IsFinalizing _Py_IsFinalizing +#endif + class PyDenseResourceElementsAttribute : public PyConcreteAttribute { public: @@ -1474,8 +1480,9 @@ class PyDenseResourceElementsAttribute // The userData is a Py_buffer* that the deleter owns. auto deleter = [](void *userData, const void *data, size_t size, size_t align) { - if (!Py_IsInitialized()) - Py_Initialize(); + if (Py_IsFinalizing()) + return; + assert(Py_IsInitialized() && "expected interpreter to be initialized"); Py_buffer *ownedView = static_cast(userData); nb::gil_scoped_acquire gil; PyBuffer_Release(ownedView); diff --git a/mlir/test/python/ir/array_attributes.py b/mlir/test/python/ir/array_attributes.py index ef1d835fc6401..66f7ec8e7fff1 100644 --- a/mlir/test/python/ir/array_attributes.py +++ b/mlir/test/python/ir/array_attributes.py @@ -31,6 +31,7 @@ def testGetDenseElementsUnsupported(): # CHECK: unimplemented array format conversion from format: print(e) + # CHECK-LABEL: TEST: testGetDenseElementsUnSupportedTypeOkIfExplicitTypeProvided @run def testGetDenseElementsUnSupportedTypeOkIfExplicitTypeProvided(): @@ -41,8 +42,9 @@ def testGetDenseElementsUnSupportedTypeOkIfExplicitTypeProvided(): # realistic example would be a NumPy extension type like the bfloat16 # type from the ml_dtypes package, which isn't a dependency of this # test. - attr = DenseElementsAttr.get(array.view(np.datetime64), - type=IntegerType.get_signless(64)) + attr = DenseElementsAttr.get( + array.view(np.datetime64), type=IntegerType.get_signless(64) + ) # CHECK: dense<{{\[}}[1, 2, 3], [4, 5, 6]]> : tensor<2x3xi64> print(attr) # CHECK: {{\[}}[1 2 3] @@ -135,6 +137,7 @@ def testGetDenseElementsFromListMixedTypes(): # Splats. ################################################################################ + # CHECK-LABEL: TEST: testGetDenseElementsSplatInt @run def testGetDenseElementsSplatInt(): @@ -617,3 +620,18 @@ def test_attribute(context, mview): # CHECK: BACKING MEMORY DELETED # CHECK: EXIT FUNCTION print("EXIT FUNCTION") + + +# CHECK-LABEL: TEST: testDanglingResource +print("TEST: testDanglingResource") +# see https://github.com/llvm/llvm-project/pull/149414, https://github.com/llvm/llvm-project/pull/150137, https://github.com/llvm/llvm-project/pull/150561 +# This error occurs only when there is an alive context with a DenseResourceElementsAttr +# in the end of the program, so we put it here without an encapsulating function. +ctx = Context() + +with ctx, Location.unknown(): + DenseResourceElementsAttr.get_from_buffer( + memoryview(np.array([1, 2, 3])), + "some_resource", + RankedTensorType.get((3,), IntegerType.get_signed(32)), + )