[Unity] Allow duplicated parameters in the same call arguments in FuseOps#14097
[Unity] Allow duplicated parameters in the same call arguments in FuseOps#14097masahi wants to merge 5 commits intoapache:unityfrom
Conversation
|
Thanks for contributing to TVM! Please refer to the contributing guidelines https://tvm.apache.org/docs/contribute/ for useful information and tips. Please request code reviews from Reviewers by @-ing them in a comment.
Generated by tvm-bot |
db6728d to
46b500c
Compare
46b500c to
0959e57
Compare
| } else { | ||
| const auto* tuple_item = var_binding->value.as<TupleGetItemNode>(); | ||
| ICHECK(tuple_item != nullptr); | ||
| CheckDefAndUpdateParam(tuple_item->tuple); |
There was a problem hiding this comment.
cc @Hzfengsy, I'm not sure what this code path is for. I can pass all tests without this.
There was a problem hiding this comment.
It is used for the TupleGetItem node. I'm surprised that it is not covered by the tests
| // If the expression has already served as an argument, no need to create another one for it. | ||
| if (std::find(arguments_.begin(), arguments_.end(), expr) != arguments_.end()) { | ||
| return; | ||
| } |
There was a problem hiding this comment.
cc @Hzfengsy, I decoupled deduplication check and the actual param update in this function, to allow duplicated expressions in arguments_ and params_. As the comment at L486 says, it is now a responsibility of the caller to do deduplication beforehand if dedup is needed.
See also the discussion in https://github.com/apache/tvm/pull/14097/files#r1116338447
|
Please run the following command to rebase the changes |
cc6e8c3 to
5eb4c85
Compare
Hzfengsy
left a comment
There was a problem hiding this comment.
Thanks @masahi for the PR. I acknowledge that duplicated parameters are useful in some cases (e.g. BYOC). However, it's a bit tricky if we only use tvm codegen, since:
- we lose part of the information at the callee side, which means it would be harder (but still possible) to optimize;
- Duplication may influence code readability.
Here, my question is: can we add a parameter for FuseOps pass to decide if we generate duplicated params? we can turn it off for tvm-codegen and turn on when BYOC
|
I think a question we need to think about is whether we need duplicated args in BYOC cases. There are design tradeoffs here: A1: Keep duplicated args so that the composite function signature is consistent with the pattern ( A2: Allow args being deduplicated. This approach indeed will generate duplicating composite function (with one arg or two args for add) for the codegen. On the other hand, We also find some cases that the composite function doesn’t have args in the consistent argument order as the pattern / or ‘so-called’ anchor op. For example, we may have composite function like: where the arg order of If the order of args in generally not assumed and we need to find such correspondence (anchor op args <-> function args) anyways, then whether the function args are deduplicated probably is less important. |
|
In this case, if we can independently fix the BYOC(so that the pattern and generated func do not depend on ordering and duplication of the argument, that would leads to a more generalized solution which might help to resolve cases like @vinx13 mentioned |
|
In #14128 I created a generalized way (https://github.com/apache/tvm/pull/14128/files#diff-5abe4ef979258cbcc4927f057f939304de762c63c445137ba570689854c8f862R553-R569) to map args of the fused function to named parameters of the offloaded operation (for example, map arg1 -> "lhs", arg0 -> "rhs", arg2 -> "bias" for matmul). This requires each pattern to be accompanied by a map from string to DFPattern, like If we think the order of args and duplication of args is a common concern for all BYOC backends, but not for other use case of FuseOps, we should be able to extract that logic from #14128 and combine with the code in this PR to create a standalone pass for reordering and duplicating args. |
Thanks for the discussion, I think we shouldn't push all responsibilities to codegen and call it "a more general solution". At least for the cases where there is a one-to-one mapping between a composite function and an op, clearly there is one "right" function signature. So each backend shouldn't need to worry about I liked @yelite suggestion of leaving the current op fusion impl as is, and instead adding a standalone pass that would identify such trivial composite functions (the one that merely wraps an op, e.g. |
Currently, when
FuseOpsandFuseOpsByPatternsee a call node whose arguments have duplicated parameters, e.g.they create a grouped function whose signature has parameters deduplicated:
This is fine if the grouped function is codegen-ed automatically by TVM, but for BYOC use cases (
FuseOpsByPattern) this is problematic. If a user creates a patternhe / she expects to create a function with two parameters, that does addition. Indeed, if I replace the RHS with an expression other than
data, such function is created. The fact that the same expression happens to be used for both LHS and RHS shouldn't matter when creating a grouped function. So the current behavior doesn't match user's intention. Moreover, a backend needs to able to handle multiple cases for code-generating the sameaddfunction with different signatures (one or two arguments).This PR modifies the behavior of
FuseOpsandFuseOpsByPattern, so that duplicated parameters in the same call arguments are allowed to appear as distinct parameters in a grouped function. If the same expression is used in different bindings, like below, it is deduplicated (the current behavior is preserved).@sunggg @Hzfengsy @vinx13 @yelite