-
Notifications
You must be signed in to change notification settings - Fork 3.5k
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
[QNN][Relay] Calling Dialect passes from inside Relay Build API. #3971
Conversation
src/relay/backend/build_module.cc
Outdated
@@ -224,6 +224,7 @@ class RelayBuildModule : public runtime::ModuleNode { | |||
const tvm::Target& target_host) { | |||
targets_ = targets; | |||
target_host_ = target_host; | |||
func = BuildDialect(func, targets); |
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.
Instead of doing BuildDialect, we can probably do "DialectOptimize" here as we've already have a module.
src/relay/qnn/pass/optimize.cc
Outdated
|
||
using transform::Pass; | ||
|
||
Function QnnOptimize(const Function& f, const Map<tvm::Integer, tvm::Target>& targets) { |
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.
Why not make this function as module->module?
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.
Good point. I will do that.
@zhiics @anijain2305 Is it possible to integrate these QNN passes into pass manager? Then we can invoke it based on build config |
@vinx13 I think we can. But it looks that users are not aware of QNN. They may not be able to feed anything into build_config. What Animesh currently does is to put them under pass manager so that he can pre-invoke it before regular Relay passes. @anijain2305 Am I right? |
I think we want to avoid adding indirections into the build function but instead investigate on api composability, see my followup comments on https://discuss.tvm.ai/t/rfc-where-to-call-dialect-passes/3951/3 |
Yes, you are correct. |
2ebc769
to
4925ee3
Compare
@tqchen Can you please review if this is what you were thinking about Legalize? |
4925ee3
to
2bc1172
Compare
Two following up thoughts:
|
So, Legalize Pass currently returns a Pass like other transforms - https://github.com/dmlc/tvm/blob/8eb3157aa42f83d03c552328fa7441219df0787e/src/relay/pass/legalize.cc#L93-L99 I am calling Legalize Pass multiple times in build_module Legalize wrapper (I should change the name of method) with different strings. Is that ok?
I see. I can do that. |
re: pass vs wrapper function: the idea is to create another pass so it can be composed further :) We want to think a bit more about the API names, especially if it is user facing. In the spirit of minimum user mind burden, perhaps we could only expose the most user friendly API as Legalize(that does not need users to think about dialect)? We could put other API under the namespace of the dialect(e.g. qnn) |
95bd222
to
6f5f53e
Compare
@tqchen Can you please take a look now? |
@tqchen I created a Legalize pass under QNN namespace that return a Pass (a sequential pass of QNN related legalizations). Now in BuildRelay, I call this Legalize pass. Is this akin to what you were thinking? |
This wrapper now looks good to me. @tqchen Do you have any comment? |
fee4f73
to
6e8129c
Compare
6e8129c
to
b99687d
Compare
Approve for now, ideally, it would be great if we can have a transform::Legalize() that users can use which is invariant from any dialect. So we don't have to change the API as we add more dialect. |
@anijain2305 specifically, it would be great if we advocate transform::Legalize API while somehow hide qnn::Legalize API(perhaps in a private header) |
Okay. I will merge it for now. We can consider and probably refactor it somehow once there are more dialects come into play. |
* master: (21 commits) [Fix][VM] Fix VM invoke with set_params (apache#4079) [QNN] Refactor fixed point multiplication in requantize (apache#4073) Fix match case in Python-side expr functor (apache#4037) Hide symbols from dependent libraries if HIDE_PRIVATE_SYMBOLS is ON. (apache#4041) Add gradient for log-softmax (apache#4069) [DOC] Fix typos in tutorials (apache#4066) dicrease the complexity of CalcDep from exponential to linear (apache#4053) [Relay][AlterOp] Minor refactor. (apache#4064) [Relay][AlterOp] Improving support for broadcast layout alteration. (apache#4040) Add parses support for zeros_like tflite operator (apache#4042) [Bugfix][TF] reset graph after getting tag of savedmodel (apache#4055) [Relay][VM] Add more passes to VMCompiler (apache#4058) [Relay][VM] Add autotvm context when compile (apache#4062) [Bugfix] Fix target host for vm compiler (apache#4057) [Relay][Training] Add gradient for Crossentropy (apache#3925) [llvm] switch to use Align for llvm trunk (apache#4051) [Relay][TopHub] Add switch to disable TopHub download (apache#4015) [Relay][Op] Add instance norm op (apache#4004) [QNN][Relay] Calling Dialect passes from inside Relay Build API. (apache#3971) [RELAY/PASS] Fix the extent for the post_stmt in the loop partition (apache#3734) ...
Background
Qnn is a dialect to support reading pre-quantized models. It has 2 passes - QnnLegalize and QNNCanonicalizeOps. After these 2 passes, we have a graph that only consists of Relay ops. If the original graph did not have any QNN ops, these two passes will keep the graph unmodified.
Problem
We want to have a single API
relay.build
to compile anything that has been parsed using the framework parsers. However, the QNN passes are currently not in the RelayBuild module. This module shows one way how to do that. The idea is that each Dialect can wrap up their passes into one API and the relay.build can call that API internally.Alternatives
Relevant Discuss post - https://discuss.tvm.ai/t/rfc-where-to-call-dialect-passes/3951?u=janimesh
@zhiics @tqchen @vinx13 @shoubhik