[Mlir-commits] [mlir] [MLIR][Python][NO MERGE] Support Python-defined passes in MLIR (PR #157369)
llvmlistbot at llvm.org
llvmlistbot at llvm.org
Sun Sep 7 20:04:53 PDT 2025
================
@@ -157,6 +159,44 @@ void mlir::python::populatePassManagerSubmodule(nb::module_ &m) {
"pipeline"_a,
"Add textual pipeline elements to the pass manager. Throws a "
"ValueError if the pipeline can't be parsed.")
+ .def(
+ "add_python_pass",
+ [](PyPassManager &passManager, const std::string &name,
+ const std::string &argument, const std::string &description,
+ const std::string &opName, const nb::callable &run) {
+ MlirTypeIDAllocator typeIDAllocator = mlirTypeIDAllocatorCreate();
+ MlirTypeID passID =
+ mlirTypeIDAllocatorAllocateTypeID(typeIDAllocator);
+ MlirExternalPassCallbacks callbacks;
+ callbacks.construct = [](void *obj) {
+ (void)nb::handle(static_cast<PyObject *>(obj)).inc_ref();
+ };
+ callbacks.destruct = [](void *obj) {
+ (void)nb::handle(static_cast<PyObject *>(obj)).dec_ref();
+ };
+ callbacks.clone = [](void *obj) {
+ auto src = nb::handle(static_cast<PyObject *>(obj));
+ nb::callable dst;
+ nb::inst_copy(dst, src);
+ return static_cast<void *>(dst.ptr());
----------------
PragmaTwice wrote:
Yeah `clone` is quite tricky since in the python side I'm not sure how to call it : )
>From the code, it seems that we first call `callback.clone`, and then call `callback.construct` in constructing an `ExternalPass`, so maybe here the pointer `dst.ptr()` will be dangling since the `nb::callable` is destructed (`callable::~callable` is called) and the ref_count become 0?
I think it is related to whether we `inc_ref` in the `callback.construct`. Maybe we can have such a design:
- in `callback.construct` we do not call `inc_ref`, it leaves to who pass the object into the `ExternalPass`;
- in `callback.clone`, we first call `inc_ref` and then pass the object (call `.release()` to prevent the `nb::object::~object` from decreasing the ref count), so that the ref count of this object can be 1, and in `callback.destruct` it is decreased to 0 and destructed;
- before the call to `mlirCreateExternalPass`, we first call `inc_ref` for the object to increase the ref count so that it should be valid at least before `callback.destruct`.
https://github.com/llvm/llvm-project/pull/157369
More information about the Mlir-commits
mailing list