Skip to content
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] Change in Pass Context for lookup table calculation #13660

Merged
merged 1 commit into from
Dec 27, 2022
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 19 additions & 4 deletions python/tvm/relay/qnn/op/canonicalizations.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,25 @@


def run_const_expr(expr: "relay.Expr") -> np.ndarray:
"""Evaluate a const expression, receiving result as np array."""
mod = tvm.IRModule.from_expr(expr)
vm_exe = relay.create_executor("vm", mod=mod)
return vm_exe.evaluate()().asnumpy()
"""Evaluate a const expression, receiving result as np array.

If a number of passes are disabled in the current Pass Context, then there is no need to disable
these passes for const expression evaluation as well. That's why we use empty list
"disabled_pass=[]", all other arguments are inherited from the current Pass Context.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you mean, without disabled_pass=[], the original disabled_pass list in the current context will be ignored during const folding?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I put here disabled_pass=[] to ignore the original disabled_pass list from the current context. Otherwise VM inherits non-empty disabled_pass list and fails.
Note, we call this code only for several qnn ops: tanh, sqrt, erf, exp + some other ops. It does not affect global constant folding.

For clarification, here is my example to illustrate this issue:
I am trying to compile subgraph with qnn.tanh operation for Hexagon target without QNN canonicalization but with QNN legalization (this is acceptable for Hexagon). For qnn.tanh we compose lookup table by means of Virtual Machine and compute it on the host. For most of users/developers host is x86 cpu. But for x86 QNN canonicalization is mandatory pass, otherwise it fails.
Looks like the simplest way to fix this issue is to create new Pass Context and ignore the original disabled_pass list for lookup table calculation and constant evaluation. Other arguments (opt_level, instruments, config ...) I inherit from the current context.

P.S. Corresponding unit test will be added in the next PR.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see, you do want to enable QNN legalization (which is disabled in the original ctx) here.

"""
curr_pass_ctx = tvm.ir.transform.PassContext.current()
with tvm.ir.transform.PassContext(
opt_level=curr_pass_ctx.opt_level,
required_pass=curr_pass_ctx.required_pass,
disabled_pass=[],
instruments=curr_pass_ctx.instruments,
config=curr_pass_ctx.config,
):
mod = tvm.IRModule.from_expr(expr)
vm_exe = relay.create_executor("vm", mod=mod)
output = vm_exe.evaluate()().asnumpy()

return output


def create_integer_lookup_table(
Expand Down