505 Commits

Author SHA1 Message Date
Maksim Levental
67f43c6ee2
[MLIR][Python] add type hints for accessors (#158455)
This PR adds type hints for accessors in the generated builders.
2025-09-18 21:12:35 -05:00
Twice
e5114a2016
[MLIR][Python] Add python bindings for IRDL dialect (#158488)
In this PR we add basic python bindings for IRDL dialect, so that python
users can create and load IRDL dialects in python. This allows users, to
some extent, to define dialects in Python without having to modify
MLIR’s CMake/TableGen/C++ code and rebuild, making prototyping more
convenient.

A basic example is shown below (and also in the added test case):
```python
# create a module with IRDL dialects
module = Module.create()
with InsertionPoint(module.body):
  dialect = irdl.DialectOp("irdl_test")
  with InsertionPoint(dialect.body):
    op = irdl.OperationOp("test_op")
    with InsertionPoint(op.body):
      f32 = irdl.is_(TypeAttr.get(F32Type.get()))
      irdl.operands_([f32], ["input"], [irdl.Variadicity.single])

# load the module
irdl.load_dialects(module)

# use the op defined in IRDL
m = Module.parse("""
  module {
    %a = arith.constant 1.0 : f32
    "irdl_test.test_op"(%a) : (f32) -> ()
  }
""")
```
2025-09-19 10:10:39 +08:00
Maksim Levental
6a4f66476f
[MLIR][Python] restore liveModuleMap (#158506)
There are cases where the same module can have multiple references (via
`PyModule::forModule` via `PyModule::createFromCapsule`) and thus when
`PyModule`s get gc'd `mlirModuleDestroy` can get called multiple times
for the same actual underlying `mlir::Module` (i.e., double free). So we
do actually need a "liveness map" for modules.

Note, if `type_caster<MlirModule>::from_cpp` weren't a thing we could guarantree
this never happened except explicitly when users called `PyModule::createFromCapsule`.
2025-09-15 06:45:30 +02:00
Twice
7123463ef9
[MLIR][Python] Add the ability to signal pass failures in python-defined passes (#157613)
This is a follow-up PR for #156000.

In this PR we add the ability to signal pass failures
(`signal_pass_failure()`) in python-defined passes.

To achieve this, we expose `MlirExternalPass` via `nb::class_` with a
method `signal_pass_failure()`, and the callable passed to `pm.add(..)`
now accepts two arguments (`op: MlirOperation, pass_:
MlirExternalPass`).

For example:
```python
def custom_pass_that_fails(op, pass_):
    if some_condition:
        pass_.signal_pass_failure()
    # do something
```
2025-09-09 08:05:39 -07:00
Sergei Lebedev
80c2da6372
[MLIR] [Python] Added a context manager for enabling traceback-based locations (#157562)
Previously this functionality was not surfaced in the public API.
2025-09-09 06:29:06 -07:00
Twice
7d04e37904
[MLIR][Python] Support Python-defined passes in MLIR (#156000)
It closes #155996.

This PR added a method `add(callable, ..)` to
`mlir.passmanager.PassManager` to accept a callable object for defining
passes in the Python side.

This is a simple example of a Python-defined pass.
```python
from mlir.passmanager import PassManager

def demo_pass_1(op):
    # do something with op
    pass

class DemoPass:
    def __init__(self, ...):
        pass
    def __call__(op):
        # do something
        pass

demo_pass_2 = DemoPass(..)

pm = PassManager('any', ctx)
pm.add(demo_pass_1)
pm.add(demo_pass_2)
pm.add("registered-passes")
pm.run(..)
```

---------

Co-authored-by: cnb.bsD2OPwAgEA <QejD2DJ2eEahUVy6Zg0aZI+cnb.bsD2OPwAgEA@noreply.cnb.cool>
Co-authored-by: Maksim Levental <maksim.levental@gmail.com>
2025-09-08 18:01:23 -07:00
Maksim Levental
c4181e51d1
[MLIR][Python] remove unnecessary arg.none() = nb::none() pattern (#157519)
We have `arg.none() = nb::none()` in a lot of places but this is no
longer necessary (as of
~[2022](62a23bb87b)).
2025-09-08 12:16:35 -07:00
Twice
aac4eb5c3c
[MLIR][Python] Add a python function to apply patterns with MlirOperation (#157487)
In https://github.com/llvm/llvm-project/pull/94714, we add a python
function `apply_patterns_and_fold_greedily` which accepts an
`MlirModule` as the argument type. However, sometimes we want to apply
patterns with an `MlirOperation` argument, and there is currently no
python API to convert an `MlirOperation` to `MlirModule`.

So here we overload this function `apply_patterns_and_fold_greedily` to
do this (also a corresponding new C API
`mlirApplyPatternsAndFoldGreedilyWithOp`)
2025-09-08 16:05:45 +00:00
Maksim Levental
9a0ed70319
[MLIR][Python] bind InsertionPointAfter (#157156) 2025-09-05 14:30:40 -07:00
Maksim Levental
70a291f322
[MLIR][Python] fix operation hashing (#156514)
https://github.com/llvm/llvm-project/pull/155114 broke op hashing
(because the python objects ceased to be reference equivalent). This PR
fixes by binding `OperationEquivalence::computeHash`.
2025-09-02 15:12:25 -05:00
Maksim Levental
b2a7369631
[MLIR][Python] remove liveOperations (#155114)
Historical context: `PyMlirContext::liveOperations` was an optimization
meant to cut down on the number of Python object allocations and
(partially) a mechanism for updating validity of ops after
transformation. E.g. during walking/transforming the AST. See original
patch [here](https://reviews.llvm.org/D87958).

Inspired by a
[renewed](https://github.com/llvm/llvm-project/pull/139721#issuecomment-3217131918)
interest in https://github.com/llvm/llvm-project/pull/139721 (which has
become a little stale...)

<p align="center">
<img width="504" height="375" alt="image"
src="https://github.com/user-attachments/assets/0daad562-d3d1-4876-8d01-5dba382ab186"
/>
</p>

In the previous go-around
(https://github.com/llvm/llvm-project/pull/92631) there were two issues
which have been resolved

1. ops that were "fetched" under a root op which has been transformed
are no longer reported as invalid. We simply "[formally
forbid](https://github.com/llvm/llvm-project/pull/92631#issuecomment-2119397018)"
this;
2. `Module._CAPICreate(module_capsule)` must now be followed by a
`module._clear_mlir_module()` to prevent double-freeing of the actual
`ModuleOp` object (i.e. calling the dtor on the
`OwningOpRef<ModuleOp>`):

     ```python
    module = ...
    module_dup = Module._CAPICreate(module._CAPIPtr)
    module._clear_mlir_module()
    ```
- **the alternative choice** here is to remove the `Module._CAPICreate`
API altogether and replace it with something like `Module._move(module)`
which will do both `Module._CAPICreate` and `module._clear_mlir_module`.

Note, the other approach I explored last year was a [weakref
system](https://github.com/llvm/llvm-project/pull/97340) for
`mlir::Operation` which would effectively hoist this `liveOperations`
thing into MLIR core. Possibly doable but I now believe it's a bad idea.

The other potentially breaking change is `is`, which checks object
equality rather than value equality, will now report `False` because we
are always allocating `new` Python objects (ie that's the whole point of
this change). Users wanting to check equality for `Operation` and
`Module` should use `==`.
2025-09-01 21:53:33 -07:00
Roman
912ce2631f
[NFC] Fix typos 'seperate' -> 'separate' (#144368)
Correct few typos: 'seperate' -> 'separate' .
2025-08-30 13:41:25 +00:00
Mehdi Amini
c767ee1b2a [MLIR] Apply clang-tidy fixes for llvm-include-order in RegisterEverything.cpp (NFC) 2025-08-27 02:35:09 -07:00
Mehdi Amini
a40a610704 [MLIR] Apply clang-tidy fixes for performance-unnecessary-value-param in Pass.cpp (NFC) 2025-08-27 02:25:02 -07:00
Mehdi Amini
79554783e6 [MLIR] Apply clang-tidy fixes for performance-unnecessary-value-param in IRTypes.cpp (NFC) 2025-08-26 15:06:31 -07:00
Mehdi Amini
2bfbae99b9 [MLIR] Apply clang-tidy fixes for readability-identifier-naming in IRCore.cpp (NFC) 2025-08-26 12:03:01 -07:00
Mehdi Amini
8344a53c0d [MLIR] Apply clang-tidy fixes for performance-move-const-arg in IRCore.cpp (NFC) 2025-08-26 12:03:01 -07:00
Mehdi Amini
e3b0e92912 [MLIR] Apply clang-tidy fixes for modernize-use-using in IRCore.cpp (NFC) 2025-08-26 12:03:01 -07:00
Mehdi Amini
e007a383d6 [MLIR] Apply clang-tidy fixes for misc-use-internal-linkage in IRCore.cpp (NFC) 2025-08-26 06:14:24 -07:00
Mehdi Amini
589cb6c612 [MLIR] Apply clang-tidy fixes for performance-unnecessary-value-param in IRAttributes.cpp (NFC) 2025-08-26 06:14:24 -07:00
Mehdi Amini
745415d655 [MLIR] Apply clang-tidy fixes for llvm-else-after-return in IRAttributes.cpp (NFC) 2025-08-26 04:48:57 -07:00
Mehdi Amini
7e581d6d2e [MLIR] Apply clang-tidy fixes for performance-unnecessary-value-param in IRAffine.cpp (NFC) 2025-08-26 04:48:57 -07:00
Mehdi Amini
40d8d41510 [MLIR] Apply clang-tidy fixes for llvm-include-order in IRAffine.cpp (NFC) 2025-08-26 04:48:57 -07:00
Mehdi Amini
3c2df33c1c [MLIR] Apply clang-tidy fixes for performance-unnecessary-value-param in ExecutionEngineModule.cpp (NFC) 2025-08-26 03:41:03 -07:00
Mehdi Amini
d9cd6ed320 [MLIR] Apply clang-tidy fixes for performance-unnecessary-value-param in DialectTransform.cpp (NFC) 2025-08-26 02:53:54 -07:00
Mehdi Amini
4e4f7a56ea [MLIR] Apply clang-tidy fixes for misc-use-internal-linkage in DialectTransform.cpp (NFC) 2025-08-26 02:53:54 -07:00
Mehdi Amini
61c7295595 [MLIR] Apply clang-tidy fixes for llvm-include-order in DialectTransform.cpp (NFC) 2025-08-23 13:47:50 -07:00
Mehdi Amini
63f2bf4748 [MLIR] Apply clang-tidy fixes for performance-unnecessary-value-param in DialectSparseTensor.cpp (NFC) 2025-08-23 13:47:50 -07:00
Mehdi Amini
a19b634e24 [MLIR] Apply clang-tidy fixes for llvm-include-order in DialectSparseTensor.cpp (NFC) 2025-08-23 13:04:00 -07:00
Mehdi Amini
a74cf81444 [MLIR] Apply clang-tidy fixes for misc-use-internal-linkage in DialectSMT.cpp (NFC) 2025-08-23 13:01:12 -07:00
Mehdi Amini
5cd0d3c6bd [MLIR] Apply clang-tidy fixes for performance-unnecessary-value-param in DialectQuant.cpp (NFC) 2025-08-23 12:58:09 -07:00
Mehdi Amini
b77f845552 [MLIR] Apply clang-tidy fixes for performance-unnecessary-value-param in DialectPDL.cpp (NFC) 2025-08-23 12:53:28 -07:00
Mehdi Amini
513c52cd61 [MLIR] Apply clang-tidy fixes for misc-use-internal-linkage in DialectPDL.cpp (NFC) 2025-08-23 12:43:57 -07:00
Mehdi Amini
d9adf25c36 [MLIR] Apply clang-tidy fixes for llvm-include-order in DialectPDL.cpp (NFC) 2025-08-23 12:43:57 -07:00
Mehdi Amini
fe7fb3e2bd [MLIR] Apply clang-tidy fixes for performance-unnecessary-value-param in DialectNVGPU.cpp (NFC) 2025-08-23 12:04:48 -07:00
Mehdi Amini
37d57b3c57 [MLIR] Apply clang-tidy fixes for llvm-include-order in DialectNVGPU.cpp (NFC) 2025-08-23 12:04:47 -07:00
Mehdi Amini
d13f40f386 [MLIR] Apply clang-tidy fixes for performance-unnecessary-value-param in DialectLLVM.cpp (NFC) 2025-08-23 07:56:15 -07:00
Mehdi Amini
35e733689b [MLIR] Apply clang-tidy fixes for misc-use-internal-linkage in DialectLLVM.cpp (NFC) 2025-08-23 03:47:41 -07:00
Mehdi Amini
07367782fd [MLIR] Apply clang-tidy fixes for llvm-include-order in DialectLLVM.cpp (NFC) 2025-08-23 03:47:41 -07:00
Mehdi Amini
51d9f31954 [MLIR] Apply clang-tidy fixes for performance-unnecessary-value-param in DialectGPU.cpp (NFC) 2025-08-22 16:13:32 -07:00
Mehdi Amini
bffa11b1fc [MLIR] Apply clang-tidy fixes for llvm-include-order in DialectGPU.cpp (NFC) 2025-08-22 16:13:32 -07:00
Shenghang Tsai
7610b13729
[MLIR] Split ExecutionEngine Initialization out of ctor into an explicit method call (#153524)
Retry landing https://github.com/llvm/llvm-project/pull/153373
## Major changes from previous attempt
- remove the test in CAPI because no existing tests in CAPI deal with
sanitizer exemptions
- update `mlir/docs/Dialects/GPU.md` to reflect the new behavior: load
GPU binary in global ctors, instead of loading them at call site.
- skip the test on Aarch64 since we have an issue with initialization there

---------

Co-authored-by: Mehdi Amini <joker.eph@gmail.com>
2025-08-17 23:07:24 +02:00
Maksim Levental
6fc1deb8b7
[mlir][python] handle more undefined symbols not covered by nanobind (#153861)
Introduced (but omitted from this CMake) in
https://github.com/llvm/llvm-project/pull/151246.
2025-08-16 09:25:15 -04:00
Mehdi Amini
bfd490e0cd
Revert "[MLIR] Split ExecutionEngine Initialization out of ctor into an explicit method call" (#153477)
Reverts llvm/llvm-project#153373

Sanitizer bot is broken
2025-08-13 19:43:04 +00:00
Shenghang Tsai
2f93693f76
[MLIR] Split ExecutionEngine Initialization out of ctor into an explicit method call (#153373)
This PR introduces a mechanism to defer JIT engine initialization,
enabling registration of required symbols before global constructor
execution.

## Problem

Modules containing `gpu.module` generate global constructors (e.g.,
kernel load/unload) that execute *during* engine creation. This can
force premature symbol resolution, causing failures when:
- Symbols are registered via `mlirExecutionEngineRegisterSymbol` *after*
creation
- Global constructors exist (even if not directly using unresolved
symbols, e.g., an external function declaration)
   - GPU modules introduce mandatory binary loading logic

## Usage
```c
// Create engine without initialization
MlirExecutionEngine jit = mlirExecutionEngineCreate(...);

// Register required symbols
mlirExecutionEngineRegisterSymbol(jit, ...);

// Explicitly initialize (runs global constructors)
mlirExecutionEngineInitialize(jit);
```

---------

Co-authored-by: Mehdi Amini <joker.eph@gmail.com>
2025-08-13 15:22:01 +02:00
Maksim Levental
2b842e5600
[mlir][python] fix PyThreadState_GetFrame again (#153333)
add more APIs missing from 3.8 (fix rocm builder)
2025-08-12 21:29:23 -05:00
Maksim Levental
9df846bf71
[mlir][python] fix PyThreadState_GetFrame (#153325)
`PyThreadState_GetFrame` wasn't added until 3.9 (fixes currently failing
rocm builder)
2025-08-13 01:16:04 +00:00
Maksim Levental
a40f47c972
[mlir][python] automatic location inference (#151246)
This PR implements "automatic" location inference in the bindings. The
way it works is it walks the frame stack collecting source locations
(Python captures these in the frame itself). It is inspired by JAX's
[implementation](523ddcfbca/jax/_src/interpreters/mlir.py (L462))
but moves the frame stack traversal into the bindings for better
performance.

The system supports registering "included" and "excluded" filenames;
frames originating from functions in included filenames **will not** be
filtered and frames originating from functions in excluded filenames
**will** be filtered (in that order). This allows excluding all the
generated `*_ops_gen.py` files.

The system is also "toggleable" and off by default to save people who
have their own systems (such as JAX) from the added cost.

Note, the system stores the entire stacktrace (subject to
`locTracebackFramesLimit`) in the `Location` using specifically a
`CallSiteLoc`. This can be useful for profiling tools (flamegraphs
etc.).

Shoutout to the folks at JAX for coming up with a good system.

---------

Co-authored-by: Jacques Pienaar <jpienaar@google.com>
2025-08-12 16:59:59 -05:00
Maksim Levental
7fb8a44ad5
[mlir][python] expose isAttached (#153045) 2025-08-11 12:21:59 -05:00
Maksim Levental
21774489f0
[mlir][python] fix PyDenseResourceElementsAttribute finalizer (#150561)
This PR melds https://github.com/llvm/llvm-project/pull/150137 and
https://github.com/llvm/llvm-project/pull/149414 *and* partially reverts
https://github.com/llvm/llvm-project/pull/124832.

The summary is the `PyDenseResourceElementsAttribute` finalizer/deleter
has/had two problems

1. wasn't threadsafe (can be called from a different thread than that
which currently holds the GIL)
2. can be called while the interpreter is "not initialized"

https://github.com/llvm/llvm-project/pull/124832 for some reason decides
to re-initialize the interpreter to avoid case 2 and runs afoul of the
fact that `Py_IsInitialized` can be false during the finalization of the
interpreter itself (e.g., at the end of a script).

I don't know why this decision was made (I missed the PR) but I believe
we should never be calling
[Py_Initialize](https://docs.python.org/3/c-api/init.html#c.Py_Initialize):

> In an application \*\*\*\***embedding Python**\*\*\*\*, this should be
called before using any other Python/C API functions

**but we aren't embedding Python**!

So therefore we will only be in case 2 when the interpreter is being
finalized and in that case we should just leak the buffer.

Note,
[lldb](548ca9e976/lldb/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.cpp (L81-L93))
does a similar sort of thing for its finalizers.

Co-authored-by: Anton Korobeynikov <anton@korobeynikov.info>
Co-authored-by: Max Manainen <maximmanainen@gmail.com>

Co-authored-by: Anton Korobeynikov <anton@korobeynikov.info>
Co-authored-by: Max Manainen <maximmanainen@gmail.com>
2025-07-25 08:05:30 -04:00