-
Notifications
You must be signed in to change notification settings - Fork 15.5k
Remove Pure attribute from Linalg::IndexOp. #68894
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
base: main
Are you sure you want to change the base?
Conversation
|
@llvm/pr-subscribers-mlir-linalg @llvm/pr-subscribers-mlir Author: None (erick-xanadu) ChangesCloses #62644 Full diff: https://github.com/llvm/llvm-project/pull/68894.diff 1 Files Affected:
diff --git a/mlir/include/mlir/Dialect/Linalg/IR/LinalgOps.td b/mlir/include/mlir/Dialect/Linalg/IR/LinalgOps.td
index da12e7c83b22b89..41d2487dd6f1479 100644
--- a/mlir/include/mlir/Dialect/Linalg/IR/LinalgOps.td
+++ b/mlir/include/mlir/Dialect/Linalg/IR/LinalgOps.td
@@ -46,7 +46,7 @@ def Linalg_YieldOp : Linalg_Op<"yield", [Pure, ReturnLike, Terminator]>,
let hasVerifier = 1;
}
-def Linalg_IndexOp : Linalg_Op<"index", [Pure]>,
+def Linalg_IndexOp : Linalg_Op<"index", []>,
Arguments<(ins ConfinedAttr<I64Attr, [IntMinValue<0>]>:$dim)>,
Results<(outs Index:$result)> {
let summary = "linalg index operation";
|
|
I don't think this is a good change. I looked at the issue and I think having linalg ops within other linalg ops is not currently supported |
MaheshRavishankar
left a comment
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.
Index ops need to be pure
|
@MaheshRavishankar ok, I'll close this then. |
|
How can linalg.index be pure? It does not take operand but returns a different value each time right? |
|
Pinging @nicolasvasilache as well! |
|
New week ping here, @MaheshRavishankar @nicolasvasilache ? |
Well, Pure is meant to allow CSE within the body of |
I understand this is a transformation you'd like to enable, but that's not a semantics rationale!!
That seems like a totally orthogonal discussion to me... (also to think about whether that composes, with inlining and other transformations)
I don't quite get this... How can an operation that produces different values without any input/operand possibly match the definition of "Pure"? |
Well maybe some context might help. At some point there used to be I am not tied to it being |
|
Seems like a load to me, but we don't want to prove that the value is constant during the region execution. All-in-all it does not change much to the problem: we shouldn't "lie" to the system about semantics just to enable generic transformations! |
Why is it a load. It resolves to induction variable value when the linalg op is lowered to loops.
Well, it has no side-effects. So not sure it is a lie. |
Because I don't see another way for the generic to pass the indices index op other than via some private variable.
Sorry but we're working on a compiler, you don't have a magic wand to escape reality :) |
That seems a bit of a convoluted reasoning. Might be making things unnecessarily complicated....
We also dont want a compiler to attach unnecessarily pessimizing semantics to something as simple as an induction variable. Thats where compilers (and presumably compiler writers) make their own life difficult. |
I don't see anything simpler that would still be sound actually. You can replace "stack alloc" by "private register file" or any conceptual abstract storage space you'd like, but I don't quite see how you can avoid the communication of the information, because it actually exists!! This is just what the ops do here...
There is no "pessimizing" semantics here: I can't see any other simpler semantics actually... |
The only real alternative is to add basic block arguments to all |
umm since this is before my time (and I'm too lazy to dig through logs...) did this
I vaguely remember there being some debate on discord about whether |
|
@makslevental I don't think we want @joker-eph 's suggestion makes sense to me -- model these operations as "reading" from some location that the Sending the indices in as a basic block argument seems cleanest of all if that's a viable path. |
|
I thought about the "read": but it's a read from a special resource, and one that is constant during the execution of the particular region. This is likely important to model this to be able to keep existing transformation working, but I don't think we have the expressiveness for describing this just now? |
|
@joker-eph I was thinking that maybe we could model |
So I'll reiterate/repeat my question: did Edit: answering my own question after searching around: no |
|
@sanjoy technically that would be enough, but that wouldn't make the transformation "local": that is you'd still need to traverse the body between two uses of |
Just answering the meta point here. It is obviously more expressive to have operations that are not orthonormal iteration spaces, but that needs to be evaluated in conjunction with complexity of transformations (like tiling and vectorization) to account for increased expressivity. (There is no free lunch). So Nicolas, I think, has been working (definitely has an extensive rfc on it) to allow reasoning about more general iteration spaces (even allowing completely irregular iteration spaces). I don't know the state of this. |
+1 to "constant within a region instance". That seems to capture exactly what is needed here. |
Yes I linked the rfc above. Nicolas and I were planning on filling it out earlier this year. I got started, made a little progress in iree-sandbox but unfortunately other things have taken higher priority. |
|
@joker-eph @MaheshRavishankar "constant within a region instance" (as opposed to "constant within a block") makes sense to me. Ideally we'd be able to express that |
Yup. Also there shouldn't be nested linalg.generics anyway. They aren't explicitly illegal today cause it could be a way of expressing programs, but it's not the "preferred way" afaik. So there are two issues here
|
Correction: I used inlining and a function call that uses linalg operations was inlined inside a linalg op. What is the limitation of linalg and why can't linalg be nested? This seems a bit of an arbitrary restriction but I don't have all the context, so I am happy to learn more about this. |
Having an operation of that granularity is also not the preferred path.
Its about how it composes with transformations. For example such a nested operation does not vectorize with |
|
If we want to decide that nested linalg.generic are illegal, then we have to forbid any "call" from within the body of a linalg.generic operation. Or alternatively you need to tame the inliner to not inline a function that contains a linalg.generic op inside another one (but that does not seem right to me: inlining or not the op is still nested). So: transformations on linalg.generic must be safe, and if they can't process nested linalg.generic they should check and bail (but it's not clear to me why they would be bothered by a nested linalg.generic and not by a call...). |
@MaheshRavishankar, when you are saying "having an operation of that granularity" you mean "having a call operation"? You are saying that having a call inside linalg is also not preferred?
Can you confirm that what you are also saying here is that lowering a nested linalg operations via I ask because we have been using |
Basically I am saying having tensor operations within the body of linalg operations does not seem necessary. It is not to say it is invalid. IIUC having such an operation in the body of a linalg op means that the computation is represented as tensor of tensors. In other words this is an alternative representation of tiled computation, instead of using loops and tiled linalg operations in the body. The latter is what is generated with linalg tiling transformations. The tensor of tensors representation might have some compositionality issues as well. For example if you have a
Well, that's great to know! Might have been fixed since the last time I saw this cause I wouldn't have expected it to work based on how the lowering to loops used to work. |
|
Hi, I am pinging this since CSE was brought up again internally. It looks like there are several different things discussed here:
So, no change there?
Happy to work on this, but I just would like a little bit more direction before starting to avoid working and having my work not being used at all. Thanks! |
|
Just bumping the discussion here since it's been a while. In my opinion attaching the pure attribute to a non-pure op is still posing an issue 🤔 |
|
I don't see why If someone can summarize/maybe start a discourse post we can get convergence there instead of a PR |
We had this discussion a few years ago, everything is already explained above in this issue!! In the current design of linalg.index there must be a side effect: a pure operation always return value computed from its arguments (i.e. a constant when there is no argument). To model the transfer of information from the enclosing linalg.generic to the linalg.index operation, you need a "channel" so either:
There is no other option within the design of MLIR today, I floated above that we could explore a different kind of model by introducing a concept of "region instance" to make the effect "local" there, but that requires some very careful design work. In the meantime: linag.index in its current form must have a side-effect. |
I agree with all your points, but making the op not pure is not the right solution. It is a pessimizing solution cause it is adding a side-effect that does not exist (at least that is not what the ops intent is). I agree this op is ill-defined because of the reasons you mentioned. As far as I can see
|
What I was describing was a change to the side effect mechanism instead to be able to model an effect that is not "escaping" from the region. Not something mechanical blocking CSE or anything (which would be a workaround for a transformation, not actually fixing the model).
Seems to match my second bullet "There is a SSA value carrying this state...", so LGTM. |
Closes #62644