This is an archive of the discontinued LLVM Phabricator instance.

[mlir] Implement one-to-n structural conversion for ForOp
ClosedPublic

Authored by sabauma on Jul 2 2023, 6:33 AM.

Details

Summary

Add the missing one-to-n structural type conversion pattern for the
scf.for operation.

Diff Detail

Event Timeline

sabauma created this revision.Jul 2 2023, 6:33 AM
Herald added a project: Restricted Project. · View Herald TranscriptJul 2 2023, 6:33 AM
sabauma retitled this revision from [mlir] Implement one-to-n structural conversion for ForOp to [mlir][scf] Implement one-to-n structural conversion for ForOp.
sabauma updated this revision to Diff 536591.Jul 2 2023, 7:35 AM
sabauma retitled this revision from [mlir][scf] Implement one-to-n structural conversion for ForOp to [mlir] Implement one-to-n structural conversion for ForOp.

Code cleanup and commenting

sabauma published this revision for review.Jul 2 2023, 7:41 AM
Herald added a project: Restricted Project. · View Herald TranscriptJul 2 2023, 7:41 AM
sabauma updated this revision to Diff 536598.Jul 2 2023, 8:24 AM

Delete implicitly created body block

sabauma updated this revision to Diff 536604.Jul 2 2023, 9:16 AM

Fix issue where operations created after the signature conversion were generated
inside the loop body rather than after the loop.

Thanks a lot for this addition! Looks good modulo the minor comments.

The build failure seems unrelated. I guess rebasing should make them pass.

mlir/lib/Dialect/SCF/Transforms/OneToNTypeConversion.cpp
158

Nit: I'd prefer if the comment used the full line length and did not have a line break in between the two sentences.

188

I think that this guard (and the scope around it) isn't necessary.

208

Nit: Please order alphabetically.

ingomueller-net accepted this revision.Jul 4 2023, 7:19 AM
This revision is now accepted and ready to land.Jul 4 2023, 7:19 AM
sabauma updated this revision to Diff 537128.Jul 4 2023, 10:42 AM
sabauma marked 2 inline comments as done.

Address comments from @ingomueller-net

sabauma added inline comments.Jul 4 2023, 10:45 AM
mlir/lib/Dialect/SCF/Transforms/OneToNTypeConversion.cpp
188

With the current implementation of applySignatureConversion, the guard is necessary since the rewriter is always left focused on the block that the signature conversion was applied to. That will results in unrealized_conversion_casts being generated in the loop body for the loop outputs when the rewriter.replaceOp is called.

It is not clear to me that is the most desirable behavior of applySignatureConversion, but I opted not to change it, as it is difficult to tell who might be depending on that particular behavior.

ingomueller-net added inline comments.Jul 5 2023, 1:35 AM
mlir/lib/Dialect/SCF/Transforms/OneToNTypeConversion.cpp
188

I can't reproduce this: I have removed guard on my machine and the tests still pass. (Also, I don't see any unrealized cast if I run the pass outside of lit.)

sabauma added inline comments.Jul 5 2023, 5:44 AM
mlir/lib/Dialect/SCF/Transforms/OneToNTypeConversion.cpp
188

Is it possible you did not have the @for_tuple_ops test? I added it later after discovering this specific issue. When I remove the insertion guard, that test fails for me with the following IR (note the pair of make_tuple ops after the scf.yield):

