This is an archive of the discontinued LLVM Phabricator instance.

Update static bound checker for Linalg to cover decreasing cases
ClosedPublic

Authored by inho9606 on Apr 22 2021, 12:49 AM.

Details

Summary

The current static checker for linalg does not work on the decreasing index cases well. So, this is to Update the current static bound checker for linalg to cover decreasing index cases.

Diff Detail

Event Timeline

inho9606 created this revision.Apr 22 2021, 12:49 AM
inho9606 requested review of this revision.Apr 22 2021, 12:49 AM

canyou please add some tests?

hanchung requested changes to this revision.Apr 22 2021, 2:46 AM

Thanks for adding this!

Please add some tests to invalid.mlir

mlir/lib/Dialect/Linalg/IR/LinalgInterfaces.cpp
472–473

We don't have to declare startLoopRangeValues above. Instead we can declare it here. E.g.,

SmallVector<int64_t, 4> startLoopRangeValues((*endLoopRangeValues).size(), 0);
492

I think we don't need to check if shapedDimSize > 0. It won't be dynamic dim because you already check it above.

493–501

Do we really need mapStr here? Can't we use indexingMaps[en.index()] directly?

508–521

How about having a inferredDimSize = std::max(firstIndex, lastIndex) + 1, so we can simplify the check. In this case, we don't have to check two times for the last part.

This revision now requires changes to proceed.Apr 22 2021, 2:46 AM
inho9606 added inline comments.Apr 22 2021, 11:30 PM
mlir/lib/Dialect/Linalg/IR/LinalgInterfaces.cpp
472–473

Oh, I remember it caused a linking error when I tried this first, but it works now.. I think I did something wrong. Thanks

492

Yes, but there is a testcase using shapes like memref<0xf32>.. If the size is 0, then the index should be -1 which would be always an error by this condition.

#accesses = [

affine_map<(i) -> (i)>

]

#trait = {

indexing_maps = #accesses,
iterator_types = ["parallel"]

}

func @dce_zero_memref(%arg0 : memref<0xf32>, %arg1: tensor<0xf32>) -> tensor<0xf32> {

// memref<0x32> is expected to be dce'ed
linalg.copy(%arg0, %arg0): memref<0xf32>, memref<0xf32>

// tensor<0xf32> cannot be dce'ed
%1 = linalg.generic #trait outs(%arg1 : tensor<0xf32>) {
^bb(%0: f32) :
  linalg.yield %0 : f32
} -> tensor<0xf32>

return %1: tensor<0xf32>

}

493–501

I couldn't find the way to use indexingMaps[en.index()] directly in the message.. I think it should be something convertable to string for the message. But the indexingMap is affineMap, so I thought I would need a method to convert it, but couldn't find.. Could you help me?

508–521

You are right. Thanks for reminding me max method..

  1. Updating D101026: Update static bound checker for Linalg to cover decreasing cases #
  2. Enter a brief description of the changes included in this update.
  3. The first line is used as subject, next lines as comment.

Reflected the comments and added invalid test cases.

hanchung requested changes to this revision.Apr 23 2021, 12:11 AM

I think you accidentally delete some invalid tests, could you add them back?

mlir/lib/Dialect/Linalg/IR/LinalgInterfaces.cpp
475–477

Let's rename them as startIndices and endIndices

492

I see. Seems to be corner case. It will be killed, though. Let's skip the check for this directly, we don't have to make it work with below logic.

493–501

I thought it is streamable and you could pass it to emitError directly. Does this work?

linalgOp.emitError("unexpected result less than 0 at expression #")
                 << j << " in affineMap\n" << indexingMaps[en.index()];
mlir/test/Dialect/Linalg/invalid.mlir
740–744

Can we use a simpler test case? This looks like an matmul with weird accessing. Let's create a reverse op test case?

This revision now requires changes to proceed.Apr 23 2021, 12:11 AM
inho9606 added inline comments.Apr 23 2021, 2:56 AM
mlir/lib/Dialect/Linalg/IR/LinalgInterfaces.cpp
492

Okay, then I'll ignore the case that dimsize is 0.

493–501

No it does not work,, it causes no match error..
error: no match for 'operator<<' (operand types are 'mlir::Diagnostic' and 'mlir::AffineMap')..

mlir/test/Dialect/Linalg/invalid.mlir
740–744

Okay sounds better! I'll update it next Monday.

  1. Updating D101026: Update static bound checker for Linalg to cover decreasing cases #
  2. Enter a brief description of the changes included in this update.
  3. The first line is used as subject, next lines as comment.

Renamed variables, fixed the logic for dimsize 0, and fixed an invalid testcase.

hanchung accepted this revision.Apr 25 2021, 11:13 PM
hanchung added inline comments.
mlir/lib/Dialect/Linalg/IR/LinalgInterfaces.cpp
491–507

I think we can move this above the if-statement because you declare it right after use it.

491–508

I see, thanks for trying this out.

I think we can delete "affineMap\n". Having a new line is a bit weird to me, and you did not check the affine map in the test.

518

update the message? We should remove "or equal to"?

This revision is now accepted and ready to land.Apr 25 2021, 11:13 PM
inho9606 added a comment.EditedApr 26 2021, 7:48 PM

