Commit Graph

227 Commits

Author SHA1 Message Date
Alexander Belyaev
f6fb0a4f35 [mlir] Make patterns for folding tensor.empty optional.
At the moment, they are a part of EmptyOp::getCanonicalizationPatterns. When
extract_slice(tensor.empty) is rewritten as a new tensor.empty, it could
happen that we end up with two tensor.empty ops, since the original
tensor.empty can have two users. After bufferization such cases result in two
allocations.

Differential Revision: https://reviews.llvm.org/D139308
2022-12-07 23:01:34 +01:00
Matthias Springer
9cdf6b641d [mlir][tensor] Support parallel_insert_slice in reassociative reshape folder
Differential Revision: https://reviews.llvm.org/D139540
2022-12-07 16:25:10 +01:00
Lorenzo Chelini
87ecf9d155 [MLIR][Tensor] Add custom builder for unpack op
Reviewed By: hanchung

Differential Revision: https://reviews.llvm.org/D139344
2022-12-07 12:40:45 +01:00
Hanhan Wang
0f297cad4d [mlir][tensor][linalg] Introduce DataLayoutPropagation pass.
It introduces a pattern that swaps `linalg.generic + tensor.pack` to
`tensor.pack + linalg.generic`. It requires all the iteration types
being parallel; the indexing map of output operand is identiy. They can
all be relaxed in the future.

The user can decide whether the propagation should be applied or not by
passing a control function.

Reviewed By: mravishankar

Differential Revision: https://reviews.llvm.org/D138882
2022-12-06 15:00:07 -08:00
Hanhan Wang
193cefd1b1 [mlir][tensor] Adapt FoldTensorCastProducerOp pattern on DPS interface.
This revision adapts the pattern in LinAlg to work on DPS interface, and
adds it to canonicalization patterns of tensor dialect. The
InsertSliceOp is skipped in the pattern because it has its own logic
about folding tensor.cast ops.

Reviewed By: pifon2a

Differential Revision: https://reviews.llvm.org/D139375
2022-12-06 12:13:37 -08:00
Hanhan Wang
0d03ba62c5 [mlir][tensor] Implement TilingInterface for tensor.pack op.
We can compute the offsets and sizes for the slice of input because the
iteration domain is defined over outer loops. If the dimension is tiled,
the i-th index is the product of offset_i and inner_tile_i.

Different from tiling a pad op, we do not have to deal with reading zero
data from input. Because the tiling sizes are indicated to packed outer
dimensions. We will read either the entire tile or partial tile for each
packed tile. The scf.if and tensor.generate ops are not needed in this
context.

Co-authored-by: Lorenzo Chelini <l.chelini@icloud.com>

Reviewed By: rengolin, mravishankar

Differential Revision: https://reviews.llvm.org/D138631
2022-12-05 14:00:10 -08:00
Adrian Kuegel
94d3df2015 [mlir][Tensor] Apply ClangTidy performance finding (NFC) 2022-12-05 11:22:20 +01:00
Matthias Springer
1403073790 [mlir][tensor] Fold rank-reducing insert_slice with inverse collapse_shape
Differential Revision: https://reviews.llvm.org/D139221
2022-12-05 09:17:29 +01:00
Matthias Springer
50a2bb95ab [mlir][tensor] Fold rank-reducing extract_slice with inverse expand_shape
Differential Revision: https://reviews.llvm.org/D139220
2022-12-05 09:17:24 +01:00
Kazu Hirata
1a36588ec6 [mlir] Use std::nullopt instead of None (NFC)
This patch mechanically replaces None with std::nullopt where the
compiler would warn if None were deprecated.  The intent is to reduce
the amount of manual work required in migrating from Optional to
std::optional.

This is part of an effort to migrate from llvm::Optional to
std::optional:

