The textual version of the Transform dialect tutorial is now available at Transform Dialect Tutorial - MLIR. It comes with compilable code examples in llvm-project/mlir/examples/transform at main · llvm/llvm-project · GitHub.
This is an offline version of the live tutorial I presented at the 2023 EuroLLVM earlier this month, the slides for which are available at Controllable Transformations in MLIR – Google Research and the recording will be made available by EuroLLVM organizers later. The offline version currently covers a subset of the live presentation material relevant to defining and using transform operations. The intention for this version is to provide an up-to-date, tested example.
As usual with documentation, patches are more than welcome.
13 Likes
Please use separate threads or file a bug on GitHub: a PSA isn’t meant for “support”.
Here it seems that some of the examples in the doc aren’t reflected in the test, mlir/test/Examples/transform/Ch1/
contains the running examples (and we should make sure all of the code samples from the doc are there).
I tried the command listed in tutorial Ch1 and something went wrong.
Chaining Transformations with Handles
the mlir as below:
transform.sequence failures(propagate) {
^bb0(%arg0: !transform.any_op,
%arg1: !transform.op<"linalg.matmul">,
%arg2: !transform.op<"linalg.elemwise_binary">):
// Since the %arg2 handle is associated with both elementwise operations,
// we need to split it into two handles so we can target only the second
// elementwise operation.
%add, %max = transform.split_handle %arg2
: (!transform.op<"linalg.elemwise_binary">)
-> (!transform.any_op, !transform.any_op)
// The actual tiling transformation takes tile sizes as attributes. It produces a
// handle to the loop generated during tiling.
%loop, %tiled = transform.structured.tile_to_forall_op %max tile_sizes [8, 32]
: (!transform.any_op) -> (!transform.any_op, !transform.any_op)
// We can now fuse the other operations into the loop. Here, we fuse
// operations one-by-one. This requires the operation that is being fused
// to define the value used within the loop, so the order of such fusions
// is important. We could also use "transform.merge_handles" to obtain
// a single handle to all operations and give it to `fuse_into_containing_op`
// that would take care of the ordering in this case.
%add_fused = transform.structured.fuse_into_containing_op %add into %loop
: (!transform.any_op, !transform.any_op) -> !transform.any_op
%matmul_fused = transform.structured.fuse_into_containing_op %arg1 into %loop
: (!transform.op<"linalg.matmul">, !transform.any_op) -> !transform.any_op
transform.yield
}
I tried command as below:
mlir-opt matmul.mlir --pass-pipeline="
builtin.module(test-transform-dialect-interpreter{
bind-first-extra-to-ops=linalg.matmul
bind-second-extra-to-ops=linalg.elemwise_binary,
enable-expensive-checks})" > matmul_out.mlir
and it made the error:
matmul.mlir:49:16: error: 'transform.structured.fuse_into_containing_op' op expected 2 results
%add_fused = transform.structured.fuse_into_containing_op %add into %loop
^
matmul.mlir:49:16: note: see current operation: %2 = "transform.structured.fuse_into_containing_op"(%0#0, %1#0) : (!transform.any_op, !transform.any_op) -> !transform.any_op
the transform.structured.fuse_into_containing_op
in doc has only one returns while two returns exist in mlir/test/Examples/transform/Ch1/invalidation-2.mlir
.
I check the transform dialect which also said it has 2 results.