I would like to define Python bindings for an out-of-tree MLIR client that uses custom dialects. It needs quite deep IR inspection capabilities – traversing the IR with a mix of standard+custom operations, inspecting and setting builtin+custom attributes.
Currently, it doesn’t look like the bindings are set up for such a use case. I started some refactoring to achieve the following state:
- most C++ bindings code is available as a library so that out-of-tree projects can
#includeheaders related to bindings and use
PyMlir*classes in their bindings code;
- the bindings entrypoint, i.e. the
_mlirmodule definition, is a separate library that depends on the former and only defines the extension module;
- same for the out-of-tree project, which has its own entrypoint library defining the
_external_projectmodule, and other extension libraries for its dialects.
My project has a custom build system so I would appreciate if somebody reflected this library layout in CMake. Currently it is still building a combined library.
An extra design point is making external dialects available in the context. Currently, my approach resorts to something like
with mlir.ir.Context(): external_project.load_dialects() # do stuff
but this looks obnoxious. I am considering to provide a dialect registry inside the bindings that can be populated when the dialect package is imported and appended to all live contexts (Python keeps track of those). This could look like
import external_project.dialects.external_dialect with mlir.ir.Context(): # do stuff directly
or, if we want a more opt-in registration behavior, like
import external_project.dialects.unregistered_dialect import external_project.dialects.external_dialect.registration with mlir.ir.Context(): # unregistered_dialect is not registered # external_dialect IS registered when the package was imported
Thoughts or suggestions?