-
Notifications
You must be signed in to change notification settings - Fork 14.3k
[mlir][SCF] scf.parallel
: Make reductions part of the terminator
#75314
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][SCF] scf.parallel
: Make reductions part of the terminator
#75314
Conversation
@llvm/pr-subscribers-mlir-spirv @llvm/pr-subscribers-mlir Author: Matthias Springer (matthias-springer) Changes
Full diff: https://github.com/llvm/llvm-project/pull/75314.diff 1 Files Affected:
diff --git a/mlir/include/mlir/Dialect/SCF/IR/SCFOps.td b/mlir/include/mlir/Dialect/SCF/IR/SCFOps.td
index 573e804b405e84..3948f145d50bd6 100644
--- a/mlir/include/mlir/Dialect/SCF/IR/SCFOps.td
+++ b/mlir/include/mlir/Dialect/SCF/IR/SCFOps.td
@@ -853,7 +853,8 @@ def ParallelOp : SCF_Op<"parallel",
// ReduceOp
//===----------------------------------------------------------------------===//
-def ReduceOp : SCF_Op<"reduce", [HasParent<"ParallelOp">]> {
+def ReduceOp : SCF_Op<"reduce", [
+ HasParent<"ParallelOp">, RecursiveMemoryEffects]> {
let summary = "reduce operation for parallel for";
let description = [{
"scf.reduce" is an operation occurring inside "scf.parallel" operations.
|
Based on the failing tests, it looks like this change can cause Motivation for this change: I am changing #75127 such that all ops with unknown memory effects will be rejected by the buffer deallocation pass. |
It's checked in |
Why is this a problem to fold it away? |
|
|
Instead of It could be useful to have such a "belongs to the enclosing op" (not sure what to call it) trait. The |
Ah right I misread and in my head was thinking about the loop construct itself. Any reason the multiple (I don't know if there are other ops like |
+1, yes, I think "belongs to the enclosing op" better conveys the intent, but I don't have a good short name either )
yes, I think this will be a better solution long term but it will be quite a lot of work and probably a lot of churn both upstream and downstream. We probably want trait as interim solution before this happens. (but I'm just a passerby, who is the owner of SCF dialect?) |
Another way to keep these alive is to return a token that is passed to the yield. (I'm not convinced about any "traits" based approach here: this does not seem like a general semantics we're modeling) |
With tokens you will still have to somehow convince |
I think it would be OK to CSE two identical However, this approach would change the op semantics a bit. I believe at the moment the reductions are guaranteed to be performed in the order in which they appear in the loop body. This would no longer be the case. (But I also cannot think of any case in which one would want to depend on a certain order.) (If we go with the token approach, we could also just use |
It does not seems entirely safe to me: we can't structurally guarantee that the use-def chain can be tracked back to the reduce op (think "function outlining" for example).
Is this documented? I'm not sure otherwise where would the guarantee come from?
Seems like the most robust option to me? |
I'm generally +1 to making Does anyone really ready to commit their time to this? |
b27dbc6
to
533b913
Compare
RecursiveMemoryEffects
to scf.reduce
scf.parallel
: Make reductions part of the terminator
You are right, this is not documented anywhere. |
Nice! This also probably requires PSA announcement on discourse forum. |
Looks good to me, but wait for other people opinions. |
533b913
to
8675d3c
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.
I suggest to wait couple more days, and if there weren't any more comments, merge it.
Not against this change. But just a drive-through comment. This might make it difficult for frontends to directly lower to |
That's a good point, but I think this is solvable in frontends, and having a clean semantics on middle level is important. E.g. in our python compiler we support code like this:
We are gradually uplifting |
b928c05
to
c3ebd54
Compare
This commit makes reductions part of the terminator. Instead of `scf.yield`, `scf.reduce` now terminates the body of `scf.parallel` ops. `scf.reduce` may contain an arbitrary number of reductions, with one region per reduction. `scf.reduce` operations can no longer be interleaved with other ops in the body of `scf.parallel`. This simplifies the op and makes it possible to assign the `RecursiveMemoryEffects` trait to `scf.reduce`. (This was not possible before because the op was not a terminator, causing the op to be DCE'd.)
c3ebd54
to
4566abd
Compare
This commit makes reductions part of the terminator. Instead of
scf.yield
,scf.reduce
now terminates the body ofscf.parallel
ops.scf.reduce
may contain an arbitrary number of reductions, with one region per reduction.Example:
scf.reduce
operations can no longer be interleaved with other ops in the body ofscf.parallel
. This simplifies the op and makes it possible to assign theRecursiveMemoryEffects
trait toscf.reduce
. (This was not possible before because the op was not a terminator, causing the op to be DCE'd.)