"func.func"() <{function_type = (i1) -> i1, sym_name = "for_tuple_ops"}> ({
  ^bb0(%arg0: i1):
    %0 = "arith.constant"() <{value = 0 : index}> : () -> index
    %1 = "arith.constant"() <{value = 1 : index}> : () -> index
    %2 = "arith.constant"() <{value = 10 : index}> : () -> index
    %3 = "scf.for"(%0, %2, %1, %arg0) ({
    ^bb0(%arg1: index, %arg2: i1):
      %7 = "test.make_tuple"() : () -> tuple<>
      %8 = "test.make_tuple"(%7, %arg2) : (tuple<>, i1) -> tuple<tuple<>, i1>
      %9 = "test.op"(%8) : (tuple<tuple<>, i1>) -> tuple<tuple<>, i1>
      %10 = "test.get_tuple_element"(%9) <{index = 0 : i32}> : (tuple<tuple<>, i1>) -> tuple<>
      %11 = "test.get_tuple_element"(%9) <{index = 1 : i32}> : (tuple<tuple<>, i1>) -> i1
      "scf.yield"(%11) : (i1) -> ()
      %12 = "test.make_tuple"() : () -> tuple<>
      %13 = "test.make_tuple"(%12, %3) : (tuple<>, i1) -> tuple<tuple<>, i1>
    }) : (index, index, index, i1) -> i1
    %4 = "test.op"(%13) : (tuple<tuple<>, i1>) -> tuple<tuple<>, i1>
    %5 = "test.get_tuple_element"(%4) <{index = 0 : i32}> : (tuple<tuple<>, i1>) -> tuple<>
    %6 = "test.get_tuple_element"(%4) <{index = 1 : i32}> : (tuple<tuple<>, i1>) -> i1
    "func.return"(%6) : (i1) -> ()
  }) : () -> ()
}

Those tuple operations should be placed after the for loop, rather than in the loop body.

sabauma marked 2 inline comments as done.Jul 6 2023, 6:35 AM
ingomueller-net added inline comments.Jul 6 2023, 7:18 AM
mlir/lib/Dialect/SCF/Transforms/OneToNTypeConversion.cpp
188

I just double-checked: the test is there in my version -- and it does not fail without the guard.

This isn't a huge deal, I guess. I am rather trying to reproduce the error in order to know how to improve the API. This behavior isn't expected and I guess I'd prefer for it not to require the guard in the usual case. (But for that, a test case were it doesn't behave that way would be helpful.)

sabauma added inline comments.Jul 6 2023, 8:29 AM
mlir/lib/Dialect/SCF/Transforms/OneToNTypeConversion.cpp
188

I agree that the guard is a bit ugly, though I'm now more concerned about the seeming non-determinism between systems.

I'll try uploading a patch with the guard removed and see if the pre-merge testing experiences the same issue I'm seeing.

sabauma updated this revision to Diff 537744.Jul 6 2023, 8:34 AM

test removing insertion guard

sabauma marked an inline comment as done.Jul 6 2023, 8:58 AM
sabauma added inline comments.
mlir/lib/Dialect/SCF/Transforms/OneToNTypeConversion.cpp
188

I'm able to reproduce this issue on the pre-merge testing machines as well:

https://buildkite.com/llvm-project/premerge-checks/builds/162767#01892bd8-a62f-42f2-9e20-9fd10789e81e

sabauma updated this revision to Diff 537759.Jul 6 2023, 9:02 AM

Re-add the InsertionGuard

mlir/lib/Dialect/SCF/Transforms/OneToNTypeConversion.cpp
188

Thanks a lot for helping me investigate and for your patience! I was finally able to reproduce the behavior you observed (I think my build set-up was broken and I ran the wrong version) and to submit a fix: https://reviews.llvm.org/D154684.

ingomueller-net added inline comments.Jul 7 2023, 2:19 AM
mlir/lib/Dialect/SCF/Transforms/OneToNTypeConversion.cpp
188

The fix has landed, so rebasing should make the insertion guard here unnecessary. Thanks for raising the issue and bearing with me!

sabauma updated this revision to Diff 538097.Jul 7 2023, 5:15 AM

Remove InsertionGuard now that https://reviews.llvm.org/D154684 has landed

ingomueller-net accepted this revision.Jul 7 2023, 6:39 AM

@ingomueller-net Would you be able to submit the change. I do not have commit access.

This revision was automatically updated to reflect the committed changes.

Sure, done! Thanks again!