| Age | Commit message (Collapse) | Author |
|
The dialect implementation mostly copies the one of `cf.switch`, but
aligns naming to the SPIR-V spec.
|
|
|
|
|
|
|
|
|
|
|
|
Same as with pass def & decl. This doesn't change anything with registry
and the big flag kept (e.g., GEN_PASS_REGISTRATION behaves like
GEN_PASS_DECL and so too for sub ones).
|
|
(#163933)
…consistent
Since the bindings now use nanobind, I changed the code examples and
mentions in the documentation prose to mention nanobind concepts and
symbols wherever applicable.
I also made the spelling of "Python" consistent by choosing the
uppercase name everywhere that's not an executable name, part of a URL,
or directory name.
----------------
Note that I left mentions of `PybindAdaptors.h` in because of
https://github.com/llvm/llvm-project/pull/162309.
Are there any thoughts about adding a virtual environment setup guide
using [uv](https://docs.astral.sh/uv/)? It has gotten pretty popular,
and is much faster than a "vanilla" Python pip install. It can also
bootstrap an interpreter not present on the user's machine, for example
a free-threaded Python build, with the `-p` flag to the `uv venv`
virtual environment creation command.
|
|
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.
|
|
Add documentation for the no-rollback conversion driver. Also improve
the documentation of the old rollback driver. In particular: which
modifications are performed immediately and which are delayed.
|
|
This PR seeks to improve the clarity of the Shard dialect documentation,
in particular the descriptions of the communication operations.
|
|
This includes the rename from `mlirOpRewritePattenCreate` to `mlirOpRewritePatternCreate` in CAPI, and other typo fixes in docs and code comments.
|
|
In the previous PR #163123 I made a mistake that unexpectedly moved the
"other functionality" section from the "[Providing Python bindings for a
dialect](https://mlir.llvm.org/docs/Bindings/Python/#providing-python-bindings-for-a-dialect)"
section to the newly-added section ([Extending MLIR in
Python](https://mlir.llvm.org/docs/Bindings/Python/#extending-mlir-in-python)).
This PR is to fix it.
|
|
As discussed in:
* https://discourse.llvm.org/t/rfc-linalg-forms/87994/
*
https://discourse.llvm.org/t/rfc-extend-linalg-elemwise-named-ops-semantics/83927
* https://discourse.llvm.org/t/rfc-op-explosion-in-linalg/82863/1
* https://discourse.llvm.org/t/rfc-mlir-linalg-operation-tree/83586
* #148424
Co-designed by Javed Absar
---------
Co-authored-by: Andrzej Warzyński <andrzej.warzynski@gmail.com>
|
|
patterns in bindings (#163123)
The MLIR Python bindings now support defining new passes, new rewrite
patterns (through either `RewritePatternSet` or `PDLModule`), as well as
new dialects using the IRDL bindings. Adding a dedicated section to
document these features would make it easier for users to discover and
understand the full capabilities of the Python bindings.
|
|
Python-defined passes have been merged into the main branch for some
time now. I believe adding a corresponding section in the documentation
will help more users learn about this feature and understand how to use
it.
This PR adds such a section to the docs of Python bindings, summarizing
the feature and providing an example.
|
|
vector.splat has been deprecated (user: please use the very similar vector.broadcast instead)
with the last PR landing about 6 weeks ago.
The discourse discussion is at
https://discourse.llvm.org/t/rfc-mlir-vector-deprecate-then-remove-vector-splat/87143/1
The last PR was #152230
This PR completely removes vector.splat. In addition to removing vector.splat from VectorOps.td, it
- Updates the few remaining places where vector::SplatOp is created (now vector::BroadcastOp is created)
- Removes temporary patterns where vector.splat is replaced by vector.broadcast
The only place 'vector.splat' appears is now the files
https://github.com/llvm/llvm-project/blob/main/mlir/utils/tree-sitter-mlir/test/corpus/op.txt
and
https://github.com/llvm/llvm-project/blob/main/mlir/utils/tree-sitter-mlir/dialect/vector.js
---------
Signed-off-by: James Newling <james.newling@gmail.com>
|
|
|
|
pybind (#161230)" (#162309)
This reverts commit 84a214856ad989f37af19f5e8aaa9ec2346dde6f.
This gives us more time to work out the alternative and also people to
migrate
|
|
(#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](https://github.com/iree-org/iree/blob/cf60359b7443b0e92e15fb6ffc011525dc40e772/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>
|
|
Fixes a small typo in the Creating a Dialect tutorial.
The rewrite rules format should be DRR (Declarative Rewrite Rules), not
DDR.
|
|
This patch fixes a documentation typo in the MLIR Toy tutorial (Ch6).
The tutorial currently refers to `examples/toy/Ch6/toy.cpp`, but the
correct
file name is `examples/toy/Ch6/toyc.cpp`.
|
|
## Details:
- Added missing compound assignment operators `|=`, `&=`, `^=` to
`mlir-tblgen`
- Replaced the arithmetic operators with added assignment operators for
`BitEnum` in the transformations
- Updated related documentation
## Tickets:
- Closes https://github.com/llvm/llvm-project/issues/158098
|
|
|
|
(#158962)
|
|
Fixes a small issue I noticed while reading through the tutorial.
|
|
conversion (#158072)
The current implementation is overly conservative and disable all
possible caching as soon as a context-aware conversion is present.
However the context-aware conversion only affects subsequent converters,
we can cache the previous ones.
This isn't NFC because if fixed a bug where we use to unconditionally
cache when using the `convertType(Type t, ...` API, while now all APIs
are aware of context-aware conversions.
|
|
Addressed code review feedback:
- Fixed some issues in the unit test
- Adjusted line wrapping in the docs
- Clarified comments in the bytecode reader
|
|
|
|
Adds a check that the bytecode buffer is aligned to any section
alignment requirements. Without this check, if the source buffer is not
sufficiently aligned, we may return early when aligning the data
pointer. In that case, we may end up trying to read successive sections
from an incorrect offset, giving the appearance of invalid bytecode.
This requirement is documented in the bytecode unit tests, but is not
otherwise documented in the code or bytecode reference.
|
|
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 `==`.
|
|
This commit adds support for context-aware type conversions: type
conversion rules that can return different types depending on the IR.
There is no change for existing (context-unaware) type conversion rules:
```c++
// Example: Conversion any integer type to f32.
converter.addConversion([](IntegerType t) {
return Float32Type::get(t.getContext());
}
```
There is now an additional overload to register context-aware type
conversion rules:
```c++
// Example: Type conversion rule for integers, depending on the context:
// Get the defining op of `v`, read its "increment" attribute and return an
// integer with a bitwidth that is increased by "increment".
converter.addConversion([](Value v) -> std::optional<Type> {
auto intType = dyn_cast<IntegerType>(v.getType());
if (!intType)
return std::nullopt;
Operation *op = v.getDefiningOp();
if (!op)
return std::nullopt;
auto incrementAttr = op->getAttrOfType<IntegerAttr>("increment");
if (!incrementAttr)
return std::nullopt;
return IntegerType::get(v.getContext(),
intType.getWidth() + incrementAttr.getInt());
});
```
For performance reasons, the type converter caches the result of type
conversions. This is no longer possible when there context-aware type
conversions because each conversion could compute a different type
depending on the context. There is no performance degradation when there
are only context-unaware type conversions.
Note: This commit just adds context-aware type conversions to the
dialect conversion framework. There are many existing patterns that
still call `converter.convertType(someValue.getType())`. These should be
gradually updated in subsequent commits to call
`converter.convertType(someValue)`.
Co-authored-by: Markus Böck <markus.boeck02@gmail.com>
|
|
(#152474)
This PR implements structured, tooling-friendly optimization remarks
with zero cost unless enabled. It implements:
- `RemarkEngine` collects finalized remarks within `MLIRContext`.
- `MLIRRemarkStreamerBase` abstract class streams them to a backend.
- Backends: `MLIRLLVMRemarkStreamer` (bridges to llvm::remarks →
YAML/Bitstream) or your own custom streamer.
- Optional mirroring to DiagnosticEngine (printAsEmitRemarks +
categories).
- Off by default; no behavior change unless enabled. Thread-safe;
ordering best-effort.
## Overview
```
Passes (reportOptimization*)
│
▼
+-------------------+
| RemarkEngine | collects
+-------------------+
│ │
│ mirror │ stream
▼ ▼
emitRemark MLIRRemarkStreamerBase (abstract)
│
├── MLIRLLVMRemarkStreamer → llvm::remarks → YAML | Bitstream
└── CustomStreamer → your sink
```
## Enable Remark engine and Plug LLVM's Remark streamer
```
// Enable once per MLIRContext. This uses `MLIRLLVMRemarkStreamer`
mlir::remark::enableOptimizationRemarksToFile(
ctx, path, llvm::remarks::Format::YAML, cats);
```
## API to emit remark
```
// Emit from a pass
remark::passed(loc, categoryVectorizer, myPassname1)
<< "vectorized loop";
remark::missed(loc, categoryUnroll, "MyPass")
<< remark::reason("not profitable at this size") // Creates structured reason arg
<< remark::suggest("increase unroll factor to >=4"); // Creates structured suggestion arg
remark::passed(loc, categoryVectorizer, myPassname1)
<< "vectorized loop"
<< remark::metric("tripCount", 128); // Create structured metric on-the-fly
```
|
|
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>
|
|
This fixes a small typo in the toy tutorial. A code block was not
correctly terminated, causing it to run into the subsequent block.
|
|
When a conversion pattern is initialized without a type converter, the
driver implementation currently looks up the most recently mapped value.
This is undesirable because the most recently mapped value could be a
materialization. I.e., the type of the value being looked up could
depend on which other patterns have run before. Such an implementation
makes the type conversion infrastructure fragile and unpredictable.
The current implementation also contradicts the documentation in the
markdown file. According to that documentation, the values provided by
the adaptor should match the types of the operands of the match
operation when running without a type converter. This mechanism is not
desirable, either, for two reasons:
1. Some patterns have started to rely on receiving the most recently
mapped value. Changing the behavior to the documented behavior will
cause regressions. (And there would be no easy way to fix those without
forcing the use of a type converter or extending the `getRemappedValue`
API.)
2. It is more useful to receive the most recently mapped value. A value
of the original operand type can be retrieved by using the operand of
the matched operation. The adaptor is not needed at all in that case.
To implement the new behavior, materializations are now annotated with a
marker attribute. The marker is needed because not all
`unrealized_conversion_cast` ops are materializations that act as "pure
type conversions". E.g., when erasing an operation, its results are
mapped to newly-created "out-of-thin-air values", which are
materializations (with no input) that should be treated like regular
replacement values during a lookup. This marker-based lookup strategy is
also compatible with the One-Shot Dialect Conversion implementation
strategy, which does not utilize the mapping infrastructure anymore and
queries all necessary information by examining the IR.
|
|
(#151315)
Fixes #151314.
|
|
This aims to lower `memref.alloc` to `emitc.call_opaque “malloc” ` or
`emitc.call_opaque “aligned_alloc” `
From:
```
module{
func.func @allocating() {
%alloc_5 = memref.alloc() : memref<999xi32>
return
}
}
```
To:
```
module {
emitc.include <"stdlib.h">
func.func @allocating() {
%0 = emitc.call_opaque "sizeof"() {args = [i32]} : () -> !emitc.size_t
%1 = "emitc.constant"() <{value = 999 : index}> : () -> index
%2 = emitc.mul %0, %1 : (!emitc.size_t, index) -> !emitc.size_t
%3 = emitc.call_opaque "malloc"(%2) : (!emitc.size_t) -> !emitc.ptr<!emitc.opaque<"void">>
%4 = emitc.cast %3 : !emitc.ptr<!emitc.opaque<"void">> to !emitc.ptr<i32>
return
}
}
```
Which is then translated as:
```
#include <stdlib.h>
void allocating() {
size_t v1 = sizeof(int32_t);
size_t v2 = 999;
size_t v3 = v1 * v2;
void* v4 = malloc(v3);
int32_t* v5 = (int32_t*) v4;
return;
}
```
|
|
(#149603)
This PR removes `vector.extractelement` and `vector.insertelement` ops
from the code base in favor of the `vector.extract` and `vector.insert`
counterparts.
See RFC:
https://discourse.llvm.org/t/rfc-psa-remove-vector-extractelement-and-vector-insertelement-ops-in-favor-of-vector-extract-and-vector-insert-ops
|
|
The Toy tutorial used outdated API. Update the example to:
* Use the `OpAdaptor` in all places.
* Do not mix `RewritePattern` and `ConversionPattern`. This cannot
always be done safely and should not be advertised in the example code.
|
|
|
|
Fixed some bugs in documentation. Add CallOpInterfaceHandle to the
arguments of ChangeCallTargetOp, after doing so the section described in
the documentation works correctly, Otherwise the following code reports
an error.
```
// Cast to our new type.
%casted = transform.cast %call : !transform.any_op to !transform.my.call_op_interface
// Using our new operation.
transform.my.change_call_target %casted, "microkernel" : !transform.my.call_op_interface
```
|
|
See https://github.com/llvm/llvm-project/pull/147168 for more info.
|
|
dialect to 'shard' (#150177)
Dialect to 'shard' (discourse 87053)
- dialect name mesh -> shard
- (device) mesh -> (device) grid
- spmdize -> partition
A lot of diffs, but simple renames only.
@tkarna @yaochengji
|
|
New extensions were added to the code but not to the documentation.
|
|
op (NFC)
|
|
Fixes #150080.
|
|
Fixed error code in example.In addition to this, the content in the documentation has been improved by adding links to the code repository.
|
|
This makes the doc consistent with the code base.
|
|
Alignment information is important to allow LLVM backends such as AMDGPU
to select wide memory accesses (e.g., dwordx4 or b128). Since this info
is not always inferable, it's better to inform LLVM backends explicitly
about it. Furthermore, alignment is not necessarily a property of the
element type, but of each individual memory access op (we can have
overaligned and underaligned accesses compared to the natural/preferred
alignment of the element type).
This patch introduces `alignment` attribute to memref/vector.load/store
ops.
Follow-up PRs will
1. Propagate the attribute to LLVM/SPIR-V.
2. Introduce `alignment` attribute to other vector memory access ops:
vector.gather + vector.scatter
vector.transfer_read + vector.transfer_write
vector.compressstore + vector.expandload
vector.maskedload + vector.maskedstore
3. Replace `--convert-vector-to-llvm='use-vector-alignment=1` with a
simple pass to populate alignment attributes based on the vector
types.
|