613 Commits

Author SHA1 Message Date
Asher Mancinelli
47d9d735a7
[MLIR][Python] Add arg_attrs and res_attrs to gpu func (#168475)
I missed these attributes when I added the wrapper for GPUFuncOp in
fbdd98f74f0d.
2025-11-18 07:55:11 -08:00
Rolf Morel
eb9d56cb55
[MLIR][Transform][Python] Expose applying named_sequences as a method (#168223)
Makes it so that a NamedSequenceOp can be directly applied to a Module,
via a method `apply(...)`.
2025-11-15 18:31:17 +00:00
Asher Mancinelli
a4e7d150ea
[MLIR][Python] Add tests for nvvm barrier ops (#167976)
Found this issue #167958 when adding these tests, thanks for the quick
fix @clementval.
2025-11-15 08:57:41 -08:00
Muzammiluddin Syed
b1262d13e0
[mlir][ROCDL] Refactor wmma intrinsics to use attributes not operands where possible (#167041)
The current implementation of the WMMA intrinsic ops as they are defined
in the ROCDL tablegen is incorrect. They represent as operands what
should be attributes such as `clamp`, `opsel`, `signA/signB`. This
change performs a refactoring to bring it in line with what we expect.

---------

Signed-off-by: Muzammiluddin Syed <muzasyed@amd.com>
2025-11-13 19:50:02 -05:00
Sergei Lebedev
31536e6e9a
[MLIR] [Python] ir.Value is now generic in the type of the value it holds (#166148)
This makes it similar to `mlir::TypedValue` in the MLIR C++ API and
allows users to be more specific about the values they produce or
accept.

Co-authored-by: Maksim Levental <maksim.levental@gmail.com>
2025-11-13 13:23:40 +00:00
Tuomas Kärnä
7f4a3a98a2
[MLIR][XeGPU][TransformOps] Add convert_layout op (#167342)
Adds `transform.xegpu.convert_layout` transform op that inserts an
`xegpu.convert_layout` op for a given `Value`.
2025-11-12 18:57:51 +00:00
Bangtian Liu
a5a78d0bb4
[mlir][linalg][python] Add Python Bindings for Inferring Contraction Dimensions from Affine Maps (#167587)
This PR exposes `linalg::inferContractionDims(ArrayRef<AffineMap>)` to
Python, allowing users to infer contraction dimensions (batch/m/n/k)
directly from a list of affine maps without needing an operation.

---------

Signed-off-by: Bangtian Liu <liubangtian@gmail.com>
2025-11-12 13:35:04 -05:00
Tuomas Kärnä
3c52f53690
[MLIR][XeGPU][TransformOps] Add insert_prefetch op (#167356)
Adds `transform.xegpu.insert_prefetch` transform op that inserts
`xegpu.prefetch_nd` ops for the given `Value` in an `scf.for` loop.
2025-11-12 10:24:23 +00:00
Asher Mancinelli
175e3becbf
[MLIR][Python] Add region_op wrappers for linalg (#167616)
Makes linalg.reduce and linalg.map region_ops so they can be constructed
from functions and be called as decorators.
2025-11-11 19:00:39 -08:00
Asher Mancinelli
ce17599553
[MLIR][Python] Add wrappers for scf.index_switch (#167458)
The C++ index switch op has utilities for `getCaseBlock(int i)` and
`getDefaultBlock()`, so these have been added.
Optional body builder args have been added: one for the default case and
one for the switch cases.
2025-11-11 15:49:45 -08:00
Maksim Levental
8346a772bc
[MLIR][Python] fix PyRegionList __iter__ (#167466)
Fixes https://github.com/llvm/llvm-project/issues/167455
2025-11-11 07:25:50 -08:00
Tuomas Kärnä
300750d4be
[MLIR][XeGPU][TransformOps] Add set_gpu_launch_threads op (#166865)
Adds `transform.xegpu.set_gpu_launch_threads` that overrides `gpu.launch` operation threads.
2025-11-11 11:57:54 +00:00
Tuomas Kärnä
94a7006445
[MLIR][XeGPU][TransformOps] Add set_op_layout_attr op (#166854)
Adds `transform.xegpu.set_op_layout_attr` transform op that attaches
`xegpu.layout` attribute to the target op.
2025-11-10 16:09:02 +01:00
Tuomas Kärnä
1553f90f93
[MLIR][XeGPU][TransformOps] Add get_desc_op (#166801)
Add `transform.xegpu.get_desc_op` transform op that finds a
`xegpu.create_nd_tdesc` producer op of a `Value`.
2025-11-10 16:02:07 +01:00
Rolf Morel
d78e0ded52
[MLIR][Transform][Python] Sync derived classes and their wrappers (#166871)
Updates the derived Op-classes for the main transform ops to have all
the arguments, etc, from the auto-generated classes. Additionally
updates and adds missing snake_case wrappers for the derived classes
which shadow the snake_case wrappers of the auto-generated classes,
which were hitherto exposed alongside the derived classes.
2025-11-07 14:04:53 +00:00
Tuomas Kärnä
3a68751190
[MLIR][XeGPU][Transform] add xegpu.set_desc_layout transform op (#165615)
Adds the first XeGPU transform op, `xegpu.set_desc_layout`, which attachs a `xegpu.layout` attribute to the descriptor that a `xegpu.create_nd_tdesc` op returns.
2025-11-06 14:25:34 +00:00
Tuomas Kärnä
718818a5cb
[MLIR][Linalg][Transform] Expose more args in VectorizeChildren[...] op's Python bindings (#166134)
Expose missing boolean arguments in
`VectorizeChildrenAndApplyPatternsOp` Python bindings.
2025-11-04 20:08:42 +00:00
Twice
492f82fa46
[MLIR][Python] Make check-mlir-python depend on runner utils (#166077)
`ninja check-mlir-python` will fail in the recent main branch due to
missing shared libraries (`libmlir_runner_utils.so` and
`libmlir_c_runner_utils.so`).

This PR adds `mlir_c_runner_utils` and `mlir_runner_utils` into
dependencies of `check-mlir-python` so it will make sure that these
libraries are available before the test cases are executed.

```
[4350/4351] Running the MLIR Python regression tests
FAIL: MLIR :: python/execution_engine.py (92 of 99)
******************** TEST 'MLIR :: python/execution_engine.py' FAILED ********************
Exit Code: 1

Command Output (stdout):
--
# RUN: at line 1
env MLIR_RUNNER_UTILS=/llvm-project/build/lib/libmlir_runner_utils.so MLIR_C_RUNNER_UTILS=/llvm-project/build/lib/libmlir_c_runner_utils.so /python-env/bin/python3 /llvm-project/mlir/test/python/execution_engine.py 2>&1 | /llvm-project/build/bin/FileCheck /llvm-project/mlir/test/python/execution_engine.py
# executed command: env MLIR_RUNNER_UTILS=/llvm-project/build/lib/libmlir_runner_utils.so MLIR_C_RUNNER_UTILS=/llvm-project/build/lib/libmlir_c_runner_utils.so /python-env/bin/python3 /llvm-project/mlir/test/python/execution_engine.py
# note: command had no output on stdout or stderr
# error: command failed with exit status: 1
# executed command: /llvm-project/build/bin/FileCheck /llvm-project/mlir/test/python/execution_engine.py
# .---command stderr------------
# | /llvm-project/mlir/test/python/execution_engine.py:741:16: error: CHECK-LABEL: expected string not found in input
# | # CHECK-LABEL: TEST: testNanoTime
# |                ^
# | <stdin>:62:24: note: scanning from here
# | TEST: testSharedLibLoad
# |                        ^
# | <stdin>:73:68: note: possible intended match here
# |  File "/llvm-project/mlir/test/python/execution_engine.py", line 732, in testSharedLibLoad
# |                                                                    ^
# | 
# | Input file: <stdin>
# | Check file: /llvm-project/mlir/test/python/execution_engine.py
# | 
# | -dump-input=help explains the following input dump.
# | 
# | Input was:
# | <<<<<<
# |              .
# |              .
# |              .
# |             57: TEST: testF8E5M2Memref 
# |             58:  
# |             59: TEST: testDynamicMemrefAdd2D 
# |             60: True 
# |             61:  
# |             62: TEST: testSharedLibLoad 
# | label:741'0                            X error: no match found
# |             63: Failed to create MemoryBuffer for: /llvm-project/build/lib/libmlir_runner_utils.so 
# | label:741'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# |             64: Error: No such file or directory 
# | label:741'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# |             65: Failed to create MemoryBuffer for: /llvm-project/build/lib/libmlir_c_runner_utils.so 
# | label:741'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# |             66: Error: No such file or directory 
# | label:741'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# |             67: JIT session error: Symbols not found: [ _mlir_ciface_printMemrefF32 ] 
# | label:741'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# |             68: Traceback (most recent call last): 
# | label:741'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# |             69:  File "/llvm-project/mlir/test/python/execution_engine.py", line 737, in <module> 
# | label:741'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# |             70:  run(testSharedLibLoad) 
# | label:741'0     ~~~~~~~~~~~~~~~~~~~~~~~~
# |             71:  File "/llvm-project/mlir/test/python/execution_engine.py", line 35, in run 
# | label:741'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# |             72:  f() 
# | label:741'0     ~~~~~
# |             73:  File "/llvm-project/mlir/test/python/execution_engine.py", line 732, in testSharedLibLoad 
# | label:741'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# | label:741'1                                                                        ?                        possible intended match
# |             74:  execution_engine.invoke("main", arg0_memref_ptr) 
# | label:741'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# |             75:  File "/llvm-project/build/tools/mlir/python_packages/mlir_core/mlir/execution_engine.py", line 31, in invoke 
# | label:741'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# |             76:  func = self.lookup(name) 
# | label:741'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~
# |             77:  ^^^^^^^^^^^^^^^^^ 
# | label:741'0     ~~~~~~~~~~~~~~~~~~~
# |             78:  File "/llvm-project/build/tools/mlir/python_packages/mlir_core/mlir/execution_engine.py", line 22, in lookup 
# | label:741'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# |              .
# |              .
# |              .
# | >>>>>>
# `-----------------------------
# error: command failed with exit status: 1

--

********************
********************
Failed Tests (1):
  MLIR :: python/execution_engine.py


Testing Time: 2.60s

Total Discovered Tests: 99
  Unsupported:  2 (2.02%)
  Passed     : 96 (96.97%)
  Failed     :  1 (1.01%)
FAILED: tools/mlir/test/python/CMakeFiles/check-mlir-python /llvm-project/build/tools/mlir/test/python/CMakeFiles/check-mlir-python 
cd /llvm-project/build/tools/mlir/test/python && /python-env/bin/python3 /llvm-project/build/./bin/llvm-lit -sv /llvm-project/build/tools/mlir/test/python
ninja: build stopped: subcommand failed.
```
2025-11-03 10:52:04 +08:00
Maksim Levental
cd9d48777e
[MLIR][ExecutionEngine] don't dump decls (#164478)
Currently ExecutionEngine tries to dump all functions declared in the
module, even those which are "external" (i.e., linked/loaded at
runtime). E.g.

```mlir
func.func private @printF32(f32)
func.func @supported_arg_types(%arg0: i32, %arg1: f32) {
  call @printF32(%arg1) : (f32) -> ()
  return
}
```
fails with
```
Could not compile printF32:
  Symbols not found: [ __mlir_printF32 ]
Program aborted due to an unhandled Error:
Symbols not found: [ __mlir_printF32 ]
```
even though `printF32` can be provided at final build time (i.e., when
the object file is linked to some executable or shlib). E.g, if our own
`libmlir_c_runner_utils` is linked.

So just skip functions which have no bodies during dump (i.e., are decls
without defns).
2025-10-27 12:22:13 -07:00
Maksim Levental
c05ce9b005
[MLIR][Python] fix getOwner to return (typed) nb::object instead of abstract PyOpView (#165053)
https://github.com/llvm/llvm-project/pull/157930 changed `nb::object
getOwner()` to `PyOpView getOwner()` which implicitly constructs the
generic OpView against from a (possibly) concrete OpView. This PR fixes
that.
2025-10-26 01:48:46 +00:00
Siavash Nazari
5129b37254
[MLIR][Python] Add shard Dialect Python Bindings (#162578)
Add Python bindings for `shard` dialect. Provide means for creating
constructs in this dialect in Python.
2025-10-21 14:22:40 -07:00
Asher Mancinelli
c375c414cb
[mlir][python] Add Pythonic wrappers for gpu ops (#163883)
Add builders on the Python side that match builders in the C++ side, add tests for launching GPU kernels and regions, and correct some small documentation mistakes. This reflects the API decisions already made in the func dialect's Python bindings and makes use of the GPU dialect's bindings work more similar to C++ interface.
2025-10-20 13:04:10 -07:00
Maksim Levental
5a112dedff
[MLIR][Python] expose translate_module_to_llvmir (#163881)
This PR exposes `translate_module_to_llvmir` in the Python bindings.
2025-10-20 09:14:52 -07:00
Rolf Morel
9351ad638b
[MLIR][Transform][SMT] Allow for declarative computations in schedules (#160895)
By allowing `transform.smt.constrain_params`'s region to yield SMT-vars,
op instances can declare relationships, through constraints, on incoming
params-as-SMT-vars and outgoing SMT-vars-as-params. This makes it
possible to declare that computations on params should be performed.

The semantics are that the yielded SMT-vars should be from any valid
satisfying assignment/model of the constraints in the region.
2025-10-18 23:48:23 +00:00
Perry Gibson
35cd291427
[mlir][python] add dict-style to IR attributes (#163200)
It makes sense that Attribute dicts/maps should behave like dicts in the
Python bindings. Previously this was not the case.
2025-10-16 18:42:05 +01:00
Asher Mancinelli
a885961216
[mlir][python] Fix lit run line for openacc test (#163797)
This test passed locally because I had a python environment with the
`python` command available, but I should have used the `%PYTHON` lit
command substitution instead. Fixes buildbot failures from #163620.
2025-10-16 07:52:56 -07:00
Asher Mancinelli
e5825c455e
[mlir][python] Add bindings for OpenACC dialect (#163620)
Adds initial support for Python bindings to the OpenACC dialect.

* The bindings do not provide any niceties yet, just the barebones
exposure of the dialect to Python. Construction of OpenACC ops is
therefore verbose and somewhat inconvenient, as evidenced by the test.
* The test only constructs one module, but I attempted to use enough
operations to be meaningful. It does not test all the ops exposed, but
does contain a realistic example of a memcpy idiom.
2025-10-16 14:30:19 +00:00
Asher Mancinelli
fbdd98f74f
[mlir][python] Add pythonic interface for GPUFuncOp (#163596)
The func dialect provides a more pythonic interface for constructing
operations, but the gpu dialect does not; this is the first PR to
provide the same conveniences for the gpu dialect, starting with the
gpu.func op.
2025-10-16 07:04:30 -07:00
Tuomas Kärnä
032df4b6f7
[MLIR][Transform] FuseOp: accept transform params, add use_forall argument (#161883)
Changes to linalg `structured.fuse` transform op:

* Adds an optional `use_forall` boolean argument which generates a tiled
  `scf.forall` loop instead of `scf.for` loops.
* `tile_sizes` can now be any parameter or handle.
* `tile_interchange` can now be any parameter or handle.
* IR formatting changes from `transform.structured.fuse %0 [4, 8] ...`
  to `transform.structured.fuse %0 tile_sizes [4, 8] ...`
- boolean arguments are now `UnitAttrs` and should be set via the op
  attr-dict: `{apply_cleanup, use_forall}`
2025-10-13 12:41:29 +02:00
Twice
06e2c78680
[MLIR][Python] Pass OpView subclasses instead of Operation in rewrite patterns (#163080)
This is a follow-up PR for #162699.

Currently, in the function where we define rewrite patterns, the `op` we
receive is of type `ir.Operation` rather than a specific `OpView` type
(such as `arith.AddIOp`). This means we can’t conveniently access
certain parts of the operation — for example, we need to use
`op.operands[0]` instead of `op.lhs`. The following example code
illustrates this situation.

```python
def to_muli(op, rewriter):
  # op is typed ir.Operation instead of arith.AddIOp
  pass

patterns.add(arith.AddIOp, to_muli)
```

In this PR, we convert the operation to its corresponding `OpView`
subclass before invoking the rewrite pattern callback, making it much
easier to write patterns.

---------

Co-authored-by: Maksim Levental <maksim.levental@gmail.com>
2025-10-13 11:56:57 +08:00
Twice
7aec3f2864
[MLIR][Python] Support Python-defined rewrite patterns (#162699)
This PR adds support for defining custom **`RewritePattern`**
implementations directly in the Python bindings.

Previously, users could define similar patterns using the PDL dialect’s
bindings. However, for more complex patterns, this often required
writing multiple Python callbacks as PDL native constraints or rewrite
functions, which made the overall logic less intuitive—though it could
be more performant than a pure Python implementation (especially for
simple patterns).

With this change, we introduce an additional, straightforward way to
define patterns purely in Python, complementing the existing PDL-based
approach.

### Example

```python
def to_muli(op, rewriter):
    with rewriter.ip:
        new_op = arith.muli(op.operands[0], op.operands[1], loc=op.location)
    rewriter.replace_op(op, new_op.owner)

with Context():
    patterns = RewritePatternSet()
    patterns.add(arith.AddIOp, to_muli) # a pattern that rewrites arith.addi to arith.muli
    frozen = patterns.freeze()

    module = ...
    apply_patterns_and_fold_greedily(module, frozen)
```

---------

Co-authored-by: Maksim Levental <maksim.levental@gmail.com>
2025-10-11 11:28:45 +08:00
Twice
d12b0e2539
[MLIR][Python] Expose PassManager::enableStatistics to CAPI and Python (#162591)
`PassManager::enableStatistics` seems currently missing in both C API
and Python bindings. So here we added them in this PR, which includes
the `PassDisplayMode` enum type and the `EnableStatistics` method.
2025-10-09 20:11:19 +08:00
Maksim Levental
93097b2d47
Revert "[MLIR][Python] use FetchContent_Declare for nanobind and remove pybind (#161230)" (#162309)
This reverts commit 84a214856ad989f37af19f5e8aaa9ec2346dde6f.

This gives us more time to work out the alternative and also people to
migrate
2025-10-07 16:30:10 +00:00
Maksim Levental
84a214856a
[MLIR][Python] use FetchContent_Declare for nanobind and remove pybind (#161230)
Inspired by this comment
https://github.com/llvm/llvm-project/pull/157930#issuecomment-3346634290
(and long-standing issues related to finding nanobind/pybind in the
right place), this PR moves to using `FetchContent_Declare` to get the
nanobind dependency. This is pretty standard (see e.g.,
[IREE](cf60359b74/CMakeLists.txt (L842-L848))).
This PR also removes pybind which has been deprecated for almost a year
(https://github.com/llvm/llvm-project/pull/117922) and which isn't
compatible (for whatever reason) with `FetchContent_Declare`.

---------

Co-authored-by: Jacques Pienaar <jpienaar@google.com>
2025-10-06 17:17:04 +00:00
Twice
8181c3deae
[MLIR][Python] Expose the insertion point of pattern rewriter (#161001)
In [#160520](https://github.com/llvm/llvm-project/pull/160520), we
discussed the current limitations of PDL rewriting in Python (see [this
comment](https://github.com/llvm/llvm-project/pull/160520#issuecomment-3332326184)).
At the moment, we cannot create new operations in PDL native (python)
rewrite functions because the `PatternRewriter` APIs are not exposed.

This PR introduces bindings to retrieve the insertion point of the
`PatternRewriter`, enabling users to create new operations within Python
rewrite functions. With this capability, more complex rewrites e.g. with
branching and loops that involve op creations become possible.

---------

Co-authored-by: Maksim Levental <maksim.levental@gmail.com>
2025-10-05 11:12:11 +08:00
Maksim Levental
fea2cca4d6
[MLIR][Python] expose Operation::setLoc (#161594) 2025-10-01 21:57:10 -07:00
Rolf Morel
f4d18c0ef8
[MLIR][Transform][Tune] Introduce transform.tune.alternatives op (#160724)
This op enables expressing uncertainty regarding what should be
happening at particular places in transform-dialect schedules. In
particular, it enables representing a choice among alternative regions.
This choice is resolved through providing a `selected_region` argument.
When this argument is provided, the semantics are such that it is valid
to rewrite the op through substituting in the selected region -- with
the op's interpreted semantics corresponding to exactly this.

This op represents another piece of the puzzle w.r.t. a toolkit for
expressing autotuning problems with the transform dialect. Note that
this goes beyond tuning knobs _on_ transforms, going further by making
it tunable which (sequences of) transforms are to be applied.
2025-10-01 13:47:35 +00:00
Maksim Levental
3834c5428d
[MLIR][Python] add unchecked gettors (#160954)
Some of the current gettors require passing locations (i.e., there be an
active location) because they're using the "checked" APIs. This PR adds
"unchecked" gettors which only require an active context.
2025-09-27 13:54:33 -05:00
Maksim Levental
d995c413c6
[MLIR][Python] fix python_test.py to not use is for type hint (#160718)
`is` causes the asserts to fail when the return hint is interpreted as 
`OpResult | OpResultList | test.SameVariadicResultSizeOpVFV`
2025-09-25 08:26:15 -07:00
Twice
440d6d0f78
[MLIR][Python] Add bindings for PDL constraint function registering (#160520)
This is a follow-up to #159926.

That PR (#159926) exposed native rewrite function registration in PDL
through the C API and Python, enabling use with
`pdl.apply_native_rewrite`.

In this PR, we add support for native constraint functions in PDL via
`pdl.apply_native_constraint`, further completing the PDL API.
2025-09-25 14:38:03 +08:00
Twice
b5daf76798
[MLIR][Python] Add bindings for PDL native rewrite function registering (#159926)
In the MLIR Python bindings, we can currently use PDL to define simple
patterns and then execute them with the greedy rewrite driver. However,
when dealing with more complex patterns—such as constant folding for
integer addition—we find that we need `apply_native_rewrite` to actually
perform arithmetic (i.e., compute the sum of two constants). For
example, consider the following PDL pseudocode:

```mlir
pdl.pattern : benefit(1) {
  %a0 = pdl.attribute
  %a1 = pdl.attribute
  %c0 = pdl.operation "arith.constant" {value = %a0}
  %c1 = pdl.operation "arith.constant" {value = %a1}

  %op = pdl.operation "arith.addi"(%c0, %c1)

  %sum = pdl.apply_native_rewrite "addIntegers"(%a0, %a1)
  %new_cst = pdl.operation "arith.constant" {value = %sum}

  pdl.replace %op with %new_cst
}
```

Here, `addIntegers` cannot be expressed in PDL alone—it requires a
*native rewrite function*. This PR introduces a mechanism to support
exactly that, allowing complex rewrite patterns to be expressed in
Python and enabling many passes to be implemented directly in Python as
well.

As a test case, we defined two new operations (`myint.constant` and
`myint.add`) in Python and implemented a constant-folding rewrite
pattern for them. The core code looks like this:

```python
m = Module.create()
with InsertionPoint(m.body):

    @pdl.pattern(benefit=1, sym_name="myint_add_fold")
    def pat():
        ...
        op0 = pdl.OperationOp(name="myint.add", args=[v0, v1], types=[t])

        @pdl.rewrite()
        def rew():
            sum = pdl.apply_native_rewrite(
                [pdl.AttributeType.get()], "add_fold", [a0, a1]
            )
            newOp = pdl.OperationOp(
                name="myint.constant", attributes={"value": sum}, types=[t]
            )
            pdl.ReplaceOp(op0, with_op=newOp)

def add_fold(rewriter, results, values):
    a0, a1 = values
    results.push_back(IntegerAttr.get(i32, a0.value + a1.value))

pdl_module = PDLModule(m)
pdl_module.register_rewrite_function("add_fold", add_fold)
```

The idea is previously discussed in Discord #mlir-python channel with
@makslevental.

---------

Co-authored-by: Maksim Levental <maksim.levental@gmail.com>
2025-09-24 09:17:24 +08:00
Maksim Levental
0d08ffd22c
[MLIR][Python] use nb::typed for return signatures (#160221)
https://github.com/llvm/llvm-project/pull/160183 removed `nb::typed`
annotation to fix bazel but it turned out to be simply a matter of not
using the correct version of nanobind (see
https://github.com/llvm/llvm-project/pull/160183#issuecomment-3321429155).
This PR restores those annotations but (mostly) moves to the return
positions of the actual methods.
2025-09-23 10:54:22 -07:00
Andrzej Warzyński
3a1111d668
[mlir][vector] Refine Vector to LLVM lowering options (#159553)
This is a follow-up to https://github.com/llvm/llvm-project/pull/144307,
where we removed `vector.matrix_multiply` and `vector.flat_transpose`
from the Vector dialect.

This PR:
* Updates comments that were missed in the previous change.
* Renames relevant `-convert-vector-to-llvm=` options:
  - `vector-contract-lowering=matmul` → `vector-contract-lowering=llvmintr`
  - `vector-transpose-lowering=flat_transpose` → `vector-transpose-lowering=llvmintr`

These new names better reflect the actual transformation target - LLVM
intrinsics - rather than the now-removed abstract operations.
2025-09-23 16:29:47 +01:00
Rolf Morel
d8b84be107
[MLIR][Transform][SMT] Introduce transform.smt.constrain_params (#159450)
Introduces a Transform-dialect SMT-extension so that we can have an op
to express constrains on Transform-dialect params, in particular when
these params are knobs -- see transform.tune.knob -- and can hence be
seen as symbolic variables. This op allows expressing joint constraints
over multiple params/knobs together.

While the op's semantics are clearly defined, per SMTLIB, the interpreted
semantics -- i.e. the `apply()` method -- for now just defaults to failure. In
the future we should support attaching an implementation so that users
can Bring Your Own Solver and thereby control performance of 
interpreting the op. For now the main usage is to walk schedule IR and 
collect these constraints so that knobs can be rewritten to constants that
satisfy the constraints.
2025-09-21 20:32:45 +00:00
Maksim Levental
efd96afedf
[MLIR][Python] reland (narrower) type stub generation (#157930)
This a reland of https://github.com/llvm/llvm-project/pull/155741 which
was reverted at https://github.com/llvm/llvm-project/pull/157831. This
version is narrower in scope - it only turns on automatic stub
generation for `MLIRPythonExtension.Core._mlir` and **does not do
anything automatically**. Specifically, the only CMake code added to
`AddMLIRPython.cmake` is the `mlir_generate_type_stubs` function which
is then used only in a manual way. The API for
`mlir_generate_type_stubs` is:

```
Arguments:
  MODULE_NAME: The fully-qualified name of the extension module (used for importing in python).
  DEPENDS_TARGETS: List of targets these type stubs depend on being built; usually corresponding to the
    specific extension module (e.g., something like StandalonePythonModules.extension._standaloneDialectsNanobind.dso)
    and the core bindings extension module (e.g., something like StandalonePythonModules.extension._mlir.dso).
  OUTPUT_DIR: The root output directory to emit the type stubs into.
  OUTPUTS: List of expected outputs.
  DEPENDS_TARGET_SRC_DEPS: List of cpp sources for extension library (for generating a DEPFILE).
  IMPORT_PATHS: List of paths to add to PYTHONPATH for stubgen.
  PATTERN_FILE: (Optional) Pattern file (see https://nanobind.readthedocs.io/en/latest/typing.html#pattern-files).
Outputs:
  NB_STUBGEN_CUSTOM_TARGET: The target corresponding to generation which other targets can depend on.
```

Downstream users should use `mlir_generate_type_stubs` in coordination
with `declare_mlir_python_sources` to turn on stub generation for their
own downstream dialect extensions and upstream dialect extensions if
they so choose. Standalone example shows an example.

Note, downstream will also need to set
`-DMLIR_PYTHON_PACKAGE_PREFIX=...` correctly for their bindings.
2025-09-20 18:47:32 +00:00
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
d0c0986387
[MLIR][Python] add not to MLIR_PYTHON_TEST_DEPENDS (#159124)
[lit complains if these aren't
found](95fc948c0a/llvm/utils/lit/lit/llvm/config.py (L466-L482))
(even if they're not used by a test...) so make sure to include all of
them in `MLIR_PYTHON_TEST_DEPENDS`.
2025-09-16 10:03:13 -07:00
Twice
10d0d955e2
[MLIR][Python] Add docstring for generated python op classes (#158198)
This PR adds support in mlir-tblgen for generating docstrings for each
Python class corresponding to an MLIR op. The docstrings are currently
derived from the op’s description in ODS, with indentation adjusted to
display nicely in Python. This makes it easier for Python users to see
the op descriptions directly in their IDE or LSP while coding.

In the future, we can extend the docstrings to include explanations for
each method, attribute, and so on.

This idea was previously discussed in the `#mlir-python` channel on
Discord with @makslevental and @superbobry.

---------

Co-authored-by: Maksim Levental <maksim.levental@gmail.com>
2025-09-16 11:16:28 +08:00
Maksim Levental
063d8d7d22
[MLIR][Python] fix generated value builder type hints (#158449)
Currently the type hints on the returns of the "value builders" are
`ir.Value`, `Sequence[ir.Value]`, and `ir.Operation`, none of which are
correct. The correct possibilities are `ir.OpResult`, `ir.OpResultList`,
the OpView class itself (e.g., `AttrSizedResultsOp`) or the union of the
3 (for variadic results). This PR fixes those hints.
2025-09-15 10:54:03 -07:00