Right now the top-level PyOperation will delete the underlying IR object when it's collected, but child PyOperations aren't keeping the parent PyOperation alive:
import weakref
import gc
from mlir import ir
from mlir.dialects import builtin
with ir.Context():
mod_op = builtin.ModuleOp.parse("""
module {
func.func @foo() {
return
}
}
""")
func_op = mod_op.body.operations[0]
ret_op = func_op.body.blocks[0].operations[0]
mod_ref = weakref.ref(mod_op, lambda _: print("module was finalized"))
func_ref = weakref.ref(func_op, lambda _: print("func was finalized"))
ret_ref = weakref.ref(ret_op, lambda _: print("return was finalized"))
# Delete module reference.
del mod_op; gc.collect()
# Try accessing child operation.
print(func_op)
output:
module was finalized
Segmentation fault (core dumped)
Ideally the reference to the nested op should keep parent IR objects alive, or at least the nested PyOperation should be set to invalid when its parent is erased.
Right now the top-level
PyOperation
will delete the underlying IR object when it's collected, but childPyOperation
s aren't keeping the parentPyOperation
alive:output:
Ideally the reference to the nested op should keep parent IR objects alive, or at least the nested
PyOperation
should be set to invalid when its parent is erased.Seems related to
TODO
comment here: https://github.com/llvm/llvm-project/blob/5784c47806cf276e8fcc1311201f437cb8169261/mlir/lib/Bindings/Python/IRCore.cpp#L1430-L1432