There are three op conversion modes: Partial, Full, and Analysis. This change modifies the Partial mode to optionally take a set of non-legalizable ops. If this parameter is specified, all ops that are not legalizable (i.e. would cause full conversion to fail) are tracked throughout the partial legalization.
Details
Diff Detail
- Repository
- rG LLVM Github Monorepo
Event Timeline
Took a first pass at this, but I'm open to different ways of approaching this change. At I've written it now, the basic idea of the Analysis conversion is "we're performing a partial conversion and emitting warnings along the way for any ops that would fail to legalize in a full conversion". Success is returned as long as the partial conversion succeeds. I did it this way because returning failure outright means that the partially converted IR doesn't get emitted, which is useful for debugging.
However, an implication of this is that if the legalization did fully succeed, we don't know that based on the Analysis conversion. As a result, I foresee a lot of users running an Analysis conversion immediately followed by a Full conversion, thus incurring an unnecessary pass over the IR. So ideally, this would return success/failure for the full conversion while still outputting the partially converted IR in the failure case.
What do you think?
Before answering, please note that we do not base these decisions based on debugging. What the result is depends on what the user intends to do with the result.
However, an implication of this is that if the legalization did fully succeed, we don't know that based on the Analysis conversion. As a result, I foresee a lot of users running an Analysis conversion immediately followed by a Full conversion, thus incurring an unnecessary pass over the IR. So ideally, this would return success/failure for the full conversion while still outputting the partially converted IR in the failure case.
Seems like the user can easily tell if the conversion was completely successful by checking if the set of unlegalized operations is empty?
What do you think?
We can change analysis conversion to whatever we want, but the main question is what are you doing with the information? What happens after the analysis conversion and what do you want to convey? We may end up with different types of analysis conversions based on the answer to that question. For example, the original envisioning for this was that a user would performs analysis conversions targeting different backends to detail which parts of the subgraph were really supported for a specific target. In that type of mode you don't want to do any conversions, because you want to splice the original graph based on the analysis. It seems that the use case you are targeting is different. For your use case, what is the pipeline that you are envisioning and how does an analysis conversion fit into it?
mlir/lib/Transforms/DialectConversion.cpp | ||
---|---|---|
1575 | I'm not sure we always want warnings here, seems like more of a DEBUG log. If a user is relying on an analysis conversion to help slice code that is supported by different backends, they may not care that certain operations weren't converted. |
mlir/lib/Transforms/DialectConversion.cpp | ||
---|---|---|
1568 | Isn't the mode necessarily Partial/Analysis here? | |
1577 | Isn't this something we'd want to track even in "Partial" mode? It seems like the difference between Partial and Analysis overall is about whether the conversion is performed or not. Anything else should be uniform. | |
1579 | Do we need to warn here? |
[Note: I haven't made code changes in this iteration because I want to settle on an approach before refactoring this. For the same reason I'm leaving some comments unresolved for now.]
Good point, don't know why I didn't think of this :)
What do you think?
We can change analysis conversion to whatever we want, but the main question is what are you doing with the information? What happens after the analysis conversion and what do you want to convey? We may end up with different types of analysis conversions based on the answer to that question. For example, the original envisioning for this was that a user would performs analysis conversions targeting different backends to detail which parts of the subgraph were really supported for a specific target. In that type of mode you don't want to do any conversions, because you want to splice the original graph based on the analysis. It seems that the use case you are targeting is different. For your use case, what is the pipeline that you are envisioning and how does an analysis conversion fit into it?
Thanks for raising these points; this helps me better understand the current design of the analysis conversion mode.
My use case (for the TF XLA bridge) is the following: we want to perform a full conversion and for the result to be fully legalized (in that sense, the same as full legalization today). However, in the case that it fails, we want to (a) know all of the ops that failed to legalize and (b) have a partially legalized graph output. I suppose in that sense, this conversion mode I'm envisioning would act like full legalization in the success case but like partial legalization in the failure case.
After considering the comments here, I see a couple of possibilities (both of which would involve leaving the existing Analysis conversion mode as it is today):
(1) Modify the partial conversion mode to take an (optional?) unlegalizedOps set as input and populate it with all ops that fail to legalize.
-In our use case, this would mean always using the Partial conversion mode, and if what we really want is a Full conversion, checking whether that set of ops is empty. That's totally fine from the TF XLA perspective, but is that a level of indirection that ought to be in Core?
-Cons: API instability if the unlegalizedOps set is not optional.
(2) Add a new (2nd type of analysis) conversion mode that aligns with this use case.
I lean toward option (1), but I want to solicit some more thoughts before making the code change.
mlir/lib/Transforms/DialectConversion.cpp | ||
---|---|---|
1577 |
I think this is a good idea and aligns with option (1) I describe in the larger comment on this reply.
This is true with Analysis mode as it is today, but this patch (in its current state) makes it such that both Partial and Analysis mode perform the conversion. The key difference is whether or not the unlegalizable ops are collected in that set.
This is the difference between Analysis and Full. Presently, Partial doesn't accumulate the unlegalizableOps, either. |
I lean toward option (1), but I want to solicit some more thoughts before making the code change.
(1) seems like a fine option to add.
Modify Partial conversion mode (instead of Analysis mode) to take an optional parameter to store non-legalizable ops.
mlir/include/mlir/Transforms/DialectConversion.h | ||
---|---|---|
669 ↗ | (On Diff #261123) | Just a nit, but I believe that if you use backticks ` to refer to arguments then doxygen link these. |
clang-format suggested style edits found: