2021-07-22 11:57:41 -08:00
|
|
|
include(AddMLIRPython)
|
|
|
|
|
|
2025-09-20 10:47:32 -08:00
|
|
|
# Specifies that all MLIR packages are co-located under the `MLIR_PYTHON_PACKAGE_PREFIX.`
|
|
|
|
|
# top level package (the API has been embedded in a relocatable way).
|
|
|
|
|
add_compile_definitions("MLIR_PYTHON_PACKAGE_PREFIX=${MLIR_PYTHON_PACKAGE_PREFIX}.")
|
[mlir][Python] create MLIRPythonSupport (#171775)
# What
This PR adds a shared library `MLIRPythonSupport` which contains all of
the CRTP classes ike `PyConcreteValue`, `PyConcreteType`,
`PyConcreteAttribute`, as well as other useful code like `Defaulting*`
and etc enabling their reuse in downstream projects. Downstream projects
can now do
```c++
struct PyTestType : mlir::python::MLIR_BINDINGS_PYTHON_DOMAIN::PyConcreteType<PyTestType> {
...
};
class PyTestAttr : public mlir::python::MLIR_BINDINGS_PYTHON_DOMAIN::PyConcreteAttribute<PyTestAttr> {
...
}
NB_MODULE(_mlirPythonTestNanobind, m) {
PyTestType::bind(m);
PyTestAttr::bind(m);
}
```
instead of using the discordant alternative
`mlir_type_subclass`/`mlir_attr_subclass` (same goes for
`PyConcreteValue`/`mlir_value_subclass`).
# Why
This PR is mostly code motion (along with CMake) but before I describe
the changes I want to state the goals/benefits:
1. Currently upstream "core" extensions and "dialect" extensions ([all
of the `Dialect*` extensions
here](https://github.com/llvm/llvm-project/tree/d7c734b5a14bd91e1c76e2ce0014c19f9deef487/mlir/lib/Bindings/Python))
are a two-tier system;
**a**. [core
extensions](https://github.com/llvm/llvm-project/blob/main/mlir/lib/Bindings/Python/IRTypes.cpp#L361)
enjoy first class support as far as type inference[^3], type stub
generation, and ease of implementation, while dialect extensions [have
poorer support](https://reviews.llvm.org/D150927), incorrect type stub
generation much more tedious (boilerplate) implementation;
**b**. Crucially, this two-tiered system is reflected in the fact that
**the two sets of types/attributes are not in the same Python object
hierarchy**. To wit: `isinstance(..., Type)` and `isinstance(...,
Attribute)` are not supported for the dialect extensions[^2];
**c**. Since these types are not exposed in public headers, downstream
users (dialect extensions or not) cannot write functions that overload
on e.g. `PyFloat8*Type` - that's quite a [useful
feature](https://github.com/nod-ai/PI/blob/fdbee98df8376f47818e6b47e1cf089528c9d48d/cpp_ext/TorchOps.cpp#L29-L69)!
2. The dialect extensions incur a sizeable performance penalty relative
to the core extensions in that every single trip across the wire (either
`python->cpp` or `cpp->python`) requires work in addition to nanobind's
own casting/construction pipeline;
**a**. When going from `python->cpp`, [we extract the capsule object
from the Python
object](https://github.com/llvm/llvm-project/blob/main/mlir/include/mlir/Bindings/Python/NanobindAdaptors.h#L219C24-L219C46)
and then extract from the capsule the `Mlir*` opaque struct/ptr. This
side isn't so onerous;
**b**. When going from `cpp->python` we call long-hand call Python
`import` APIs and construct the Python object using `_CAPICreate`. Note,
there at least 2 `attr` calls incurred in addition to `_CAPICreate`;
this is already much more [efficiently handled by nanobind
itself](https://github.com/wjakob/nanobind/blob/4ba51fcf795971c5d603d875ae4184bc0c9bd8e6/src/nb_internals.h#L381-L382)!
3. This division blocks various features: in some configurations[^1] we
trigger a circular import bug because "dialect" types and attributes
perform an [import of the root `_mlir`
module](https://github.com/llvm/llvm-project/blob/bd9651bf78f2b1713a8203e0bd5b97f7ff199924/mlir/include/mlir/Bindings/Python/NanobindAdaptors.h#L585)
when they are created (the types themselves, not even instances of those
types). This blocks type stub generation for dialect extensions (i.e.,
the reason we currently only generate type stubs for `_mlir`).
# How
Prior this was not done/possible because of "ODR" issues but I have
resolved those issues; the basic idea for how we solve this is "move
things we want to share into shared libraries":
1. Move IRCore (stuff like `PyConcreteValue`, `PyConcreteType`,
`PyConcreteAttribute`) into `MLIRPythonSupport`;
- Note, we move the rest of the things in `IRModule.h` (renamed to
`IRCore.h`) because `PyConcreteValue`, `PyConcreteType`,
`PyConcreteAttribute` depend on them. This makes for a bigger PR than
one would hope for but ultimately I think we should give people access
to these classes to use as they see fit (specifically inherit from, but
also liberally use in bindings signatures instead of the opaque `Mlir*`
struct wrappers).
2. Put all of this code into a nested namespace
`MLIR_BINDINGS_PYTHON_DOMAIN` which is determined by a compile time
define (and tied to `MLIR_BINDINGS_PYTHON_NB_DOMAIN`). This is necessary
in order to prevent conflicts on both symbol name **and** typeid
(necessary for nanobind to not double register binded types) between
multiple bindings libraries (e.g., `torch-mlir`, and `jax`). Note
[nanobind doesn't support `module_local` like
pybind11](https://nanobind.readthedocs.io/en/latest/porting.html#removed-features).
It does support `NB_DOMAIN` but that is not sufficient for
disambiguating typeids across projects (to wit: we currently define
`NB_DOMAIN` and it was still necessary to move everything to a nested
namespace);
3. Build the [nanobind library itself as a shared
object](https://github.com/wjakob/nanobind/blob/master/cmake/nanobind-config.cmake#L127)
(and link it to both the extensions and `MLIRPythonSupport`).
4. CMake to make this work, in-tree, out-of-tree, downstream, upstream,
etc.
# Testing
Three tests are added here
1. `PythonTestModuleNanobind` is ported to use
`PyConcreteType<PyTestType>` instead of `mlir_type_subclass` and
`PyConcreteAttribute<PyTestAttr>` instead of `mlir_atrr_subclass`,
verifying this works for non-core extensions in-tree;
2. `StandaloneExtensionNanobind` is ported to use `struct PyCustomType :
mlir::python::MLIR_BINDINGS_PYTHON_DOMAIN::PyConcreteType<PyCustomType>`
instead of `mlir_type_subclass` verifying this works for non-core
extensions out-of-tree;
3. `StandaloneExtensionNanobind`'s `smoketest` is extended to also load
another bindings package (namely `mlir`) verifying
`MLIR_BINDINGS_PYTHON_DOMAIN` successfully disambiguates symbols and
typeids.
I have also tested this downstream:
https://github.com/llvm/eudsl/pull/287 as well run the following builder
bots:
mlir-nvidia-gcc7:
https://lab.llvm.org/buildbot/#/buildrequests/6654424?redirect_to_build=true
I have also tested against IREE:
https://github.com/iree-org/iree/pull/21916
# Integration
It is highly recommended to set the CMake var
`MLIR_BINDINGS_PYTHON_NB_DOMAIN` (which will also determine
`MLIR_BINDINGS_PYTHON_DOMAIN`) to something unique for each downstream.
This can also be passed explicitly to `add_mlir_python_modules` if your
project builds multiple bindings packages. I added a `WARNING` to this
effect in `AddMLIRPython.cmake`.
[^3]: Python values being typed correctly when exiting from cpp;
[^1]: Specifically when the modules are imported using `importlib`,
which occurs with nanobind's
[stubgen](https://github.com/wjakob/nanobind/blob/master/src/stubgen.py#L965);
[^2]: The workaround we implemented was a class method for the dialect
bindings called `Class.isinstance(...)`;
2026-01-05 08:08:13 -09:00
|
|
|
set(MLIRPythonModules_ROOT_PREFIX "${MLIR_BINARY_DIR}/${MLIR_BINDINGS_PYTHON_INSTALL_PREFIX}")
|
|
|
|
|
set(PYTHON_SOURCE_DIR "${MLIR_SOURCE_DIR}/lib/Bindings/Python")
|
2025-09-20 10:47:32 -08:00
|
|
|
|
2021-04-28 12:04:17 -08:00
|
|
|
################################################################################
|
2021-07-22 11:57:41 -08:00
|
|
|
# Structural groupings.
|
2021-04-28 12:04:17 -08:00
|
|
|
################################################################################
|
|
|
|
|
|
2021-07-22 11:57:41 -08:00
|
|
|
declare_mlir_python_sources(MLIRPythonSources)
|
|
|
|
|
declare_mlir_python_sources(MLIRPythonSources.Dialects
|
|
|
|
|
ADD_TO_PARENT MLIRPythonSources)
|
2023-11-07 16:52:43 -09:00
|
|
|
declare_mlir_python_sources(MLIRPythonSources.Core
|
|
|
|
|
ADD_TO_PARENT MLIRPythonSources)
|
2021-07-22 11:57:41 -08:00
|
|
|
|
|
|
|
|
################################################################################
|
|
|
|
|
# Pure python sources and generated code
|
|
|
|
|
################################################################################
|
|
|
|
|
|
2023-11-07 16:52:43 -09:00
|
|
|
declare_mlir_python_sources(MLIRPythonSources.Core.Python
|
2021-07-22 11:57:41 -08:00
|
|
|
ROOT_DIR "${CMAKE_CURRENT_SOURCE_DIR}/mlir"
|
2023-11-07 16:52:43 -09:00
|
|
|
ADD_TO_PARENT MLIRPythonSources.Core
|
2021-07-22 11:57:41 -08:00
|
|
|
SOURCES
|
|
|
|
|
_mlir_libs/__init__.py
|
2025-09-20 10:47:32 -08:00
|
|
|
_mlir_libs/_mlir/py.typed
|
2021-07-22 11:57:41 -08:00
|
|
|
ir.py
|
|
|
|
|
passmanager.py
|
2024-06-11 06:45:12 -08:00
|
|
|
rewrite.py
|
2021-07-22 11:57:41 -08:00
|
|
|
dialects/_ods_common.py
|
[MLIR][Python] Add a DSL for defining dialects in Python bindings (#169045)
Python bindings for the IRDL dialect were introduced in #158488. They
are currently usable—for constructing IR and dynamically loading modules
that contain `irdl.dialect` into MLIR. However, there are still several
pain points when working with them:
* The IRDL IR-building interface is not very intuitive and tends to be
quite verbose.
* We do not yet have the corresponding `OpView` classes for IRDL-defined
operations.
To address these issues, I propose creating a wrapper (effectively a
small “DSL”) on top of the existing IRDL Python bindings. This wrapper
aims to simplify IR construction and automatically generate the
corresponding `OpView` types. A simple example is shown below.
Currently, using the IRDL bindings looks like this:
```python
m = Module.create()
with InsertionPoint(m.body):
myint = irdl.dialect("myint")
with InsertionPoint(myint.body):
constant = irdl.operation_("constant")
with InsertionPoint(constant.body):
iattr = irdl.base(base_name="#builtin.integer")
i32 = irdl.is_(TypeAttr.get(IntegerType.get_signless(32)))
irdl.attributes_([iattr], ["value"])
irdl.results_([i32], ["cst"], [irdl.Variadicity.single])
add = irdl.operation_("add")
with InsertionPoint(add.body):
i32 = irdl.is_(TypeAttr.get(IntegerType.get_signless(32)))
irdl.operands_(
[i32, i32],
["lhs", "rhs"],
[irdl.Variadicity.single, irdl.Variadicity.single],
)
irdl.results_([i32], ["res"], [irdl.Variadicity.single])
irdl.load_dialects(m)
```
With the proposed DSL (module name `mlir.dialects.ext`), the equivalent
implementation becomes:
```python
class MyInt(Dialect, name="myint"):
pass
i32 = IntegerType[32]
class ConstantOp(MyInt.Operation, name="constant"):
value: IntegerAttr
cst: Result[i32]
class AddOp(MyInt.Operation, name="add"):
lhs: Operand[i32]
rhs: Operand[i32]
res: Result[i32]
MyInt.load()
```
Compared with the current IRDL Python bindings, this DSL mainly adds the
following:
* **A more intuitive interface** for constructing IRDL definitions (as
shown in the example).
* **Automatic generation of the corresponding `OpView`
classes**—including `__init__` methods and property getters for each
defined operation. Similar to TableGen’s `ins`, operands and attributes
can be interleaved in arbitrary order. Special handling is also
implemented for optional and variadic operands/results (such as
computing segment sizes) so that they feel as natural to use as native
operations.
* **Lazy insertion of ops**: all ops are created and inserted only when
`Dialect.load()` is called, which makes it unnecessary to specify an
MLIR context immediately when defining an IRDL dialect.
* **Basic type inference** in operation builders (i.e.
`OpViewCls.__init__`) for trivial result types.
The current DSL does not yet cover all IRDL operations. Several features
are not supported at the moment:
- Defining new types or attributes
- Parametric constraints
- Adding regions to operations
---------
Co-authored-by: Rolf Morel <rolfmorel@gmail.com>
2026-01-25 06:08:45 -09:00
|
|
|
dialects/ext.py
|
2021-04-28 12:04:17 -08:00
|
|
|
)
|
|
|
|
|
|
2023-12-21 08:20:29 -09:00
|
|
|
declare_mlir_python_sources(MLIRPythonSources.Core.Python.Extras
|
|
|
|
|
ROOT_DIR "${CMAKE_CURRENT_SOURCE_DIR}/mlir"
|
|
|
|
|
ADD_TO_PARENT MLIRPythonSources.Core.Python
|
|
|
|
|
SOURCES
|
|
|
|
|
extras/types.py
|
|
|
|
|
extras/meta.py
|
|
|
|
|
)
|
|
|
|
|
|
2026-07-22 23:15:12 -08:00
|
|
|
# Keep this source group unconditional because runtime/*.py contains generic
|
|
|
|
|
# memref helpers that do not depend on the ExecutionEngine extension. Only the
|
|
|
|
|
# wrapper and type stub require _mlirExecutionEngine.
|
|
|
|
|
set(_execution_engine_python_sources)
|
|
|
|
|
if(MLIR_ENABLE_EXECUTION_ENGINE)
|
|
|
|
|
set(_execution_engine_python_sources
|
|
|
|
|
execution_engine.py
|
|
|
|
|
_mlir_libs/_mlirExecutionEngine.pyi
|
|
|
|
|
)
|
|
|
|
|
endif()
|
|
|
|
|
|
2021-07-22 11:57:41 -08:00
|
|
|
declare_mlir_python_sources(MLIRPythonSources.ExecutionEngine
|
|
|
|
|
ROOT_DIR "${CMAKE_CURRENT_SOURCE_DIR}/mlir"
|
|
|
|
|
ADD_TO_PARENT MLIRPythonSources
|
|
|
|
|
SOURCES
|
2026-07-22 23:15:12 -08:00
|
|
|
${_execution_engine_python_sources}
|
2021-07-22 11:57:41 -08:00
|
|
|
SOURCES_GLOB
|
|
|
|
|
runtime/*.py
|
|
|
|
|
)
|
2026-07-22 23:15:12 -08:00
|
|
|
unset(_execution_engine_python_sources)
|
2021-07-22 11:57:41 -08:00
|
|
|
|
2022-06-28 09:39:13 -08:00
|
|
|
declare_mlir_python_sources(MLIRPythonCAPI.HeaderSources
|
[mlir] Overhaul C/Python registration APIs to properly scope registration/loading activities.
Since the very first commits, the Python and C MLIR APIs have had mis-placed registration/load functionality for dialects, extensions, etc. This was done pragmatically in order to get bootstrapped and then just grew in. Downstreams largely bypass and do their own thing by providing various APIs to register things they need. Meanwhile, the C++ APIs have stabilized around this and it would make sense to follow suit.
The thing we have observed in canonical usage by downstreams is that each downstream tends to have native entry points that configure its installation to its preferences with one-stop APIs. This patch leans in to this approach with `RegisterEverything.h` and `mlir._mlir_libs._mlirRegisterEverything` being the one-stop entry points for the "upstream packages". The `_mlir_libs.__init__.py` now allows customization of the environment and Context by adding "initialization modules" to the `_mlir_libs` package. If present, `_mlirRegisterEverything` is treated as such a module. Others can be added by downstreams by adding a `_site_initialize_{i}.py` module, where '{i}' is a number starting with zero. The number will be incremented and corresponding module loaded until one is not found. Initialization modules can:
* Perform load time customization to the global environment (i.e. registering passes, hooks, etc).
* Define a `register_dialects(registry: DialectRegistry)` function that can extend the `DialectRegistry` that will be used to bootstrap the `Context`.
* Define a `context_init_hook(context: Context)` function that will be added to a list of callbacks which will be invoked after dialect registration during `Context` initialization.
Note that the `MLIRPythonExtension.RegisterEverything` is not included by default when building a downstream (its corresponding behavior was prior). For downstreams which need the default MLIR initialization to take place, they must add this back in to their Python CMake build just like they add their own components (i.e. to `add_mlir_python_common_capi_library` and `add_mlir_python_modules`). It is perfectly valid to not do this, in which case, only the things explicitly depended on and initialized by downstreams will be built/packaged. If the downstream has not been set up for this, it is recommended to simply add this back for the time being and pay the build time/package size cost.
CMake changes:
* `MLIRCAPIRegistration` -> `MLIRCAPIRegisterEverything` (renamed to signify what it does and force an evaluation: a number of places were incidentally linking this very expensive target)
* `MLIRPythonSoure.Passes` removed (without replacement: just drop)
* `MLIRPythonExtension.AllPassesRegistration` removed (without replacement: just drop)
* `MLIRPythonExtension.Conversions` removed (without replacement: just drop)
* `MLIRPythonExtension.Transforms` removed (without replacement: just drop)
Header changes:
* `mlir-c/Registration.h` is deleted. Dialect registration functionality is now in `IR.h`. Registration of upstream features are in `mlir-c/RegisterEverything.h`. When updating MLIR and a couple of downstreams, I found that proper usage was commingled so required making a choice vs just blind S&R.
Python APIs removed:
* mlir.transforms and mlir.conversions (previously only had an __init__.py which indirectly triggered `mlirRegisterTransformsPasses()` and `mlirRegisterConversionPasses()` respectively). Downstream impact: Remove these imports if present (they now happen as part of default initialization).
* mlir._mlir_libs._all_passes_registration, mlir._mlir_libs._mlirTransforms, mlir._mlir_libs._mlirConversions. Downstream impact: None expected (these were internally used).
C-APIs changed:
* mlirRegisterAllDialects(MlirContext) now takes an MlirDialectRegistry instead. It also used to trigger loading of all dialects, which was already marked with a TODO to remove -- it no longer does, and for direct use, dialects must be explicitly loaded. Downstream impact: Direct C-API users must ensure that needed dialects are loaded or call `mlirContextLoadAllAvailableDialects(MlirContext)` to emulate the prior behavior. Also see the `ir.c` test case (e.g. ` mlirContextGetOrLoadDialect(ctx, mlirStringRefCreateFromCString("func"));`).
* mlirDialectHandle* APIs were moved from Registration.h (which now is restricted to just global/upstream registration) to IR.h, arguably where it should have been. Downstream impact: include correct header (likely already doing so).
C-APIs added:
* mlirContextLoadAllAvailableDialects(MlirContext): Corresponds to C++ API with the same purpose.
Python APIs added:
* mlir.ir.DialectRegistry: Mapping for an MlirDialectRegistry.
* mlir.ir.Context.append_dialect_registry(MlirDialectRegistry)
* mlir.ir.Context.load_all_available_dialects()
* mlir._mlir_libs._mlirAllRegistration: New native extension that exposes a `register_dialects(MlirDialectRegistry)` entry point and performs all upstream pass/conversion/transforms registration on init. In this first step, we eagerly load this as part of the __init__.py and use it to monkey patch the Context to emulate prior behavior.
* Type caster and capsule support for MlirDialectRegistry
This should make it possible to build downstream Python dialects that only depend on a subset of MLIR. See: https://github.com/llvm/llvm-project/issues/56037
Here is an example PR, minimally adapting IREE to these changes: https://github.com/iree-org/iree/pull/9638/files In this situation, IREE is opting to not link everything, since it is already configuring the Context to its liking. For projects that would just like to not think about it and pull in everything, add `MLIRPythonExtension.RegisterEverything` to the list of Python sources getting built, and the old behavior will continue.
Reviewed By: mehdi_amini, ftynse
Differential Revision: https://reviews.llvm.org/D128593
2022-07-16 15:09:03 -08:00
|
|
|
ROOT_DIR "${MLIR_SOURCE_DIR}/include"
|
2021-07-29 11:06:22 -08:00
|
|
|
SOURCES_GLOB "mlir-c/*.h"
|
|
|
|
|
)
|
|
|
|
|
|
2021-07-22 11:57:41 -08:00
|
|
|
################################################################################
|
|
|
|
|
# Dialect bindings
|
|
|
|
|
################################################################################
|
|
|
|
|
|
2023-10-11 12:37:11 -08:00
|
|
|
declare_mlir_dialect_python_bindings(
|
|
|
|
|
ADD_TO_PARENT MLIRPythonSources.Dialects
|
|
|
|
|
ROOT_DIR "${CMAKE_CURRENT_SOURCE_DIR}/mlir"
|
|
|
|
|
TD_FILE dialects/AffineOps.td
|
|
|
|
|
SOURCES
|
|
|
|
|
dialects/affine.py
|
|
|
|
|
DIALECT_NAME affine
|
|
|
|
|
GEN_ENUM_BINDINGS)
|
|
|
|
|
|
2023-08-13 10:30:28 -08:00
|
|
|
declare_mlir_dialect_python_bindings(
|
|
|
|
|
ADD_TO_PARENT MLIRPythonSources.Dialects
|
|
|
|
|
ROOT_DIR "${CMAKE_CURRENT_SOURCE_DIR}/mlir"
|
|
|
|
|
TD_FILE dialects/AMDGPUOps.td
|
|
|
|
|
SOURCES
|
|
|
|
|
dialects/amdgpu.py
|
[mlir][python bindings] generate all the enums
This PR implements python enum bindings for *all* the enums - this includes `I*Attrs` (including positional/bit) and `Dialect/EnumAttr`.
There are a few parts to this:
1. CMake: a small addition to `declare_mlir_dialect_python_bindings` and `declare_mlir_dialect_extension_python_bindings` to generate the enum, a boolean arg `GEN_ENUM_BINDINGS` to make it opt-in (even though it works for basically all of the dialects), and an optional `GEN_ENUM_BINDINGS_TD_FILE` for handling corner cases.
2. EnumPythonBindingGen.cpp: there are two weedy aspects here that took investigation:
1. If an enum attribute is not a `Dialect/EnumAttr` then the `EnumAttrInfo` record is canonical, as far as both the cases of the enum **and the `AttrDefName`**. On the otherhand, if an enum is a `Dialect/EnumAttr` then the `EnumAttr` record has the correct `AttrDefName` ("load bearing", i.e., populates `ods.ir.AttributeBuilder('<NAME>')`) but its `enum` field contains the cases, which is an instance of `EnumAttrInfo`. The solution is to generate an one enum class for both `Dialect/EnumAttr` and "independent" `EnumAttrInfo` but to make that class interopable with two builder registrations that both do the right thing (see next sub-bullet).
2. Because we don't have a good connection to cpp `EnumAttr`, i.e., only the `enum class` getters are exposed (like `DimensionAttr::get(Dimension value)`), we have to resort to parsing e.g., `Attribute.parse(f'#gpu<dim {x}>')`. This means that the set of supported `assemblyFormat`s (for the enum) is fixed at compile of MLIR (currently 2, the only 2 I saw). There might be some things that could be done here but they would require quite a bit more C API work to support generically (e.g., casting ints to enum cases and binding all the getters or going generically through the `symbolize*` methods, like `symbolizeDimension(uint32_t)` or `symbolizeDimension(StringRef)`).
A few small changes:
1. In addition, since this patch registers default builders for attributes where people might've had their own builders already written, I added a `replace` param to `AttributeBuilder.insert` (`False` by default).
2. `makePythonEnumCaseName` can't handle all the different ways in which people write their enum cases, e.g., `llvm.CConv.Intel_OCL_BI`, which gets turned into `INTEL_O_C_L_B_I` (because `llvm::convertToSnakeFromCamelCase` doesn't look for runs of caps). So I dropped it. On the otherhand regularization does need to done because some enums have `None` as a case (and others might have other python keywords).
3. I turned on `llvm` dialect generation here in order to test `nvvm.WGMMAScaleIn`, which is an enum with [[ https://github.com/llvm/llvm-project/blob/d7e26b56207cbd8995296c5bb7c11ce676b649da/mlir/include/mlir/IR/EnumAttr.td#L22-L25 | no explicit discriminator ]] for the `neg` case.
Note, dialects that didn't get a `GEN_ENUM_BINDINGS` don't have any enums to generate.
Let me know if I should add more tests (the three trivial ones I added exercise both the supported `assemblyFormat`s and `replace=True`).
Reviewed By: stellaraccident
Differential Revision: https://reviews.llvm.org/D157934
2023-08-23 10:27:08 -08:00
|
|
|
DIALECT_NAME amdgpu
|
|
|
|
|
GEN_ENUM_BINDINGS)
|
2023-08-13 10:30:28 -08:00
|
|
|
|
2021-07-22 11:57:41 -08:00
|
|
|
declare_mlir_dialect_python_bindings(
|
|
|
|
|
ADD_TO_PARENT MLIRPythonSources.Dialects
|
|
|
|
|
ROOT_DIR "${CMAKE_CURRENT_SOURCE_DIR}/mlir"
|
|
|
|
|
TD_FILE dialects/AsyncOps.td
|
|
|
|
|
SOURCES_GLOB dialects/async_dialect/*.py
|
2024-04-20 17:49:39 -08:00
|
|
|
DIALECT_NAME async)
|
2021-07-22 11:57:41 -08:00
|
|
|
|
2022-05-23 08:10:12 -08:00
|
|
|
declare_mlir_dialect_python_bindings(
|
|
|
|
|
ADD_TO_PARENT MLIRPythonSources.Dialects
|
|
|
|
|
ROOT_DIR "${CMAKE_CURRENT_SOURCE_DIR}/mlir"
|
|
|
|
|
TD_FILE dialects/BufferizationOps.td
|
|
|
|
|
SOURCES
|
|
|
|
|
dialects/bufferization.py
|
[mlir][python bindings] generate all the enums
This PR implements python enum bindings for *all* the enums - this includes `I*Attrs` (including positional/bit) and `Dialect/EnumAttr`.
There are a few parts to this:
1. CMake: a small addition to `declare_mlir_dialect_python_bindings` and `declare_mlir_dialect_extension_python_bindings` to generate the enum, a boolean arg `GEN_ENUM_BINDINGS` to make it opt-in (even though it works for basically all of the dialects), and an optional `GEN_ENUM_BINDINGS_TD_FILE` for handling corner cases.
2. EnumPythonBindingGen.cpp: there are two weedy aspects here that took investigation:
1. If an enum attribute is not a `Dialect/EnumAttr` then the `EnumAttrInfo` record is canonical, as far as both the cases of the enum **and the `AttrDefName`**. On the otherhand, if an enum is a `Dialect/EnumAttr` then the `EnumAttr` record has the correct `AttrDefName` ("load bearing", i.e., populates `ods.ir.AttributeBuilder('<NAME>')`) but its `enum` field contains the cases, which is an instance of `EnumAttrInfo`. The solution is to generate an one enum class for both `Dialect/EnumAttr` and "independent" `EnumAttrInfo` but to make that class interopable with two builder registrations that both do the right thing (see next sub-bullet).
2. Because we don't have a good connection to cpp `EnumAttr`, i.e., only the `enum class` getters are exposed (like `DimensionAttr::get(Dimension value)`), we have to resort to parsing e.g., `Attribute.parse(f'#gpu<dim {x}>')`. This means that the set of supported `assemblyFormat`s (for the enum) is fixed at compile of MLIR (currently 2, the only 2 I saw). There might be some things that could be done here but they would require quite a bit more C API work to support generically (e.g., casting ints to enum cases and binding all the getters or going generically through the `symbolize*` methods, like `symbolizeDimension(uint32_t)` or `symbolizeDimension(StringRef)`).
A few small changes:
1. In addition, since this patch registers default builders for attributes where people might've had their own builders already written, I added a `replace` param to `AttributeBuilder.insert` (`False` by default).
2. `makePythonEnumCaseName` can't handle all the different ways in which people write their enum cases, e.g., `llvm.CConv.Intel_OCL_BI`, which gets turned into `INTEL_O_C_L_B_I` (because `llvm::convertToSnakeFromCamelCase` doesn't look for runs of caps). So I dropped it. On the otherhand regularization does need to done because some enums have `None` as a case (and others might have other python keywords).
3. I turned on `llvm` dialect generation here in order to test `nvvm.WGMMAScaleIn`, which is an enum with [[ https://github.com/llvm/llvm-project/blob/d7e26b56207cbd8995296c5bb7c11ce676b649da/mlir/include/mlir/IR/EnumAttr.td#L22-L25 | no explicit discriminator ]] for the `neg` case.
Note, dialects that didn't get a `GEN_ENUM_BINDINGS` don't have any enums to generate.
Let me know if I should add more tests (the three trivial ones I added exercise both the supported `assemblyFormat`s and `replace=True`).
Reviewed By: stellaraccident
Differential Revision: https://reviews.llvm.org/D157934
2023-08-23 10:27:08 -08:00
|
|
|
DIALECT_NAME bufferization
|
|
|
|
|
GEN_ENUM_BINDINGS_TD_FILE
|
|
|
|
|
"../../include/mlir/Dialect/Bufferization/IR/BufferizationEnums.td"
|
|
|
|
|
)
|
2022-05-23 08:10:12 -08:00
|
|
|
|
2021-07-22 11:57:41 -08:00
|
|
|
declare_mlir_dialect_python_bindings(
|
|
|
|
|
ADD_TO_PARENT MLIRPythonSources.Dialects
|
|
|
|
|
ROOT_DIR "${CMAKE_CURRENT_SOURCE_DIR}/mlir"
|
|
|
|
|
TD_FILE dialects/BuiltinOps.td
|
|
|
|
|
SOURCES
|
|
|
|
|
dialects/builtin.py
|
|
|
|
|
DIALECT_NAME builtin)
|
|
|
|
|
|
2022-06-15 15:00:51 -08:00
|
|
|
declare_mlir_dialect_python_bindings(
|
|
|
|
|
ADD_TO_PARENT MLIRPythonSources.Dialects
|
|
|
|
|
ROOT_DIR "${CMAKE_CURRENT_SOURCE_DIR}/mlir"
|
|
|
|
|
TD_FILE dialects/ComplexOps.td
|
|
|
|
|
SOURCES
|
|
|
|
|
dialects/complex.py
|
|
|
|
|
DIALECT_NAME complex)
|
|
|
|
|
|
2024-03-20 07:56:22 -08:00
|
|
|
declare_mlir_dialect_python_bindings(
|
|
|
|
|
ADD_TO_PARENT MLIRPythonSources.Dialects
|
|
|
|
|
ROOT_DIR "${CMAKE_CURRENT_SOURCE_DIR}/mlir"
|
|
|
|
|
TD_FILE dialects/IndexOps.td
|
|
|
|
|
SOURCES
|
|
|
|
|
dialects/index.py
|
|
|
|
|
DIALECT_NAME index
|
|
|
|
|
GEN_ENUM_BINDINGS)
|
|
|
|
|
|
2022-02-05 20:50:27 -09:00
|
|
|
declare_mlir_dialect_python_bindings(
|
|
|
|
|
ADD_TO_PARENT MLIRPythonSources.Dialects
|
|
|
|
|
ROOT_DIR "${CMAKE_CURRENT_SOURCE_DIR}/mlir"
|
|
|
|
|
TD_FILE dialects/ControlFlowOps.td
|
|
|
|
|
SOURCES
|
|
|
|
|
dialects/cf.py
|
|
|
|
|
DIALECT_NAME cf)
|
|
|
|
|
|
2022-02-26 13:49:54 -09:00
|
|
|
declare_mlir_dialect_python_bindings(
|
|
|
|
|
ADD_TO_PARENT MLIRPythonSources.Dialects
|
|
|
|
|
ROOT_DIR "${CMAKE_CURRENT_SOURCE_DIR}/mlir"
|
|
|
|
|
TD_FILE dialects/FuncOps.td
|
|
|
|
|
SOURCES
|
|
|
|
|
dialects/func.py
|
|
|
|
|
DIALECT_NAME func)
|
|
|
|
|
|
2025-10-16 06:30:19 -08:00
|
|
|
declare_mlir_dialect_python_bindings(
|
|
|
|
|
ADD_TO_PARENT MLIRPythonSources.Dialects
|
|
|
|
|
ROOT_DIR "${CMAKE_CURRENT_SOURCE_DIR}/mlir"
|
|
|
|
|
TD_FILE dialects/OpenACCOps.td
|
|
|
|
|
SOURCES
|
|
|
|
|
dialects/openacc.py
|
|
|
|
|
DIALECT_NAME acc
|
|
|
|
|
DEPENDS acc_common_td
|
|
|
|
|
)
|
|
|
|
|
|
2021-07-22 11:57:41 -08:00
|
|
|
declare_mlir_dialect_python_bindings(
|
|
|
|
|
ADD_TO_PARENT MLIRPythonSources.Dialects
|
|
|
|
|
ROOT_DIR "${CMAKE_CURRENT_SOURCE_DIR}/mlir"
|
|
|
|
|
TD_FILE dialects/GPUOps.td
|
|
|
|
|
SOURCES_GLOB dialects/gpu/*.py
|
[mlir][python bindings] generate all the enums
This PR implements python enum bindings for *all* the enums - this includes `I*Attrs` (including positional/bit) and `Dialect/EnumAttr`.
There are a few parts to this:
1. CMake: a small addition to `declare_mlir_dialect_python_bindings` and `declare_mlir_dialect_extension_python_bindings` to generate the enum, a boolean arg `GEN_ENUM_BINDINGS` to make it opt-in (even though it works for basically all of the dialects), and an optional `GEN_ENUM_BINDINGS_TD_FILE` for handling corner cases.
2. EnumPythonBindingGen.cpp: there are two weedy aspects here that took investigation:
1. If an enum attribute is not a `Dialect/EnumAttr` then the `EnumAttrInfo` record is canonical, as far as both the cases of the enum **and the `AttrDefName`**. On the otherhand, if an enum is a `Dialect/EnumAttr` then the `EnumAttr` record has the correct `AttrDefName` ("load bearing", i.e., populates `ods.ir.AttributeBuilder('<NAME>')`) but its `enum` field contains the cases, which is an instance of `EnumAttrInfo`. The solution is to generate an one enum class for both `Dialect/EnumAttr` and "independent" `EnumAttrInfo` but to make that class interopable with two builder registrations that both do the right thing (see next sub-bullet).
2. Because we don't have a good connection to cpp `EnumAttr`, i.e., only the `enum class` getters are exposed (like `DimensionAttr::get(Dimension value)`), we have to resort to parsing e.g., `Attribute.parse(f'#gpu<dim {x}>')`. This means that the set of supported `assemblyFormat`s (for the enum) is fixed at compile of MLIR (currently 2, the only 2 I saw). There might be some things that could be done here but they would require quite a bit more C API work to support generically (e.g., casting ints to enum cases and binding all the getters or going generically through the `symbolize*` methods, like `symbolizeDimension(uint32_t)` or `symbolizeDimension(StringRef)`).
A few small changes:
1. In addition, since this patch registers default builders for attributes where people might've had their own builders already written, I added a `replace` param to `AttributeBuilder.insert` (`False` by default).
2. `makePythonEnumCaseName` can't handle all the different ways in which people write their enum cases, e.g., `llvm.CConv.Intel_OCL_BI`, which gets turned into `INTEL_O_C_L_B_I` (because `llvm::convertToSnakeFromCamelCase` doesn't look for runs of caps). So I dropped it. On the otherhand regularization does need to done because some enums have `None` as a case (and others might have other python keywords).
3. I turned on `llvm` dialect generation here in order to test `nvvm.WGMMAScaleIn`, which is an enum with [[ https://github.com/llvm/llvm-project/blob/d7e26b56207cbd8995296c5bb7c11ce676b649da/mlir/include/mlir/IR/EnumAttr.td#L22-L25 | no explicit discriminator ]] for the `neg` case.
Note, dialects that didn't get a `GEN_ENUM_BINDINGS` don't have any enums to generate.
Let me know if I should add more tests (the three trivial ones I added exercise both the supported `assemblyFormat`s and `replace=True`).
Reviewed By: stellaraccident
Differential Revision: https://reviews.llvm.org/D157934
2023-08-23 10:27:08 -08:00
|
|
|
DIALECT_NAME gpu
|
|
|
|
|
GEN_ENUM_BINDINGS)
|
2021-07-22 11:57:41 -08:00
|
|
|
|
|
|
|
|
declare_mlir_dialect_python_bindings(
|
|
|
|
|
ADD_TO_PARENT MLIRPythonSources.Dialects
|
|
|
|
|
ROOT_DIR "${CMAKE_CURRENT_SOURCE_DIR}/mlir"
|
|
|
|
|
TD_FILE dialects/LinalgOps.td
|
|
|
|
|
SOURCES
|
|
|
|
|
SOURCES_GLOB
|
|
|
|
|
dialects/linalg/*.py
|
|
|
|
|
DIALECT_NAME linalg
|
[mlir][python bindings] generate all the enums
This PR implements python enum bindings for *all* the enums - this includes `I*Attrs` (including positional/bit) and `Dialect/EnumAttr`.
There are a few parts to this:
1. CMake: a small addition to `declare_mlir_dialect_python_bindings` and `declare_mlir_dialect_extension_python_bindings` to generate the enum, a boolean arg `GEN_ENUM_BINDINGS` to make it opt-in (even though it works for basically all of the dialects), and an optional `GEN_ENUM_BINDINGS_TD_FILE` for handling corner cases.
2. EnumPythonBindingGen.cpp: there are two weedy aspects here that took investigation:
1. If an enum attribute is not a `Dialect/EnumAttr` then the `EnumAttrInfo` record is canonical, as far as both the cases of the enum **and the `AttrDefName`**. On the otherhand, if an enum is a `Dialect/EnumAttr` then the `EnumAttr` record has the correct `AttrDefName` ("load bearing", i.e., populates `ods.ir.AttributeBuilder('<NAME>')`) but its `enum` field contains the cases, which is an instance of `EnumAttrInfo`. The solution is to generate an one enum class for both `Dialect/EnumAttr` and "independent" `EnumAttrInfo` but to make that class interopable with two builder registrations that both do the right thing (see next sub-bullet).
2. Because we don't have a good connection to cpp `EnumAttr`, i.e., only the `enum class` getters are exposed (like `DimensionAttr::get(Dimension value)`), we have to resort to parsing e.g., `Attribute.parse(f'#gpu<dim {x}>')`. This means that the set of supported `assemblyFormat`s (for the enum) is fixed at compile of MLIR (currently 2, the only 2 I saw). There might be some things that could be done here but they would require quite a bit more C API work to support generically (e.g., casting ints to enum cases and binding all the getters or going generically through the `symbolize*` methods, like `symbolizeDimension(uint32_t)` or `symbolizeDimension(StringRef)`).
A few small changes:
1. In addition, since this patch registers default builders for attributes where people might've had their own builders already written, I added a `replace` param to `AttributeBuilder.insert` (`False` by default).
2. `makePythonEnumCaseName` can't handle all the different ways in which people write their enum cases, e.g., `llvm.CConv.Intel_OCL_BI`, which gets turned into `INTEL_O_C_L_B_I` (because `llvm::convertToSnakeFromCamelCase` doesn't look for runs of caps). So I dropped it. On the otherhand regularization does need to done because some enums have `None` as a case (and others might have other python keywords).
3. I turned on `llvm` dialect generation here in order to test `nvvm.WGMMAScaleIn`, which is an enum with [[ https://github.com/llvm/llvm-project/blob/d7e26b56207cbd8995296c5bb7c11ce676b649da/mlir/include/mlir/IR/EnumAttr.td#L22-L25 | no explicit discriminator ]] for the `neg` case.
Note, dialects that didn't get a `GEN_ENUM_BINDINGS` don't have any enums to generate.
Let me know if I should add more tests (the three trivial ones I added exercise both the supported `assemblyFormat`s and `replace=True`).
Reviewed By: stellaraccident
Differential Revision: https://reviews.llvm.org/D157934
2023-08-23 10:27:08 -08:00
|
|
|
DEPENDS LinalgOdsGen
|
|
|
|
|
GEN_ENUM_BINDINGS)
|
|
|
|
|
|
|
|
|
|
declare_mlir_dialect_python_bindings(
|
|
|
|
|
ADD_TO_PARENT MLIRPythonSources.Dialects
|
|
|
|
|
ROOT_DIR "${CMAKE_CURRENT_SOURCE_DIR}/mlir"
|
|
|
|
|
TD_FILE dialects/LLVMOps.td
|
|
|
|
|
SOURCES
|
|
|
|
|
dialects/llvm.py
|
|
|
|
|
DIALECT_NAME llvm
|
|
|
|
|
GEN_ENUM_BINDINGS)
|
2021-07-22 11:57:41 -08:00
|
|
|
|
2023-05-22 06:36:58 -08:00
|
|
|
declare_mlir_dialect_extension_python_bindings(
|
|
|
|
|
ADD_TO_PARENT MLIRPythonSources.Dialects
|
|
|
|
|
ROOT_DIR "${CMAKE_CURRENT_SOURCE_DIR}/mlir"
|
|
|
|
|
TD_FILE dialects/TransformPDLExtensionOps.td
|
|
|
|
|
SOURCES
|
|
|
|
|
dialects/transform/pdl.py
|
|
|
|
|
DIALECT_NAME transform
|
|
|
|
|
EXTENSION_NAME transform_pdl_extension)
|
|
|
|
|
|
2025-06-25 07:39:01 -08:00
|
|
|
declare_mlir_dialect_extension_python_bindings(
|
|
|
|
|
ADD_TO_PARENT MLIRPythonSources.Dialects
|
2025-09-21 12:32:45 -08:00
|
|
|
ROOT_DIR "${CMAKE_CURRENT_SOURCE_DIR}/mlir"
|
|
|
|
|
TD_FILE dialects/TransformSMTExtensionOps.td
|
|
|
|
|
SOURCES
|
|
|
|
|
dialects/transform/smt.py
|
|
|
|
|
DIALECT_NAME transform
|
|
|
|
|
EXTENSION_NAME transform_smt_extension)
|
|
|
|
|
|
|
|
|
|
declare_mlir_dialect_extension_python_bindings(
|
|
|
|
|
ADD_TO_PARENT MLIRPythonSources.Dialects
|
2025-06-25 07:39:01 -08:00
|
|
|
ROOT_DIR "${CMAKE_CURRENT_SOURCE_DIR}/mlir"
|
|
|
|
|
TD_FILE dialects/TransformDebugExtensionOps.td
|
|
|
|
|
SOURCES
|
|
|
|
|
dialects/transform/debug.py
|
|
|
|
|
DIALECT_NAME transform
|
|
|
|
|
EXTENSION_NAME transform_debug_extension)
|
|
|
|
|
|
2025-07-08 02:00:34 -08:00
|
|
|
declare_mlir_dialect_extension_python_bindings(
|
|
|
|
|
ADD_TO_PARENT MLIRPythonSources.Dialects
|
|
|
|
|
ROOT_DIR "${CMAKE_CURRENT_SOURCE_DIR}/mlir"
|
|
|
|
|
TD_FILE dialects/TransformTuneExtensionOps.td
|
|
|
|
|
SOURCES
|
|
|
|
|
dialects/transform/tune.py
|
|
|
|
|
DIALECT_NAME transform
|
|
|
|
|
EXTENSION_NAME transform_tune_extension)
|
|
|
|
|
|
2022-05-30 05:14:02 -08:00
|
|
|
declare_mlir_dialect_python_bindings(
|
|
|
|
|
ADD_TO_PARENT MLIRPythonSources.Dialects
|
|
|
|
|
ROOT_DIR "${CMAKE_CURRENT_SOURCE_DIR}/mlir"
|
|
|
|
|
TD_FILE dialects/TransformOps.td
|
|
|
|
|
SOURCES
|
|
|
|
|
dialects/transform/__init__.py
|
2025-09-10 03:35:38 -08:00
|
|
|
_mlir_libs/_mlir/dialects/transform/__init__.pyi
|
[mlir][python bindings] generate all the enums
This PR implements python enum bindings for *all* the enums - this includes `I*Attrs` (including positional/bit) and `Dialect/EnumAttr`.
There are a few parts to this:
1. CMake: a small addition to `declare_mlir_dialect_python_bindings` and `declare_mlir_dialect_extension_python_bindings` to generate the enum, a boolean arg `GEN_ENUM_BINDINGS` to make it opt-in (even though it works for basically all of the dialects), and an optional `GEN_ENUM_BINDINGS_TD_FILE` for handling corner cases.
2. EnumPythonBindingGen.cpp: there are two weedy aspects here that took investigation:
1. If an enum attribute is not a `Dialect/EnumAttr` then the `EnumAttrInfo` record is canonical, as far as both the cases of the enum **and the `AttrDefName`**. On the otherhand, if an enum is a `Dialect/EnumAttr` then the `EnumAttr` record has the correct `AttrDefName` ("load bearing", i.e., populates `ods.ir.AttributeBuilder('<NAME>')`) but its `enum` field contains the cases, which is an instance of `EnumAttrInfo`. The solution is to generate an one enum class for both `Dialect/EnumAttr` and "independent" `EnumAttrInfo` but to make that class interopable with two builder registrations that both do the right thing (see next sub-bullet).
2. Because we don't have a good connection to cpp `EnumAttr`, i.e., only the `enum class` getters are exposed (like `DimensionAttr::get(Dimension value)`), we have to resort to parsing e.g., `Attribute.parse(f'#gpu<dim {x}>')`. This means that the set of supported `assemblyFormat`s (for the enum) is fixed at compile of MLIR (currently 2, the only 2 I saw). There might be some things that could be done here but they would require quite a bit more C API work to support generically (e.g., casting ints to enum cases and binding all the getters or going generically through the `symbolize*` methods, like `symbolizeDimension(uint32_t)` or `symbolizeDimension(StringRef)`).
A few small changes:
1. In addition, since this patch registers default builders for attributes where people might've had their own builders already written, I added a `replace` param to `AttributeBuilder.insert` (`False` by default).
2. `makePythonEnumCaseName` can't handle all the different ways in which people write their enum cases, e.g., `llvm.CConv.Intel_OCL_BI`, which gets turned into `INTEL_O_C_L_B_I` (because `llvm::convertToSnakeFromCamelCase` doesn't look for runs of caps). So I dropped it. On the otherhand regularization does need to done because some enums have `None` as a case (and others might have other python keywords).
3. I turned on `llvm` dialect generation here in order to test `nvvm.WGMMAScaleIn`, which is an enum with [[ https://github.com/llvm/llvm-project/blob/d7e26b56207cbd8995296c5bb7c11ce676b649da/mlir/include/mlir/IR/EnumAttr.td#L22-L25 | no explicit discriminator ]] for the `neg` case.
Note, dialects that didn't get a `GEN_ENUM_BINDINGS` don't have any enums to generate.
Let me know if I should add more tests (the three trivial ones I added exercise both the supported `assemblyFormat`s and `replace=True`).
Reviewed By: stellaraccident
Differential Revision: https://reviews.llvm.org/D157934
2023-08-23 10:27:08 -08:00
|
|
|
DIALECT_NAME transform
|
|
|
|
|
GEN_ENUM_BINDINGS_TD_FILE
|
|
|
|
|
"../../include/mlir/Dialect/Transform/IR/TransformAttrs.td"
|
|
|
|
|
)
|
2023-07-28 08:03:33 -08:00
|
|
|
|
2023-12-15 03:04:43 -09:00
|
|
|
declare_mlir_python_sources(
|
|
|
|
|
MLIRPythonSources.Dialects.transform.extras
|
|
|
|
|
ADD_TO_PARENT MLIRPythonSources.Dialects
|
|
|
|
|
ROOT_DIR "${CMAKE_CURRENT_SOURCE_DIR}/mlir"
|
|
|
|
|
GEN_ENUM_BINDINGS
|
|
|
|
|
SOURCES
|
2023-12-20 14:29:11 -09:00
|
|
|
dialects/transform/extras/__init__.py)
|
2023-12-15 03:04:43 -09:00
|
|
|
|
2024-02-21 01:01:00 -09:00
|
|
|
declare_mlir_python_sources(
|
|
|
|
|
MLIRPythonSources.Dialects.transform.interpreter
|
|
|
|
|
ADD_TO_PARENT MLIRPythonSources.Dialects
|
|
|
|
|
ROOT_DIR "${CMAKE_CURRENT_SOURCE_DIR}/mlir"
|
|
|
|
|
SOURCES
|
|
|
|
|
dialects/transform/interpreter/__init__.py)
|
|
|
|
|
|
2023-07-18 00:15:53 -08:00
|
|
|
declare_mlir_dialect_extension_python_bindings(
|
|
|
|
|
ADD_TO_PARENT MLIRPythonSources.Dialects
|
|
|
|
|
ROOT_DIR "${CMAKE_CURRENT_SOURCE_DIR}/mlir"
|
|
|
|
|
TD_FILE dialects/BufferizationTransformOps.td
|
|
|
|
|
SOURCES
|
|
|
|
|
dialects/transform/bufferization.py
|
|
|
|
|
DIALECT_NAME transform
|
|
|
|
|
EXTENSION_NAME bufferization_transform)
|
|
|
|
|
|
2023-07-18 07:02:32 -08:00
|
|
|
declare_mlir_dialect_extension_python_bindings(
|
|
|
|
|
ADD_TO_PARENT MLIRPythonSources.Dialects
|
|
|
|
|
ROOT_DIR "${CMAKE_CURRENT_SOURCE_DIR}/mlir"
|
|
|
|
|
TD_FILE dialects/GPUTransformOps.td
|
|
|
|
|
SOURCES
|
|
|
|
|
dialects/transform/gpu.py
|
|
|
|
|
DIALECT_NAME transform
|
|
|
|
|
EXTENSION_NAME gpu_transform)
|
|
|
|
|
|
2022-06-09 01:10:32 -08:00
|
|
|
declare_mlir_dialect_extension_python_bindings(
|
|
|
|
|
ADD_TO_PARENT MLIRPythonSources.Dialects
|
|
|
|
|
ROOT_DIR "${CMAKE_CURRENT_SOURCE_DIR}/mlir"
|
|
|
|
|
TD_FILE dialects/SCFLoopTransformOps.td
|
|
|
|
|
SOURCES
|
|
|
|
|
dialects/transform/loop.py
|
|
|
|
|
DIALECT_NAME transform
|
|
|
|
|
EXTENSION_NAME loop_transform)
|
|
|
|
|
|
2023-07-28 05:47:23 -08:00
|
|
|
declare_mlir_dialect_extension_python_bindings(
|
|
|
|
|
ADD_TO_PARENT MLIRPythonSources.Dialects
|
|
|
|
|
ROOT_DIR "${CMAKE_CURRENT_SOURCE_DIR}/mlir"
|
|
|
|
|
TD_FILE dialects/MemRefTransformOps.td
|
|
|
|
|
SOURCES
|
|
|
|
|
dialects/transform/memref.py
|
|
|
|
|
DIALECT_NAME transform
|
|
|
|
|
EXTENSION_NAME memref_transform)
|
|
|
|
|
|
2023-10-03 04:52:52 -08:00
|
|
|
declare_mlir_dialect_extension_python_bindings(
|
|
|
|
|
ADD_TO_PARENT MLIRPythonSources.Dialects
|
|
|
|
|
ROOT_DIR "${CMAKE_CURRENT_SOURCE_DIR}/mlir"
|
|
|
|
|
TD_FILE dialects/NVGPUTransformOps.td
|
|
|
|
|
SOURCES
|
|
|
|
|
dialects/transform/nvgpu.py
|
|
|
|
|
DIALECT_NAME transform
|
|
|
|
|
EXTENSION_NAME nvgpu_transform)
|
|
|
|
|
|
2022-05-30 05:14:02 -08:00
|
|
|
declare_mlir_dialect_extension_python_bindings(
|
|
|
|
|
ADD_TO_PARENT MLIRPythonSources.Dialects
|
|
|
|
|
ROOT_DIR "${CMAKE_CURRENT_SOURCE_DIR}/mlir"
|
|
|
|
|
TD_FILE dialects/LinalgStructuredTransformOps.td
|
|
|
|
|
SOURCES
|
|
|
|
|
dialects/transform/structured.py
|
|
|
|
|
DIALECT_NAME transform
|
[mlir][python bindings] generate all the enums
This PR implements python enum bindings for *all* the enums - this includes `I*Attrs` (including positional/bit) and `Dialect/EnumAttr`.
There are a few parts to this:
1. CMake: a small addition to `declare_mlir_dialect_python_bindings` and `declare_mlir_dialect_extension_python_bindings` to generate the enum, a boolean arg `GEN_ENUM_BINDINGS` to make it opt-in (even though it works for basically all of the dialects), and an optional `GEN_ENUM_BINDINGS_TD_FILE` for handling corner cases.
2. EnumPythonBindingGen.cpp: there are two weedy aspects here that took investigation:
1. If an enum attribute is not a `Dialect/EnumAttr` then the `EnumAttrInfo` record is canonical, as far as both the cases of the enum **and the `AttrDefName`**. On the otherhand, if an enum is a `Dialect/EnumAttr` then the `EnumAttr` record has the correct `AttrDefName` ("load bearing", i.e., populates `ods.ir.AttributeBuilder('<NAME>')`) but its `enum` field contains the cases, which is an instance of `EnumAttrInfo`. The solution is to generate an one enum class for both `Dialect/EnumAttr` and "independent" `EnumAttrInfo` but to make that class interopable with two builder registrations that both do the right thing (see next sub-bullet).
2. Because we don't have a good connection to cpp `EnumAttr`, i.e., only the `enum class` getters are exposed (like `DimensionAttr::get(Dimension value)`), we have to resort to parsing e.g., `Attribute.parse(f'#gpu<dim {x}>')`. This means that the set of supported `assemblyFormat`s (for the enum) is fixed at compile of MLIR (currently 2, the only 2 I saw). There might be some things that could be done here but they would require quite a bit more C API work to support generically (e.g., casting ints to enum cases and binding all the getters or going generically through the `symbolize*` methods, like `symbolizeDimension(uint32_t)` or `symbolizeDimension(StringRef)`).
A few small changes:
1. In addition, since this patch registers default builders for attributes where people might've had their own builders already written, I added a `replace` param to `AttributeBuilder.insert` (`False` by default).
2. `makePythonEnumCaseName` can't handle all the different ways in which people write their enum cases, e.g., `llvm.CConv.Intel_OCL_BI`, which gets turned into `INTEL_O_C_L_B_I` (because `llvm::convertToSnakeFromCamelCase` doesn't look for runs of caps). So I dropped it. On the otherhand regularization does need to done because some enums have `None` as a case (and others might have other python keywords).
3. I turned on `llvm` dialect generation here in order to test `nvvm.WGMMAScaleIn`, which is an enum with [[ https://github.com/llvm/llvm-project/blob/d7e26b56207cbd8995296c5bb7c11ce676b649da/mlir/include/mlir/IR/EnumAttr.td#L22-L25 | no explicit discriminator ]] for the `neg` case.
Note, dialects that didn't get a `GEN_ENUM_BINDINGS` don't have any enums to generate.
Let me know if I should add more tests (the three trivial ones I added exercise both the supported `assemblyFormat`s and `replace=True`).
Reviewed By: stellaraccident
Differential Revision: https://reviews.llvm.org/D157934
2023-08-23 10:27:08 -08:00
|
|
|
EXTENSION_NAME structured_transform
|
|
|
|
|
GEN_ENUM_BINDINGS_TD_FILE
|
|
|
|
|
"../../include/mlir/Dialect/Linalg/TransformOps/LinalgTransformEnums.td"
|
|
|
|
|
)
|
2022-05-30 05:14:02 -08:00
|
|
|
|
2023-09-20 14:35:50 -08:00
|
|
|
declare_mlir_dialect_extension_python_bindings(
|
|
|
|
|
ADD_TO_PARENT MLIRPythonSources.Dialects
|
|
|
|
|
ROOT_DIR "${CMAKE_CURRENT_SOURCE_DIR}/mlir"
|
|
|
|
|
TD_FILE dialects/SparseTensorTransformOps.td
|
|
|
|
|
SOURCES
|
|
|
|
|
dialects/transform/sparse_tensor.py
|
|
|
|
|
DIALECT_NAME transform
|
|
|
|
|
EXTENSION_NAME sparse_tensor_transform)
|
|
|
|
|
|
2023-08-02 08:58:44 -08:00
|
|
|
declare_mlir_dialect_extension_python_bindings(
|
|
|
|
|
ADD_TO_PARENT MLIRPythonSources.Dialects
|
|
|
|
|
ROOT_DIR "${CMAKE_CURRENT_SOURCE_DIR}/mlir"
|
|
|
|
|
TD_FILE dialects/TensorTransformOps.td
|
|
|
|
|
SOURCES
|
|
|
|
|
dialects/transform/tensor.py
|
|
|
|
|
DIALECT_NAME transform
|
|
|
|
|
EXTENSION_NAME tensor_transform)
|
|
|
|
|
|
2023-07-28 08:06:31 -08:00
|
|
|
declare_mlir_dialect_extension_python_bindings(
|
|
|
|
|
ADD_TO_PARENT MLIRPythonSources.Dialects
|
|
|
|
|
ROOT_DIR "${CMAKE_CURRENT_SOURCE_DIR}/mlir"
|
|
|
|
|
TD_FILE dialects/VectorTransformOps.td
|
|
|
|
|
SOURCES
|
|
|
|
|
dialects/transform/vector.py
|
|
|
|
|
DIALECT_NAME transform
|
[mlir][python bindings] generate all the enums
This PR implements python enum bindings for *all* the enums - this includes `I*Attrs` (including positional/bit) and `Dialect/EnumAttr`.
There are a few parts to this:
1. CMake: a small addition to `declare_mlir_dialect_python_bindings` and `declare_mlir_dialect_extension_python_bindings` to generate the enum, a boolean arg `GEN_ENUM_BINDINGS` to make it opt-in (even though it works for basically all of the dialects), and an optional `GEN_ENUM_BINDINGS_TD_FILE` for handling corner cases.
2. EnumPythonBindingGen.cpp: there are two weedy aspects here that took investigation:
1. If an enum attribute is not a `Dialect/EnumAttr` then the `EnumAttrInfo` record is canonical, as far as both the cases of the enum **and the `AttrDefName`**. On the otherhand, if an enum is a `Dialect/EnumAttr` then the `EnumAttr` record has the correct `AttrDefName` ("load bearing", i.e., populates `ods.ir.AttributeBuilder('<NAME>')`) but its `enum` field contains the cases, which is an instance of `EnumAttrInfo`. The solution is to generate an one enum class for both `Dialect/EnumAttr` and "independent" `EnumAttrInfo` but to make that class interopable with two builder registrations that both do the right thing (see next sub-bullet).
2. Because we don't have a good connection to cpp `EnumAttr`, i.e., only the `enum class` getters are exposed (like `DimensionAttr::get(Dimension value)`), we have to resort to parsing e.g., `Attribute.parse(f'#gpu<dim {x}>')`. This means that the set of supported `assemblyFormat`s (for the enum) is fixed at compile of MLIR (currently 2, the only 2 I saw). There might be some things that could be done here but they would require quite a bit more C API work to support generically (e.g., casting ints to enum cases and binding all the getters or going generically through the `symbolize*` methods, like `symbolizeDimension(uint32_t)` or `symbolizeDimension(StringRef)`).
A few small changes:
1. In addition, since this patch registers default builders for attributes where people might've had their own builders already written, I added a `replace` param to `AttributeBuilder.insert` (`False` by default).
2. `makePythonEnumCaseName` can't handle all the different ways in which people write their enum cases, e.g., `llvm.CConv.Intel_OCL_BI`, which gets turned into `INTEL_O_C_L_B_I` (because `llvm::convertToSnakeFromCamelCase` doesn't look for runs of caps). So I dropped it. On the otherhand regularization does need to done because some enums have `None` as a case (and others might have other python keywords).
3. I turned on `llvm` dialect generation here in order to test `nvvm.WGMMAScaleIn`, which is an enum with [[ https://github.com/llvm/llvm-project/blob/d7e26b56207cbd8995296c5bb7c11ce676b649da/mlir/include/mlir/IR/EnumAttr.td#L22-L25 | no explicit discriminator ]] for the `neg` case.
Note, dialects that didn't get a `GEN_ENUM_BINDINGS` don't have any enums to generate.
Let me know if I should add more tests (the three trivial ones I added exercise both the supported `assemblyFormat`s and `replace=True`).
Reviewed By: stellaraccident
Differential Revision: https://reviews.llvm.org/D157934
2023-08-23 10:27:08 -08:00
|
|
|
EXTENSION_NAME vector_transform
|
|
|
|
|
GEN_ENUM_BINDINGS_TD_FILE
|
|
|
|
|
"../../include/mlir/Dialect/Vector/Transforms/VectorTransformsBase.td"
|
|
|
|
|
)
|
2023-07-28 08:06:31 -08:00
|
|
|
|
2026-02-05 10:05:17 -09:00
|
|
|
declare_mlir_dialect_extension_python_bindings(
|
|
|
|
|
ADD_TO_PARENT MLIRPythonSources.Dialects
|
|
|
|
|
ROOT_DIR "${CMAKE_CURRENT_SOURCE_DIR}/mlir"
|
2026-02-26 01:21:58 -09:00
|
|
|
TD_FILE dialects/X86TransformOps.td
|
2026-02-05 10:05:17 -09:00
|
|
|
SOURCES
|
2026-02-26 01:21:58 -09:00
|
|
|
dialects/transform/x86.py
|
2026-02-05 10:05:17 -09:00
|
|
|
DIALECT_NAME transform
|
2026-02-26 01:21:58 -09:00
|
|
|
EXTENSION_NAME x86_transform)
|
2026-02-05 10:05:17 -09:00
|
|
|
|
2025-11-06 05:25:34 -09:00
|
|
|
declare_mlir_dialect_extension_python_bindings(
|
|
|
|
|
ADD_TO_PARENT MLIRPythonSources.Dialects
|
|
|
|
|
ROOT_DIR "${CMAKE_CURRENT_SOURCE_DIR}/mlir"
|
|
|
|
|
TD_FILE dialects/XeGPUTransformOps.td
|
|
|
|
|
SOURCES
|
|
|
|
|
dialects/transform/xegpu.py
|
|
|
|
|
DIALECT_NAME transform
|
|
|
|
|
EXTENSION_NAME xegpu_transform)
|
|
|
|
|
|
2021-07-22 11:57:41 -08:00
|
|
|
declare_mlir_dialect_python_bindings(
|
|
|
|
|
ADD_TO_PARENT MLIRPythonSources.Dialects
|
|
|
|
|
ROOT_DIR "${CMAKE_CURRENT_SOURCE_DIR}/mlir"
|
|
|
|
|
TD_FILE dialects/MathOps.td
|
|
|
|
|
SOURCES dialects/math.py
|
|
|
|
|
DIALECT_NAME math)
|
|
|
|
|
|
2021-10-12 15:14:57 -08:00
|
|
|
declare_mlir_dialect_python_bindings(
|
|
|
|
|
ADD_TO_PARENT MLIRPythonSources.Dialects
|
|
|
|
|
ROOT_DIR "${CMAKE_CURRENT_SOURCE_DIR}/mlir"
|
2022-09-29 07:14:47 -08:00
|
|
|
TD_FILE dialects/ArithOps.td
|
2021-10-12 15:14:57 -08:00
|
|
|
SOURCES
|
|
|
|
|
dialects/arith.py
|
[mlir][python bindings] generate all the enums
This PR implements python enum bindings for *all* the enums - this includes `I*Attrs` (including positional/bit) and `Dialect/EnumAttr`.
There are a few parts to this:
1. CMake: a small addition to `declare_mlir_dialect_python_bindings` and `declare_mlir_dialect_extension_python_bindings` to generate the enum, a boolean arg `GEN_ENUM_BINDINGS` to make it opt-in (even though it works for basically all of the dialects), and an optional `GEN_ENUM_BINDINGS_TD_FILE` for handling corner cases.
2. EnumPythonBindingGen.cpp: there are two weedy aspects here that took investigation:
1. If an enum attribute is not a `Dialect/EnumAttr` then the `EnumAttrInfo` record is canonical, as far as both the cases of the enum **and the `AttrDefName`**. On the otherhand, if an enum is a `Dialect/EnumAttr` then the `EnumAttr` record has the correct `AttrDefName` ("load bearing", i.e., populates `ods.ir.AttributeBuilder('<NAME>')`) but its `enum` field contains the cases, which is an instance of `EnumAttrInfo`. The solution is to generate an one enum class for both `Dialect/EnumAttr` and "independent" `EnumAttrInfo` but to make that class interopable with two builder registrations that both do the right thing (see next sub-bullet).
2. Because we don't have a good connection to cpp `EnumAttr`, i.e., only the `enum class` getters are exposed (like `DimensionAttr::get(Dimension value)`), we have to resort to parsing e.g., `Attribute.parse(f'#gpu<dim {x}>')`. This means that the set of supported `assemblyFormat`s (for the enum) is fixed at compile of MLIR (currently 2, the only 2 I saw). There might be some things that could be done here but they would require quite a bit more C API work to support generically (e.g., casting ints to enum cases and binding all the getters or going generically through the `symbolize*` methods, like `symbolizeDimension(uint32_t)` or `symbolizeDimension(StringRef)`).
A few small changes:
1. In addition, since this patch registers default builders for attributes where people might've had their own builders already written, I added a `replace` param to `AttributeBuilder.insert` (`False` by default).
2. `makePythonEnumCaseName` can't handle all the different ways in which people write their enum cases, e.g., `llvm.CConv.Intel_OCL_BI`, which gets turned into `INTEL_O_C_L_B_I` (because `llvm::convertToSnakeFromCamelCase` doesn't look for runs of caps). So I dropped it. On the otherhand regularization does need to done because some enums have `None` as a case (and others might have other python keywords).
3. I turned on `llvm` dialect generation here in order to test `nvvm.WGMMAScaleIn`, which is an enum with [[ https://github.com/llvm/llvm-project/blob/d7e26b56207cbd8995296c5bb7c11ce676b649da/mlir/include/mlir/IR/EnumAttr.td#L22-L25 | no explicit discriminator ]] for the `neg` case.
Note, dialects that didn't get a `GEN_ENUM_BINDINGS` don't have any enums to generate.
Let me know if I should add more tests (the three trivial ones I added exercise both the supported `assemblyFormat`s and `replace=True`).
Reviewed By: stellaraccident
Differential Revision: https://reviews.llvm.org/D157934
2023-08-23 10:27:08 -08:00
|
|
|
DIALECT_NAME arith
|
|
|
|
|
GEN_ENUM_BINDINGS)
|
2021-10-12 15:14:57 -08:00
|
|
|
|
2021-07-22 11:57:41 -08:00
|
|
|
declare_mlir_dialect_python_bindings(
|
|
|
|
|
ADD_TO_PARENT MLIRPythonSources.Dialects
|
|
|
|
|
ROOT_DIR "${CMAKE_CURRENT_SOURCE_DIR}/mlir"
|
|
|
|
|
TD_FILE dialects/MemRefOps.td
|
2021-10-13 07:29:19 -08:00
|
|
|
SOURCES
|
|
|
|
|
dialects/memref.py
|
2021-07-22 11:57:41 -08:00
|
|
|
DIALECT_NAME memref)
|
|
|
|
|
|
2025-10-21 13:22:40 -08:00
|
|
|
declare_mlir_dialect_python_bindings(
|
|
|
|
|
ADD_TO_PARENT MLIRPythonSources.Dialects
|
|
|
|
|
ROOT_DIR "${CMAKE_CURRENT_SOURCE_DIR}/mlir"
|
|
|
|
|
TD_FILE dialects/ShardOps.td
|
|
|
|
|
SOURCES
|
|
|
|
|
dialects/shard.py
|
|
|
|
|
DIALECT_NAME shard
|
|
|
|
|
GEN_ENUM_BINDINGS)
|
|
|
|
|
|
2022-05-17 21:42:39 -08:00
|
|
|
declare_mlir_dialect_python_bindings(
|
|
|
|
|
ADD_TO_PARENT MLIRPythonSources.Dialects
|
|
|
|
|
ROOT_DIR "${CMAKE_CURRENT_SOURCE_DIR}/mlir"
|
|
|
|
|
TD_FILE dialects/MLProgramOps.td
|
|
|
|
|
SOURCES
|
|
|
|
|
dialects/ml_program.py
|
|
|
|
|
DIALECT_NAME ml_program)
|
|
|
|
|
|
2023-08-13 10:30:28 -08:00
|
|
|
declare_mlir_dialect_python_bindings(
|
|
|
|
|
ADD_TO_PARENT MLIRPythonSources.Dialects
|
|
|
|
|
ROOT_DIR "${CMAKE_CURRENT_SOURCE_DIR}/mlir"
|
|
|
|
|
TD_FILE dialects/NVGPUOps.td
|
|
|
|
|
SOURCES
|
|
|
|
|
dialects/nvgpu.py
|
[mlir][python bindings] generate all the enums
This PR implements python enum bindings for *all* the enums - this includes `I*Attrs` (including positional/bit) and `Dialect/EnumAttr`.
There are a few parts to this:
1. CMake: a small addition to `declare_mlir_dialect_python_bindings` and `declare_mlir_dialect_extension_python_bindings` to generate the enum, a boolean arg `GEN_ENUM_BINDINGS` to make it opt-in (even though it works for basically all of the dialects), and an optional `GEN_ENUM_BINDINGS_TD_FILE` for handling corner cases.
2. EnumPythonBindingGen.cpp: there are two weedy aspects here that took investigation:
1. If an enum attribute is not a `Dialect/EnumAttr` then the `EnumAttrInfo` record is canonical, as far as both the cases of the enum **and the `AttrDefName`**. On the otherhand, if an enum is a `Dialect/EnumAttr` then the `EnumAttr` record has the correct `AttrDefName` ("load bearing", i.e., populates `ods.ir.AttributeBuilder('<NAME>')`) but its `enum` field contains the cases, which is an instance of `EnumAttrInfo`. The solution is to generate an one enum class for both `Dialect/EnumAttr` and "independent" `EnumAttrInfo` but to make that class interopable with two builder registrations that both do the right thing (see next sub-bullet).
2. Because we don't have a good connection to cpp `EnumAttr`, i.e., only the `enum class` getters are exposed (like `DimensionAttr::get(Dimension value)`), we have to resort to parsing e.g., `Attribute.parse(f'#gpu<dim {x}>')`. This means that the set of supported `assemblyFormat`s (for the enum) is fixed at compile of MLIR (currently 2, the only 2 I saw). There might be some things that could be done here but they would require quite a bit more C API work to support generically (e.g., casting ints to enum cases and binding all the getters or going generically through the `symbolize*` methods, like `symbolizeDimension(uint32_t)` or `symbolizeDimension(StringRef)`).
A few small changes:
1. In addition, since this patch registers default builders for attributes where people might've had their own builders already written, I added a `replace` param to `AttributeBuilder.insert` (`False` by default).
2. `makePythonEnumCaseName` can't handle all the different ways in which people write their enum cases, e.g., `llvm.CConv.Intel_OCL_BI`, which gets turned into `INTEL_O_C_L_B_I` (because `llvm::convertToSnakeFromCamelCase` doesn't look for runs of caps). So I dropped it. On the otherhand regularization does need to done because some enums have `None` as a case (and others might have other python keywords).
3. I turned on `llvm` dialect generation here in order to test `nvvm.WGMMAScaleIn`, which is an enum with [[ https://github.com/llvm/llvm-project/blob/d7e26b56207cbd8995296c5bb7c11ce676b649da/mlir/include/mlir/IR/EnumAttr.td#L22-L25 | no explicit discriminator ]] for the `neg` case.
Note, dialects that didn't get a `GEN_ENUM_BINDINGS` don't have any enums to generate.
Let me know if I should add more tests (the three trivial ones I added exercise both the supported `assemblyFormat`s and `replace=True`).
Reviewed By: stellaraccident
Differential Revision: https://reviews.llvm.org/D157934
2023-08-23 10:27:08 -08:00
|
|
|
DIALECT_NAME nvgpu
|
|
|
|
|
GEN_ENUM_BINDINGS)
|
2023-08-13 10:30:28 -08:00
|
|
|
|
|
|
|
|
declare_mlir_dialect_python_bindings(
|
|
|
|
|
ADD_TO_PARENT MLIRPythonSources.Dialects
|
|
|
|
|
ROOT_DIR "${CMAKE_CURRENT_SOURCE_DIR}/mlir"
|
|
|
|
|
TD_FILE dialects/NVVMOps.td
|
|
|
|
|
SOURCES
|
|
|
|
|
dialects/nvvm.py
|
[mlir][python bindings] generate all the enums
This PR implements python enum bindings for *all* the enums - this includes `I*Attrs` (including positional/bit) and `Dialect/EnumAttr`.
There are a few parts to this:
1. CMake: a small addition to `declare_mlir_dialect_python_bindings` and `declare_mlir_dialect_extension_python_bindings` to generate the enum, a boolean arg `GEN_ENUM_BINDINGS` to make it opt-in (even though it works for basically all of the dialects), and an optional `GEN_ENUM_BINDINGS_TD_FILE` for handling corner cases.
2. EnumPythonBindingGen.cpp: there are two weedy aspects here that took investigation:
1. If an enum attribute is not a `Dialect/EnumAttr` then the `EnumAttrInfo` record is canonical, as far as both the cases of the enum **and the `AttrDefName`**. On the otherhand, if an enum is a `Dialect/EnumAttr` then the `EnumAttr` record has the correct `AttrDefName` ("load bearing", i.e., populates `ods.ir.AttributeBuilder('<NAME>')`) but its `enum` field contains the cases, which is an instance of `EnumAttrInfo`. The solution is to generate an one enum class for both `Dialect/EnumAttr` and "independent" `EnumAttrInfo` but to make that class interopable with two builder registrations that both do the right thing (see next sub-bullet).
2. Because we don't have a good connection to cpp `EnumAttr`, i.e., only the `enum class` getters are exposed (like `DimensionAttr::get(Dimension value)`), we have to resort to parsing e.g., `Attribute.parse(f'#gpu<dim {x}>')`. This means that the set of supported `assemblyFormat`s (for the enum) is fixed at compile of MLIR (currently 2, the only 2 I saw). There might be some things that could be done here but they would require quite a bit more C API work to support generically (e.g., casting ints to enum cases and binding all the getters or going generically through the `symbolize*` methods, like `symbolizeDimension(uint32_t)` or `symbolizeDimension(StringRef)`).
A few small changes:
1. In addition, since this patch registers default builders for attributes where people might've had their own builders already written, I added a `replace` param to `AttributeBuilder.insert` (`False` by default).
2. `makePythonEnumCaseName` can't handle all the different ways in which people write their enum cases, e.g., `llvm.CConv.Intel_OCL_BI`, which gets turned into `INTEL_O_C_L_B_I` (because `llvm::convertToSnakeFromCamelCase` doesn't look for runs of caps). So I dropped it. On the otherhand regularization does need to done because some enums have `None` as a case (and others might have other python keywords).
3. I turned on `llvm` dialect generation here in order to test `nvvm.WGMMAScaleIn`, which is an enum with [[ https://github.com/llvm/llvm-project/blob/d7e26b56207cbd8995296c5bb7c11ce676b649da/mlir/include/mlir/IR/EnumAttr.td#L22-L25 | no explicit discriminator ]] for the `neg` case.
Note, dialects that didn't get a `GEN_ENUM_BINDINGS` don't have any enums to generate.
Let me know if I should add more tests (the three trivial ones I added exercise both the supported `assemblyFormat`s and `replace=True`).
Reviewed By: stellaraccident
Differential Revision: https://reviews.llvm.org/D157934
2023-08-23 10:27:08 -08:00
|
|
|
DIALECT_NAME nvvm
|
|
|
|
|
GEN_ENUM_BINDINGS)
|
2023-08-13 10:30:28 -08:00
|
|
|
|
|
|
|
|
declare_mlir_dialect_python_bindings(
|
|
|
|
|
ADD_TO_PARENT MLIRPythonSources.Dialects
|
|
|
|
|
ROOT_DIR "${CMAKE_CURRENT_SOURCE_DIR}/mlir"
|
|
|
|
|
TD_FILE dialects/ROCDLOps.td
|
|
|
|
|
SOURCES
|
|
|
|
|
dialects/rocdl.py
|
|
|
|
|
DIALECT_NAME rocdl)
|
|
|
|
|
|
2022-01-04 07:43:44 -09:00
|
|
|
declare_mlir_python_sources(
|
|
|
|
|
MLIRPythonSources.Dialects.quant
|
|
|
|
|
ADD_TO_PARENT MLIRPythonSources.Dialects
|
|
|
|
|
ROOT_DIR "${CMAKE_CURRENT_SOURCE_DIR}/mlir"
|
[mlir][python bindings] generate all the enums
This PR implements python enum bindings for *all* the enums - this includes `I*Attrs` (including positional/bit) and `Dialect/EnumAttr`.
There are a few parts to this:
1. CMake: a small addition to `declare_mlir_dialect_python_bindings` and `declare_mlir_dialect_extension_python_bindings` to generate the enum, a boolean arg `GEN_ENUM_BINDINGS` to make it opt-in (even though it works for basically all of the dialects), and an optional `GEN_ENUM_BINDINGS_TD_FILE` for handling corner cases.
2. EnumPythonBindingGen.cpp: there are two weedy aspects here that took investigation:
1. If an enum attribute is not a `Dialect/EnumAttr` then the `EnumAttrInfo` record is canonical, as far as both the cases of the enum **and the `AttrDefName`**. On the otherhand, if an enum is a `Dialect/EnumAttr` then the `EnumAttr` record has the correct `AttrDefName` ("load bearing", i.e., populates `ods.ir.AttributeBuilder('<NAME>')`) but its `enum` field contains the cases, which is an instance of `EnumAttrInfo`. The solution is to generate an one enum class for both `Dialect/EnumAttr` and "independent" `EnumAttrInfo` but to make that class interopable with two builder registrations that both do the right thing (see next sub-bullet).
2. Because we don't have a good connection to cpp `EnumAttr`, i.e., only the `enum class` getters are exposed (like `DimensionAttr::get(Dimension value)`), we have to resort to parsing e.g., `Attribute.parse(f'#gpu<dim {x}>')`. This means that the set of supported `assemblyFormat`s (for the enum) is fixed at compile of MLIR (currently 2, the only 2 I saw). There might be some things that could be done here but they would require quite a bit more C API work to support generically (e.g., casting ints to enum cases and binding all the getters or going generically through the `symbolize*` methods, like `symbolizeDimension(uint32_t)` or `symbolizeDimension(StringRef)`).
A few small changes:
1. In addition, since this patch registers default builders for attributes where people might've had their own builders already written, I added a `replace` param to `AttributeBuilder.insert` (`False` by default).
2. `makePythonEnumCaseName` can't handle all the different ways in which people write their enum cases, e.g., `llvm.CConv.Intel_OCL_BI`, which gets turned into `INTEL_O_C_L_B_I` (because `llvm::convertToSnakeFromCamelCase` doesn't look for runs of caps). So I dropped it. On the otherhand regularization does need to done because some enums have `None` as a case (and others might have other python keywords).
3. I turned on `llvm` dialect generation here in order to test `nvvm.WGMMAScaleIn`, which is an enum with [[ https://github.com/llvm/llvm-project/blob/d7e26b56207cbd8995296c5bb7c11ce676b649da/mlir/include/mlir/IR/EnumAttr.td#L22-L25 | no explicit discriminator ]] for the `neg` case.
Note, dialects that didn't get a `GEN_ENUM_BINDINGS` don't have any enums to generate.
Let me know if I should add more tests (the three trivial ones I added exercise both the supported `assemblyFormat`s and `replace=True`).
Reviewed By: stellaraccident
Differential Revision: https://reviews.llvm.org/D157934
2023-08-23 10:27:08 -08:00
|
|
|
GEN_ENUM_BINDINGS
|
2022-01-04 07:43:44 -09:00
|
|
|
SOURCES
|
2025-09-10 03:35:38 -08:00
|
|
|
dialects/quant.py
|
|
|
|
|
_mlir_libs/_mlir/dialects/quant.pyi)
|
2022-01-04 07:43:44 -09:00
|
|
|
|
2024-12-11 09:07:21 -09:00
|
|
|
declare_mlir_dialect_python_bindings(
|
|
|
|
|
ADD_TO_PARENT MLIRPythonSources.Dialects
|
|
|
|
|
ROOT_DIR "${CMAKE_CURRENT_SOURCE_DIR}/mlir"
|
|
|
|
|
TD_FILE dialects/EmitC.td
|
2025-06-23 11:49:01 -08:00
|
|
|
SOURCES
|
2024-12-11 09:07:21 -09:00
|
|
|
dialects/emitc.py
|
|
|
|
|
DIALECT_NAME emitc)
|
|
|
|
|
|
2022-01-19 03:42:14 -09:00
|
|
|
declare_mlir_dialect_python_bindings(
|
2022-01-13 00:53:21 -09:00
|
|
|
ADD_TO_PARENT MLIRPythonSources.Dialects
|
|
|
|
|
ROOT_DIR "${CMAKE_CURRENT_SOURCE_DIR}/mlir"
|
2022-01-19 03:42:14 -09:00
|
|
|
TD_FILE dialects/PDLOps.td
|
2022-01-13 00:53:21 -09:00
|
|
|
SOURCES
|
|
|
|
|
dialects/pdl.py
|
2025-09-10 03:35:38 -08:00
|
|
|
_mlir_libs/_mlir/dialects/pdl.pyi
|
2022-01-19 03:42:14 -09:00
|
|
|
DIALECT_NAME pdl)
|
2022-01-13 00:53:21 -09:00
|
|
|
|
2023-08-23 14:41:04 -08:00
|
|
|
declare_mlir_dialect_python_bindings(
|
|
|
|
|
ADD_TO_PARENT MLIRPythonSources.Dialects
|
|
|
|
|
ROOT_DIR "${CMAKE_CURRENT_SOURCE_DIR}/mlir"
|
|
|
|
|
TD_FILE dialects/OpenMPOps.td
|
|
|
|
|
SOURCES
|
|
|
|
|
dialects/openmp.py
|
2023-12-07 02:22:45 -09:00
|
|
|
DIALECT_NAME omp
|
|
|
|
|
DEPENDS omp_common_td)
|
2023-08-23 14:41:04 -08:00
|
|
|
|
2021-09-29 11:42:53 -08:00
|
|
|
declare_mlir_dialect_python_bindings(
|
|
|
|
|
ADD_TO_PARENT MLIRPythonSources.Dialects
|
|
|
|
|
ROOT_DIR "${CMAKE_CURRENT_SOURCE_DIR}/mlir"
|
|
|
|
|
TD_FILE dialects/SCFOps.td
|
|
|
|
|
SOURCES
|
|
|
|
|
dialects/scf.py
|
|
|
|
|
DIALECT_NAME scf)
|
|
|
|
|
|
2021-07-22 11:57:41 -08:00
|
|
|
declare_mlir_dialect_python_bindings(
|
|
|
|
|
ADD_TO_PARENT MLIRPythonSources.Dialects
|
|
|
|
|
ROOT_DIR "${CMAKE_CURRENT_SOURCE_DIR}/mlir"
|
|
|
|
|
TD_FILE dialects/ShapeOps.td
|
|
|
|
|
SOURCES dialects/shape.py
|
|
|
|
|
DIALECT_NAME shape)
|
|
|
|
|
|
|
|
|
|
declare_mlir_dialect_python_bindings(
|
|
|
|
|
ADD_TO_PARENT MLIRPythonSources.Dialects
|
|
|
|
|
ROOT_DIR "${CMAKE_CURRENT_SOURCE_DIR}/mlir"
|
2021-09-30 05:09:30 -08:00
|
|
|
TD_FILE dialects/SparseTensorOps.td
|
2021-07-22 11:57:41 -08:00
|
|
|
SOURCES dialects/sparse_tensor.py
|
[mlir][python bindings] generate all the enums
This PR implements python enum bindings for *all* the enums - this includes `I*Attrs` (including positional/bit) and `Dialect/EnumAttr`.
There are a few parts to this:
1. CMake: a small addition to `declare_mlir_dialect_python_bindings` and `declare_mlir_dialect_extension_python_bindings` to generate the enum, a boolean arg `GEN_ENUM_BINDINGS` to make it opt-in (even though it works for basically all of the dialects), and an optional `GEN_ENUM_BINDINGS_TD_FILE` for handling corner cases.
2. EnumPythonBindingGen.cpp: there are two weedy aspects here that took investigation:
1. If an enum attribute is not a `Dialect/EnumAttr` then the `EnumAttrInfo` record is canonical, as far as both the cases of the enum **and the `AttrDefName`**. On the otherhand, if an enum is a `Dialect/EnumAttr` then the `EnumAttr` record has the correct `AttrDefName` ("load bearing", i.e., populates `ods.ir.AttributeBuilder('<NAME>')`) but its `enum` field contains the cases, which is an instance of `EnumAttrInfo`. The solution is to generate an one enum class for both `Dialect/EnumAttr` and "independent" `EnumAttrInfo` but to make that class interopable with two builder registrations that both do the right thing (see next sub-bullet).
2. Because we don't have a good connection to cpp `EnumAttr`, i.e., only the `enum class` getters are exposed (like `DimensionAttr::get(Dimension value)`), we have to resort to parsing e.g., `Attribute.parse(f'#gpu<dim {x}>')`. This means that the set of supported `assemblyFormat`s (for the enum) is fixed at compile of MLIR (currently 2, the only 2 I saw). There might be some things that could be done here but they would require quite a bit more C API work to support generically (e.g., casting ints to enum cases and binding all the getters or going generically through the `symbolize*` methods, like `symbolizeDimension(uint32_t)` or `symbolizeDimension(StringRef)`).
A few small changes:
1. In addition, since this patch registers default builders for attributes where people might've had their own builders already written, I added a `replace` param to `AttributeBuilder.insert` (`False` by default).
2. `makePythonEnumCaseName` can't handle all the different ways in which people write their enum cases, e.g., `llvm.CConv.Intel_OCL_BI`, which gets turned into `INTEL_O_C_L_B_I` (because `llvm::convertToSnakeFromCamelCase` doesn't look for runs of caps). So I dropped it. On the otherhand regularization does need to done because some enums have `None` as a case (and others might have other python keywords).
3. I turned on `llvm` dialect generation here in order to test `nvvm.WGMMAScaleIn`, which is an enum with [[ https://github.com/llvm/llvm-project/blob/d7e26b56207cbd8995296c5bb7c11ce676b649da/mlir/include/mlir/IR/EnumAttr.td#L22-L25 | no explicit discriminator ]] for the `neg` case.
Note, dialects that didn't get a `GEN_ENUM_BINDINGS` don't have any enums to generate.
Let me know if I should add more tests (the three trivial ones I added exercise both the supported `assemblyFormat`s and `replace=True`).
Reviewed By: stellaraccident
Differential Revision: https://reviews.llvm.org/D157934
2023-08-23 10:27:08 -08:00
|
|
|
DIALECT_NAME sparse_tensor
|
|
|
|
|
GEN_ENUM_BINDINGS_TD_FILE
|
|
|
|
|
"../../include/mlir/Dialect/SparseTensor/IR/SparseTensorAttrDefs.td"
|
|
|
|
|
)
|
2021-07-22 11:57:41 -08:00
|
|
|
|
2025-04-16 14:17:09 -08:00
|
|
|
declare_mlir_dialect_python_bindings(
|
|
|
|
|
ADD_TO_PARENT MLIRPythonSources.Dialects
|
|
|
|
|
ROOT_DIR "${CMAKE_CURRENT_SOURCE_DIR}/mlir"
|
|
|
|
|
TD_FILE dialects/SMTOps.td
|
|
|
|
|
GEN_ENUM_BINDINGS
|
|
|
|
|
SOURCES
|
|
|
|
|
dialects/smt.py
|
|
|
|
|
DIALECT_NAME smt)
|
|
|
|
|
|
2024-01-02 07:11:44 -09:00
|
|
|
declare_mlir_dialect_python_bindings(
|
2025-12-19 08:51:22 -09:00
|
|
|
ADD_TO_PARENT MLIRPythonSources.Dialects
|
|
|
|
|
ROOT_DIR "${CMAKE_CURRENT_SOURCE_DIR}/mlir"
|
|
|
|
|
TD_FILE dialects/SPIRVOps.td
|
|
|
|
|
SOURCES dialects/spirv.py
|
|
|
|
|
DIALECT_NAME spirv)
|
2024-01-02 07:11:44 -09:00
|
|
|
|
2021-07-22 11:57:41 -08:00
|
|
|
declare_mlir_dialect_python_bindings(
|
|
|
|
|
ADD_TO_PARENT MLIRPythonSources.Dialects
|
|
|
|
|
ROOT_DIR "${CMAKE_CURRENT_SOURCE_DIR}/mlir"
|
|
|
|
|
TD_FILE dialects/TensorOps.td
|
2022-10-04 00:06:00 -08:00
|
|
|
SOURCES
|
|
|
|
|
dialects/tensor.py
|
2021-07-22 11:57:41 -08:00
|
|
|
DIALECT_NAME tensor)
|
|
|
|
|
|
|
|
|
|
declare_mlir_dialect_python_bindings(
|
|
|
|
|
ADD_TO_PARENT MLIRPythonSources.Dialects
|
|
|
|
|
ROOT_DIR "${CMAKE_CURRENT_SOURCE_DIR}/mlir"
|
|
|
|
|
TD_FILE dialects/TosaOps.td
|
|
|
|
|
SOURCES dialects/tosa.py
|
[mlir][python bindings] generate all the enums
This PR implements python enum bindings for *all* the enums - this includes `I*Attrs` (including positional/bit) and `Dialect/EnumAttr`.
There are a few parts to this:
1. CMake: a small addition to `declare_mlir_dialect_python_bindings` and `declare_mlir_dialect_extension_python_bindings` to generate the enum, a boolean arg `GEN_ENUM_BINDINGS` to make it opt-in (even though it works for basically all of the dialects), and an optional `GEN_ENUM_BINDINGS_TD_FILE` for handling corner cases.
2. EnumPythonBindingGen.cpp: there are two weedy aspects here that took investigation:
1. If an enum attribute is not a `Dialect/EnumAttr` then the `EnumAttrInfo` record is canonical, as far as both the cases of the enum **and the `AttrDefName`**. On the otherhand, if an enum is a `Dialect/EnumAttr` then the `EnumAttr` record has the correct `AttrDefName` ("load bearing", i.e., populates `ods.ir.AttributeBuilder('<NAME>')`) but its `enum` field contains the cases, which is an instance of `EnumAttrInfo`. The solution is to generate an one enum class for both `Dialect/EnumAttr` and "independent" `EnumAttrInfo` but to make that class interopable with two builder registrations that both do the right thing (see next sub-bullet).
2. Because we don't have a good connection to cpp `EnumAttr`, i.e., only the `enum class` getters are exposed (like `DimensionAttr::get(Dimension value)`), we have to resort to parsing e.g., `Attribute.parse(f'#gpu<dim {x}>')`. This means that the set of supported `assemblyFormat`s (for the enum) is fixed at compile of MLIR (currently 2, the only 2 I saw). There might be some things that could be done here but they would require quite a bit more C API work to support generically (e.g., casting ints to enum cases and binding all the getters or going generically through the `symbolize*` methods, like `symbolizeDimension(uint32_t)` or `symbolizeDimension(StringRef)`).
A few small changes:
1. In addition, since this patch registers default builders for attributes where people might've had their own builders already written, I added a `replace` param to `AttributeBuilder.insert` (`False` by default).
2. `makePythonEnumCaseName` can't handle all the different ways in which people write their enum cases, e.g., `llvm.CConv.Intel_OCL_BI`, which gets turned into `INTEL_O_C_L_B_I` (because `llvm::convertToSnakeFromCamelCase` doesn't look for runs of caps). So I dropped it. On the otherhand regularization does need to done because some enums have `None` as a case (and others might have other python keywords).
3. I turned on `llvm` dialect generation here in order to test `nvvm.WGMMAScaleIn`, which is an enum with [[ https://github.com/llvm/llvm-project/blob/d7e26b56207cbd8995296c5bb7c11ce676b649da/mlir/include/mlir/IR/EnumAttr.td#L22-L25 | no explicit discriminator ]] for the `neg` case.
Note, dialects that didn't get a `GEN_ENUM_BINDINGS` don't have any enums to generate.
Let me know if I should add more tests (the three trivial ones I added exercise both the supported `assemblyFormat`s and `replace=True`).
Reviewed By: stellaraccident
Differential Revision: https://reviews.llvm.org/D157934
2023-08-23 10:27:08 -08:00
|
|
|
DIALECT_NAME tosa
|
|
|
|
|
)
|
2021-07-22 11:57:41 -08:00
|
|
|
|
2025-09-05 07:52:01 -08:00
|
|
|
declare_mlir_dialect_python_bindings(
|
|
|
|
|
ADD_TO_PARENT MLIRPythonSources.Dialects
|
|
|
|
|
ROOT_DIR "${CMAKE_CURRENT_SOURCE_DIR}/mlir"
|
|
|
|
|
TD_FILE dialects/UBOps.td
|
|
|
|
|
SOURCES dialects/ub.py
|
|
|
|
|
DIALECT_NAME ub
|
|
|
|
|
)
|
|
|
|
|
|
2021-07-22 11:57:41 -08:00
|
|
|
declare_mlir_dialect_python_bindings(
|
|
|
|
|
ADD_TO_PARENT MLIRPythonSources.Dialects
|
|
|
|
|
ROOT_DIR "${CMAKE_CURRENT_SOURCE_DIR}/mlir"
|
|
|
|
|
TD_FILE dialects/VectorOps.td
|
|
|
|
|
SOURCES dialects/vector.py
|
[mlir][python bindings] generate all the enums
This PR implements python enum bindings for *all* the enums - this includes `I*Attrs` (including positional/bit) and `Dialect/EnumAttr`.
There are a few parts to this:
1. CMake: a small addition to `declare_mlir_dialect_python_bindings` and `declare_mlir_dialect_extension_python_bindings` to generate the enum, a boolean arg `GEN_ENUM_BINDINGS` to make it opt-in (even though it works for basically all of the dialects), and an optional `GEN_ENUM_BINDINGS_TD_FILE` for handling corner cases.
2. EnumPythonBindingGen.cpp: there are two weedy aspects here that took investigation:
1. If an enum attribute is not a `Dialect/EnumAttr` then the `EnumAttrInfo` record is canonical, as far as both the cases of the enum **and the `AttrDefName`**. On the otherhand, if an enum is a `Dialect/EnumAttr` then the `EnumAttr` record has the correct `AttrDefName` ("load bearing", i.e., populates `ods.ir.AttributeBuilder('<NAME>')`) but its `enum` field contains the cases, which is an instance of `EnumAttrInfo`. The solution is to generate an one enum class for both `Dialect/EnumAttr` and "independent" `EnumAttrInfo` but to make that class interopable with two builder registrations that both do the right thing (see next sub-bullet).
2. Because we don't have a good connection to cpp `EnumAttr`, i.e., only the `enum class` getters are exposed (like `DimensionAttr::get(Dimension value)`), we have to resort to parsing e.g., `Attribute.parse(f'#gpu<dim {x}>')`. This means that the set of supported `assemblyFormat`s (for the enum) is fixed at compile of MLIR (currently 2, the only 2 I saw). There might be some things that could be done here but they would require quite a bit more C API work to support generically (e.g., casting ints to enum cases and binding all the getters or going generically through the `symbolize*` methods, like `symbolizeDimension(uint32_t)` or `symbolizeDimension(StringRef)`).
A few small changes:
1. In addition, since this patch registers default builders for attributes where people might've had their own builders already written, I added a `replace` param to `AttributeBuilder.insert` (`False` by default).
2. `makePythonEnumCaseName` can't handle all the different ways in which people write their enum cases, e.g., `llvm.CConv.Intel_OCL_BI`, which gets turned into `INTEL_O_C_L_B_I` (because `llvm::convertToSnakeFromCamelCase` doesn't look for runs of caps). So I dropped it. On the otherhand regularization does need to done because some enums have `None` as a case (and others might have other python keywords).
3. I turned on `llvm` dialect generation here in order to test `nvvm.WGMMAScaleIn`, which is an enum with [[ https://github.com/llvm/llvm-project/blob/d7e26b56207cbd8995296c5bb7c11ce676b649da/mlir/include/mlir/IR/EnumAttr.td#L22-L25 | no explicit discriminator ]] for the `neg` case.
Note, dialects that didn't get a `GEN_ENUM_BINDINGS` don't have any enums to generate.
Let me know if I should add more tests (the three trivial ones I added exercise both the supported `assemblyFormat`s and `replace=True`).
Reviewed By: stellaraccident
Differential Revision: https://reviews.llvm.org/D157934
2023-08-23 10:27:08 -08:00
|
|
|
DIALECT_NAME vector
|
2023-09-21 02:57:41 -08:00
|
|
|
GEN_ENUM_BINDINGS_TD_FILE
|
|
|
|
|
"dialects/VectorAttributes.td")
|
2021-07-22 11:57:41 -08:00
|
|
|
|
2026-02-05 10:05:17 -09:00
|
|
|
declare_mlir_dialect_python_bindings(
|
|
|
|
|
ADD_TO_PARENT MLIRPythonSources.Dialects
|
|
|
|
|
ROOT_DIR "${CMAKE_CURRENT_SOURCE_DIR}/mlir"
|
2026-02-26 01:21:58 -09:00
|
|
|
TD_FILE dialects/X86.td
|
|
|
|
|
SOURCES dialects/x86.py
|
|
|
|
|
DIALECT_NAME x86)
|
2026-02-05 10:05:17 -09:00
|
|
|
|
2025-09-18 18:10:39 -08:00
|
|
|
declare_mlir_dialect_python_bindings(
|
|
|
|
|
ADD_TO_PARENT MLIRPythonSources.Dialects
|
|
|
|
|
ROOT_DIR "${CMAKE_CURRENT_SOURCE_DIR}/mlir"
|
|
|
|
|
TD_FILE dialects/IRDLOps.td
|
|
|
|
|
SOURCES dialects/irdl.py
|
|
|
|
|
DIALECT_NAME irdl
|
|
|
|
|
GEN_ENUM_BINDINGS
|
|
|
|
|
)
|
|
|
|
|
|
2021-07-22 11:57:41 -08:00
|
|
|
################################################################################
|
|
|
|
|
# Python extensions.
|
|
|
|
|
# The sources for these are all in lib/Bindings/Python, but since they have to
|
|
|
|
|
# be rebuilt for each package and integrate with the source setup here, we
|
|
|
|
|
# just reference them here instead of having ordered, cross package target
|
|
|
|
|
# dependencies.
|
|
|
|
|
################################################################################
|
|
|
|
|
|
|
|
|
|
declare_mlir_python_extension(MLIRPythonExtension.Core
|
|
|
|
|
MODULE_NAME _mlir
|
|
|
|
|
ADD_TO_PARENT MLIRPythonSources.Core
|
2021-11-14 13:44:25 -09:00
|
|
|
ROOT_DIR "${PYTHON_SOURCE_DIR}"
|
2021-07-22 11:57:41 -08:00
|
|
|
SOURCES
|
2021-11-14 13:44:25 -09:00
|
|
|
MainModule.cpp
|
|
|
|
|
IRAffine.cpp
|
|
|
|
|
IRInterfaces.cpp
|
|
|
|
|
Pass.cpp
|
2024-06-11 06:45:12 -08:00
|
|
|
Rewrite.cpp
|
2021-11-14 13:44:25 -09:00
|
|
|
|
|
|
|
|
# Headers must be included explicitly so they are installed.
|
|
|
|
|
Pass.h
|
2024-06-12 04:17:13 -08:00
|
|
|
Rewrite.h
|
2021-07-22 11:57:41 -08:00
|
|
|
PRIVATE_LINK_LIBS
|
|
|
|
|
LLVMSupport
|
|
|
|
|
EMBED_CAPI_LINK_LIBS
|
|
|
|
|
MLIRCAPIDebug
|
|
|
|
|
MLIRCAPIIR
|
2021-10-14 07:18:28 -08:00
|
|
|
MLIRCAPIInterfaces
|
2021-07-22 11:57:41 -08:00
|
|
|
|
|
|
|
|
# Dialects
|
2022-02-26 13:49:54 -09:00
|
|
|
MLIRCAPIFunc
|
2022-01-05 01:21:21 -09:00
|
|
|
)
|
|
|
|
|
|
[mlir] Overhaul C/Python registration APIs to properly scope registration/loading activities.
Since the very first commits, the Python and C MLIR APIs have had mis-placed registration/load functionality for dialects, extensions, etc. This was done pragmatically in order to get bootstrapped and then just grew in. Downstreams largely bypass and do their own thing by providing various APIs to register things they need. Meanwhile, the C++ APIs have stabilized around this and it would make sense to follow suit.
The thing we have observed in canonical usage by downstreams is that each downstream tends to have native entry points that configure its installation to its preferences with one-stop APIs. This patch leans in to this approach with `RegisterEverything.h` and `mlir._mlir_libs._mlirRegisterEverything` being the one-stop entry points for the "upstream packages". The `_mlir_libs.__init__.py` now allows customization of the environment and Context by adding "initialization modules" to the `_mlir_libs` package. If present, `_mlirRegisterEverything` is treated as such a module. Others can be added by downstreams by adding a `_site_initialize_{i}.py` module, where '{i}' is a number starting with zero. The number will be incremented and corresponding module loaded until one is not found. Initialization modules can:
* Perform load time customization to the global environment (i.e. registering passes, hooks, etc).
* Define a `register_dialects(registry: DialectRegistry)` function that can extend the `DialectRegistry` that will be used to bootstrap the `Context`.
* Define a `context_init_hook(context: Context)` function that will be added to a list of callbacks which will be invoked after dialect registration during `Context` initialization.
Note that the `MLIRPythonExtension.RegisterEverything` is not included by default when building a downstream (its corresponding behavior was prior). For downstreams which need the default MLIR initialization to take place, they must add this back in to their Python CMake build just like they add their own components (i.e. to `add_mlir_python_common_capi_library` and `add_mlir_python_modules`). It is perfectly valid to not do this, in which case, only the things explicitly depended on and initialized by downstreams will be built/packaged. If the downstream has not been set up for this, it is recommended to simply add this back for the time being and pay the build time/package size cost.
CMake changes:
* `MLIRCAPIRegistration` -> `MLIRCAPIRegisterEverything` (renamed to signify what it does and force an evaluation: a number of places were incidentally linking this very expensive target)
* `MLIRPythonSoure.Passes` removed (without replacement: just drop)
* `MLIRPythonExtension.AllPassesRegistration` removed (without replacement: just drop)
* `MLIRPythonExtension.Conversions` removed (without replacement: just drop)
* `MLIRPythonExtension.Transforms` removed (without replacement: just drop)
Header changes:
* `mlir-c/Registration.h` is deleted. Dialect registration functionality is now in `IR.h`. Registration of upstream features are in `mlir-c/RegisterEverything.h`. When updating MLIR and a couple of downstreams, I found that proper usage was commingled so required making a choice vs just blind S&R.
Python APIs removed:
* mlir.transforms and mlir.conversions (previously only had an __init__.py which indirectly triggered `mlirRegisterTransformsPasses()` and `mlirRegisterConversionPasses()` respectively). Downstream impact: Remove these imports if present (they now happen as part of default initialization).
* mlir._mlir_libs._all_passes_registration, mlir._mlir_libs._mlirTransforms, mlir._mlir_libs._mlirConversions. Downstream impact: None expected (these were internally used).
C-APIs changed:
* mlirRegisterAllDialects(MlirContext) now takes an MlirDialectRegistry instead. It also used to trigger loading of all dialects, which was already marked with a TODO to remove -- it no longer does, and for direct use, dialects must be explicitly loaded. Downstream impact: Direct C-API users must ensure that needed dialects are loaded or call `mlirContextLoadAllAvailableDialects(MlirContext)` to emulate the prior behavior. Also see the `ir.c` test case (e.g. ` mlirContextGetOrLoadDialect(ctx, mlirStringRefCreateFromCString("func"));`).
* mlirDialectHandle* APIs were moved from Registration.h (which now is restricted to just global/upstream registration) to IR.h, arguably where it should have been. Downstream impact: include correct header (likely already doing so).
C-APIs added:
* mlirContextLoadAllAvailableDialects(MlirContext): Corresponds to C++ API with the same purpose.
Python APIs added:
* mlir.ir.DialectRegistry: Mapping for an MlirDialectRegistry.
* mlir.ir.Context.append_dialect_registry(MlirDialectRegistry)
* mlir.ir.Context.load_all_available_dialects()
* mlir._mlir_libs._mlirAllRegistration: New native extension that exposes a `register_dialects(MlirDialectRegistry)` entry point and performs all upstream pass/conversion/transforms registration on init. In this first step, we eagerly load this as part of the __init__.py and use it to monkey patch the Context to emulate prior behavior.
* Type caster and capsule support for MlirDialectRegistry
This should make it possible to build downstream Python dialects that only depend on a subset of MLIR. See: https://github.com/llvm/llvm-project/issues/56037
Here is an example PR, minimally adapting IREE to these changes: https://github.com/iree-org/iree/pull/9638/files In this situation, IREE is opting to not link everything, since it is already configuring the Context to its liking. For projects that would just like to not think about it and pull in everything, add `MLIRPythonExtension.RegisterEverything` to the list of Python sources getting built, and the old behavior will continue.
Reviewed By: mehdi_amini, ftynse
Differential Revision: https://reviews.llvm.org/D128593
2022-07-16 15:09:03 -08:00
|
|
|
# This extension exposes an API to register all dialects, extensions, and passes
|
|
|
|
|
# packaged in upstream MLIR and it is used for the upstream "mlir" Python
|
|
|
|
|
# package. Downstreams will likely want to provide their own and not depend
|
|
|
|
|
# on this one, since it links in the world.
|
|
|
|
|
# Note that this is not added to any top-level source target for transitive
|
|
|
|
|
# inclusion: It must be included explicitly by downstreams if desired. Note that
|
|
|
|
|
# this has a very large impact on what gets built/packaged.
|
|
|
|
|
declare_mlir_python_extension(MLIRPythonExtension.RegisterEverything
|
|
|
|
|
MODULE_NAME _mlirRegisterEverything
|
|
|
|
|
ROOT_DIR "${PYTHON_SOURCE_DIR}"
|
|
|
|
|
SOURCES
|
|
|
|
|
RegisterEverything.cpp
|
|
|
|
|
PRIVATE_LINK_LIBS
|
|
|
|
|
LLVMSupport
|
|
|
|
|
EMBED_CAPI_LINK_LIBS
|
|
|
|
|
MLIRCAPIConversion
|
|
|
|
|
MLIRCAPITransforms
|
|
|
|
|
MLIRCAPIRegisterEverything
|
|
|
|
|
)
|
|
|
|
|
|
2025-12-19 08:51:22 -09:00
|
|
|
declare_mlir_python_extension(MLIRPythonExtension.Dialects.Linalg.Nanobind
|
2022-01-05 01:21:21 -09:00
|
|
|
MODULE_NAME _mlirDialectsLinalg
|
|
|
|
|
ADD_TO_PARENT MLIRPythonSources.Dialects.linalg
|
|
|
|
|
ROOT_DIR "${PYTHON_SOURCE_DIR}"
|
|
|
|
|
SOURCES
|
|
|
|
|
DialectLinalg.cpp
|
|
|
|
|
PRIVATE_LINK_LIBS
|
|
|
|
|
LLVMSupport
|
|
|
|
|
EMBED_CAPI_LINK_LIBS
|
|
|
|
|
MLIRCAPIIR
|
|
|
|
|
MLIRCAPILinalg
|
|
|
|
|
)
|
|
|
|
|
|
2025-12-19 08:51:22 -09:00
|
|
|
declare_mlir_python_extension(MLIRPythonExtension.Dialects.GPU.Nanobind
|
2024-04-18 13:31:55 -08:00
|
|
|
MODULE_NAME _mlirDialectsGPU
|
|
|
|
|
ADD_TO_PARENT MLIRPythonSources.Dialects.gpu
|
|
|
|
|
ROOT_DIR "${PYTHON_SOURCE_DIR}"
|
|
|
|
|
SOURCES
|
|
|
|
|
DialectGPU.cpp
|
|
|
|
|
PRIVATE_LINK_LIBS
|
|
|
|
|
LLVMSupport
|
|
|
|
|
EMBED_CAPI_LINK_LIBS
|
|
|
|
|
MLIRCAPIIR
|
|
|
|
|
MLIRCAPIGPU
|
|
|
|
|
)
|
|
|
|
|
|
2025-12-19 08:51:22 -09:00
|
|
|
declare_mlir_python_extension(MLIRPythonExtension.Dialects.LLVM.Nanobind
|
2024-02-14 05:03:04 -09:00
|
|
|
MODULE_NAME _mlirDialectsLLVM
|
|
|
|
|
ADD_TO_PARENT MLIRPythonSources.Dialects.llvm
|
|
|
|
|
ROOT_DIR "${PYTHON_SOURCE_DIR}"
|
|
|
|
|
SOURCES
|
|
|
|
|
DialectLLVM.cpp
|
|
|
|
|
PRIVATE_LINK_LIBS
|
|
|
|
|
LLVMSupport
|
|
|
|
|
EMBED_CAPI_LINK_LIBS
|
|
|
|
|
MLIRCAPIIR
|
|
|
|
|
MLIRCAPILLVM
|
2025-10-20 08:14:52 -08:00
|
|
|
# Misnomer - this is only the LLVMIR translation target.
|
|
|
|
|
MLIRCAPITarget
|
2024-02-14 05:03:04 -09:00
|
|
|
)
|
|
|
|
|
|
2025-12-19 08:51:22 -09:00
|
|
|
declare_mlir_python_extension(MLIRPythonExtension.Dialects.Quant.Nanobind
|
2022-01-05 01:21:21 -09:00
|
|
|
MODULE_NAME _mlirDialectsQuant
|
|
|
|
|
ADD_TO_PARENT MLIRPythonSources.Dialects.quant
|
|
|
|
|
ROOT_DIR "${PYTHON_SOURCE_DIR}"
|
|
|
|
|
SOURCES
|
|
|
|
|
DialectQuant.cpp
|
|
|
|
|
PRIVATE_LINK_LIBS
|
|
|
|
|
LLVMSupport
|
|
|
|
|
EMBED_CAPI_LINK_LIBS
|
|
|
|
|
MLIRCAPIIR
|
|
|
|
|
MLIRCAPIQuant
|
|
|
|
|
)
|
|
|
|
|
|
2025-12-19 08:51:22 -09:00
|
|
|
declare_mlir_python_extension(MLIRPythonExtension.Dialects.NVGPU.Nanobind
|
2024-05-12 23:08:04 -08:00
|
|
|
MODULE_NAME _mlirDialectsNVGPU
|
2024-04-17 05:59:18 -08:00
|
|
|
ADD_TO_PARENT MLIRPythonSources.Dialects.nvgpu
|
|
|
|
|
ROOT_DIR "${PYTHON_SOURCE_DIR}"
|
|
|
|
|
SOURCES
|
|
|
|
|
DialectNVGPU.cpp
|
|
|
|
|
PRIVATE_LINK_LIBS
|
|
|
|
|
LLVMSupport
|
|
|
|
|
EMBED_CAPI_LINK_LIBS
|
|
|
|
|
MLIRCAPIIR
|
|
|
|
|
MLIRCAPINVGPU
|
|
|
|
|
)
|
|
|
|
|
|
2025-12-19 08:51:22 -09:00
|
|
|
declare_mlir_python_extension(MLIRPythonExtension.Dialects.PDL.Nanobind
|
2022-01-13 00:53:21 -09:00
|
|
|
MODULE_NAME _mlirDialectsPDL
|
|
|
|
|
ADD_TO_PARENT MLIRPythonSources.Dialects.pdl
|
|
|
|
|
ROOT_DIR "${PYTHON_SOURCE_DIR}"
|
|
|
|
|
SOURCES
|
|
|
|
|
DialectPDL.cpp
|
|
|
|
|
PRIVATE_LINK_LIBS
|
|
|
|
|
LLVMSupport
|
|
|
|
|
EMBED_CAPI_LINK_LIBS
|
|
|
|
|
MLIRCAPIIR
|
|
|
|
|
MLIRCAPIPDL
|
|
|
|
|
)
|
|
|
|
|
|
2025-12-19 08:51:22 -09:00
|
|
|
declare_mlir_python_extension(MLIRPythonExtension.Dialects.SparseTensor.Nanobind
|
2022-01-05 01:21:21 -09:00
|
|
|
MODULE_NAME _mlirDialectsSparseTensor
|
|
|
|
|
ADD_TO_PARENT MLIRPythonSources.Dialects.sparse_tensor
|
|
|
|
|
ROOT_DIR "${PYTHON_SOURCE_DIR}"
|
|
|
|
|
SOURCES
|
|
|
|
|
DialectSparseTensor.cpp
|
|
|
|
|
PRIVATE_LINK_LIBS
|
|
|
|
|
LLVMSupport
|
|
|
|
|
EMBED_CAPI_LINK_LIBS
|
|
|
|
|
MLIRCAPIIR
|
|
|
|
|
MLIRCAPISparseTensor
|
2021-07-22 11:57:41 -08:00
|
|
|
)
|
|
|
|
|
|
2025-12-19 08:51:22 -09:00
|
|
|
declare_mlir_python_extension(MLIRPythonExtension.Dialects.Transform.Nanobind
|
2022-10-10 06:33:59 -08:00
|
|
|
MODULE_NAME _mlirDialectsTransform
|
|
|
|
|
ADD_TO_PARENT MLIRPythonSources.Dialects.transform
|
|
|
|
|
ROOT_DIR "${PYTHON_SOURCE_DIR}"
|
|
|
|
|
SOURCES
|
|
|
|
|
DialectTransform.cpp
|
[MLIR][Python] Impl XOpInterface(s) from Python, with X=Transform and X=MemoryEffects (#176920)
Provides the infrastructure for implementing and late-binding
OpInterfaces from Python.
* On the mlir-c API declaration side, each `XOpInterface` has a callback
struct, with a callback for each method and a userdata member (provided
as an arg to each method), and a
`mlirXOpInterfaceAttachFallbackModel(ctx, op_name, callbacks)` func.
* This CAPI is implemented by defining a subclass of
`XOpInterface::FallbackModel` that holds the callback struct and has
each method call the corresponding callback (with userdata as an arg).
Given a callback struct, a new `FallbackModel` is created and attached,
i.e. late bound, to the named op. (MLIR's interface infrastructure is
such that the thus registered `FallbackModel` will be returned in case
the op gets cast to the `XOpInterface`.)
* On the Python side, we expose a stand-in `XOpInterface` base class
which has one (class)method: `XOpInterface.attach(cls, op_name, ctx)`.
Python users subclass this class (`class MyInterfaceImpl(XOpInterface):
...`) and implement the interface's methods (with the right names and
signatures). The user calls `attach` on the subclass
(`MyInterfaceImpl.attach("my_dialect.my_op", ctx)`) which prepares the
callbacks struct _with userdata set to the subclass_ (as we use it to
lookup methods). These callbacks (and userdata) are then registered as
an `XOpInterface::FallbackModel` by
`mlirXOpInterfaceAttachFallbackModel(...)`. From then on the Python
methods will be used to respond to calls to the interface methods
(originating in C++).
This PR enables implementing the TransformOpInterface and the
MemoryEffectsOpInterface, both of which are required for making an op
into a transform op.
Everything besides the above linked code is there to facilitate exposing
the interfaces: the right types for the arguments of the methods are
exposed as are functions/methods for manipulating these arguments (e.g.
specifying side effects on `OpOperand`s and `OpResult`s and being able
to access and set the transform handles associated with args and
results).
2026-02-12 05:07:10 -09:00
|
|
|
Rewrite.h
|
2022-10-10 06:33:59 -08:00
|
|
|
PRIVATE_LINK_LIBS
|
|
|
|
|
LLVMSupport
|
[MLIR][Python] Impl XOpInterface(s) from Python, with X=Transform and X=MemoryEffects (#176920)
Provides the infrastructure for implementing and late-binding
OpInterfaces from Python.
* On the mlir-c API declaration side, each `XOpInterface` has a callback
struct, with a callback for each method and a userdata member (provided
as an arg to each method), and a
`mlirXOpInterfaceAttachFallbackModel(ctx, op_name, callbacks)` func.
* This CAPI is implemented by defining a subclass of
`XOpInterface::FallbackModel` that holds the callback struct and has
each method call the corresponding callback (with userdata as an arg).
Given a callback struct, a new `FallbackModel` is created and attached,
i.e. late bound, to the named op. (MLIR's interface infrastructure is
such that the thus registered `FallbackModel` will be returned in case
the op gets cast to the `XOpInterface`.)
* On the Python side, we expose a stand-in `XOpInterface` base class
which has one (class)method: `XOpInterface.attach(cls, op_name, ctx)`.
Python users subclass this class (`class MyInterfaceImpl(XOpInterface):
...`) and implement the interface's methods (with the right names and
signatures). The user calls `attach` on the subclass
(`MyInterfaceImpl.attach("my_dialect.my_op", ctx)`) which prepares the
callbacks struct _with userdata set to the subclass_ (as we use it to
lookup methods). These callbacks (and userdata) are then registered as
an `XOpInterface::FallbackModel` by
`mlirXOpInterfaceAttachFallbackModel(...)`. From then on the Python
methods will be used to respond to calls to the interface methods
(originating in C++).
This PR enables implementing the TransformOpInterface and the
MemoryEffectsOpInterface, both of which are required for making an op
into a transform op.
Everything besides the above linked code is there to facilitate exposing
the interfaces: the right types for the arguments of the methods are
exposed as are functions/methods for manipulating these arguments (e.g.
specifying side effects on `OpOperand`s and `OpResult`s and being able
to access and set the transform handles associated with args and
results).
2026-02-12 05:07:10 -09:00
|
|
|
MLIRPythonExtension.Core
|
2022-10-10 06:33:59 -08:00
|
|
|
EMBED_CAPI_LINK_LIBS
|
|
|
|
|
MLIRCAPIIR
|
|
|
|
|
MLIRCAPITransformDialect
|
|
|
|
|
)
|
|
|
|
|
|
2025-12-19 08:51:22 -09:00
|
|
|
declare_mlir_python_extension(MLIRPythonExtension.Dialects.IRDL.Nanobind
|
2025-09-18 18:10:39 -08:00
|
|
|
MODULE_NAME _mlirDialectsIRDL
|
|
|
|
|
ADD_TO_PARENT MLIRPythonSources.Dialects.irdl
|
|
|
|
|
ROOT_DIR "${PYTHON_SOURCE_DIR}"
|
|
|
|
|
SOURCES
|
|
|
|
|
DialectIRDL.cpp
|
|
|
|
|
PRIVATE_LINK_LIBS
|
|
|
|
|
LLVMSupport
|
|
|
|
|
EMBED_CAPI_LINK_LIBS
|
|
|
|
|
MLIRCAPIIR
|
|
|
|
|
MLIRCAPIIRDL
|
|
|
|
|
)
|
|
|
|
|
|
2021-07-22 11:57:41 -08:00
|
|
|
declare_mlir_python_extension(MLIRPythonExtension.AsyncDialectPasses
|
|
|
|
|
MODULE_NAME _mlirAsyncPasses
|
2024-04-20 17:49:39 -08:00
|
|
|
ADD_TO_PARENT MLIRPythonSources.Dialects.async
|
2021-11-14 13:44:25 -09:00
|
|
|
ROOT_DIR "${PYTHON_SOURCE_DIR}"
|
2021-07-22 11:57:41 -08:00
|
|
|
SOURCES
|
2021-11-14 13:44:25 -09:00
|
|
|
AsyncPasses.cpp
|
2021-07-22 11:57:41 -08:00
|
|
|
PRIVATE_LINK_LIBS
|
|
|
|
|
LLVMSupport
|
|
|
|
|
EMBED_CAPI_LINK_LIBS
|
|
|
|
|
MLIRCAPIAsync
|
|
|
|
|
)
|
|
|
|
|
|
2022-08-03 05:28:49 -08:00
|
|
|
if(MLIR_ENABLE_EXECUTION_ENGINE)
|
2022-01-13 22:47:47 -09:00
|
|
|
declare_mlir_python_extension(MLIRPythonExtension.ExecutionEngine
|
|
|
|
|
MODULE_NAME _mlirExecutionEngine
|
|
|
|
|
ADD_TO_PARENT MLIRPythonSources.ExecutionEngine
|
|
|
|
|
ROOT_DIR "${PYTHON_SOURCE_DIR}"
|
|
|
|
|
SOURCES
|
|
|
|
|
ExecutionEngineModule.cpp
|
|
|
|
|
PRIVATE_LINK_LIBS
|
|
|
|
|
LLVMSupport
|
|
|
|
|
EMBED_CAPI_LINK_LIBS
|
|
|
|
|
MLIRCAPIExecutionEngine
|
|
|
|
|
)
|
|
|
|
|
endif()
|
2021-07-28 12:00:02 -08:00
|
|
|
|
2021-07-22 11:57:41 -08:00
|
|
|
declare_mlir_python_extension(MLIRPythonExtension.GPUDialectPasses
|
|
|
|
|
MODULE_NAME _mlirGPUPasses
|
|
|
|
|
ADD_TO_PARENT MLIRPythonSources.Dialects.gpu
|
2021-11-14 13:44:25 -09:00
|
|
|
ROOT_DIR "${PYTHON_SOURCE_DIR}"
|
2021-07-22 11:57:41 -08:00
|
|
|
SOURCES
|
2021-11-14 13:44:25 -09:00
|
|
|
GPUPasses.cpp
|
2021-07-22 11:57:41 -08:00
|
|
|
PRIVATE_LINK_LIBS
|
|
|
|
|
LLVMSupport
|
|
|
|
|
EMBED_CAPI_LINK_LIBS
|
|
|
|
|
MLIRCAPIGPU
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
declare_mlir_python_extension(MLIRPythonExtension.LinalgPasses
|
|
|
|
|
MODULE_NAME _mlirLinalgPasses
|
|
|
|
|
ADD_TO_PARENT MLIRPythonSources.Dialects.linalg
|
2021-11-14 13:44:25 -09:00
|
|
|
ROOT_DIR "${PYTHON_SOURCE_DIR}"
|
2021-07-22 11:57:41 -08:00
|
|
|
SOURCES
|
2021-11-14 13:44:25 -09:00
|
|
|
LinalgPasses.cpp
|
2021-07-22 11:57:41 -08:00
|
|
|
PRIVATE_LINK_LIBS
|
|
|
|
|
LLVMSupport
|
|
|
|
|
EMBED_CAPI_LINK_LIBS
|
|
|
|
|
MLIRCAPILinalg
|
|
|
|
|
)
|
2021-04-28 12:04:17 -08:00
|
|
|
|
2025-12-19 08:51:22 -09:00
|
|
|
declare_mlir_python_extension(MLIRPythonExtension.Dialects.SMT.Nanobind
|
2025-04-16 14:17:09 -08:00
|
|
|
MODULE_NAME _mlirDialectsSMT
|
|
|
|
|
ADD_TO_PARENT MLIRPythonSources.Dialects.smt
|
|
|
|
|
ROOT_DIR "${PYTHON_SOURCE_DIR}"
|
|
|
|
|
SOURCES
|
|
|
|
|
DialectSMT.cpp
|
|
|
|
|
PRIVATE_LINK_LIBS
|
|
|
|
|
LLVMSupport
|
|
|
|
|
EMBED_CAPI_LINK_LIBS
|
|
|
|
|
MLIRCAPIIR
|
|
|
|
|
MLIRCAPISMT
|
|
|
|
|
MLIRCAPIExportSMTLIB
|
|
|
|
|
)
|
|
|
|
|
|
2021-07-22 11:57:41 -08:00
|
|
|
declare_mlir_python_extension(MLIRPythonExtension.SparseTensorDialectPasses
|
|
|
|
|
MODULE_NAME _mlirSparseTensorPasses
|
|
|
|
|
ADD_TO_PARENT MLIRPythonSources.Dialects.sparse_tensor
|
2021-11-14 13:44:25 -09:00
|
|
|
ROOT_DIR "${PYTHON_SOURCE_DIR}"
|
2021-07-22 11:57:41 -08:00
|
|
|
SOURCES
|
2021-11-14 13:44:25 -09:00
|
|
|
SparseTensorPasses.cpp
|
2021-07-22 11:57:41 -08:00
|
|
|
PRIVATE_LINK_LIBS
|
|
|
|
|
LLVMSupport
|
|
|
|
|
EMBED_CAPI_LINK_LIBS
|
|
|
|
|
MLIRCAPISparseTensor
|
2021-04-28 12:04:17 -08:00
|
|
|
)
|
|
|
|
|
|
2024-02-21 01:01:00 -09:00
|
|
|
declare_mlir_python_extension(MLIRPythonExtension.TransformInterpreter
|
|
|
|
|
MODULE_NAME _mlirTransformInterpreter
|
|
|
|
|
ADD_TO_PARENT MLIRPythonSources.Dialects.transform
|
|
|
|
|
ROOT_DIR "${PYTHON_SOURCE_DIR}"
|
|
|
|
|
SOURCES
|
|
|
|
|
TransformInterpreter.cpp
|
|
|
|
|
PRIVATE_LINK_LIBS
|
|
|
|
|
LLVMSupport
|
|
|
|
|
EMBED_CAPI_LINK_LIBS
|
|
|
|
|
MLIRCAPITransformDialectTransforms
|
|
|
|
|
)
|
|
|
|
|
|
2025-12-19 08:51:22 -09:00
|
|
|
declare_mlir_python_extension(MLIRPythonExtension.Dialects.AMDGPU.Nanobind
|
2025-12-16 01:43:08 -09:00
|
|
|
MODULE_NAME _mlirDialectsAMDGPU
|
|
|
|
|
ADD_TO_PARENT MLIRPythonSources.Dialects.amdgpu
|
|
|
|
|
ROOT_DIR "${PYTHON_SOURCE_DIR}"
|
|
|
|
|
SOURCES
|
|
|
|
|
DialectAMDGPU.cpp
|
|
|
|
|
PRIVATE_LINK_LIBS
|
|
|
|
|
LLVMSupport
|
|
|
|
|
EMBED_CAPI_LINK_LIBS
|
|
|
|
|
MLIRCAPIIR
|
|
|
|
|
MLIRCAPIAMDGPU
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
2021-10-26 09:14:50 -08:00
|
|
|
# TODO: Figure out how to put this in the test tree.
|
|
|
|
|
# This should not be included in the main Python extension. However,
|
2021-10-14 07:18:28 -08:00
|
|
|
# putting it into MLIRPythonTestSources along with the dialect declaration
|
|
|
|
|
# above confuses Python module loader when running under lit.
|
2021-10-26 09:14:50 -08:00
|
|
|
set(_ADDL_TEST_SOURCES)
|
|
|
|
|
if(MLIR_INCLUDE_TESTS)
|
|
|
|
|
set(_ADDL_TEST_SOURCES MLIRPythonTestSources)
|
|
|
|
|
declare_mlir_python_sources(MLIRPythonTestSources)
|
|
|
|
|
declare_mlir_python_sources(MLIRPythonTestSources.Dialects
|
|
|
|
|
ADD_TO_PARENT MLIRPythonTestSources)
|
|
|
|
|
|
|
|
|
|
# TODO: this uses a tablegen file from the test directory and should be
|
|
|
|
|
# decoupled from here.
|
|
|
|
|
declare_mlir_python_sources(
|
|
|
|
|
MLIRPythonTestSources.Dialects.PythonTest
|
|
|
|
|
ROOT_DIR "${CMAKE_CURRENT_SOURCE_DIR}/mlir"
|
|
|
|
|
ADD_TO_PARENT MLIRPythonTestSources.Dialects
|
2024-12-09 12:37:43 -09:00
|
|
|
SOURCES
|
|
|
|
|
dialects/python_test.py
|
|
|
|
|
)
|
2021-10-26 09:14:50 -08:00
|
|
|
set(LLVM_TARGET_DEFINITIONS
|
|
|
|
|
"${MLIR_MAIN_SRC_DIR}/test/python/python_test_ops.td")
|
|
|
|
|
mlir_tablegen(
|
|
|
|
|
"dialects/_python_test_ops_gen.py"
|
|
|
|
|
-gen-python-op-bindings
|
|
|
|
|
-bind-dialect=python_test)
|
|
|
|
|
add_public_tablegen_target(PythonTestDialectPyIncGen)
|
|
|
|
|
declare_mlir_python_sources(
|
|
|
|
|
MLIRPythonTestSources.Dialects.PythonTest.ops_gen
|
|
|
|
|
ROOT_DIR "${CMAKE_CURRENT_BINARY_DIR}"
|
|
|
|
|
ADD_TO_PARENT MLIRPythonTestSources.Dialects.PythonTest
|
|
|
|
|
SOURCES "dialects/_python_test_ops_gen.py")
|
|
|
|
|
|
2024-12-09 12:37:43 -09:00
|
|
|
declare_mlir_python_extension(MLIRPythonTestSources.PythonTestExtensionNanobind
|
|
|
|
|
MODULE_NAME _mlirPythonTestNanobind
|
2021-10-26 09:14:50 -08:00
|
|
|
ADD_TO_PARENT MLIRPythonTestSources.Dialects
|
2021-11-14 13:44:25 -09:00
|
|
|
ROOT_DIR "${MLIR_SOURCE_DIR}/test/python/lib"
|
2021-10-26 09:14:50 -08:00
|
|
|
SOURCES
|
2024-12-09 12:37:43 -09:00
|
|
|
PythonTestModuleNanobind.cpp
|
2021-10-26 09:14:50 -08:00
|
|
|
PRIVATE_LINK_LIBS
|
|
|
|
|
LLVMSupport
|
|
|
|
|
EMBED_CAPI_LINK_LIBS
|
|
|
|
|
MLIRCAPIPythonTestDialect
|
|
|
|
|
)
|
|
|
|
|
endif()
|
2021-10-14 07:18:28 -08:00
|
|
|
|
[mlir][Python] create MLIRPythonSupport (#171775)
# What
This PR adds a shared library `MLIRPythonSupport` which contains all of
the CRTP classes ike `PyConcreteValue`, `PyConcreteType`,
`PyConcreteAttribute`, as well as other useful code like `Defaulting*`
and etc enabling their reuse in downstream projects. Downstream projects
can now do
```c++
struct PyTestType : mlir::python::MLIR_BINDINGS_PYTHON_DOMAIN::PyConcreteType<PyTestType> {
...
};
class PyTestAttr : public mlir::python::MLIR_BINDINGS_PYTHON_DOMAIN::PyConcreteAttribute<PyTestAttr> {
...
}
NB_MODULE(_mlirPythonTestNanobind, m) {
PyTestType::bind(m);
PyTestAttr::bind(m);
}
```
instead of using the discordant alternative
`mlir_type_subclass`/`mlir_attr_subclass` (same goes for
`PyConcreteValue`/`mlir_value_subclass`).
# Why
This PR is mostly code motion (along with CMake) but before I describe
the changes I want to state the goals/benefits:
1. Currently upstream "core" extensions and "dialect" extensions ([all
of the `Dialect*` extensions
here](https://github.com/llvm/llvm-project/tree/d7c734b5a14bd91e1c76e2ce0014c19f9deef487/mlir/lib/Bindings/Python))
are a two-tier system;
**a**. [core
extensions](https://github.com/llvm/llvm-project/blob/main/mlir/lib/Bindings/Python/IRTypes.cpp#L361)
enjoy first class support as far as type inference[^3], type stub
generation, and ease of implementation, while dialect extensions [have
poorer support](https://reviews.llvm.org/D150927), incorrect type stub
generation much more tedious (boilerplate) implementation;
**b**. Crucially, this two-tiered system is reflected in the fact that
**the two sets of types/attributes are not in the same Python object
hierarchy**. To wit: `isinstance(..., Type)` and `isinstance(...,
Attribute)` are not supported for the dialect extensions[^2];
**c**. Since these types are not exposed in public headers, downstream
users (dialect extensions or not) cannot write functions that overload
on e.g. `PyFloat8*Type` - that's quite a [useful
feature](https://github.com/nod-ai/PI/blob/fdbee98df8376f47818e6b47e1cf089528c9d48d/cpp_ext/TorchOps.cpp#L29-L69)!
2. The dialect extensions incur a sizeable performance penalty relative
to the core extensions in that every single trip across the wire (either
`python->cpp` or `cpp->python`) requires work in addition to nanobind's
own casting/construction pipeline;
**a**. When going from `python->cpp`, [we extract the capsule object
from the Python
object](https://github.com/llvm/llvm-project/blob/main/mlir/include/mlir/Bindings/Python/NanobindAdaptors.h#L219C24-L219C46)
and then extract from the capsule the `Mlir*` opaque struct/ptr. This
side isn't so onerous;
**b**. When going from `cpp->python` we call long-hand call Python
`import` APIs and construct the Python object using `_CAPICreate`. Note,
there at least 2 `attr` calls incurred in addition to `_CAPICreate`;
this is already much more [efficiently handled by nanobind
itself](https://github.com/wjakob/nanobind/blob/4ba51fcf795971c5d603d875ae4184bc0c9bd8e6/src/nb_internals.h#L381-L382)!
3. This division blocks various features: in some configurations[^1] we
trigger a circular import bug because "dialect" types and attributes
perform an [import of the root `_mlir`
module](https://github.com/llvm/llvm-project/blob/bd9651bf78f2b1713a8203e0bd5b97f7ff199924/mlir/include/mlir/Bindings/Python/NanobindAdaptors.h#L585)
when they are created (the types themselves, not even instances of those
types). This blocks type stub generation for dialect extensions (i.e.,
the reason we currently only generate type stubs for `_mlir`).
# How
Prior this was not done/possible because of "ODR" issues but I have
resolved those issues; the basic idea for how we solve this is "move
things we want to share into shared libraries":
1. Move IRCore (stuff like `PyConcreteValue`, `PyConcreteType`,
`PyConcreteAttribute`) into `MLIRPythonSupport`;
- Note, we move the rest of the things in `IRModule.h` (renamed to
`IRCore.h`) because `PyConcreteValue`, `PyConcreteType`,
`PyConcreteAttribute` depend on them. This makes for a bigger PR than
one would hope for but ultimately I think we should give people access
to these classes to use as they see fit (specifically inherit from, but
also liberally use in bindings signatures instead of the opaque `Mlir*`
struct wrappers).
2. Put all of this code into a nested namespace
`MLIR_BINDINGS_PYTHON_DOMAIN` which is determined by a compile time
define (and tied to `MLIR_BINDINGS_PYTHON_NB_DOMAIN`). This is necessary
in order to prevent conflicts on both symbol name **and** typeid
(necessary for nanobind to not double register binded types) between
multiple bindings libraries (e.g., `torch-mlir`, and `jax`). Note
[nanobind doesn't support `module_local` like
pybind11](https://nanobind.readthedocs.io/en/latest/porting.html#removed-features).
It does support `NB_DOMAIN` but that is not sufficient for
disambiguating typeids across projects (to wit: we currently define
`NB_DOMAIN` and it was still necessary to move everything to a nested
namespace);
3. Build the [nanobind library itself as a shared
object](https://github.com/wjakob/nanobind/blob/master/cmake/nanobind-config.cmake#L127)
(and link it to both the extensions and `MLIRPythonSupport`).
4. CMake to make this work, in-tree, out-of-tree, downstream, upstream,
etc.
# Testing
Three tests are added here
1. `PythonTestModuleNanobind` is ported to use
`PyConcreteType<PyTestType>` instead of `mlir_type_subclass` and
`PyConcreteAttribute<PyTestAttr>` instead of `mlir_atrr_subclass`,
verifying this works for non-core extensions in-tree;
2. `StandaloneExtensionNanobind` is ported to use `struct PyCustomType :
mlir::python::MLIR_BINDINGS_PYTHON_DOMAIN::PyConcreteType<PyCustomType>`
instead of `mlir_type_subclass` verifying this works for non-core
extensions out-of-tree;
3. `StandaloneExtensionNanobind`'s `smoketest` is extended to also load
another bindings package (namely `mlir`) verifying
`MLIR_BINDINGS_PYTHON_DOMAIN` successfully disambiguates symbols and
typeids.
I have also tested this downstream:
https://github.com/llvm/eudsl/pull/287 as well run the following builder
bots:
mlir-nvidia-gcc7:
https://lab.llvm.org/buildbot/#/buildrequests/6654424?redirect_to_build=true
I have also tested against IREE:
https://github.com/iree-org/iree/pull/21916
# Integration
It is highly recommended to set the CMake var
`MLIR_BINDINGS_PYTHON_NB_DOMAIN` (which will also determine
`MLIR_BINDINGS_PYTHON_DOMAIN`) to something unique for each downstream.
This can also be passed explicitly to `add_mlir_python_modules` if your
project builds multiple bindings packages. I added a `WARNING` to this
effect in `AddMLIRPython.cmake`.
[^3]: Python values being typed correctly when exiting from cpp;
[^1]: Specifically when the modules are imported using `importlib`,
which occurs with nanobind's
[stubgen](https://github.com/wjakob/nanobind/blob/master/src/stubgen.py#L965);
[^2]: The workaround we implemented was a class method for the dialect
bindings called `Class.isinstance(...)`;
2026-01-05 08:08:13 -09:00
|
|
|
declare_mlir_python_extension(MLIRPythonExtension.MLIRPythonSupport
|
|
|
|
|
_PRIVATE_SUPPORT_LIB
|
|
|
|
|
MODULE_NAME MLIRPythonSupport
|
|
|
|
|
ADD_TO_PARENT MLIRPythonSources.Core
|
|
|
|
|
ROOT_DIR "${PYTHON_SOURCE_DIR}"
|
|
|
|
|
SOURCES
|
|
|
|
|
Globals.cpp
|
2026-01-05 08:34:58 -09:00
|
|
|
IRAttributes.cpp
|
|
|
|
|
IRCore.cpp
|
|
|
|
|
IRTypes.cpp
|
[mlir][Python] create MLIRPythonSupport (#171775)
# What
This PR adds a shared library `MLIRPythonSupport` which contains all of
the CRTP classes ike `PyConcreteValue`, `PyConcreteType`,
`PyConcreteAttribute`, as well as other useful code like `Defaulting*`
and etc enabling their reuse in downstream projects. Downstream projects
can now do
```c++
struct PyTestType : mlir::python::MLIR_BINDINGS_PYTHON_DOMAIN::PyConcreteType<PyTestType> {
...
};
class PyTestAttr : public mlir::python::MLIR_BINDINGS_PYTHON_DOMAIN::PyConcreteAttribute<PyTestAttr> {
...
}
NB_MODULE(_mlirPythonTestNanobind, m) {
PyTestType::bind(m);
PyTestAttr::bind(m);
}
```
instead of using the discordant alternative
`mlir_type_subclass`/`mlir_attr_subclass` (same goes for
`PyConcreteValue`/`mlir_value_subclass`).
# Why
This PR is mostly code motion (along with CMake) but before I describe
the changes I want to state the goals/benefits:
1. Currently upstream "core" extensions and "dialect" extensions ([all
of the `Dialect*` extensions
here](https://github.com/llvm/llvm-project/tree/d7c734b5a14bd91e1c76e2ce0014c19f9deef487/mlir/lib/Bindings/Python))
are a two-tier system;
**a**. [core
extensions](https://github.com/llvm/llvm-project/blob/main/mlir/lib/Bindings/Python/IRTypes.cpp#L361)
enjoy first class support as far as type inference[^3], type stub
generation, and ease of implementation, while dialect extensions [have
poorer support](https://reviews.llvm.org/D150927), incorrect type stub
generation much more tedious (boilerplate) implementation;
**b**. Crucially, this two-tiered system is reflected in the fact that
**the two sets of types/attributes are not in the same Python object
hierarchy**. To wit: `isinstance(..., Type)` and `isinstance(...,
Attribute)` are not supported for the dialect extensions[^2];
**c**. Since these types are not exposed in public headers, downstream
users (dialect extensions or not) cannot write functions that overload
on e.g. `PyFloat8*Type` - that's quite a [useful
feature](https://github.com/nod-ai/PI/blob/fdbee98df8376f47818e6b47e1cf089528c9d48d/cpp_ext/TorchOps.cpp#L29-L69)!
2. The dialect extensions incur a sizeable performance penalty relative
to the core extensions in that every single trip across the wire (either
`python->cpp` or `cpp->python`) requires work in addition to nanobind's
own casting/construction pipeline;
**a**. When going from `python->cpp`, [we extract the capsule object
from the Python
object](https://github.com/llvm/llvm-project/blob/main/mlir/include/mlir/Bindings/Python/NanobindAdaptors.h#L219C24-L219C46)
and then extract from the capsule the `Mlir*` opaque struct/ptr. This
side isn't so onerous;
**b**. When going from `cpp->python` we call long-hand call Python
`import` APIs and construct the Python object using `_CAPICreate`. Note,
there at least 2 `attr` calls incurred in addition to `_CAPICreate`;
this is already much more [efficiently handled by nanobind
itself](https://github.com/wjakob/nanobind/blob/4ba51fcf795971c5d603d875ae4184bc0c9bd8e6/src/nb_internals.h#L381-L382)!
3. This division blocks various features: in some configurations[^1] we
trigger a circular import bug because "dialect" types and attributes
perform an [import of the root `_mlir`
module](https://github.com/llvm/llvm-project/blob/bd9651bf78f2b1713a8203e0bd5b97f7ff199924/mlir/include/mlir/Bindings/Python/NanobindAdaptors.h#L585)
when they are created (the types themselves, not even instances of those
types). This blocks type stub generation for dialect extensions (i.e.,
the reason we currently only generate type stubs for `_mlir`).
# How
Prior this was not done/possible because of "ODR" issues but I have
resolved those issues; the basic idea for how we solve this is "move
things we want to share into shared libraries":
1. Move IRCore (stuff like `PyConcreteValue`, `PyConcreteType`,
`PyConcreteAttribute`) into `MLIRPythonSupport`;
- Note, we move the rest of the things in `IRModule.h` (renamed to
`IRCore.h`) because `PyConcreteValue`, `PyConcreteType`,
`PyConcreteAttribute` depend on them. This makes for a bigger PR than
one would hope for but ultimately I think we should give people access
to these classes to use as they see fit (specifically inherit from, but
also liberally use in bindings signatures instead of the opaque `Mlir*`
struct wrappers).
2. Put all of this code into a nested namespace
`MLIR_BINDINGS_PYTHON_DOMAIN` which is determined by a compile time
define (and tied to `MLIR_BINDINGS_PYTHON_NB_DOMAIN`). This is necessary
in order to prevent conflicts on both symbol name **and** typeid
(necessary for nanobind to not double register binded types) between
multiple bindings libraries (e.g., `torch-mlir`, and `jax`). Note
[nanobind doesn't support `module_local` like
pybind11](https://nanobind.readthedocs.io/en/latest/porting.html#removed-features).
It does support `NB_DOMAIN` but that is not sufficient for
disambiguating typeids across projects (to wit: we currently define
`NB_DOMAIN` and it was still necessary to move everything to a nested
namespace);
3. Build the [nanobind library itself as a shared
object](https://github.com/wjakob/nanobind/blob/master/cmake/nanobind-config.cmake#L127)
(and link it to both the extensions and `MLIRPythonSupport`).
4. CMake to make this work, in-tree, out-of-tree, downstream, upstream,
etc.
# Testing
Three tests are added here
1. `PythonTestModuleNanobind` is ported to use
`PyConcreteType<PyTestType>` instead of `mlir_type_subclass` and
`PyConcreteAttribute<PyTestAttr>` instead of `mlir_atrr_subclass`,
verifying this works for non-core extensions in-tree;
2. `StandaloneExtensionNanobind` is ported to use `struct PyCustomType :
mlir::python::MLIR_BINDINGS_PYTHON_DOMAIN::PyConcreteType<PyCustomType>`
instead of `mlir_type_subclass` verifying this works for non-core
extensions out-of-tree;
3. `StandaloneExtensionNanobind`'s `smoketest` is extended to also load
another bindings package (namely `mlir`) verifying
`MLIR_BINDINGS_PYTHON_DOMAIN` successfully disambiguates symbols and
typeids.
I have also tested this downstream:
https://github.com/llvm/eudsl/pull/287 as well run the following builder
bots:
mlir-nvidia-gcc7:
https://lab.llvm.org/buildbot/#/buildrequests/6654424?redirect_to_build=true
I have also tested against IREE:
https://github.com/iree-org/iree/pull/21916
# Integration
It is highly recommended to set the CMake var
`MLIR_BINDINGS_PYTHON_NB_DOMAIN` (which will also determine
`MLIR_BINDINGS_PYTHON_DOMAIN`) to something unique for each downstream.
This can also be passed explicitly to `add_mlir_python_modules` if your
project builds multiple bindings packages. I added a `WARNING` to this
effect in `AddMLIRPython.cmake`.
[^3]: Python values being typed correctly when exiting from cpp;
[^1]: Specifically when the modules are imported using `importlib`,
which occurs with nanobind's
[stubgen](https://github.com/wjakob/nanobind/blob/master/src/stubgen.py#L965);
[^2]: The workaround we implemented was a class method for the dialect
bindings called `Class.isinstance(...)`;
2026-01-05 08:08:13 -09:00
|
|
|
)
|
|
|
|
|
|
2021-04-28 12:04:17 -08:00
|
|
|
################################################################################
|
2021-07-22 11:57:41 -08:00
|
|
|
# Common CAPI dependency DSO.
|
|
|
|
|
# All python extensions must link through one DSO which exports the CAPI, and
|
|
|
|
|
# this must have a globally unique name amongst all embeddors of the python
|
|
|
|
|
# library since it will effectively have global scope.
|
|
|
|
|
#
|
|
|
|
|
# The presence of this aggregate library is part of the long term plan, but its
|
|
|
|
|
# use needs to be made more flexible.
|
|
|
|
|
#
|
|
|
|
|
# TODO: Upgrade to the aggregate utility in https://reviews.llvm.org/D106419
|
|
|
|
|
# once ready.
|
2021-04-28 12:04:17 -08:00
|
|
|
################################################################################
|
|
|
|
|
|
2021-07-22 11:57:41 -08:00
|
|
|
add_mlir_python_common_capi_library(MLIRPythonCAPI
|
|
|
|
|
INSTALL_COMPONENT MLIRPythonModules
|
2025-06-23 11:49:01 -08:00
|
|
|
INSTALL_DESTINATION "${MLIR_BINDINGS_PYTHON_INSTALL_PREFIX}/_mlir_libs"
|
2025-09-20 10:47:32 -08:00
|
|
|
OUTPUT_DIRECTORY "${MLIRPythonModules_ROOT_PREFIX}/_mlir_libs"
|
2021-07-22 11:57:41 -08:00
|
|
|
RELATIVE_INSTALL_ROOT "../../../.."
|
2022-06-28 09:39:13 -08:00
|
|
|
DECLARED_HEADERS
|
|
|
|
|
MLIRPythonCAPI.HeaderSources
|
2021-07-22 11:57:41 -08:00
|
|
|
DECLARED_SOURCES
|
|
|
|
|
MLIRPythonSources
|
[mlir] Overhaul C/Python registration APIs to properly scope registration/loading activities.
Since the very first commits, the Python and C MLIR APIs have had mis-placed registration/load functionality for dialects, extensions, etc. This was done pragmatically in order to get bootstrapped and then just grew in. Downstreams largely bypass and do their own thing by providing various APIs to register things they need. Meanwhile, the C++ APIs have stabilized around this and it would make sense to follow suit.
The thing we have observed in canonical usage by downstreams is that each downstream tends to have native entry points that configure its installation to its preferences with one-stop APIs. This patch leans in to this approach with `RegisterEverything.h` and `mlir._mlir_libs._mlirRegisterEverything` being the one-stop entry points for the "upstream packages". The `_mlir_libs.__init__.py` now allows customization of the environment and Context by adding "initialization modules" to the `_mlir_libs` package. If present, `_mlirRegisterEverything` is treated as such a module. Others can be added by downstreams by adding a `_site_initialize_{i}.py` module, where '{i}' is a number starting with zero. The number will be incremented and corresponding module loaded until one is not found. Initialization modules can:
* Perform load time customization to the global environment (i.e. registering passes, hooks, etc).
* Define a `register_dialects(registry: DialectRegistry)` function that can extend the `DialectRegistry` that will be used to bootstrap the `Context`.
* Define a `context_init_hook(context: Context)` function that will be added to a list of callbacks which will be invoked after dialect registration during `Context` initialization.
Note that the `MLIRPythonExtension.RegisterEverything` is not included by default when building a downstream (its corresponding behavior was prior). For downstreams which need the default MLIR initialization to take place, they must add this back in to their Python CMake build just like they add their own components (i.e. to `add_mlir_python_common_capi_library` and `add_mlir_python_modules`). It is perfectly valid to not do this, in which case, only the things explicitly depended on and initialized by downstreams will be built/packaged. If the downstream has not been set up for this, it is recommended to simply add this back for the time being and pay the build time/package size cost.
CMake changes:
* `MLIRCAPIRegistration` -> `MLIRCAPIRegisterEverything` (renamed to signify what it does and force an evaluation: a number of places were incidentally linking this very expensive target)
* `MLIRPythonSoure.Passes` removed (without replacement: just drop)
* `MLIRPythonExtension.AllPassesRegistration` removed (without replacement: just drop)
* `MLIRPythonExtension.Conversions` removed (without replacement: just drop)
* `MLIRPythonExtension.Transforms` removed (without replacement: just drop)
Header changes:
* `mlir-c/Registration.h` is deleted. Dialect registration functionality is now in `IR.h`. Registration of upstream features are in `mlir-c/RegisterEverything.h`. When updating MLIR and a couple of downstreams, I found that proper usage was commingled so required making a choice vs just blind S&R.
Python APIs removed:
* mlir.transforms and mlir.conversions (previously only had an __init__.py which indirectly triggered `mlirRegisterTransformsPasses()` and `mlirRegisterConversionPasses()` respectively). Downstream impact: Remove these imports if present (they now happen as part of default initialization).
* mlir._mlir_libs._all_passes_registration, mlir._mlir_libs._mlirTransforms, mlir._mlir_libs._mlirConversions. Downstream impact: None expected (these were internally used).
C-APIs changed:
* mlirRegisterAllDialects(MlirContext) now takes an MlirDialectRegistry instead. It also used to trigger loading of all dialects, which was already marked with a TODO to remove -- it no longer does, and for direct use, dialects must be explicitly loaded. Downstream impact: Direct C-API users must ensure that needed dialects are loaded or call `mlirContextLoadAllAvailableDialects(MlirContext)` to emulate the prior behavior. Also see the `ir.c` test case (e.g. ` mlirContextGetOrLoadDialect(ctx, mlirStringRefCreateFromCString("func"));`).
* mlirDialectHandle* APIs were moved from Registration.h (which now is restricted to just global/upstream registration) to IR.h, arguably where it should have been. Downstream impact: include correct header (likely already doing so).
C-APIs added:
* mlirContextLoadAllAvailableDialects(MlirContext): Corresponds to C++ API with the same purpose.
Python APIs added:
* mlir.ir.DialectRegistry: Mapping for an MlirDialectRegistry.
* mlir.ir.Context.append_dialect_registry(MlirDialectRegistry)
* mlir.ir.Context.load_all_available_dialects()
* mlir._mlir_libs._mlirAllRegistration: New native extension that exposes a `register_dialects(MlirDialectRegistry)` entry point and performs all upstream pass/conversion/transforms registration on init. In this first step, we eagerly load this as part of the __init__.py and use it to monkey patch the Context to emulate prior behavior.
* Type caster and capsule support for MlirDialectRegistry
This should make it possible to build downstream Python dialects that only depend on a subset of MLIR. See: https://github.com/llvm/llvm-project/issues/56037
Here is an example PR, minimally adapting IREE to these changes: https://github.com/iree-org/iree/pull/9638/files In this situation, IREE is opting to not link everything, since it is already configuring the Context to its liking. For projects that would just like to not think about it and pull in everything, add `MLIRPythonExtension.RegisterEverything` to the list of Python sources getting built, and the old behavior will continue.
Reviewed By: mehdi_amini, ftynse
Differential Revision: https://reviews.llvm.org/D128593
2022-07-16 15:09:03 -08:00
|
|
|
MLIRPythonExtension.RegisterEverything
|
2021-10-26 09:14:50 -08:00
|
|
|
${_ADDL_TEST_SOURCES}
|
2021-07-22 11:57:41 -08:00
|
|
|
)
|
|
|
|
|
|
2023-07-15 01:44:42 -08:00
|
|
|
################################################################################
|
|
|
|
|
# Custom targets.
|
|
|
|
|
################################################################################
|
|
|
|
|
|
|
|
|
|
_flatten_mlir_python_targets(mlir_python_sources_deps MLIRPythonSources)
|
2025-10-22 21:49:07 -08:00
|
|
|
|
2025-11-19 06:07:28 -09:00
|
|
|
if(MLIR_PYTHON_STUBGEN_ENABLED)
|
2025-09-25 15:59:12 -08:00
|
|
|
# _mlir stubgen
|
|
|
|
|
# Note: All this needs to come before add_mlir_python_modules(MLIRPythonModules so that the install targets for the
|
|
|
|
|
# generated type stubs get created.
|
|
|
|
|
|
|
|
|
|
set(_core_type_stub_sources
|
|
|
|
|
_mlir/__init__.pyi
|
|
|
|
|
_mlir/ir.pyi
|
|
|
|
|
_mlir/passmanager.pyi
|
|
|
|
|
_mlir/rewrite.pyi
|
|
|
|
|
)
|
2025-09-20 10:47:32 -08:00
|
|
|
|
2025-09-25 15:59:12 -08:00
|
|
|
# Note 1: INTERFACE_SOURCES is a genex ($<BUILD_INTERFACE> $<INSTALL_INTERFACE>)
|
|
|
|
|
# which will be evaluated by file(GENERATE ...) inside mlir_generate_type_stubs. This will evaluate to the correct
|
|
|
|
|
# thing in the build dir (i.e., actual source dir paths) and in the install dir
|
|
|
|
|
# (where it's a conventional path; see install/lib/cmake/mlir/MLIRTargets.cmake).
|
|
|
|
|
#
|
|
|
|
|
# Note 2: MLIRPythonExtension.Core is the target that is defined using target_sources(INTERFACE)
|
|
|
|
|
# **NOT** MLIRPythonModules.extension._mlir.dso. So be sure to use the correct target!
|
|
|
|
|
get_target_property(_core_extension_srcs MLIRPythonExtension.Core INTERFACE_SOURCES)
|
|
|
|
|
|
|
|
|
|
# Why is MODULE_NAME _mlir here but mlir._mlir_libs._mlirPythonTestNanobind below???
|
|
|
|
|
# The _mlir extension can be imported independently of any other python code and/or extension modules.
|
|
|
|
|
# I.e., you could do `cd $MLIRPythonModules_ROOT_PREFIX/_mlir_libs && python -c "import _mlir"` (try it!).
|
|
|
|
|
# _mlir is also (currently) the only extension for which this is possible because dialect extensions modules,
|
|
|
|
|
# which generally make use of `mlir_value_subclass/mlir_type_subclass/mlir_attribute_subclass`, perform an
|
|
|
|
|
# `import mlir` right when they're loaded (see the mlir_*_subclass ctors in NanobindAdaptors.h).
|
|
|
|
|
# Note, this also why IMPORT_PATHS "${MLIRPythonModules_ROOT_PREFIX}/_mlir_libs" here while below
|
|
|
|
|
# "${MLIRPythonModules_ROOT_PREFIX}/.." (because MLIR_BINDINGS_PYTHON_INSTALL_PREFIX, by default, ends at mlir).
|
|
|
|
|
#
|
|
|
|
|
# Further note: this function creates file targets like
|
|
|
|
|
# "${CMAKE_CURRENT_BINARY_DIR}/type_stubs/_mlir_libs/_mlir/__init__.pyi". These must match the file targets
|
|
|
|
|
# that declare_mlir_python_sources expects, which are like "${ROOT_DIR}/${WHATEVER_SOURCE}".
|
|
|
|
|
# This is why _mlir_libs is prepended below.
|
2025-09-20 10:47:32 -08:00
|
|
|
mlir_generate_type_stubs(
|
2025-09-25 15:59:12 -08:00
|
|
|
MODULE_NAME _mlir
|
|
|
|
|
DEPENDS_TARGETS MLIRPythonModules.extension._mlir.dso
|
2025-09-20 10:47:32 -08:00
|
|
|
OUTPUT_DIR "${CMAKE_CURRENT_BINARY_DIR}/type_stubs/_mlir_libs"
|
2025-09-25 15:59:12 -08:00
|
|
|
OUTPUTS "${_core_type_stub_sources}"
|
|
|
|
|
DEPENDS_TARGET_SRC_DEPS "${_core_extension_srcs}"
|
|
|
|
|
IMPORT_PATHS "${MLIRPythonModules_ROOT_PREFIX}/_mlir_libs"
|
2025-09-20 10:47:32 -08:00
|
|
|
)
|
2025-09-25 15:59:12 -08:00
|
|
|
set(_mlir_typestub_gen_target "${NB_STUBGEN_CUSTOM_TARGET}")
|
|
|
|
|
|
|
|
|
|
list(TRANSFORM _core_type_stub_sources PREPEND "_mlir_libs/")
|
|
|
|
|
# Note, we do not do ADD_TO_PARENT here so that the type stubs are not associated (as mlir_DEPENDS) with
|
|
|
|
|
# MLIRPythonSources.Core (or something) when a distro is installed/created. Otherwise they would not be regenerated
|
|
|
|
|
# by users of the distro (the stubs are still installed in the distro - they are just not added to mlir_DEPENDS).
|
2025-09-20 10:47:32 -08:00
|
|
|
declare_mlir_python_sources(
|
2025-09-25 15:59:12 -08:00
|
|
|
MLIRPythonExtension.Core.type_stub_gen
|
2025-09-20 10:47:32 -08:00
|
|
|
ROOT_DIR "${CMAKE_CURRENT_BINARY_DIR}/type_stubs"
|
2025-09-25 15:59:12 -08:00
|
|
|
SOURCES "${_core_type_stub_sources}"
|
2025-09-20 10:47:32 -08:00
|
|
|
)
|
2025-11-19 06:07:28 -09:00
|
|
|
list(APPEND mlir_python_sources_deps MLIRPythonExtension.Core.type_stub_gen)
|
2025-09-25 15:59:12 -08:00
|
|
|
|
|
|
|
|
# _mlirPythonTestNanobind stubgen
|
|
|
|
|
|
|
|
|
|
if(MLIR_INCLUDE_TESTS)
|
|
|
|
|
get_target_property(_test_extension_srcs MLIRPythonTestSources.PythonTestExtensionNanobind INTERFACE_SOURCES)
|
|
|
|
|
mlir_generate_type_stubs(
|
|
|
|
|
# This is the FQN path because dialect modules import _mlir when loaded. See above.
|
|
|
|
|
MODULE_NAME mlir._mlir_libs._mlirPythonTestNanobind
|
|
|
|
|
DEPENDS_TARGETS
|
|
|
|
|
# You need both _mlir and _mlirPythonTestNanobind because dialect modules import _mlir when loaded
|
|
|
|
|
# (so _mlir needs to be built before calling stubgen).
|
|
|
|
|
MLIRPythonModules.extension._mlir.dso
|
|
|
|
|
MLIRPythonModules.extension._mlirPythonTestNanobind.dso
|
|
|
|
|
# You need this one so that ir.py "built" because mlir._mlir_libs.__init__.py import mlir.ir in _site_initialize.
|
|
|
|
|
MLIRPythonModules.sources.MLIRPythonSources.Core.Python
|
|
|
|
|
OUTPUT_DIR "${CMAKE_CURRENT_BINARY_DIR}/type_stubs/_mlir_libs"
|
|
|
|
|
OUTPUTS _mlirPythonTestNanobind.pyi
|
|
|
|
|
DEPENDS_TARGET_SRC_DEPS "${_test_extension_srcs}"
|
|
|
|
|
IMPORT_PATHS "${MLIRPythonModules_ROOT_PREFIX}/.."
|
|
|
|
|
)
|
|
|
|
|
set(_mlirPythonTestNanobind_typestub_gen_target "${NB_STUBGEN_CUSTOM_TARGET}")
|
|
|
|
|
declare_mlir_python_sources(
|
|
|
|
|
MLIRPythonTestSources.PythonTestExtensionNanobind.type_stub_gen
|
|
|
|
|
ROOT_DIR "${CMAKE_CURRENT_BINARY_DIR}/type_stubs"
|
|
|
|
|
ADD_TO_PARENT MLIRPythonTestSources.Dialects
|
|
|
|
|
SOURCES _mlir_libs/_mlirPythonTestNanobind.pyi
|
|
|
|
|
)
|
|
|
|
|
endif()
|
2025-09-20 10:47:32 -08:00
|
|
|
endif()
|
|
|
|
|
|
2025-11-19 06:07:28 -09:00
|
|
|
add_custom_target("mlir-python-sources" DEPENDS ${mlir_python_sources_deps})
|
|
|
|
|
if(NOT LLVM_ENABLE_IDE)
|
|
|
|
|
add_llvm_install_targets(install-mlir-python-sources
|
|
|
|
|
DEPENDS mlir-python-sources
|
|
|
|
|
COMPONENT mlir-python-sources
|
|
|
|
|
)
|
|
|
|
|
endif()
|
|
|
|
|
|
2021-07-22 11:57:41 -08:00
|
|
|
################################################################################
|
|
|
|
|
# The fully assembled package of modules.
|
|
|
|
|
# This must come last.
|
|
|
|
|
################################################################################
|
|
|
|
|
|
2025-09-25 15:59:12 -08:00
|
|
|
set(_declared_sources MLIRPythonSources MLIRPythonExtension.RegisterEverything)
|
2025-11-19 06:07:28 -09:00
|
|
|
if(MLIR_PYTHON_STUBGEN_ENABLED)
|
2025-09-25 15:59:12 -08:00
|
|
|
list(APPEND _declared_sources MLIRPythonExtension.Core.type_stub_gen)
|
|
|
|
|
endif()
|
|
|
|
|
|
2021-07-22 11:57:41 -08:00
|
|
|
add_mlir_python_modules(MLIRPythonModules
|
2025-09-20 10:47:32 -08:00
|
|
|
ROOT_PREFIX ${MLIRPythonModules_ROOT_PREFIX}
|
2025-06-23 11:49:01 -08:00
|
|
|
INSTALL_PREFIX "${MLIR_BINDINGS_PYTHON_INSTALL_PREFIX}"
|
2021-07-22 11:57:41 -08:00
|
|
|
DECLARED_SOURCES
|
2025-09-25 15:59:12 -08:00
|
|
|
${_declared_sources}
|
2021-10-26 09:14:50 -08:00
|
|
|
${_ADDL_TEST_SOURCES}
|
2021-07-22 11:57:41 -08:00
|
|
|
COMMON_CAPI_LINK_LIBS
|
|
|
|
|
MLIRPythonCAPI
|
2022-06-28 09:39:13 -08:00
|
|
|
)
|
2025-11-19 06:07:28 -09:00
|
|
|
if(MLIR_PYTHON_STUBGEN_ENABLED)
|
2025-09-25 15:59:12 -08:00
|
|
|
add_dependencies(MLIRPythonModules "${_mlir_typestub_gen_target}")
|
|
|
|
|
if(MLIR_INCLUDE_TESTS)
|
|
|
|
|
add_dependencies(MLIRPythonModules "${_mlirPythonTestNanobind_typestub_gen_target}")
|
|
|
|
|
endif()
|
2025-09-20 10:47:32 -08:00
|
|
|
endif()
|