Phase 1, week 6retrospective

linalg vectorization

linalg vectorization maps the iteration space onto vector ops, with transfer maps derived from the indexing maps.


The maps become the plan

Vectorization rewrites an op’s iteration space onto vector ops: the loops inside the tile disappear, each operand becomes a transfer, and the reduction becomes a contraction. Drive it from a script:

module attributes {transform.with_named_sequence} {
  transform.named_sequence @__transform_main(%root: !transform.any_op) {
    %mm = transform.structured.match ops{["linalg.matmul"]} in %root
        : (!transform.any_op) -> !transform.any_op
    transform.structured.vectorize %mm : !transform.any_op
    transform.yield
  }
}
mlir-opt tiled.mlir --transform-interpreter

On a 4x4 memref matmul the result is three vector.transfer_read of vector<4x4xf32>, a vector.contract with the original (m, k), (k, n), (m, n) maps, and one vector.transfer_write. The op is gone; its iteration space is now the contraction’s.

What survives, and what the tile has to be

The indexing maps are the part that survives, which is why the vectorised form is still readable as the operation you started with. Operand order that differs from iteration order does not vanish either: it becomes a permutation map on that operand’s transfer, rather than an explicit transpose.

The other requirement is a static tile. The vectorizer picks vector types from the op’s static extents and builds transfers from projected-permutation maps. A tile with a dynamic extent from a non-dividing size, or a map that is not a projected permutation, fails to vectorize. Padding the shape or passing explicit vector sizes are the two ways out, and the second one masks rather than shrinks.

Vectorization is also not tiling. It replaces one op with vector ops inside whatever loop nest already surrounds it, so vectorizing an untiled 512x512 matmul asks for vector<512x512xf32> and gets a rewrite you cannot lower usefully.

Things that break

A silenceable failure propagates out of @__transform_main and fails the pass, but transform.sequence failures(suppress) swallows it: the matmul stays a matmul and mlir-opt exits zero. Count the vector.contract ops in the output rather than trusting the exit code. A linalg.matmul still in the function after the run means the vectorize op never applied to it, so check that the match ran after tiling created the tile and that the tile has a static shape.

Sources

A version records the documentation the claim was checked against, not a house pin. Confirm flags with --help on the release you installed.

Check yourself

Where do the indexing maps of `linalg.matmul` end up after vectorization?

Vectorizing the tiled op fails on one of the tiles. What is the usual cause?

What happens to the outer tile loops during `transform.structured.vectorize`?

0 / 3 correct

← back to the map