200 Commits

Author SHA1 Message Date
Ryan Kim
ac88f7bcd4
[mlir][python] Support Arbitrary Precision Integers in MLIR C API and Python Bindings (#177733)
This PR extends the MLIR C API and Python bindings to support
**arbitrary-precision integers (`APInt`)**, overcoming the previous
limitation where `IntegerAttr` values were restricted to 64 bits.

Cryptographic applications often require integer types much larger than
standard machine words (e.g., the 256-bit modulus for the BN254 curve).
Previously, attempting to bind these values resulted in truncation or
errors. This PR exposes the underlying word-based `APInt` structure via
the C API and updates the Python bindings to seamlessly handle Python's
arbitrary-precision integers.
2026-01-24 23:05:03 -08:00
Maksim Levental
619a9c1e81
[mlir][Python] downcast Value to BlockArgument or OpResult (#175264)
This PR adds "downcasting" of `ir.Value` to either `BlockArgument` or
`OpResult` (and then potentially further down if a user-registered
"value caster" exists). Also this PR changes `__str__` to return the
correct thing (`OpResult(...)` or `BlockArgument(...)` instead of
generic `Value(...)`).
2026-01-12 17:20:53 +00:00
MaPePeR
524fde8a4d
[MLIR][Python] Register OpAttributeMap as Mapping for match compatibility (#174292)
This is a continuation of the idea from #174091 to add `match` support
for MLIR containers. In this PR the `OpAttributeMap` container is
registered as a `Mapping`, so be mapped as a "dictionary" in `match`
statements.

For this to work the `get(key, default=None)` method had to be
implemented. Those are pretty much copys of `dunderGetItemNamed` and
`dunderGetItemIndexed` with an added argument and `nb::object` as return
type, because they can now return other types than just `PyAttribute`.
Was unsure if I should refactor this to make `dunderGetItem...` use the
new `getWithDefault...` or if a separate method is preferred. Kept it as
a copy for simplicitys sake for now.

Even though the `OpAttributeMap` supports indexing by `int` and `str`,
Python does not allow to register it as a `Sequence` and a `Mapping` at
the same time. If it is registered as a Sequence it only returns the
attribute names as string, not as `NamedAttribute`. It is technically
possible to also use integer keys for the `dict`-like match, but it
doesn't provide any constraints on the number of attributes, etc., so
probably not recommended.

<details><summary>Example</summary>

```python
from mlir.ir import Context, Module, OpAttributeMap
from collections.abc import Sequence

ctx = Context()
ctx.allow_unregistered_dialects = True
module = Module.parse(
    r"""
"some.op"() { some.attribute = 1 : i8,
                other.attribute = 3.0,
                dependent = "text" } : () -> ()
""",
    ctx,
)
op = module.body.operations[0]

def test(attr):
    match attr:
        case [*args]:
            print("matched a Sequence", args)
        case _:
            print("Didn't match as Sequence")
    match attr:
        case {"some.attribute": a, "other.attribute": b, "dependent": c}:
            print("Matched as Mapping individually", a, b, c)
        case _:
            print("Didn't match a Mapping")
    match attr:
        case {0: a, 1: b}:
            print("Matched as Mapping with 2 int keys", a, b)
        case _:
            print("Didn't match as Mapping with 2 int keys")
print("Registered as Mapping only:")
test(op.attributes)
print("\nAfter additonally registering as Sequence:")
Sequence.register(OpAttributeMap)
test(op.attributes)
```
Output:
```
Registered as Mapping only:
Didn't match as Sequence
Matched as Mapping individually 1 : i8 3.000000e+00 : f64 "text"
Matched as Mapping with 2 int keys NamedAttribute(dependent="text") NamedAttribute(other.attribute=3.000000e+00 : f64)

After additonally registering as Sequence:
matched a Sequence ['dependent', 'other.attribute', 'some.attribute']
Didn't match a Mapping
Didn't match as Mapping with 2 int keys
```
</details>

makslevental Would be great if you could take a look again ❤️

---------

Co-authored-by: Maksim Levental <maksim.levental@gmail.com>
2026-01-10 09:09:05 -08:00
Twice
271a62f838
[MLIR][Python] Add attr_name for FloatAttr (#175306)
After #174756 I found that attribute name for `FloatAttr` is missing.
And this PR is to add it.

This is actually part of changes in #169045, but I think that we can
make it a separate PR to make #169045 easier to review.
2026-01-10 22:57:29 +08:00
Oleksandr "Alex" Zinenko
5958842aee
[mlir][py] ability to downcast AffineExpr after #172892 (#174808)
AffineExpr is a separate hierarchy of LLVM-style nested classes that
doesn't rely on TypeID and is not extensible. We need the ability to
downcast the Python equivalent of those to a specific subclass that was
seemingly lost in PR #172892. Bring it back by having an explicit cast.
We don't really need user-defined type casters here since AffineExpr is
entirely closed and not typed, unlike values.
2026-01-07 17:40:27 +00:00
Twice
ae4bbd0ec6
[MLIR][Python] Forward the name of MLIR attrs to Python side (#174756)
This PR is quite similiar to #174700.

In this PR, I added a C API for each (upstream) MLIR attributes to
retrieve its name (for example, `StringAttr -> mlirStringAttrGetName()
-> "builtin.string"`), and exposed a corresponding type_name class
attribute in the Python bindings (e.g., `StringAttr.attr_name ->
"builtin.string"`). This can be used in various places to avoid
hard-coded strings, such as eliminating the manual string in
`irdl.base("#builtin.string")`.

Note that parts of this PR (mainly mechanical changes) were produced via
GitHub Copilot and GPT-5.2. I have manually reviewed the changes and
verified them with tests to ensure correctness.
2026-01-07 22:57:14 +08:00
Twice
b919d62eae
[MLIR][Python] Forward the name of MLIR types to Python side (#174700)
In this PR, I added a C API for each (upstream) MLIR type to retrieve
its type name (for example, `IntegerType` -> `mlirIntegerTypeGetName()`
-> `"builtin.integer"`), and exposed a corresponding `type_name` class
attribute in the Python bindings (e.g., `IntegerType.type_name` ->
`"builtin.integer"`). This can be used in various places to avoid
hard-coded strings, such as eliminating the manual string in
`irdl.base("!builtin.integer")`.

Note that parts of this PR (mainly mechanical changes) were produced via
GitHub Copilot and GPT-5.2. I have manually reviewed the changes and
verified them with tests to ensure correctness.
2026-01-07 16:27:31 +08:00
Twice
c1de1543bf
[MLIR][Python] Add a .get method to IntegerType (#174406)
In this PR, I added a `.get` class method to `IntegerType`. The main
goal is to ensure that types from upstream dialects have a `.get` method
(at least for the builtin dialect). The benefit is that, for any MLIR
type, we can construct an instance directly without special-casing types
that don’t provide a `.get` method.

The design mirrors `mlir::IntegerType` in C++: it takes `width` and
`signedness` parameters, and `signedness` defaults to `signless`.

It is related to #169045.
2026-01-06 11:57:39 +08:00
Maksim Levental
fb8bbd4ed8
[mlir][Python] use canonical Python isinstance instead of Type.isinstance (#172892)
We've been able to do `isinstance(x, Type)` for a quite a while now
(since
bfb1ba7526)
so remove `Type.isinstance` and the the special-casing
(`_is_integer_type`, `_is_floating_point_type`, `_is_index_type`) in
some places (and therefore support various `fp8`, `fp6`, `fp4` types).
2026-01-05 21:07:24 +00:00
MaPePeR
6d8dd3da4b
[MLIR][Python] Register Containers as Sequences for match compatibility (#174091)
This allows these containers to be used in `match` statements, which
allows extracting properties and asserting a shape at the same time.

It seems to be only possible, to match as _either_ a `Mapping` _or_ a
`Sequence`, so the `OpAttributeMap` is only a `Mapping`.

I couldn't find a way to make these C++ based types properly inherit
from `Sequence` or `Mapping`, so the Mixins are not provided (nanobind
only allows C++ parent classes, modifying `__base__` complains about
differing destructors).
`OpAttributeMap` was lacking the `get` method, so I simply copied it
from `collections.abc.Mapping`.

When writing the tests i ran into the error, that I wrote
`func.FuncOp(body=[Block(...)])` instead of
`func.FuncOp(body=Region(blocks=[Block(...)]))`. So maybe also turning
`Region` itself into a Sequence would be a good addition as well? Would
extend the Scope of this PR, though.

makslevental You suggested I make the PR, so i'm tagging you here as a
potential reviewer. I hope that is ok with you. :)

---------

Co-authored-by: Maksim Levental <maksim.levental@gmail.com>
2026-01-03 09:56:24 -08:00
Hongzheng Chen
86cc934b4a
[python] Expose replaceUsesOfWith C API (#171892)
This PR exposes the `replaceUsesOfWith` C API to Python
2025-12-11 16:09:18 -08:00
Maksim Levental
e6d1deae3e
[MLIR][Python] make Sliceable inherit from Sequence (#170551)
Generates type stubs like

```python
class RegionSequence(Sequence[Region]):
    def __add__(self, arg: RegionSequence, /) -> list[Region]: ...

    def __iter__(self) -> RegionIterator:
        """Returns an iterator over the regions in the sequence."""
```
2025-12-05 05:41:55 -08:00
James Molloy
d17284ae29
[python] Fix loc_tracebacks() (#170831)
There were two bugs lurking in mlir.ir.loc_tracebacks():
  1) The default None parameter was not handled correctly (passed to a
     C++ function that expects ints.
  2) The `yield` was incorrectly indented meaning loc_tracebacks()
     could not be nested (a "generator didn't yield" exception would be
     raised).

Added testing of loc_tracebacks by replacing the custom contextmanager
in the auto_location.py test with the loc_tracebacks() API.

Had to harden the test to line number differences.

---------

Co-authored-by: James Molloy <jmolloy@google.com>
2025-12-05 11:58:40 +00:00
Benjamin Chetioui
012721d320
[mlir][python] Propagate error diagnostics when an op couldn't be created. (#169499) 2025-11-25 17:41:01 +00:00
Jacques Pienaar
5ab49edde2
[mlir][py][c] Enable setting block arg locations. (#169033)
This enables changing the location of a block argument. Follows the
approach for updating type of block arg.
2025-11-21 13:31:46 +00: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
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
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
Maksim Levental
fea2cca4d6
[MLIR][Python] expose Operation::setLoc (#161594) 2025-10-01 21:57:10 -07: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
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
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
Maksim Levental
9a0ed70319
[MLIR][Python] bind InsertionPointAfter (#157156) 2025-09-05 14:30:40 -07:00
Twice
55d9c91c36
[MLIR][Python] Add optional results parameter for building op with inferable result types (#156818)
Currently in MLIR python bindings, operations with inferable result
types (e.g. with `InferTypeOpInterface` or `SameOperandsAndResultType`)
will generate such builder functions:

```python
def my_op(arg1, arg2 .. argN, *, loc=None, ip=None):
  ... # result types will be inferred automatically
```

However, in some cases we may want to provide the result types
explicitly. For example, the implementation of interface method
`inferResultTypes(..)` can return a failure and then we cannot build the
op in that way. Also, in the C++ side we have multiple `build` methods
for both explicitly specify the result types and automatically inferring
them.

In this PR, we change the signature of this builder function to:

```python
def my_op(arg1, arg2 .. argN, *, results=None, loc=None, ip=None):
  ... # result types will be inferred automatically if results is None
```

If the `results` is not provided, it will be inferred automatically,
otherwise the provided result types will be utilized. Also, `__init__`
methods of the generated op classes are changed correspondingly. Note
that for operations without inferable result types, the signature remain
unchanged, i.e. `def my_op(res1 .. resN, arg1 .. argN, *, loc=None,
ip=None)`.

---

Previously I have considered an approach like `my_op(arg, *, res1=None,
res2=None, loc=None, ip=None)`, but I quickly realized it had some
issues. For example, if the user only provides some of the arguments—say
`my_op(v1, res1=i32)`—this could lead to problems. Moreover, we don’t
seem to have a mechanism for inferring only part of result types. A
unified `results` parameter seems to be more simple and straightforward.
2025-09-04 17:57:39 -07:00
Anatoly Myachev
c93e2de67f
Fix python/ir/auto_location.py test on Windows (#156711)
Initially found in:
https://github.com/llvm/llvm-project/pull/151246#discussion_r2318830512

To fix:
```txt
******************** TEST 'MLIR :: python/ir/auto_location.py' FAILED ********************
Exit Code: 1

Command Output (stdout):
--
# RUN: at line 1
"C:/hostedtoolcache/windows/Python/3.11.9/x64/python3.exe" D:\a\triton\triton\llvm-project\mlir\test\python\ir\auto_location.py | d:\a\triton\triton\llvm-project\build\bin\filecheck.exe D:\a\triton\triton\llvm-project\mlir\test\python\ir\auto_location.py
# executed command: C:/hostedtoolcache/windows/Python/3.11.9/x64/python3.exe 'D:\a\triton\triton\llvm-project\mlir\test\python\ir\auto_location.py'
# executed command: 'd:\a\triton\triton\llvm-project\build\bin\filecheck.exe' 'D:\a\triton\triton\llvm-project\mlir\test\python\ir\auto_location.py'
# .---command stderr------------
# | D:\a\triton\triton\llvm-project\mlir\test\python\ir\auto_location.py:37:11: error: CHECK: expected string not found in input
# |  # CHECK: loc(callsite("testInferLocations"("{{.*}}[[SEP:[/\\]]]test[[SEP]]python[[SEP]]ir[[SEP]]auto_location.py":31:13 to :43) at callsite("run"("{{.*}}[[SEP]]test[[SEP]]python[[SEP]]ir[[SEP]]auto_location.py":13:4 to :7) at "<module>"("{{.*}}[[SEP]]test[[SEP]]python[[SEP]]ir[[SEP]]auto_location.py":26:1 to :4))))
# |           ^
# | <stdin>:2:25: note: scanning from here
# | TEST: testInferLocations
# |                         ^
# | 
# | Input file: <stdin>
# | Check file: D:\a\triton\triton\llvm-project\mlir\test\python\ir\auto_location.py
# | 
# | -dump-input=help explains the following input dump.
# | 
# | Input was:
# | <<<<<<
# |           1:  
# |           2: TEST: testInferLocations 
# | check:37                             X error: no match found
# |           3: loc(callsite("testInferLocations"("D:\\a\\triton\\triton\\llvm-project\\mlir\\test\\python\\ir\\auto_location.py":31:13 to :43) at callsite("run"("D:\\a\\triton\\triton\\llvm-project\\mlir\\test\\python\\ir\\auto_location.py":13:4 to :7) at "<module>"("D:\\a\\triton\\triton\\llvm-project\\mlir\\test\\python\\ir\\auto_location.py":26:1 to :4)))) 
# | check:37     
```
2025-09-03 17:34:31 +00: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
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
Maksim Levental
a36508483e
[mlir][python,CAPI] expose Op::isBeforeInBlock (#150271) 2025-07-23 12:33:42 -05:00
Akshay Khadse
e4a3541ff8
[MLIR][Python] Support eliding large resource strings in PassManager (#149187)
- Introduces a `large_resource_limit` parameter across Python bindings,
enabling the eliding of resource strings exceeding a specified character
limit during IR printing.
- To maintain backward compatibilty, when using `operation.print()` API,
if `large_resource_limit` is None and the `large_elements_limit` is set,
the later will be used to elide the resource string as well. This change
was introduced by https://github.com/llvm/llvm-project/pull/125738.
- For printing using pass manager, the `large_resource_limit` and
`large_elements_limit` are completely independent of each other.
2025-07-17 12:57:04 -04:00
Jakub Kuderski
6512ca7ddb
[mlir] Add isStatic* size check for ShapedTypes. NFCI. (#147085)
The motivation is to avoid having to negate `isDynamic*` checks, avoid
double negations, and allow for `ShapedType::isStaticDim` to be used in
ADT functions without having to wrap it in a lambda performing the
negation.

Also add the new functions to C and Python bindings.
2025-07-07 14:57:27 -04:00
Maksim Levental
a2aa812a31
[mlir][python] bind block predecessors and successors (#145116)
bind `block.getSuccessor` and `block.getPredecessors`.
2025-06-23 19:59:03 -04:00
Maksim Levental
9b50167ed9
[mlir][python] add use_name_loc_as_prefix to value.get_name() (#135052)
Add `use_name_loc_as_prefix` to `value.get_name()`.
2025-04-09 19:28:59 -04:00
Matthias Springer
b7b3758e88
[mlir][IR] Add VectorTypeElementInterface with !llvm.ptr (#133455)
This commit extends the MLIR vector type to support pointer-like types
such as `!llvm.ptr` and `!ptr.ptr`, as indicated by the newly added
`VectorTypeElementInterface`. This makes the LLVM dialect closer to LLVM
IR. LLVM IR already supports pointers as vector element type.

Only integers, floats, pointers and index are valid vector element types
for now. Additional vector element types may be added in the future
after further discussions. The interface is still evolving and may
eventually turn into one of the alternatives that were discussed on the
RFC.

This commit also disallows `!llvm.ptr` as an element type of
`!llvm.vec`. This type exists due to limitations of the MLIR vector
type.

RFC:
https://discourse.llvm.org/t/rfc-allow-pointers-as-element-type-of-vector/85360
2025-04-08 19:21:45 +02:00
Ivan Butygin
1f194ff34e
[mlir] Expose simplifyAffineExpr through python api (#133926) 2025-04-01 19:28:53 +03:00
Sergei Lebedev
c8a9a4109a
[MLIR] [python] A few improvements to the Python bindings (#131686)
* `PyRegionList` is now sliceable. The dialect bindings generator seems
to assume it is sliceable already (!), yet accessing e.g. `cases` on
`scf.IndexedSwitchOp` raises a `TypeError` at runtime.
* `PyBlockList` and `PyOperationList` support negative indexing. It is
common for containers to do that in Python, and most container in the
MLIR Python bindings already allow the index to be negative.
2025-03-21 00:13:13 -04:00
Ivan Butygin
7c98cddc5a
[mlir] Expose AffineExpr.shift_dims/shift_symbols through C and Python bindings (#131521) 2025-03-16 19:57:56 +03:00
Nikhil Kalra
b15ccd436a
[mlir] Better Python diagnostics (#128581)
Updated the Python diagnostics handler to emit notes (in addition to
errors) into the output stream so that users have more context as to
where in the IR the error is occurring.
2025-03-10 15:59:47 -07:00
vfdev
ab18cc246c
[MLIR][py] Add PyThreadPool as wrapper around MlirLlvmThreadPool in MLIR python bindings (#130109)
In some projects like JAX ir.Context are used with disabled multi-threading to avoid
caching multiple threading pools:

623865fe95/jax/_src/interpreters/mlir.py (L606-L611)

However, when context has enabled multithreading it also uses locks on
the StorageUniquers and this can be helpful to avoid data races in the
multi-threaded execution (for example with free-threaded cpython,
https://github.com/jax-ml/jax/issues/26272).
With this PR user can enable the multi-threading: 1) enables additional
locking and 2) set a shared threading pool such that cached contexts can
have one global pool.
2025-03-10 11:19:23 +01:00
Maksim Levental
0264d42dc7
[mlir][CAPI][python] bind CallSiteLoc, FileLineColRange, FusedLoc, NameLoc (#129351)
This PR extends the python bindings for CallSiteLoc, FileLineColRange,
FusedLoc, NameLoc with field accessors. It also adds the missing
`value.location` accessor.

I also did some "spring cleaning" here (`cast` -> `dyn_cast`) after
running into some of my own illegal casts.
2025-03-10 05:10:34 -04:00
Jacques Pienaar
540d7ddb15
[mlir][py] Plumb OpPrintingFlags::printNameLocAsPrefix() through the C/Python APIs (#129607) 2025-03-04 11:49:34 -08:00
Nikhil Kalra
a60e8a2c25
[mlir] Python: write bytecode to a file path (#127118)
The current `write_bytecode` implementation necessarily requires the
serialized module to be duplicated in memory when the python `bytes`
object is created and sent over the binding. For modules with large
resources, we may want to avoid this in-memory copy by serializing
directly to a file instead of sending bytes across the boundary.
2025-02-24 17:51:49 -08:00
Nikhil Kalra
65ed4fa57e
[mlir] Python: Parse ModuleOp from file path (#126572)
For extremely large models, it may be inefficient to load the model into
memory in Python prior to passing it to the MLIR C APIs for
deserialization. This change adds an API to parse a ModuleOp directly
from a file path.

Re-lands
[4e14b8a](4e14b8afb4).
2025-02-12 14:02:41 -08:00
Mehdi Amini
67b7a2590f
Revert "[mlir] Python: Parse ModuleOp from file path" (#126482)
Reverts llvm/llvm-project#125736

The gcc7 Bot is broken at the moment.
2025-02-10 09:09:58 +01:00
Nikhil Kalra
4e14b8afb4
[mlir] Python: Parse ModuleOp from file path (#125736)
For extremely large models, it may be inefficient to load the model into
memory in Python prior to passing it to the MLIR C APIs for
deserialization. This change adds an API to parse a ModuleOp directly
from a file path.
2025-02-05 11:48:37 -08:00
Nikhil Kalra
0ad1f8369c
[mlir] Python: Extend print large elements limit to resources (#125738)
If the large element limit is specified, large elements are hidden from
the asm but large resources are not. This change extends the large
elements limit to apply to printed resources as well.
2025-02-05 11:48:11 -08:00