-
Notifications
You must be signed in to change notification settings - Fork 14.3k
[MLIR][Tensor] Remove tensor.dim canonicalization patterns registered on tensor.expand_shape/tensor.collapse_shape #134219
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
dad4284
532a053
835a35c
3defa99
df091ce
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -1105,15 +1105,13 @@ func.func @compose_expand_of_collapse_last_two_dims(%arg0: tensor<?x64x1xf32>) - | |
%expanded = tensor.expand_shape %collapsed [[0, 1]] output_shape [%div, 384] : tensor<?xf32> into tensor<?x384xf32> | ||
return %expanded : tensor<?x384xf32> | ||
} | ||
// CHECK: #[[$MAP:.*]] = affine_map<()[s0] -> (s0 * 64)> | ||
// CHECK-LABEL: @compose_expand_of_collapse_last_two_dims | ||
// CHECK-SAME: %[[ARG0:.+]]: tensor<?x64x1xf32> | ||
// CHECK: %[[CONSTANT0:.+]] = arith.constant 0 : index | ||
// CHECK: %[[CONSTANT384:.+]] = arith.constant 384 : index | ||
// CHECK: %[[CONSTANT0:.+]] = arith.constant 0 : index | ||
// CHECK: %[[COLLAPSE:.+]] = tensor.collapse_shape %[[ARG0]] {{\[}}[0, 1, 2]] : tensor<?x64x1xf32> into tensor<?xf32> | ||
// CHECK: %[[DIM:.+]] = tensor.dim %[[ARG0]], %[[CONSTANT0]] : tensor<?x64x1xf32> | ||
// CHECK: %[[AFFAPPLY:.+]] = affine.apply #[[$MAP]]()[%[[DIM]]] | ||
// CHECK: %[[DIVUI:.+]] = arith.divui %[[AFFAPPLY]], %[[CONSTANT384]] : index | ||
// CHECK: %[[DIM:.+]] = tensor.dim %[[COLLAPSE]], %[[CONSTANT0]] : tensor<?xf32> | ||
// CHECK: %[[DIVUI:.+]] = arith.divui %[[DIM]], %[[CONSTANT384]] : index | ||
// CHECK: %[[RESULT:.+]] = tensor.expand_shape %[[COLLAPSE]] {{\[}}[0, 1]] output_shape [%[[DIVUI]], 384] : tensor<?xf32> into tensor<?x384xf32> | ||
// CHECK: return %[[RESULT]] | ||
|
||
|
@@ -2137,13 +2135,12 @@ func.func @empty_tensor_canonicalize(%i : index) { | |
|
||
// ----- | ||
|
||
// CHECK: #[[$map:.*]] = affine_map<()[s0] -> (s0 floordiv 40)> | ||
// CHECK-LABEL: func @dim_of_expand_shape( | ||
// CHECK-SAME: %[[t:.*]]: tensor<?x?xf32> | ||
// CHECK: %[[c1:.*]] = arith.constant 1 : index | ||
// CHECK: %[[dim:.*]] = tensor.dim %[[t]], %[[c1]] : tensor<?x?xf32> | ||
// CHECK: %[[apply:.*]] = affine.apply #[[$map]]()[%[[dim]]] | ||
// CHECK: return %[[apply]] | ||
// CHECK: %[[c2:.*]] = arith.constant 2 : index | ||
// CHECK: %[[expanded:.*]] = tensor.expand_shape %[[t]] {{\[\[}}0], [1, 2, 3, 4, 5]] output_shape [%arg1, 1, %arg2, 5, 1, 8] : tensor<?x?xf32> into tensor<?x1x?x5x1x8xf32> | ||
// CHECK: %[[dim:.*]] = tensor.dim %[[expanded]], %[[c2]] : tensor<?x1x?x5x1x8xf32> | ||
// CHECK: return %[[dim]] | ||
Comment on lines
-2140
to
+2143
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @joker-eph For an example of the old pattern being wrong, notice that we already know the output shape. The result should just be %arg2 here! But it's instead it was doing some magic with affine.apply, which is wrong. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We could implement a folder for this for tensor.dim, but that doesn't change the fact that this pattern is wrong, and doesn't even belong as a canonicalization to expand_shape. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We could implement a folder for this for tensor.dim, but that doesn't change the fact that this pattern is wrong, and doesn't even belong as a canonicalization to expand_shape. |
||
func.func @dim_of_expand_shape(%t: tensor<?x?xf32>, %sz0: index, %sz1: index) -> index { | ||
%c2 = arith.constant 2 : index | ||
%0 = tensor.expand_shape %t [[0], [1, 2, 3, 4, 5]] output_shape [%sz0, 1, %sz1, 5, 1, 8] | ||
|
@@ -2154,17 +2151,12 @@ func.func @dim_of_expand_shape(%t: tensor<?x?xf32>, %sz0: index, %sz1: index) -> | |
|
||
// ----- | ||
|
||
// CHECK: #[[$map:.*]] = affine_map<()[s0, s1, s2] -> (((s0 * s1) * s2) * 7)> | ||
// CHECK-LABEL: func @dim_of_collapse_shape( | ||
// CHECK-SAME: %[[t:.*]]: tensor<?x?x?x7x?xf32> | ||
// CHECK-DAG: %[[c1:.*]] = arith.constant 1 : index | ||
// CHECK-DAG: %[[c2:.*]] = arith.constant 2 : index | ||
// CHECK-DAG: %[[c4:.*]] = arith.constant 4 : index | ||
// CHECK-DAG: %[[dim1:.*]] = tensor.dim %[[t]], %[[c1]] | ||
// CHECK-DAG: %[[dim2:.*]] = tensor.dim %[[t]], %[[c2]] | ||
// CHECK-DAG: %[[dim4:.*]] = tensor.dim %[[t]], %[[c4]] | ||
// CHECK: %[[apply:.*]] = affine.apply #[[$map]]()[%[[dim1]], %[[dim2]], %[[dim4]]] | ||
// CHECK: return %[[apply]] | ||
// CHECK-DAG: %[[collapsed:.*]] = tensor.collapse_shape %[[t]] {{\[\[}}0], [1, 2, 3, 4]] : tensor<?x?x?x7x?xf32> into tensor<?x?xf32> | ||
// CHECK-DAG: %[[dim:.*]] = tensor.dim %[[collapsed]], %[[c1]] | ||
// CHECK: return %[[dim]] | ||
func.func @dim_of_collapse_shape(%t: tensor<?x?x?x7x?xf32>) -> index { | ||
%c1 = arith.constant 1 : index | ||
%0 = tensor.collapse_shape %t [[0], [1, 2, 3, 4]] | ||
vivekkhandelwal1 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@joker-eph For an example of non-local effects, the previous canonicalization pattern for collapse_shape, was not moving collapse_shape to a more canonical form. It's actually not touching the collapse_shape at all, and is doing things around it.
It's very hard to say what the canonical form of where tensor.dim should be here is. There is no reason for the tensor.dim, when propagated up to be more canonical. It can possibly introduce 2 tensor.dim operations, if there were 2 dynamic dimensions before the collapse shape. If there is a cost to a tensor.dim operation, you now pay the cost twice. We cannot really say if one form is more canonical than the other.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In this current example, simplified we have:
If I want to know something about the dim, it's just the first dimension of the collapsed_shape and I have now to reason about it.
After canonicalization we have:
The dimension computation is made pretty explicit in terms of the input (the calculation is explicit) and the tensor.collapse_shape even disappears.
It's not always obvious what the "best" canonical form should be, that does not mean we can't pick one though: often it resolves just about picking one convention and sticking to it to be consistent (I don't know if this is the right convention here, just saying).
Here is the example you describe I believe:
Becomes:
As mentioned elsewhere, the cost of "dim" does not seem meaningful to me here. The question is rather about whether this IR is more amenable to reasoning on the values, or equivalence between values in further analysis. Any argument long this line of reasoning can be very valuable to make a statement about whether it is clearly belonging / not belonging to canonicalization.