https://discourse.llvm.org/t/deprecating-llvm-optional-x-hasvalue-getvalue-getvalueor/63716
2022-12-03 18:50:27 -08:00
Matthias Springer
f92c7506e3 Revert "[mlir][tensor] Fold rank-reducing extract_slice with inverse expand_shape"
This reverts commit a076f57a1a.
2022-12-02 21:22:20 +01:00
Matthias Springer
c837a94754 Revert "[mlir][tensor] Fold rank-reducing insert_slice with inverse collapse_shape"
This reverts commit 1522a3b7b3.
2022-12-02 21:22:04 +01:00
Matthias Springer
1522a3b7b3 [mlir][tensor] Fold rank-reducing insert_slice with inverse collapse_shape
Differential Revision: https://reviews.llvm.org/D139104
2022-12-02 10:42:52 +01:00
Matthias Springer
a076f57a1a [mlir][tensor] Fold rank-reducing extract_slice with inverse expand_shape
Differential Revision: https://reviews.llvm.org/D139103
2022-12-02 10:42:46 +01:00
Lorenzo Chelini
44f7356005 [MLIR][Tensor] Add canonicalization for UnpackOp
pack(unpack(x)) -> x

Reviewed By: hanchung

Differential Revision: https://reviews.llvm.org/D138917
2022-12-01 15:17:50 +01:00
Hanhan Wang
a971d51932 [mlir][tensor] Enhance the verifier of pack and unpack op.
The outer_dims_perm must be a permutation or empty.

Reviewed By: chelini

Differential Revision: https://reviews.llvm.org/D138936
2022-11-29 15:47:52 -08:00
Hanhan Wang
e86169f090 [mlir][tensor] Add a custom builder for pack op.
The `paddingValue` and `outerDimsPerm` are optional to the op;
`innerTiles` can be variadic in terms of static sizes and dynamic sizes.
Add a custom builder for building pack op easier.

Reviewed By: mravishankar

Differential Revision: https://reviews.llvm.org/D138860
2022-11-28 15:18:42 -08:00
Matthias Springer
13593dc9dc [mlir][tensor][bufferize] Fix tensor.insert_slice regression
This reverts D132662 (apart from overall cleanups), which introduced a too aggressive optimization for tensor.insert_slice bufferization. Instead, bufferizesToMemoryRead is improved to handle some of these cases. The remaining cases can still bufferize efficiently when running the canonicalizer before the bufferization.

Differential Revision: https://reviews.llvm.org/D138745
2022-11-26 19:14:33 +01:00
Lorenzo Chelini
a9733b8a5e [MLIR] Adopt DenseI64ArrayAttr in tensor, memref and linalg transform
This commit is a first step toward removing inconsistencies between dynamic
and static attributes (i64 v. index) by dropping `I64ArrayAttr` and
using `DenseI64ArrayAttr` in Tensor, Memref and Linalg Transform ops.
In Linalg Transform ops only `TileToScfForOp` and `TileOp` have been updated.

See related discussion: https://discourse.llvm.org/t/rfc-inconsistency-between-dynamic-and-static-attributes-i64-v-index/66612/1

Reviewed By: nicolasvasilache

Differential Revision: https://reviews.llvm.org/D138567
2022-11-25 09:43:30 +01:00
Matthias Springer
f2d91a7ae1 [mlir][utils] Fix invalid reshapes in ComposeCollapseOfExpandOp
Do not generate CollapseShapeOps/ExpandShapeOps that have the same source and result shape. Generate casts instead. Such reshapes became invalid with D138498.

Differential Revision: https://reviews.llvm.org/D138557
2022-11-23 13:52:00 +01:00
Matthias Springer
b9745ad812 [mlir][tensor/memref] Disallow Collapse/ExpandShapeOps that do not reduce/increase the rank
CollapseShapeOp/ExpandShapeOp that do not change the rank (or increase/reduce it) are invalid.

Differential Revision: https://reviews.llvm.org/D138498
2022-11-23 09:19:35 +01:00
Matthias Springer
6052b17aab [mlir][tensor] Add dim(expand_shape/collapse_shape) folding
Differential Revision: https://reviews.llvm.org/D138487
2022-11-22 17:34:49 +01:00
Lorenzo Chelini
85e38e5292 [MLIR][Tensor] Use the existing helper function applyPermutationToVector (NFC)
Avoid duplicate code by using an existing helper function to interchange
a vector based on a permutation. Address comments emerged after landing
D138119.

Reviewed By: nicolasvasilache

