This is an archive of the discontinued LLVM Phabricator instance.

[mlir][vector] Add gather lowering patterns
ClosedPublic

Authored by kuhar on Mar 13 2023, 7:48 AM.

Details

Summary

This is for targets that do not support gather-like ops, e.g., SPIR-V.

Gather is expanded into lower-level vector ops with memory accesses
guarded with scf.if.

I also considered generating vector.maskedloads, but decided against
it to keep the memref and tensor codepath closer together. There's a
good chance that if a target doesn't support gather it does not support
masked loads either.

Issue: https://github.com/llvm/llvm-project/issues/60905

Diff Detail

Event Timeline

kuhar created this revision.Mar 13 2023, 7:48 AM
Herald added a project: Restricted Project. · View Herald Transcript
kuhar requested review of this revision.Mar 13 2023, 7:48 AM
kuhar updated this revision to Diff 504657.Mar 13 2023, 7:50 AM

Remove unnecessary includes

kuhar added inline comments.Mar 13 2023, 7:54 AM
mlir/lib/Dialect/Vector/Transforms/VectorTransforms.cpp
3251

Could someone confirm if this index calculation is correct? The current version of the spec says:

The gather operation gathers elements from memory or ranked tensor into a n-D vector as defined by a base with indices and an additional n-D index vector (each index is a 1-D offset on the base)

So I'd think that base [indices] defines a base pointer and then all accesses are offset relative to this base pointer. However, I'm not sure if can turn these into individual loads/extract by adding the offset to the last index only.

ThomasRaoux added inline comments.Mar 13 2023, 8:41 AM
mlir/include/mlir/Dialect/Vector/Transforms/VectorRewritePatterns.h
342

nit: I'm not sure emulation is the right term. This is just a lowering of vector.gather to vector.maskedload as emulation would suggest we have some assumption that this maps to a native hw functionality.
Could we pick a name suggesting lowering instead?

kuhar updated this revision to Diff 504770.Mar 13 2023, 11:26 AM
kuhar marked an inline comment as done.

Rebase. Rename populate function (emulation -> lowering). Do not rely on temporary array refs.

kuhar retitled this revision from [mlir][vector] Add gather emulation patterns to [mlir][vector] Add gather lowering patterns.Mar 13 2023, 11:26 AM
kuhar added inline comments.
mlir/include/mlir/Dialect/Vector/Transforms/VectorRewritePatterns.h
342

Done, thanks for the suggestion!

kuhar updated this revision to Diff 504773.Mar 13 2023, 11:28 AM

Also rename the test

ThomasRaoux accepted this revision.Mar 13 2023, 6:17 PM

LGTM

mlir/lib/Dialect/Vector/Transforms/VectorTransforms.cpp
3251

I'm not an expert but that looks correct to me.

This revision is now accepted and ready to land.Mar 13 2023, 6:17 PM
This revision was landed with ongoing or failed builds.Mar 14 2023, 8:00 AM
This revision was automatically updated to reflect the committed changes.

LGTM! A couple of comments.

mlir/lib/Dialect/Vector/Transforms/VectorTransforms.cpp
3259

you could do simple memref load?

mlir/test/Dialect/Vector/vector-gather-lowering.mlir
18

it would be good to check that we have the patterns to canonicalize an all-one mask.

kuhar added inline comments.Mar 15 2023, 8:22 AM
mlir/lib/Dialect/Vector/Transforms/VectorTransforms.cpp
3259

Is it generally considered simpler or prefered for some other reason? The reason I used vector.load is that it seemed lower-level (no indexing map like in memre.load).

kuhar marked an inline comment as done.Mar 15 2023, 8:44 AM
kuhar added inline comments.
mlir/test/Dialect/Vector/vector-gather-lowering.mlir
18
dcaballe added inline comments.Mar 16 2023, 6:42 AM
mlir/lib/Dialect/Vector/Transforms/VectorTransforms.cpp
3259

memref.load is mostly to load scalar values and you wouldn't have to generate any extract op so I think. I don't think one is lower level than the other. IIRC, the map in memref.load is to describe the layout.

mlir/test/Dialect/Vector/vector-gather-lowering.mlir
18

Thanks!