Commit Graph

807 Commits

Author SHA1 Message Date
Matthias Springer
9df63b2651 [mlir][Transforms] Add 1:N matchAndRewrite overload (#116470)
This commit adds a new `matchAndRewrite` overload to `ConversionPattern`
to support 1:N replacements. This is the first of two main PRs that
merge the 1:1 and 1:N dialect conversion drivers.

The existing `matchAndRewrite` function supports only 1:1 replacements,
as can be seen from the `ArrayRef<Value>` parameter.
```c++
LogicalResult ConversionPattern::matchAndRewrite(
    Operation *op, ArrayRef<Value> operands /*adaptor values*/,
    ConversionPatternRewriter &rewriter) const;
```

This commit adds a `matchAndRewrite` overload that is called by the
dialect conversion driver. By default, this new overload dispatches to
the original 1:1 `matchAndRewrite` implementation. Existing
`ConversionPattern`s do not need to be changed as long as there are no
1:N type conversions or value replacements.
```c++
LogicalResult ConversionPattern::matchAndRewrite(
    Operation *op, ArrayRef<ValueRange> operands /*adaptor values*/,
    ConversionPatternRewriter &rewriter) const {
  // Note: getOneToOneAdaptorOperands produces a fatal error if at least one
  // ValueRange has 0 or more than 1 value.
  return matchAndRewrite(op, getOneToOneAdaptorOperands(operands), rewriter);
}
```

The `ConversionValueMapping`, which keeps track of value replacements
and materializations, still does not support 1:N replacements. We still
rely on argument materializations to convert N replacement values back
into a single value. The `ConversionValueMapping` will be generalized to
1:N mappings in the second main PR.

Before handing the adaptor values to a `ConversionPattern`, all argument
materializations are "unpacked". The `ConversionPattern` receives N
replacement values and does not see any argument materializations. This
implementation strategy allows us to use the 1:N infrastructure/API in
`ConversionPattern`s even though some functionality is still missing in
the driver. This strategy was chosen to keep the sizes of the PRs
smaller and to make it easier for downstream users to adapt to API
changes.

This commit also updates the the "decompose call graphs" transformation
and the "sparse tensor codegen" transformation to use the new 1:N
`ConversionPattern` API.

Note for LLVM conversion: If you are using a type converter with 1:N
type conversion rules or if your patterns are performing 1:N
replacements (via `replaceOpWithMultiple` or
`applySignatureConversion`), conversion pattern applications will start
failing (fatal LLVM error) with this error message: `pattern 'name' does
not support 1:N conversion`. The name of the failing pattern is shown in
the error message. These patterns must be updated to the new 1:N
`matchAndRewrite` API.
2024-11-30 09:27:47 +09:00
Matthias Springer
204234a69c [mlir][SparseTensor][NFC] Pass tensor type to descriptor helper (#116468)
`getDescriptorFromTensorTuple` and `getMutDescriptorFromTensorTuple`
extract the tensor type from an `unrealized_conversion_cast` op that
serves as a workaround for missing 1:N dialect conversion support.

This commit changes these functions so that they explicitly receive the
tensor type as a function argument. This is in preparation of merging
the 1:1 and 1:N conversion drivers. The conversion patterns in this file
will soon start receiving multiple SSA values (`ValueRange`) from their
adaptors (instead of a single value that is the result of
`unrealized_conversion_cast`). It will no longer be possible to take the
tensor type from the `unrealized_conversion_cast` op. The
`unrealized_conversion_cast` workaround will disappear entirely.
2024-11-19 09:27:51 +09:00
Matthias Springer
aed4356252 [mlir][Transforms] Dialect Conversion: Add replaceOpWithMultiple (#115816)
This commit adds a new function
`ConversionPatternRewriter::replaceOpWithMultiple`. This function is
similar to `replaceOp`, but it accepts multiple `ValueRange`
replacements, one per op result.

Note: This function is not an overload of `replaceOp` because of
ambiguous overload resolution that would make the API difficult to use.

This commit aligns "block signature conversions" with "op replacements":
both support 1:N replacements now. Due to incomplete 1:N support in the
dialect conversion driver, an argument materialization is inserted when
an SSA value is replaced with multiple values; same as block signature
conversions already work around the problem. These argument
materializations are going to be removed in a subsequent commit that
adds full 1:N support. The purpose of this PR is to add missing features
gradually in small increments.

This commit also updates two MLIR transformations that have their custom
workarounds around missing 1:N support. These can already start using
`replaceOpWithMultiple`.

Co-authored-by: Markus Böck <markus.boeck02@gmail.com>
2024-11-14 10:27:58 +09:00
Manupa Karunaratne
a6e72f9392 [MLIR][Vector] Add Lowering for vector.step (#113655)
Currently, the lowering for vector.step lives
under a folder. This is not ideal if we want
to do transformation on it and defer the
 materizaliztion of the constants much later.

This commits adds a rewrite pattern that
could be used by using
`transform.structured.vectorize_children_and_apply_patterns`
transform dialect operation.

Moreover, the rewriter of vector.step is also
now used in -convert-vector-to-llvm pass where
it handles scalable and non-scalable types as
LLVM expects it.

As a consequence of removing the vector.step
lowering as its folder, linalg vectorization
will keep vector.step intact.
2024-11-01 16:38:36 +00:00
Matthias Springer
f18c3e4e73 [mlir][Transforms] Dialect Conversion: Simplify materialization fn result type (#113031)
This commit simplifies the result type of materialization functions.

Previously: `std::optional<Value>`
Now: `Value`

The previous implementation allowed 3 possible return values:
- Non-null value: The materialization function produced a valid
materialization.
- `std::nullopt`: The materialization function failed, but another
materialization can be attempted.
- `Value()`: The materialization failed and so should the dialect
conversion. (Previously: Dialect conversion can roll back.)

This commit removes the last variant. It is not particularly useful
because the dialect conversion will fail anyway if all other
materialization functions produced `std::nullopt`.

Furthermore, in contrast to type conversions, at least one
materialization callback is expected to succeed. In case of a failing
type conversion, the current dialect conversion can roll back and try a
different pattern. This also used to be the case for materializations,
but that functionality was removed with #107109: failed materializations
can no longer trigger a rollback. (They can just make the entire dialect
conversion fail without rollback.) With this in mind, it is even less
useful to have an additional error state for materialization functions.

This commit is in preparation of merging the 1:1 and 1:N type
converters. Target materializations will have to return multiple values
instead of a single one. With this commit, we can keep the API simple:
`SmallVector<Value>` instead of `std::optional<SmallVector<Value>>`.

Note for LLVM integration: All 1:1 materializations should return
`Value` instead of `std::optional<Value>`. Instead of `std::nullopt`
return `Value()`.
2024-10-23 07:29:17 -07:00
Matthias Springer
206fad0e21 [mlir][NFC] Mark type converter in populate... functions as const (#111250)
This commit marks the type converter in `populate...` functions as
`const`. This is useful for debugging.

Patterns already take a `const` type converter. However, some
`populate...` functions do not only add new patterns, but also add
additional type conversion rules. That makes it difficult to find the
place where a type conversion was added in the code base. With this
change, all `populate...` functions that only populate pattern now have
a `const` type converter. Programmers can then conclude from the
function signature that these functions do not register any new type
conversion rules.

Also some minor cleanups around the 1:N dialect conversion
infrastructure, which did not always pass the type converter as a
`const` object internally.
2024-10-05 21:32:40 +02:00
Matthias Springer
49df12c01e [mlir][NFC] Minor cleanup around ModuleOp usage (#110498)
Use `moduleOp.getBody()` instead of `moduleOp.getBodyRegion().front()`.
2024-09-30 21:20:48 +02:00
Longsheng Mou
129ade21bd [mlir][sparse] Replace getSparseTensorType with tryGetSparseTensorType (#109435)
This PR fixes a bug in `SparseTensorDimOpRewriter` when `tensor.dim` has
an unranked tensor type. To prevent crashes, we now use
`tryGetSparseTensorType` instead of `getSparseTensorType`. Fixes
#107807.
2024-09-30 09:16:55 +08:00
Aart Bik
0e34dbb4f4 [mlir][sparse] fix bug with all-dense assembler (#108615)
When only all-dense "sparse" tensors occur in a function prototype, the
assembler would skip the method conversion purely based on input/output
counts. It should rewrite based on the presence of any annotation,
however.
2024-09-13 17:24:48 -07:00
Yinying Li
8f0c014b12 [mlir][sparse] add parallelization options to mini pipeline (#104233) 2024-08-30 17:47:37 -04:00
Christopher Bate
8bf69ceb00 Reapply "[mlir] NFC: fix dependence of (Tensor|Linalg|MemRef|Complex) dialects on LLVM Dialect and LLVM Core in CMake build (#104832)" (#105703)
Reapply the commit 43b5085667 with
additional fixes for building with
BUILD_SHARED_LIBS=ON.
2024-08-28 22:34:14 -06:00
Peiming Liu
b48ef8d8d4 [mlir][sparse] unify block arguments order between iterate/coiterate operations. (#105567) 2024-08-23 14:49:00 -07:00
Peiming Liu
7186704204 [mlir][sparse] refactoring sparse_tensor.iterate lowering pattern implementation. (#105566) 2024-08-23 11:21:44 -07:00
Peiming Liu
f607102a0d [mlir][sparse] partially support lowering sparse coiteration loops to scf.while/for. (#105565) 2024-08-23 10:47:44 -07:00
Peiming Liu
c44202574f [mlir][sparse] support sparsification to coiterate operations. (#102546) 2024-08-20 11:13:38 -07:00
Kazu Hirata
5262865aac [mlir] Construct SmallVector with ArrayRef (NFC) (#101896) 2024-08-04 11:43:05 -07:00
Peiming Liu
785a24f156 [mlir][sparse] introduce sparse_tensor.coiterate operation. (#101100)
This PR introduces `sparse_tensor.coiterate` operation, which represents
a loop that traverses multiple sparse iteration space.
2024-07-31 15:14:27 -07:00
Peiming Liu
951a363097 [mlir][sparse] implement sparse_tensor.extract_value operation. (#101220) 2024-07-31 14:47:29 -07:00
Cullen Rhodes
074414fdbd [mlir][sparse] Use vector.step for index vector generation (#97692) 2024-07-08 08:29:49 +01:00
Peiming Liu
1ba2768c63 [mlir][sparse] expose emit strategy option to mini pipeline (#96238) 2024-06-20 14:23:36 -07:00
Peiming Liu
a02010b3e9 [mlir][sparse] support sparsifying sparse kernels to sparse-iterator-based loop (#95858) 2024-06-17 16:50:12 -07:00
Peiming Liu
d6cc35f7f6 Reapply "[mlir][sparse] implement lowering rules for IterateOp." (#95836) 2024-06-17 13:29:53 -07:00
Shivam Gupta
bba5951b6f [MLIR] Fix an assert that contains a mistake in conditional operator (#95668)
This is described in (N2) https://pvs-studio.com/en/blog/posts/cpp/1126/
so caught by the PVS Studio analyzer.

Warning message -
V502 Perhaps the '?:' operator works in a different way than it was
expected. The '?:' operator has a lower priority than the '+' operator.
LoopEmitter.cpp 983
V502 Perhaps the '?:' operator works in a different way than it was
expected. The '?:' operator has a lower priority than the '+' operator.
LoopEmitter.cpp 1039

The assert should be
assert(bArgs.size() == reduc.size() + (needsUniv ? 1 : 0));
since + has higher precedence and ? has lower.

This further can be reduce to
assert(aArgs.size() == reduc.size() + needsUniv);
because needUniv is a bool value which is implicitly converted to 0 or
2024-06-18 01:09:30 +05:30
Peiming Liu
996905d815 Revert "[mlir][sparse] implement lowering rules for IterateOp." (#95826)
Reverts llvm/llvm-project#95286
2024-06-17 11:35:23 -07:00
Peiming Liu
3a2e442893 [mlir][sparse] implement lowering rules for IterateOp. (#95286) 2024-06-17 10:45:50 -07:00
Peiming Liu
c42bbda425 [mlir][sparse] implement lowering rules for ExtractIterSpaceOp. (#89143)
**DO NOT MERGE** until https://github.com/llvm/llvm-project/pull/89003
2024-06-12 10:49:12 -07:00
Aart Bik
438a7d4c98 [mlir][sparse] expose optimization flags to mini pipeline (#95158)
Some of the options only fed into the full sparse pipeline. However,
some backends prefer to use the sparse minipipeline. This change exposes
some important optimization flags to the pass as well. This prepares
some SIMDization of PyTorch sparsified code.
2024-06-11 14:20:58 -07:00
Peiming Liu
c6d85baf9f [mlir][sparse] implement sparse space collapse pass. (#89003) 2024-06-11 12:10:54 -07:00
Kazu Hirata
197c3a3efc Use llvm::less_first (NFC) (#94136) 2024-06-02 07:45:50 -07:00
Peiming Liu
99835922ca [mlir][sparse] remove sparse encoding propagation pass. (#93593) 2024-05-28 11:23:15 -07:00
Peiming Liu
fb8f492a1c [mlir][sparse] clone a empty sparse tensor when fuse convert into pro… (#92158)
…ducer.
2024-05-14 13:26:49 -07:00
Peiming Liu
ad1083dce4 [mlir][sparse] introduce new pass to propagate sparse encodings. (#92052) 2024-05-13 17:29:01 -07:00
Yinying Li
eb177803bf [mlir][sparse] Change sparse_tensor.print format (#91528)
1. Remove the trailing comma for the last element of memref and add
closing parenthesis.
2. Change integration tests to use the new format.
2024-05-09 12:09:40 -04:00
Aart Bik
c4e5a8a4d3 [mlir][sparse] support 'batch' dimensions in sparse_tensor.print (#91411) 2024-05-07 19:01:36 -07:00
Aart Bik
5c5116556f [mlir][sparse] force a properly sized view on pos/crd/val under codegen (#91288)
Codegen "vectors" for pos/crd/val use the capacity as memref size, not
the actual used size. Although the sparsifier itself always uses just
the defined pos/crd/val parts, printing these and passing them back to a
runtime environment could benefit from wrapping the basic pos/crd/val
getters into a proper memref view that sets the right size.
2024-05-07 09:20:56 -07:00
Yinying Li
e71eacc5b1 [mlir][sparse] Support explicit/implicit value for complex type (#90771) 2024-05-02 12:28:34 -04:00
Peiming Liu
78885395c8 [mlir][sparse] support tensor.pad on CSR tensors (#90687) 2024-05-01 15:37:38 -07:00
Peiming Liu
dbe376651a [mlir][sparse] handle padding on sparse levels. (#90527) 2024-04-30 09:53:44 -07:00
Gaurav Shukla
97069a8619 [MLIR] Generalize expand_shape to take shape as explicit input (#90040)
This patch generalizes tensor.expand_shape and memref.expand_shape to
consume the output shape as a list of SSA values. This enables us to
implement generic reshape operations with dynamic shapes using
collapse_shape/expand_shape pairs.

The output_shape input to expand_shape follows the static/dynamic
representation that's also used in `tensor.extract_slice`.

Differential Revision: https://reviews.llvm.org/D140821

---------

Signed-off-by: Gaurav Shukla<gaurav.shukla@amd.com>
Signed-off-by: Gaurav Shukla <gaurav.shukla@amd.com>
Co-authored-by: Ramiro Leal-Cavazos <ramiroleal050@gmail.com>
2024-04-30 09:28:35 -07:00
Aart Bik
65ee8f10b2 [mlir][sparse] fold explicit value during sparsification (#90530)
This ensures the explicit value is generated (and not a load into the
values array). Note that actually not storing values array at all is
still TBD, this is just the very first step.
2024-04-29 18:06:07 -07:00
Peiming Liu
7e2eeb5753 [mlir][sparse] use ValueRange instead of std::pair for iterator position. (#90243)
`ValueRange` is more easy to be extended (e.g., for padded iterator).
2024-04-29 10:47:07 -07:00
Peiming Liu
3aeb28b93f [mlir][sparse] fold sparse convert into producer linalg op. (#89999) 2024-04-26 10:48:15 -07:00
Troy Butler
468fecfc39 Fix mismatches between function parameter definitions and declarations (#89512)
Addresses issue #88716.

Some function parameter names in the affected header files did not match
the parameter names in the definitions, or were listed in a different
order.

---------

Signed-off-by: Troy-Butler <squintik@outlook.com>
2024-04-26 13:00:31 +02:00
Peiming Liu
ea3eeb483f [mlir][sparse] fuse concat and extract_slice op if possible. (#89825) 2024-04-24 13:51:41 -07:00
Mehdi Amini
8c0341df02 Revert "[MLIR] Generalize expand_shape to take shape as explicit input" (#89540)
Reverts llvm/llvm-project#69267

this broke some bots.
2024-04-21 14:33:48 +02:00
Gaurav Shukla
e095d978ba [MLIR] Generalize expand_shape to take shape as explicit input (#69267)
This patch generalizes tensor.expand_shape and memref.expand_shape to
consume the output shape as a list of SSA values. This enables us to
implement generic reshape operations with dynamic shapes using
collapse_shape/expand_shape pairs.

The output_shape input to expand_shape follows the static/dynamic
representation that's also used in `tensor.extract_slice`.

Differential Revision: https://reviews.llvm.org/D140821

Co-authored-by: Ramiro Leal-Cavazos <ramiroleal050@gmail.com>
2024-04-21 07:37:02 -04:00
Christian Sigg
a5757c5b65 Switch member calls to isa/dyn_cast/cast/... to free function calls. (#89356)
This change cleans up call sites. Next step is to mark the member
functions deprecated.

See https://mlir.llvm.org/deprecation and
https://discourse.llvm.org/t/preferred-casting-style-going-forward.
2024-04-19 15:58:27 +02:00
Matthias Springer
9f3334e993 [mlir][SparseTensor] Add missing dependent dialect to pass (#88870)
This commit fixes the following error when stopping the sparse compiler
pipeline after bufferization (e.g., with `test-analysis-only`):

```
LLVM ERROR: Building op `vector.print` but it isn't known in this MLIRContext: the dialect may not be loaded or this operation hasn't been added by the dialect. See also https://mlir.llvm.org/getting_started/Faq/#registered-loaded-dependent-whats-up-with-dialects-management
```
2024-04-17 09:20:55 +02:00
Aart Bik
5122a2c232 [mlir][sparse] allow for direct-out passing of sparse tensor buffers (#88327)
In order to support various external frameworks (JAX vs PyTorch) we need
a bit more flexibility in [dis]assembling external buffers to and from
sparse tensors in MLIR land. This PR adds a direct-out option that
avoids the rigid pre-allocated for copy-out semantics.

Note that over time, we expect the [dis]assemble operations to converge
into something that supports all sorts of external frameworks. Until
then, this option helps in experimenting with different options.
2024-04-11 10:07:24 -07:00
Peiming Liu
a454d92c5a [mlir][sparse] rename files and unifies APIs (#88162) 2024-04-09 10:59:15 -07:00