Differential Revision: https://reviews.llvm.org/D138480
2022-11-22 11:34:44 +01:00
Lorenzo Chelini
9aa505a28d Introduce tensor.pack and tensor.unpack operations
Pack and Unpack return new tensors within which the individual elements
are reshuffled according to the packing specification. This has the
consequence of modifying the canonical order in which a given operator
(i.e., Matmul) accesses the individual elements. After bufferization,
this typically translates to increased access locality and cache
behavior improvement, e.g., eliminating cache line splitting.

Co-authored-by: Mahesh Ravishankar <ravishankarm@google.com>
Co-authored-by: Han-Chung Wang <hanchung@google.com>

RFC: https://discourse.llvm.org/t/rfc-tensor-pack-and-tensor-unpack/66408/1

Reviewed By: nicolasvasilache, rengolin, hanchung

Differential Revision: https://reviews.llvm.org/D138119
2022-11-22 09:11:59 +01:00
Lei Zhang
9bb633741a [mlir][bufferization] Support general Attribute as memory space
MemRef has been accepting a general Attribute as memory space for
a long time. This commits updates bufferization side to catch up,
which allows downstream users to plugin customized symbolic memory
space. This also eliminates quite a few `getMemorySpaceAsInt`
calls, which is deprecated.

Reviewed By: springerm

Differential Revision: https://reviews.llvm.org/D138330
2022-11-21 09:40:50 -05:00
Aliia Khasanova
399638f98c Merge kDynamicSize and kDynamicSentinel into one constant.
resolve conflicts

Differential Revision: https://reviews.llvm.org/D138282
2022-11-21 13:01:26 +00:00
Mahesh Ravishankar
24f9293de8 [mlir][Tensor] Allow builders of tensor.empty to accept encoding attribute.
The `RankedTensorType` can have an optional encoding
attribute. Allowing the builders of `tensor.empty` to accept the
encoding attribute (optionally), allows building empty tensors with
the type having the encoding attribute.

Reviewed By: nicolasvasilache, hanchung, springerm

Differential Revision: https://reviews.llvm.org/D137297
2022-11-03 20:30:12 +00:00
Matthias Springer
09dfb44193 [mlir][tensor][bufferize] Support memory_space for tensor.pad
This change adds memory space support to tensor.pad. (tensor.generate and tensor.from_elements do not support memory spaces yet.)

The memory space is inferred from the buffer of the source tensor.

Instead of lowering tensor.pad to tensor.generate + tensor.insert_slice, it is now lowered to bufferization.alloc_tensor (with the correct memory space) + linalg.map + tensor.insert_slice.

Memory space support for the remaining two tensor ops is left for a later point, as this requires some more design discussions.

Differential Revision: https://reviews.llvm.org/D136265
2022-10-27 12:29:57 +02:00
Matthias Springer
c1f0a15c65 [mlir][tensor][bufferize] Lower tensor.generate to linalg.map
There is no memref equivalent of tensor.generate. The purpose of this change is to avoid creating scf.parallel loops during bufferization.

Differential Revision: https://reviews.llvm.org/D136767
2022-10-27 12:03:13 +02:00
Matthias Springer
2d5edc644d [mlir][bufferize] Provide default BufferizableOpInterface impl for destination style ops
tensor.insert and tensor.insert_slice (as destination style ops) do no longer need to implement the entire BufferizableOpInterface.

Differential Revision: https://reviews.llvm.org/D136347
2022-10-27 10:52:47 +02:00
Matthias Springer
cfaf3292df [mlir][tensor] Disallow unranked tensors for tensor.extract/insert
When writing a tensor.extract/tensor.insert, the rank of the tensor is implied by the number of specified indices. When extracting from/inserting into an unranked tensor, it should first be casted to a ranked version.

Differential Revision: https://reviews.llvm.org/D136756
2022-10-27 10:09:31 +02:00
Mahesh Ravishankar
188b041bf5 [mlir][Tensor] Change createDimValues to return a list of OpFoldResults.
Reviewed By: nicolasvasilache, hanchung, ThomasRaoux

Differential Revision: https://reviews.llvm.org/D136733
2022-10-27 03:13:56 +00:00
Mahesh Ravishankar
94b8469a88 [mlir][Tensor] Add a helper build method for pad operations with constant padding.
Drop the `createPadScalarOp` from Utils.h since it is a duplicate of
the `build` method added here.

