# Chapter 4: Matching Payload with Transform Operations

**Check the continuously-tested version of MLIR files under
[mlir/test/Examples/transform/Ch4](https://github.com/llvm/llvm-project/tree/main/mlir/test/Examples/transform/Ch4).**

Up until now, we were applying transform dialect scripts under the assumption
that specific payload operations are identified by the caller when the transform
dialect interpreter is invoked. This may be seen as contrary to the idea of
driving transformations from a dialect since the transformation targets must be
identified through mechanisms external to the transform dialect interpreter, for
example, when invoking the interpreter programmatically in C++ or through pass
arguments as seen in previous chapters. It also adds practical overhead due to
increased interaction with the interpreter in C++, and cognitive overhead of
manipulating two interfaces at once. To remedy this, Transform dialect proposes
a subset of operations for _matching_ payload operations that need to be
transformed.

_Match_ operations are simply transform operations with some additional
guarantees. In particular, they are not expected to modify the payload IR and
are expected to fail if their operands (typically payload operation handles) are
not associated with payload IR objects having desired properties, such as
operation names or kinds of arguments. Using simple combinator operations, it
becomes possible to set up a higher-level match and rewrite infrastructure
directly within the transform dialect.


## Simple match

Let us reconsider the “fully connected layer” example from [Chapter
1](Ch1.md/#chaining-transformations-with-handles), reproduced below for
convenience.


```mlir
// Original function to optimize.
func.func @fc_relu(%lhs: tensor<512x512xf32>, %rhs: tensor<512x512xf32>,
                   %bias: tensor<512x512xf32>, %output: tensor<512x512xf32>)
                   -> tensor<512x512xf32> {
  // Matrix-matrix multiplication.
  %matmul = linalg.matmul
            ins(%lhs, %rhs: tensor<512x512xf32>, tensor<512x512xf32>)
            outs(%output: tensor<512x512xf32>) -> tensor<512x512xf32>

  // Elementwise addition.
  %biased = linalg.elementwise <add>
    ins(%matmul, %bias : tensor<512x512xf32>, tensor<512x512xf32>)
    outs(%output : tensor<512x512xf32>) -> tensor<512x512xf32>

  // Elementwise max with 0 (ReLU).
  %c0f = arith.constant 0.0 : f32
  %relued = linalg.elementwise <max_signed>
    ins(%biased, %c0f : tensor<512x512xf32>, f32)
    outs(%output : tensor<512x512xf32>) -> tensor<512x512xf32>
  func.return %relued : tensor<512x512xf32>
}

```


In Chapter 1, we were calling the test transform interpreter pass with
additional arguments, `bind-first-extra-to-ops=linalg.matmul
bind-second-extra-to-ops=linalg.elementwise`, to provide initial
associations for operation handles. Instead, we can use match operations to
discover relevant operations in the payload IR. Match operations can be combined
with “regular” transform operations using, e.g., the
`transform.collect_matching` combinator operation that leverages the concept of
named sequences to organize matchers.


```mlir
// The module containing named sequences must have an attribute allowing them
// to enable verification.
module @transforms attributes { transform.with_named_sequence } {
  // Entry point. This takes as the only argument the root operation (typically
  // pass root) given to the transform interpreter.
  transform.named_sequence @__transform_main(
      %root: !transform.any_op {transform.readonly}) {
    // Collect operations that match the criteria specified in named sequence.
    // If the named sequence fails with a silenceable failure, silences it (the
    // message is forwarded to the debug stream). If the named sequence
    // succeeds, appends its results to the results of this operation.
    %elemwise = transform.collect_matching @match_elemwise in %root
      : (!transform.any_op) -> !transform.any_op
    %matmul = transform.collect_matching @match_matmul in %root
      : (!transform.any_op) -> !transform.any_op
    transform.include @print_elemwise failures(propagate)  (%elemwise)
      : (!transform.any_op) -> ()
    transform.include @print_matmul failures(propagate)  (%matmul)
      : (!transform.any_op) -> ()

    transform.yield
  }

  // This is a matcher sequence. It is given an operation to match and the
  // match is considered successful unless any nested operation produces a
  // failure. The values yielded by this operation will be forwarded to the
  // rewriter sequence on success.
  transform.named_sequence @match_elemwise(
      %entry: !transform.any_op {transform.readonly}) -> !transform.any_op {
    transform.match.operation_name %entry ["linalg.elementwise"]
      : !transform.any_op
    transform.yield %entry : !transform.any_op
  }
  transform.named_sequence @match_matmul(
      %entry: !transform.any_op {transform.readonly}) -> !transform.any_op {
    transform.match.operation_name %entry ["linalg.matmul"] : !transform.any_op
    transform.yield %entry : !transform.any_op
  }

  // This is a rewriter sequence.
  transform.named_sequence @print_elemwise(
      %elemwise_binary: !transform.any_op {transform.readonly}) {
    transform.debug.emit_remark_at
      %elemwise_binary, "elementwise binary" : !transform.any_op
    transform.yield
  }
  transform.named_sequence @print_matmul(
      %matmul: !transform.any_op {transform.readonly}) {
    transform.debug.emit_remark_at %matmul, "matmul" : !transform.any_op
    transform.yield
  }
}

```


This script can be executed using the non-test interpreter pass running on the
root operation of the translation unit without additional flags: `mlir-opt
--transform-interpreter`. It will emit corresponding remarks at
`linalg.elementwise` and `linalg.matmul` operations. In debug builds, the
infrastructure provides a convenient method to understand the matching process
by passing `-debug-only=transform-matcher` to `mlir-opt` or a derived tool. It
will print the silenceable failure messages produced by the match operations
into the debug stream, for example:


```
<...>
[transform-matcher] matching %0 = linalg.matmul ins(%arg0, %arg1 : tensor<512x512xf32>, tensor<512x512xf32>) outs(%arg3 : tensor<512x512xf32>) -> tensor<512x512xf32> @0x5622eee08410
[transform-matcher] matcher match_elemwise failed: wrong operation name
<...>
```


This is now sufficient to run the rest of the transform script from Chapter 1,
substituting `%arg1` with `%matmul` and `%arg2` with `%elemwise`.


## Matching Chains of Operations

The matcher above remains naive as it matches _all_ operations of the certain
kind under the payload root. These operations may or may not be related, and
may, for example, belong to different functions. Even if they are in a single
function, if there are multiple groups of such operations, we wouldn’t be able
to differentiate them with this approach. In reality, we want to match a
specific group of operations where a `matmul` operation produces a result that
is used by an elementwise operation, which in turn feeds another elementwise
operation in a similar way.

This can be achieved using the following matcher sequence.


```mlir
// This is also a matcher sequence. It is similarly given an operation to
// match and nested operations must succeed in order for a match to be deemed
// successful. It starts matching from the last operation in the use-def chain
// and goes back because each operand (use) has exactly one definition.
transform.named_sequence @match_matmul_elemwise(
    %last: !transform.any_op {transform.readonly})
    -> (!transform.any_op, !transform.any_op, !transform.any_op) {
  // The last operation must be an elementwise binary.
  transform.match.operation_name %last ["linalg.elementwise"]
    : !transform.any_op
  // Its first operand must be defined by another operation, to which we
  // will get a handle here. We are guaranteed that the first operand exists
  // because we know the operation is binary, but even in absence of such a
  // guarantee, this operation would have produced a silenceable failure when
  // `%last` does not have enough operands.
  %middle = transform.get_producer_of_operand %last[0]
    : (!transform.any_op) -> !transform.any_op
  // The defining operation must itself be an elementwise binary.
  transform.match.operation_name %middle ["linalg.elementwise"]
    : !transform.any_op
  // And the first operand of that operation must be defined by yet another
  // operation.
  %matmul = transform.get_producer_of_operand %middle[0]
    : (!transform.any_op) -> !transform.any_op
  // And that operation is a matmul.
  transform.match.operation_name %matmul ["linalg.matmul"] : !transform.any_op
  // We will yield the handles to the matmul and the two elementwise
  // operations separately.
  transform.yield %matmul, %middle, %last
    : !transform.any_op, !transform.any_op, !transform.any_op
}
```

This matcher is applicable in presence of other `elemwise` and `matmul`
operations and will return the triple of _related_ operations rather than
operations in the order in which they are found. It can be exercised similarly
to the previous incarnation, as follows.

```mlir
// Alternative entry point.
transform.named_sequence @__transform_main(
    %root: !transform.any_op {transform.readonly}) {
  // Collect groups of operations that match the criteria specified in the
  // named sequence.
  %matmul, %el1, %el2 = transform.collect_matching @match_matmul_elemwise in %root
    : (!transform.any_op) -> (!transform.any_op, !transform.any_op, !transform.any_op)
  %elemwise = transform.merge_handles %el1, %el2 : !transform.any_op

  transform.include @print_elemwise failures(propagate)  (%elemwise)
    : (!transform.any_op) -> ()
  transform.include @print_matmul failures(propagate)  (%matmul)
    : (!transform.any_op) -> ()

  transform.yield
}
```


## Defining Match Operations

The matcher of a chain of operations is correct in presence of other operations,
but is still insufficiently robust for many cases of interest. In particular,
using `transform.get_producer_of_operand %last[0]` requires that the _first_
operand of elementwise operations is produced by another operation. The same
transformation strategy may however apply regardless of the operand position:
many binary operations are associative. Let us use this opportunity to introduce
a new match operation. Specifically, we would like this operation to succeed if
_any_ of the operands satisfies certain conditions that can be expressed as
other match operations. We also want it to return some of the state and the
position of the matched operand in the operand list.

Match operations are defined similarly to other transform operations, with the
only difference of additionally implementing the `MatchOpInterface`. Note that
this interface has _no additional methods_ (though it may add some eventually)
and is only used as a verification contract that the operation is intended for
matching and will not attempt to transform the payload. The minimal definition
of our operation is as follows.


```tablegen
// Define the new operation. By convention, prefix its name with `match`
// followed by the name of the dialect extension.
def HasOperandSatisfyingOp : TransformDialectOp<"match.my.has_operand_satisfying",
    [DeclareOpInterfaceMethods<MemoryEffectsOpInterface>,
     DeclareOpInterfaceMethods<TransformOpInterface>,
     // Indicate that the operation implements MatchOpInterface in addition to
     // the TransformOpInterface. This interface is only used as a tag at this
     // point and has no methods that are mandatory to implement.
     MatchOpInterface,
     SingleBlockImplicitTerminator<"::mlir::transform::YieldOp">]> {
  let summary = "Succeed if any of the operands matches all nested criteria";
  let arguments = (ins TransformHandleTypeInterface:$op);
  let results = (outs TransformParamTypeInterface:$position,
                      Variadic<Transform_AnyHandleOrParamType>:$results);

  // Match operations can be arbitrarily complex, e.g., containing regions.
  let regions = (region SizedRegion<1>:$body);
  let hasVerifier = 1;
  let assemblyFormat = [{
    $op `:` functional-type($op, results) attr-dict-with-keyword $body
  }];
}
```


It takes as argument the handle associated with the payload operations whose
operands it will match, has an associated single-block region containing the
match criteria, and returns the position of the matched operand as well as any
other transform value yielded from the body on the successful match.

The matching logic is implemented in the `apply` method of the
`TransformOpInterface` and is easily composable with other transform operations.
All facilities for managing the interpreter state and recursively entering the
blocks are available in the same way as they are for “regular” transform
operations. Match operations are expected to return a silenceable failure to
indicate failure to match, and to immediately propagate definite failures. If
they have nested operations, they are expected to handle and, in most cases,
silence the silenceable failures produced when applying those operations. For
our operation, the matching is essentially a loop iterating over all operands of
the (single) payload operation and applying nested transform ops until they all
succeed for one of the operands.


```cpp
// Matcher ops implement `apply` similarly to other transform ops. They are not
// expected to modify payload, but use the tri-state result to signal failure or
// success to match, as well as potential irrecoverable errors.
mlir::DiagnosedSilenceableFailure
mlir::transform::HasOperandSatisfyingOp::apply(
    mlir::transform::TransformRewriter &rewriter,
    mlir::transform::TransformResults &results,
    mlir::transform::TransformState &state) {
  // For simplicity, only handle a single payload op. Actual implementations
  // can use `SingleOpMatcher` trait to simplify implementation and document
  // this expectation.
  auto payloadOps = state.getPayloadOps(getOp());
  if (!llvm::hasSingleElement(payloadOps))
    return emitSilenceableError() << "expected single payload";

  // Iterate over all operands of the payload op to see if they can be matched
  // using the body of this op.
  Operation *payload = *payloadOps.begin();
  for (OpOperand &operand : payload->getOpOperands()) {
    // Create a scope for transform values defined in the body. This corresponds
    // to the syntactic scope of the region attached to this op. Any values
    // associated with payloads from now on will be automatically dissociated
    // when this object is destroyed, i.e. at the end of the iteration.
    // Associate the block argument handle with the operand.
    auto matchScope = state.make_region_scope(getBody());
    if (failed(state.mapBlockArgument(getBody().getArgument(0),
                                      {operand.get()}))) {
      return DiagnosedSilenceableFailure::definiteFailure();
    }

    // Iterate over all nested matchers with the current mapping and see if they
    // succeed.
    bool matchSucceeded = true;
    for (Operation &matcher : getBody().front().without_terminator()) {
      // Matcher ops are applied similarly to any other transform op.
      DiagnosedSilenceableFailure diag =
          state.applyTransform(cast<TransformOpInterface>(matcher));

      // Definite failures are immediately propagated as they are irrecoverable.
      if (diag.isDefiniteFailure())
        return diag;

      // On success, keep checking the remaining conditions.
      if (diag.succeeded())
        continue;

      // Report failure-to-match for debugging purposes and stop matching this
      // operand.
      assert(diag.isSilenceableFailure());
      DEBUG_MATCHER(DBGS_MATCHER()
                    << "failed to match operand #" << operand.getOperandNumber()
                    << ": " << diag.getMessage());
      (void)diag.silence();
      matchSucceeded = false;
      break;
    }
    // If failed to match this operand, try other operands.
    if (!matchSucceeded)
      continue;

    // If we reached this point, the matching succeeded for the current operand.
    // Remap the values associated with terminator operands to be associated
    // with op results, and also map the parameter result to the operand's
    // position. Note that it is safe to do here despite the end of the scope
    // as `results` are integrated into `state` by the interpreter after `apply`
    // returns rather than immediately.
    SmallVector<SmallVector<MappedValue>> yieldedMappings;
    transform::detail::prepareValueMappings(
        yieldedMappings, getBody().front().getTerminator()->getOperands(),
        state);
    results.setParams(cast<OpResult>(getPosition()),
                      {rewriter.getI32IntegerAttr(operand.getOperandNumber())});
    for (auto &&[result, mapping] : llvm::zip(getResults(), yieldedMappings))
      results.setMappedValues(result, mapping);
    return DiagnosedSilenceableFailure::success();
  }

  // If we reached this point, none of the operands succeeded the match.
  return emitSilenceableError()
         << "none of the operands satisfied the conditions";
}

```


By convention, operations implementing `MatchOpInterface` must not modify
payload IR and must therefore specify that they only read operand handles and
payload as their effects.


```cpp
void transform::CollectMatchingOp::getEffects(
    SmallVectorImpl<MemoryEffects::EffectInstance> &effects) {
  onlyReadsHandle(getRoot(), effects);
  producesHandle(getResults(), effects);
  onlyReadsPayload(effects);
}
```


This operation can now be included in a transform dialect extension, loaded and
used in our matcher. Specifically, we will use it to indicate that either of the
operands of the “max” elementwise operation in our example can be produced by
the previous elementwise operation. The previous operation will still require
the matmul to produce the first operand for simplicity. The updated matcher
sequence looks as follows.


```mlir
transform.named_sequence @match_matmul_elemwise(
    %last: !transform.any_op {transform.readonly})
    -> (!transform.any_op, !transform.any_op, !transform.any_op,
        !transform.param<i32>) {
  // The last operation must be an elementwise binary.
  transform.match.operation_name %last ["linalg.elementwise"]
    : !transform.any_op

  // One of its operands must be defined by another operation, to which we
  // will get a handle here. This is achieved thanks to a newly defined
  // operation that tries to match operands one by one using the match
  // operations nested in its region.
  %pos, %middle = transform.match.my.has_operand_satisfying %last
      : (!transform.any_op) -> (!transform.param<i32>, !transform.any_op) {
  ^bb0(%operand: !transform.any_value):
    // The operand must be defined by an operation.
    %def = transform.get_defining_op %operand
      : (!transform.any_value) -> !transform.any_op
    // The defining operation must itself be an elementwise binary.
    transform.match.operation_name %def ["linalg.elementwise"]
      : !transform.any_op
    transform.yield %def : !transform.any_op
  }

  // And the first operand of that operation must be defined by yet another
  // operation.
  %matmul = transform.get_producer_of_operand %middle[0]
    : (!transform.any_op) -> !transform.any_op
  // And that operation is a matmul.
  transform.match.operation_name %matmul ["linalg.matmul"] : !transform.any_op
  // We will yield the handles to the matmul and the two elementwise
  // operations separately.
  transform.yield %matmul, %middle, %last, %pos
    : !transform.any_op, !transform.any_op, !transform.any_op,
      !transform.param<i32>
}
```


This achieves the desired effect and matches both `max(add(matmul(...), bias),
0)` and `max(0, add(matmul(...), bias))` in the same values. The `%pos` value is
a transform dialect _parameter_, which is used to store lists of entities known
to be constant throughout the transform application. Most often, parameters are
numeric values, but they can generally be any MLIR attributes.

In order to demonstrate that groups of operations are matched independently of
each other, let us use the `transform.foreach_match` operation that allows one
to implement a simple high-level pattern rewriting approach within the transform
dialect (for advanced or lower-level pattern rewriting, consider PDL(L) or C++
rewriting APIs). It maps a matcher named sequence to an action named sequence,
and the latter gets invoked whenever the former succeeds.


```mlir
// Traverses the payload IR associated with the operand handle, invoking
// @match_matmul_elemwise on each of the operations. If the named sequence
// succeeds, i.e., if none of the nested match (transform) operations
// produced a silenceable failure, invokes @print_matmul_elemwise and
// forwards the values yielded as arguments of the new invocation. If the
// named sequence fails with a silenceable failure, silences it (the message
// is forwarded to the debug stream). Definite failures are propagated
// immediately and unconditionally, as usual.
transform.foreach_match in %root
  @match_matmul_elemwise -> @print_matmul_elemwise
  : (!transform.any_op) -> !transform.any_op
```


The `@print_matmul_elemwise` named sequence, available in `multiple.mlir`, will
use the parameter with the position of the operand to differentiate the two
groups.


## Matchers for Inferred Features

The matcher sequences described above, although useful to drive transformations
from within the transform dialect interpreter, are rather basic since they
mostly rely on operation names and use-def chains. Alternative implementations
using APIs or various declarative rewrite rules are barely less expressive and
sometimes more concise. The real power of transform dialect matcher ops lies in
the possibility to define matchers of _inferred properties_ of payloads, i.e.,
properties that are not directly accessible as an attribute of an operation or
any straightforward relation between IR components.

The utility of such matchers can be easily demonstrated by slightly modifying
our original example. If matrix multiplication is expressed as a special case of
tensor contraction using `linalg.generic` instead of `linalg.matmul`, the
operation name-based matcher no longer applies. Yet such a representation is
very common and can appear both in the original input and during the course of
transformation, e.g., where a higher-dimensional contraction is decomposed into
loops around a matrix multiplication.

In order to be a (potentially transposed) matrix multiplication, the
`linalg.generic` operation must have the following features:



*   Total rank of 3.
*   Two inputs accessed as projected permutation of iteration dimensions.
*   One output accessed as projected permutation of iteration dimensions.
*   Iteration dimensions can be subdivided into LHS parallel, RHS parallel and reduction dimensions.
*   The body block consists of a multiplication and an addition.

Most of these features can be derived from the properties of the operation,
e.g., the total rank corresponds to the number of entries in the `iterators`
attribute, but almost none of them are immediately accessible in the IR or in
any declarative form, which is usually limited to checking the presence or the
exact match of an attribute or a type.  The transform dialect allows these
features to be implemented in the `apply` method of a matcher op and reused
across multiple matching cases. For structured linear algebra payload
operations, many such match operations are readily available in the `structured`
extension. They are sufficient to implement a matrix multiplication matcher
using the features listed above almost verbatim.


```mlir
transform.named_sequence @match_generic_matmul(
    %candidate: !transform.any_op {transform.readonly}) -> !transform.any_op {
  // Match a structured linear algebra operation.
  transform.match.structured %candidate : !transform.any_op {
  ^bb0(%c: !transform.any_op):
    // With a rank equal to 3.
    %rank = transform.match.structured.rank %c
      : (!transform.any_op) -> !transform.param<i64>
    %c3 = transform.param.constant 3 : i64 -> !transform.param<i64>
    transform.match.param.cmpi eq %rank, %c3 : !transform.param<i64>

    // With 2 inputs.
    %n_ins = transform.match.structured.num_inputs %c
      : (!transform.any_op) -> !transform.param<i64>
    %c2 = transform.param.constant 2 : i64 -> !transform.param<i64>
    transform.match.param.cmpi eq %n_ins, %c2 : !transform.param<i64>

    // With 1 output (note that structured ops in destination passing style
    // has as many inits as outputs).
    %n_inits = transform.match.structured.num_inits %c
      : (!transform.any_op) -> !transform.param<i64>
    %c1 = transform.param.constant 1 : i64 -> !transform.param<i64>
    transform.match.param.cmpi eq %n_inits, %c1 : !transform.param<i64>

    // All inputs and inits are accessed with a projected permutation.
    transform.match.structured.input %c[all] {projected_permutation}
      : !transform.any_op
    transform.match.structured.init %c[0] {projected_permutation}
      : !transform.any_op

    // The body is a mulf/addf contraction with appropriate dimensions.
    transform.match.structured.body %c
      { contraction = ["arith.mulf", "arith.addf"] } : !transform.any_op
    %batch, %lhs, %rhs, %reduction =
    transform.match.structured.classify_contraction_dims %c
      : (!transform.any_op)
      -> (!transform.param<i64>, !transform.param<i64>, !transform.param<i64>,
          !transform.param<i64>)


    // There is one of lhs, rhs and reduction dimensions and zero batch
    // dimensions.
    %n_batch = transform.num_associations %batch
      : (!transform.param<i64>) -> !transform.param<i64>
    %n_lhs = transform.num_associations %lhs
      : (!transform.param<i64>) -> !transform.param<i64>
    %n_rhs = transform.num_associations %rhs
      : (!transform.param<i64>) -> !transform.param<i64>
    %n_reduction = transform.num_associations %reduction
      : (!transform.param<i64>) -> !transform.param<i64>
    %c0 = transform.param.constant 0 : i64 -> !transform.param<i64>
    transform.match.param.cmpi eq %n_batch, %c0 : !transform.param<i64>
    transform.match.param.cmpi eq %n_lhs, %c1 : !transform.param<i64>
    transform.match.param.cmpi eq %n_rhs, %c1 : !transform.param<i64>
    transform.match.param.cmpi eq %n_reduction, %c1 : !transform.param<i64>
  }
  transform.yield %candidate : !transform.any_op
}
```


While this example leverages the contraction-specific matchers that have a
rather non-trivial C++ implementation, the transform dialect is sufficiently
flexible to implement this reasoning directly if desired. One could, for
example, obtain the access map of each input as a parameter and extract the
accessed dimensions as other parameters that can be compared with each other to
ensure the subscripts are `m,k` for LHS, `k,n` for RHS and `m,n` for the
init/result given the `m,n,k` notation for loops.

## Appendix: Autogenerated Documentation

[include "Tutorials/transform/MyExtensionCh4.md"]

