summaryrefslogtreecommitdiff
path: root/mlir/test/python/ir
AgeCommit message (Collapse)Author
2025-11-21[mlir][py][c] Enable setting block arg locations. (#169033)Jacques Pienaar
This enables changing the location of a block argument. Follows the approach for updating type of block arg.
2025-11-11[MLIR][Python] Add wrappers for scf.index_switch (#167458)Asher Mancinelli
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[MLIR][Python] fix PyRegionList `__iter__` (#167466)Maksim Levental
Fixes https://github.com/llvm/llvm-project/issues/167455
2025-10-26[MLIR][Python] fix getOwner to return (typed) nb::object instead of abstract ↵Maksim Levental
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-16[mlir][python] add dict-style to IR attributes (#163200)Perry Gibson
It makes sense that Attribute dicts/maps should behave like dicts in the Python bindings. Previously this was not the case.
2025-10-01[MLIR][Python] expose Operation::setLoc (#161594)Maksim Levental
2025-09-27[MLIR][Python] add unchecked gettors (#160954)Maksim Levental
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-16[MLIR][Python] Add docstring for generated python op classes (#158198)Twice
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-15[MLIR][Python] fix generated value builder type hints (#158449)Maksim Levental
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[MLIR][Python] restore `liveModuleMap` (#158506)Maksim Levental
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-05[MLIR][Python] bind InsertionPointAfter (#157156)Maksim Levental
2025-09-04[MLIR][Python] Add optional `results` parameter for building op with ↵Twice
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-03Fix `python/ir/auto_location.py` test on Windows (#156711)Anatoly Myachev
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-02[MLIR][Python] fix operation hashing (#156514)Maksim Levental
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-01[MLIR][Python] remove `liveOperations` (#155114)Maksim Levental
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-08-12[mlir][python] automatic location inference (#151246)Maksim Levental
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](https://github.com/jax-ml/jax/blob/523ddcfbcad005deab5a7d542df4c706f5ee5e9c/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-11[mlir][python] expose isAttached (#153045)Maksim Levental
2025-07-25[mlir][python] fix PyDenseResourceElementsAttribute finalizer (#150561)Maksim Levental
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](https://github.com/llvm/llvm-project/blob/548ca9e97673a168023a616d311d901ca04b29a3/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-23[mlir][python,CAPI] expose Op::isBeforeInBlock (#150271)Maksim Levental
2025-07-17[MLIR][Python] Support eliding large resource strings in PassManager (#149187)Akshay Khadse
- 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-07[mlir] Add `isStatic`* size check for `ShapedType`s. NFCI. (#147085)Jakub Kuderski
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-06-23[mlir][python] bind block predecessors and successors (#145116)Maksim Levental
bind `block.getSuccessor` and `block.getPredecessors`.
2025-04-09[mlir][python] add use_name_loc_as_prefix to value.get_name() (#135052)Maksim Levental
Add `use_name_loc_as_prefix` to `value.get_name()`.
2025-04-08[mlir][IR] Add `VectorTypeElementInterface` with `!llvm.ptr` (#133455)Matthias Springer
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-01[mlir] Expose `simplifyAffineExpr` through python api (#133926)Ivan Butygin
2025-03-21[MLIR] [python] A few improvements to the Python bindings (#131686)Sergei Lebedev
* `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-16[mlir] Expose `AffineExpr.shift_dims/shift_symbols` through C and Python ↵Ivan Butygin
bindings (#131521)
2025-03-10[mlir] Better Python diagnostics (#128581)Nikhil Kalra
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[MLIR][py] Add PyThreadPool as wrapper around MlirLlvmThreadPool in MLIR ↵vfdev
python bindings (#130109) In some projects like JAX ir.Context are used with disabled multi-threading to avoid caching multiple threading pools: https://github.com/jax-ml/jax/blob/623865fe9538100d877ba9d36f788d0f95a11ed2/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[mlir][CAPI][python] bind CallSiteLoc, FileLineColRange, FusedLoc, NameLoc ↵Maksim Levental
(#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-04[mlir][py] Plumb OpPrintingFlags::printNameLocAsPrefix() through the ↵Jacques Pienaar
C/Python APIs (#129607)
2025-02-24[mlir] Python: write bytecode to a file path (#127118)Nikhil Kalra
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-12[mlir] Python: Parse ModuleOp from file path (#126572)Nikhil Kalra
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](https://github.com/llvm/llvm-project/commit/4e14b8afb44af58ab7073bb8c0b52875599b0ae1).
2025-02-10Revert "[mlir] Python: Parse ModuleOp from file path" (#126482)Mehdi Amini
Reverts llvm/llvm-project#125736 The gcc7 Bot is broken at the moment.
2025-02-05[mlir] Python: Parse ModuleOp from file path (#125736)Nikhil Kalra
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[mlir] Python: Extend print large elements limit to resources (#125738)Nikhil Kalra
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-01-29Reapply "[mlir][python] allow DenseIntElementsAttr for index type (#118947)" ↵Matthias Gehre
(#124804) This reapplies #118947 and adapts to nanobind.
2025-01-28Revert "[mlir][python] allow DenseIntElementsAttr for index type (#118947)"Matthias Gehre
This reverts commit 9dd762e8b10586e749b0ddf3542e5dccf8392395.
2025-01-28[mlir][python] allow DenseIntElementsAttr for index type (#118947)Matthias Gehre
Model the `IndexType` as `uint64_t` when converting to a python integer. With the python bindings, ```python DenseIntElementsAttr(op.attributes["attr"]) ``` used to `assert` when `attr` had `index` type like `dense<[1, 2, 3, 4]> : vector<4xindex>`. --------- Co-authored-by: Christopher McGirr <christopher.mcgirr@amd.com> Co-authored-by: Tiago Trevisan Jost <tiago.trevisanjost@amd.com>
2025-01-22[mlir] Add C and Python interface for file range (#123276)Jacques Pienaar
Plumbs through creating file ranges to C and Python.
2025-01-02[mlir][py] Enable loading only specified dialects during creation. (#121421)Jacques Pienaar
Gives option post as global list as well as arg to control which dialects are loaded during context creation. This enables setting either a good base set or skipping in individual cases.
2024-12-18[mlir python] Port Python core code to nanobind. (#120473)Peter Hawkins
Relands #118583, with a fix for Python 3.8 compatibility. It was not possible to set the buffer protocol accessers via slots in Python 3.8. Why? https://nanobind.readthedocs.io/en/latest/why.html says it better than I can, but my primary motivation for this change is to improve MLIR IR construction time from JAX. For a complicated Google-internal LLM model in JAX, this change improves the MLIR lowering time by around 5s (out of around 30s), which is a significant speedup for simply switching binding frameworks. To a large extent, this is a mechanical change, for instance changing `pybind11::` to `nanobind::`. Notes: * this PR needs Nanobind 2.4.0, because it needs a bug fix (https://github.com/wjakob/nanobind/pull/806) that landed in that release. * this PR does not port the in-tree dialect extension modules. They can be ported in a future PR. * I removed the py::sibling() annotations from def_static and def_class in `PybindAdapters.h`. These ask pybind11 to try to form an overload with an existing method, but it's not possible to form mixed pybind11/nanobind overloads this ways and the parent class is now defined in nanobind. Better solutions may be possible here. * nanobind does not contain an exact equivalent of pybind11's buffer protocol support. It was not hard to add a nanobind implementation of a similar API. * nanobind is pickier about casting to std::vector<bool>, expecting that the input is a sequence of bool types, not truthy values. In a couple of places I added code to support truthy values during casting. * nanobind distinguishes bytes (`nb::bytes`) from strings (e.g., `std::string`). This required nb::bytes overloads in a few places.
2024-12-18Revert "[mlir python] Port Python core code to nanobind. (#118583)"Jacques Pienaar
This reverts commit 41bd35b58bb482fd466aa4b13aa44a810ad6470f. Breakage detected, rolling back.
2024-12-18[mlir python] Port Python core code to nanobind. (#118583)Peter Hawkins
Why? https://nanobind.readthedocs.io/en/latest/why.html says it better than I can, but my primary motivation for this change is to improve MLIR IR construction time from JAX. For a complicated Google-internal LLM model in JAX, this change improves the MLIR lowering time by around 5s (out of around 30s), which is a significant speedup for simply switching binding frameworks. To a large extent, this is a mechanical change, for instance changing `pybind11::` to `nanobind::`. Notes: * this PR needs Nanobind 2.4.0, because it needs a bug fix (https://github.com/wjakob/nanobind/pull/806) that landed in that release. * this PR does not port the in-tree dialect extension modules. They can be ported in a future PR. * I removed the py::sibling() annotations from def_static and def_class in `PybindAdapters.h`. These ask pybind11 to try to form an overload with an existing method, but it's not possible to form mixed pybind11/nanobind overloads this ways and the parent class is now defined in nanobind. Better solutions may be possible here. * nanobind does not contain an exact equivalent of pybind11's buffer protocol support. It was not hard to add a nanobind implementation of a similar API. * nanobind is pickier about casting to std::vector<bool>, expecting that the input is a sequence of bool types, not truthy values. In a couple of places I added code to support truthy values during casting. * nanobind distinguishes bytes (`nb::bytes`) from strings (e.g., `std::string`). This required nb::bytes overloads in a few places.
2024-11-19[mlir,python] Expose replaceAllUsesExcept to Python bindings (#115850)Perry Gibson
Problem originally described in [the forums here](https://discourse.llvm.org/t/mlir-python-expose-replaceallusesexcept/83068/1). Using the MLIR Python bindings, the method [`replaceAllUsesWith`](https://mlir.llvm.org/doxygen/classmlir_1_1Value.html#ac56b0fdb6246bcf7fa1805ba0eb71aa2) for `Value` is exposed, e.g., ```python orig_value.replace_all_uses_with( new_value ) ``` However, in my use-case I am separating a block into multiple blocks, so thus want to exclude certain Operations from having their Values replaced (since I want them to diverge). Within Value, we have [`replaceAllUsesExcept`](https://mlir.llvm.org/doxygen/classmlir_1_1Value.html#a9ec8d5c61f8a6aada4062f609372cce4), where we can pass the Operations which should be skipped. This is not currently exposed in the Python bindings: this PR fixes this. Adds `replace_all_uses_except`, which works with individual Operations, and lists of Operations.
2024-11-19[mlir][python] Add `T.tf32` and missing tests for `tf32` (#116725)Matthias Springer
2024-11-13[MLIR,Python] Support converting boolean numpy arrays to and from mlir ↵Kasper Nielsen
attributes (unrevert) (#115481) This PR re-introduces the functionality of https://github.com/llvm/llvm-project/pull/113064, which was reverted in https://github.com/llvm/llvm-project/commit/0a68171b3c67503f7143856580f1b22a93ef566e due to memory lifetime issues. Notice that I was not able to re-produce the ASan results myself, so I have not been able to verify that this PR really fixes the issue. --- Currently it is unsupported to: 1. Convert a MlirAttribute with type i1 to a numpy array 2. Convert a boolean numpy array to a MlirAttribute Currently the entire Python application violently crashes with a quite poor error message https://github.com/pybind/pybind11/issues/3336 The complication handling these conversions, is that MlirAttribute represent booleans as a bit-packed i1 type, whereas numpy represents booleans as a byte array with 8 bit used per boolean. This PR proposes the following approach: 1. When converting a i1 typed MlirAttribute to a numpy array, we can not directly use the underlying raw data backing the MlirAttribute as a buffer to Python, as done for other types. Instead, a copy of the data is generated using numpy's unpackbits function, and the result is send back to Python. 2. When constructing a MlirAttribute from a numpy array, first the python data is read as a uint8_t to get it converted to the endianess used internally in mlir. Then the booleans are bitpacked using numpy's bitpack function, and the bitpacked array is saved as the MlirAttribute representation.
2024-11-05Revert "[MLIR,Python] Support converting boolean numpy arrays to and from ↵Dmitri Gribenko
mlir attributes (#113064)" This reverts commit fb7bf7a5acc65be44fc546f282942b91472553b3. There is an ASan issue here, see the discussion on https://github.com/llvm/llvm-project/pull/113064.
2024-11-02[MLIR,Python] Support converting boolean numpy arrays to and from mlir ↵Kasper Nielsen
attributes (#113064) Currently it is unsupported to: 1. Convert a `MlirAttribute` with type `i1` to a numpy array 2. Convert a boolean numpy array to a `MlirAttribute` Currently the entire Python application violently crashes with a quite poor error message https://github.com/pybind/pybind11/issues/3336 The complication handling these conversions, is that `MlirAttribute` represent booleans as a bit-packed `i1` type, whereas numpy represents booleans as a byte array with 8 bit used per boolean. This PR proposes the following approach: 1. When converting a `i1` typed `MlirAttribute` to a numpy array, we can not directly use the underlying raw data backing the `MlirAttribute` as a buffer to Python, as done for other types. Instead, a copy of the data is generated using numpy's unpackbits function, and the result is send back to Python. 2. When constructing a `MlirAttribute` from a numpy array, first the python data is read as a `uint8_t` to get it converted to the endianess used internally in mlir. Then the booleans are bitpacked using numpy's bitpack function, and the bitpacked array is saved as the `MlirAttribute` representation. Please note that I am not sure if this approach is the desired solution. I'd appreciate any feedback.
2024-10-04[MLIR] Add f8E8M0FNU type (#111028)Sergey Kozub
This PR adds `f8E8M0FNU` type to MLIR. `f8E8M0FNU` type is proposed in [OpenCompute MX Specification](https://www.opencompute.org/documents/ocp-microscaling-formats-mx-v1-0-spec-final-pdf). It defines a 8-bit floating point number with bit layout S0E8M0. Unlike IEEE-754 types, there are no infinity, denormals, zeros or negative values. ```c f8E8M0FNU - Exponent bias: 127 - Maximum stored exponent value: 254 (binary 1111'1110) - Maximum unbiased exponent value: 254 - 127 = 127 - Minimum stored exponent value: 0 (binary 0000'0000) - Minimum unbiased exponent value: 0 − 127 = -127 - Doesn't have zero - Doesn't have infinity - NaN is encoded as binary 1111'1111 Additional details: - Zeros cannot be represented - Negative values cannot be represented - Mantissa is always 1 ``` Related PRs: - [PR-107127](https://github.com/llvm/llvm-project/pull/107127) [APFloat] Add APFloat support for E8M0 type - [PR-105573](https://github.com/llvm/llvm-project/pull/105573) [MLIR] Add f6E3M2FN type - was used as a template for this PR - [PR-107999](https://github.com/llvm/llvm-project/pull/107999) [MLIR] Add f6E2M3FN type - [PR-108877](https://github.com/llvm/llvm-project/pull/108877) [MLIR] Add f4E2M1FN type