Uh, I think I found a case that this solution can't check, which does not have its maximum and minimum indices with the start and end indices. For example, if the affine_map is <(d0, d1) -> (d1 - d0)> and the ranges of d0 and d1 are 0 and 1, then this expression has
0 when d0 is 0 and d1 is 0,
1 when d0 is 0 and d1 is 1,
-1 when d0 is 1 and d1 is 0,
0 when d0 is 1 and d1 is 1.
I wanted to share this case.. And I think we should substitude
the maximum values for negative dims, and the minimum values for positive dims in order to get the real minimum indices. For the maximum indices, we need the minimum values for negative dims, and the maximum values for positive dims..

mlir/lib/Dialect/Linalg/IR/LinalgInterfaces.cpp
491–507

You are right, I missed the point. Thanks

491–508

Ah I see

518

Hmm, I think we should remain it because:
Let's say A is inferredSize, and B is shapedDimSize. Then,
A > B == B < A if statement (invalid case)
!(B < A) == B >= A
Negation to Make the statement true
Am I correct?

  1. Updating D101026: Update static bound checker for Linalg to cover decreasing cases #
  2. Enter a brief description of the changes included in this update.
  3. The first line is used as subject, next lines as comment.

Moved declaring a variable and updated the error message

hanchung accepted this revision.EditedApr 27 2021, 6:16 AM

Uh, I think I found a case that this solution can't check, which does not have its maximum and minimum indices with the start and end indices. For example, if the affine_map is <(d0, d1) -> (d1 - d0)> and the ranges of d0 and d1 are 0 and 1, then this expression has
0 when d0 is 0 and d1 is 0,
1 when d0 is 0 and d1 is 1,
-1 when d0 is 1 and d1 is 0,
0 when d0 is 1 and d1 is 1.
I wanted to share this case.. And I think we should substitude
the maximum values for negative dims, and the minimum values for positive dims in order to get the real minimum indices. For the maximum indices, we need the minimum values for negative dims, and the maximum values for positive dims..

I never see this kind of statement before, and I highly suspect that this will be the case. For now, let's treat it as invalid. We can revert it if this is really the case in the future.

mlir/lib/Dialect/Linalg/IR/LinalgInterfaces.cpp
518

Yes, you're right. Sorry for the bad review comment.

There are conflicts, could you rebase and fix it?

There are conflicts, could you rebase and fix it?

Ah, I can't see the conflicts in my repository.. Rebase was successfully done. Could you tell me what files have conflicts?
Thanks

There are conflicts, could you rebase and fix it?

Ah, I can't see the conflicts in my repository.. Rebase was successfully done. Could you tell me what files have conflicts?
Thanks

I can not patch this, and the bot can not do it either. If you rebase successfully, you can update the patch. arc will ask you to provide some description and update the patch I think.

  1. Updating D101026: Update static bound checker for Linalg to cover decreasing cases #
  2. Enter a brief description of the changes included in this update.
  3. The first line is used as subject, next lines as comment.

Rebased for merge?

There are conflicts, could you rebase and fix it?

Ah, I can't see the conflicts in my repository.. Rebase was successfully done. Could you tell me what files have conflicts?
Thanks

I can not patch this, and the bot can not do it either. If you rebase successfully, you can update the patch. arc will ask you to provide some description and update the patch I think.

I updated the patch with arc,, could you please check if it works again? Interesting..

Uh, I think I found a case that this solution can't check, which does not have its maximum and minimum indices with the start and end indices. For example, if the affine_map is <(d0, d1) -> (d1 - d0)> and the ranges of d0 and d1 are 0 and 1, then this expression has
0 when d0 is 0 and d1 is 0,
1 when d0 is 0 and d1 is 1,
-1 when d0 is 1 and d1 is 0,
0 when d0 is 1 and d1 is 1.
I wanted to share this case.. And I think we should substitude
the maximum values for negative dims, and the minimum values for positive dims in order to get the real minimum indices. For the maximum indices, we need the minimum values for negative dims, and the maximum values for positive dims..

I never see this kind of statement before, and I highly suspect that this will be the case. For now, let's treat it as invalid. We can revert it if this is really the case in the future.

I think I can make the checker cover this interesting case as well using affineExpr to get maximum and minimum values. I'd like to try to push it more to make it as perfect as possible. Can I try to fix it more..?

Hey Inho, the bot still could not apply the patch. The diff details show that it's failed. And I can't patch it locally either.

Could you try to run arc patch D1010260 on main branch?

And you will see

This diff is against commit a2c783f910b6034118f3d18dcd1519e9ff74f43f, but
    the commit is nowhere in the working copy. Try to apply it against the
    current working copy state? (a67a377014ceaaed55b2ba2259e080bc3fc42b43 \
    D101610)

I think I can make the checker cover this interesting case as well using affineExpr to get maximum and minimum values. I'd like to try to push it more to make it as perfect as possible. Can I try to fix it more..?

It's a rare case. If you'd like to push it more, I'd suggest to create another patch for it.

  1. Updating D101026: Update static bound checker for Linalg to cover decreasing cases #
  2. Enter a brief description of the changes included in this update.
  3. The first line is used as subject, next lines as comment

#i
Try to fix the apply issue

hanchung closed this revision.May 12 2021, 11:15 AM