Differential Revision: https://reviews.llvm.org/D136493
2022-10-24 18:11:53 +00:00
Matthias Springer
b169643f3a [mlir][interfaces] Remove getDestinationOperands from TilingInterface
`getDestinationOperands` was almost a duplicate of `DestinationStyleOpInterface::getOutputOperands`. Now that the interface has been moved to mlir/Interfaces, it is no longer needed.

Differential Revision: https://reviews.llvm.org/D136240
2022-10-24 09:26:19 +02:00
Christopher Bate
446981bdb6 [mlir][tensor] ExtractSliceFromReshape: handle collapsing of unit dim edge cases
Prior to this change, the "ExtractSliceFromReshape" pattern would transform

```
%collapsed = tensor.collapse_shape %input [[0, 1], [2]]
                : tensor<1x11x100xf32> into tensor<11x100xf32>
%slice = tensor.extract_slice %collapsed [%offt, 0] [%size, 100] [1, 1]
                : tensor<11x100xf32> to tensor<?x100xf32>
```

into a loop that iterated over the range `%size - %offt`, that pieces
together multiple sub-slices of `%input` along the first dimension. This
is correct but obviously inefficient. The technical condition is that
collapsing at-most-one non-unit dimension of `%src` will not result in a
subsequent slice along the corresponding dimension of `%collapsed`
mapping across discontinuities in the index space of `%src`. Thus, the
definition of a "linearized dimension" (from the perspective of
`tensor.collapse_shape`) is updated to reflect this condition.

The transform will now generate

```
%slice = tensor.extract_slice %input [0, %offt, 0][1, %size, 100] [1, 1]
            : tensor<1x11x100xf32> to tensor<1x?x100xf32>
%result = tensor.collapse_shape [[0, 1], [2]]
            : tensor<1x?x100xf32> to tensor<?x100xf32>
```

which can be further canonicalized.

Additional tests are added to check this family of edge cases.

Reviewed By: ThomasRaoux

Differential Revision: https://reviews.llvm.org/D135726
2022-10-22 13:29:34 -06:00
Lorenzo Chelini
9bcac22be5 [MLIR][Tensor] Remove assert in PadOp builder
The assert is misplaced as the result type is allowed to be null. A few
lines below the result type is inferred if it is passed a nullptr.
Besides, this behavior is described in the documentation of the builder.

Reviewed By: ftynse

Differential Revision: https://reviews.llvm.org/D136262
2022-10-19 18:02:50 +02:00
Sanjoy Das
adabce4118 Correctly model undefined behavior in {tensor|memref}.dim
These operations have undefined behavior if the index is not less than the rank of the source tensor / memref, so they cannot be freely speculated like they were before this patch.  After this patch we speculate them only if we can prove that they don't have UB.

Depends on D135505.

Reviewed By: mravishankar

Differential Revision: https://reviews.llvm.org/D135748
2022-10-12 17:30:13 -07:00
Matthias Springer
6cdd34b973 [mlir][tensor][bufferize] Bufferize inserts into equivalent tensors in-place
Inserting a tensor into an equivalent tensor is a no-op after bufferization. No alloc is needed.

Differential Revision: https://reviews.llvm.org/D132662
2022-10-06 15:06:33 +09:00
Nicolas Vasilache
54a4e9685d [mlir][Tensor] NFC - Add result pretty printing to TensorOps
Differential Revision: https://reviews.llvm.org/D135135
2022-10-04 09:16:51 -07:00
Matthias Springer
81ca5aa452 [mlir][tensor][NFC] Rename linalg.init_tensor to tensor.empty
tensor.empty/linalg.init_tensor produces an uninititalized tensor that can be used as a destination operand for destination-style ops (ops that implement `DestinationStyleOpInterface`).

This change makes it possible to implement `TilingInterface` for non-destination-style ops without depending on the Linalg dialect.

RFC: https://discourse.llvm.org/t/rfc-add-tensor-from-shape-operation/65101

Differential Revision: https://reviews.llvm.org/D135129
2022-10-04 17:25:35 +09:00
Matthias Springer
598f5275c1 [mlir][interfaces] Add ShapedDimOpInterface
This interface is implemented by memref.dim and tensor.dim. This change makes it possible to remove a build dependency of the Affine dialect on the Tensor dialect (and maybe also the MemRef dialect in the future).

