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
[MLIR][XLA] Remove redundant LHLO CopyOp #36335
[MLIR][XLA] Remove redundant LHLO CopyOp #36335
Conversation
6f34210
to
f62aff3
Compare
@dfki-ehna can you please include test cases around the new changes ? |
tensorflow/compiler/mlir/xla/transforms/hlo_legalize_to_lhlo.cc
Outdated
Show resolved
Hide resolved
tensorflow/compiler/mlir/xla/transforms/hlo_legalize_to_lhlo.cc
Outdated
Show resolved
Hide resolved
tensorflow/compiler/mlir/xla/transforms/hlo_legalize_to_lhlo.cc
Outdated
Show resolved
Hide resolved
f62aff3
to
522b296
Compare
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.
Thanks!
@pifon2a can you please merge this change internally. |
beed553
to
aa2d06d
Compare
PiperOrigin-RevId: 294433205 Change-Id: I32e9bb27f9cdd49158938f05d4e676506fc30dac
} | ||
auto allocOp = operand.getDefiningOp(); | ||
if (auto deallocOp = | ||
mlir::dyn_cast<mlir::DeallocOp>(*allocOp->getUsers().begin())) { |
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.
(transmitting @joker-eph): You are dereferencing the user of the allocOp while you already deleted the copyOp, which mean there might be no user left.
Here is a minimal reproducer that will show it:
func @Fusion(%arg0: memref<2x2xf32>) -> memref<2x2xf32> {
%0 = alloc() {temp = true} : memref<2x2xf32>
"xla_lhlo.copy"(%0, %arg0) : (memref<2x2xf32>, memref<2x2xf32>) -> ()
return %0 : memref<2x2xf32>
}
This comes back to my other point about testing: with dedicated testing for this pass, I would have expected this IR to be the first basic test to validate the pass.
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.
Thanks for the hint. You are right that this code snippet would break our current version. Although this code could exist from a theoretical point of view as an input program, the current implementation of the HLO-to-LHLO-Legalization
pass ensures that there will always be a dealloc. Furthermore, it is even worse: currently, the Std.Return-to-LHLO
converter expects a final dealloc operation to place a proper CopyOp
. The following code snippet is taken from the hlo_legalize_to_lhlo.cc
file (starting in line 425):
if (dealloc == nullptr) {
returnOp.emitOpError()
<< "Missing dealloc for operand " << operand.index();
return matchFailure();
}
This code snippet also fails in the following tiny test case:
func @TestFunc(%arg0: tensor<2xf32>) -> tensor<2xf32> {
return %arg0 : tensor<2xf32>
}
We have addressed all the comments in the new PR. |
(GitHub does not let me answer inline apparently)
I think this hits a principle of development for MLIR passes: the only invariant you can assume on your input is that the verifier is passing. It isn't allowed to crash on random vali input, we should be able to fuzz your pass safely (you can gracefully signal a pass failure and return though) |
The redundant LHLO CopyOp that copies an allocated buffer to a block argument is removed. The uses of the allocated buffer are replaced with the block argument. The associated Alloc and Dealloc are removed.