Differential Revision: https://reviews.llvm.org/D133595
2022-10-03 13:58:52 +09:00
Jakub Kuderski
abc362a107 [mlir][arith] Change dialect name from Arithmetic to Arith
Suggested by @lattner in https://discourse.llvm.org/t/rfc-define-precise-arith-semantics/65507/22.

Tested with:
`ninja check-mlir check-mlir-integration check-mlir-mlir-spirv-cpu-runner check-mlir-mlir-vulkan-runner check-mlir-examples`

and `bazel build --config=generic_clang @llvm-project//mlir:all`.

Reviewed By: lattner, Mogball, rriddle, jpienaar, mehdi_amini

Differential Revision: https://reviews.llvm.org/D134762
2022-09-29 11:23:28 -04:00
Lorenzo Chelini
4db3a649ea [MLIR] Expose getAsValues in StaticValueUtils.h (NFC) [reland]
The utility function should live in `StaticValueUtils.h` as it provides
a convenient way to convert a vector of OpFoldResults into a vector of
Values.

Reviewed By: nicolasvasilache, cota

Differential Revision: https://reviews.llvm.org/D134451
2022-09-27 11:18:25 -04:00
Lorenzo Chelini
59080febfc Revert "[MLIR] Expose getAsValues in StaticValueUtils.h (NFC)"
It introduces a circular build dependence: DialectUtils <-
ArithmeticUtils <- ArithDialect <- DialectUtils

This reverts commit 27224fe727.
2022-09-26 22:11:40 +02:00
Lorenzo Chelini
27224fe727 [MLIR] Expose getAsValues in StaticValueUtils.h (NFC)
The utility function should live in `StaticValueUtils.h` as it provides
a convenient way to convert a vector of OpFoldResults into a vector of
Values.

Reviewed By: nicolasvasilache

Differential Revision: https://reviews.llvm.org/D134451
2022-09-26 18:09:27 +02:00
Oleg Shyshkov
4f1c124251 [mlir] Add IteratorType enum to StructuredOpsUtils.
Summary:
Use the new enum in TilingIterface and verify that `iterator_type` attribute in
LinalgOp interface is compatible with the enum values. Later IteratorType enum
will be used in LinalgInterface to replace the current `iterator_type` attribute
array of string.

Existing enums in Linalg are moved into a separate td file and tablegen build
target. This is necessary, have one I32EnumAttr in a shared space that generated
enum class definition and EnumAttrs is dialect-specific location. Otherwise
there might be a conflict that I32EnumAttr generates enum definitions in
multiple places.

Differential Revision: https://reviews.llvm.org/D134634
2022-09-26 11:09:46 +00:00
Lorenzo Chelini
941d122370 Revert "[MLIR] Expose getAsValues in StaticValueUtils.h (NFC)"
This reverts commit 730ae80d3e.

It fails with a linking errors: `undefined reference to
`mlir::getValueOrCreateConstantIndexOp` in `libMLIRDialectUtils`.
2022-09-26 10:01:23 +02:00
Lorenzo Chelini
730ae80d3e [MLIR] Expose getAsValues in StaticValueUtils.h (NFC)
The utility function should live in `StaticValueUtils.h` as it provides
a convenient way to convert a vector of OpFoldResults into a vector of
Values.

Reviewed By: nicolasvasilache

Differential Revision: https://reviews.llvm.org/D134451
2022-09-26 09:37:03 +02:00
Lei Zhang
465ec4e0b4 [mlir] NFC: move mergeOffsetsSizesAndStrides into Affine/Utils
So that these utility functions can also be used ViewLikeInterface
ops not in the memref dialect.

Reviewed By: mravishankar, christopherbate

Differential Revision: https://reviews.llvm.org/D134487
2022-09-23 13:28:11 -04:00
Lei Zhang
bd81524e7f Reland "[mlir][tensor] Support more cases in MergeConsecutiveExtractSlice"
This relands commit 5d4603a02d.
It cludes fixes to GCC test failures and simplification to
the implementation.

Co-authored-by: Mahesh Ravishankar <ravishankarm@google.com>
Co-authored-by: Christopher Bate <cbate@nvidia.com>
2022-09-22 17:28:50 -04:00