分析 TVM 自动量化结果

目录

分析 TVM 自动量化结果#

import numpy as np
from tvm import relay
import tvm
from tvm_book.tvm_utils.llvm_utils import run_llvm_graph
from tqdm import tqdm
from tvm_book.tvm_utils.relay_pattern import *

def load_model(input_shape=[1, 3, 224, 224]):
    """加载前端模型"""
    import torch
    from torchvision.models import mobilenet_v2 as model
    from torchvision.models.mobilenet import MobileNet_V2_Weights
    model = model(weights=MobileNet_V2_Weights.IMAGENET1K_V1)
    data = torch.randn(*input_shape)
    return torch.jit.trace(model.eval(), data)

size = 224, 224
input_shape = (1, 3, *size)
input_name = "data"
traced_model = load_model(input_shape).eval()
# 将前端模型翻译为 relay 模型
origin_mod, origin_params = relay.frontend.from_pytorch(traced_model, [(input_name, input_shape)])

先以 mod 子图为例研究定义量化过程:

from tvm_book.tvm_utils.split_graph import graph_split

split_conf = [{"op_name": "clip", "op_index": 1}]
mod = graph_split(origin_mod["main"], split_conf)[0]
print(mod["main"])

记录量化过程:

# 定义校准数据集
def data_iter(input_name, input_shape, num=1):
    for _ in range(num):
        yield {input_name: np.random.normal(size=input_shape)}

dataset = data_iter(input_name, input_shape)

calibrate_pass = tvm.transform.module_pass(
    relay.quantize.calibrate(dataset), opt_level=1, name="QuantizeCalibrate"
)

with tvm.transform.PassContext(opt_level=3):
    with relay.quantize.qconfig(
        calibrate_mode="kl_divergence",
        weight_scale="max",
        skip_conv_layers=[],
        skip_dense_layer=False
    ):
        # 量化前准备
        opt_mod = relay.quantize.prerequisite_optimize(mod, origin_params)
        # 划分计算图
        partition_mod = relay.quantize.partition()(opt_mod)
        # 注解计算图
        annotate_mod = relay.quantize.annotate()(partition_mod)
        # 校准量化
        calibrate_mod = calibrate_pass(annotate_mod)
        # 量化实现
        qmod = relay.quantize.realize()(calibrate_mod)

定义融合规则:

# 配置融合规则
compiler_name = "ccompiler"
pattern_table = [
    (f"{compiler_name}.conv_add_relu_max_pool2d", make_conv_add_relu_max_pool2d_pattern()),
    (f"{compiler_name}.conv2d_transpose_add_activate", make_conv2d_transpose_add_activate_pattern()),
    (f"{compiler_name}.conv_add_activate", make_conv_add_activate_pattern()),
    (f"{compiler_name}.max_pool2d", make_max_pool2d_pattern()),
    (f"{compiler_name}.dense_add", make_dense_add_pattern()),
    (f"{compiler_name}.adaptive_avg_pool2d", make_adaptive_avg_pool2d_pattern()),
    (f"{compiler_name}.avg_pool2dd", make_avg_pool2d_pattern()),
    (f"{compiler_name}.add_multiply_add", make_add_multiply_add_pattern()),
    (f"{compiler_name}.add", make_add_pattern()),
    (f"{compiler_name}.multiply", make_multiply_pattern()),
    # (f"{compiler_name}.strided_slice", make_strided_slice_pattern()),
]
merge_passes = tvm.transform.Sequential([
    relay.transform.InferType(),
    relay.transform.MergeComposite(pattern_table),
    # relay.transform.ToANormalForm(),
    # relay.transform.ToGraphNormalForm(),
])
with tvm.transform.PassContext(opt_level=3):
    partition_mod_f = merge_passes(partition_mod)
    calibrate_mod_f = merge_passes(calibrate_mod)
print(calibrate_mod_f)
print(partition_mod_f["main"])

部分量化#

from tvm.relay.testing import run_opt_pass
from tvm.relay.expr import Constant, Call, Let
from tvm.relay.function import Function, FunctionWithFields
from tvm.relay import GlobalVar
from tvm.relay.op.annotation import compiler_begin, compiler_end

class DefuseMutator(tvm.relay.ExprMutator):
    def __init__(self, mod):
        super().__init__()
        self.mod = mod
        self.bind_params = {}
    
    # def visit_let(self, let):
    #     new_var = self.visit(let.var)
    #     new_val = self.visit(let.value)
    #     new_body = self.visit(let.body)
    #     if new_var == let.var and new_val == let.value and new_body == let.body:
    #         new_let = let
    #     else:
    #         new_let = Let(new_var, new_val, new_body)
    #     return new_let

    def visit_call(self, call):
        new_fn = self.visit(call.op)
        new_args = [self.visit(arg) for arg in call.args]
        
        if isinstance(new_fn, GlobalVar):
            self.bind_params[new_fn.name_hint] = new_args
            new_fn = self.mod[new_fn.name_hint].body
            new_fn = run_opt_pass(new_fn, relay.transform.DefuseOps())
            # _bind_dict = dict(zip(new_fn.params, new_args))
            # new_fn = relay.bind(new_fn, _bind_dict)
        new_call = Call(new_fn, new_args, call.attrs, call.type_args, call.span)
        return new_call

@tvm.relay.transform.function_pass(opt_level=1)
class CalibrateGraphTransform:
    def __init__(self, compiler):
        self.reset()
        self.compiler = compiler
        
    def reset(self):
        self._func_index = 0
        self.bind_dict = {}
        self.nodes = []

    def transform_function(self, func, mod, ctx):
        obj = self
        class Replace(tvm.relay.ExprMutator):
            def visit_call(self, call):
                new_fn = self.visit(call.op)
                new_args = [self.visit(arg) for arg in call.args]
                
                if isinstance(new_fn, Function):
                    compiler = obj.compiler
                    func_name = f"f_{obj._func_index:04d}"
                    # obj.nodes.append(call)
                    new_args = [compiler_begin(arg, obj.compiler) for arg in new_args]
                    # obj.bind_dict[func_name] = new_args
                    # _bind_dict = dict(zip(new_fn.params, new_args))
                    # new_fn = relay.bind(new_fn, _bind_dict)
                    
                    # if new_fn.attrs:
                    #     name = new_fn.attrs["PartitionedFromPattern"].replace("relay.op.annotation.simulated_quantize_", "").replace("annotation.cast_hint_", "")
                    #     if "conv" in name:
                    #         data = new_args[0]
                    #         old_data = new_fn.params[0]
                    #         body = new_fn.body
                    #         if data.op.name == "relay.op.annotation.simulated_quantize":
                    #             ...
                    
                    # mod[func_name] = new_fn
                    # # # new_args = new_fn.params
                    # new_fn = mod.get_global_var(func_name)
                    # obj._func_index += 1
                else:
                    compiler = "default"
                call = Call(new_fn, new_args, call.attrs, call.type_args, call.span)
                return compiler_end(call, compiler)
        return Replace().visit(func)

@tvm.relay.transform.function_pass(opt_level=1)
class PartitionGraphTransform:
    def __init__(self):
        self.reset()
        
    def reset(self):
        self._func_index = 0
        self.bind_dict = {}

    def transform_function(self, func, mod, ctx):
        obj = self
        class Replace(tvm.relay.ExprMutator):
            def visit_call(self, call):
                new_fn = self.visit(call.op)
                new_args = [self.visit(arg) for arg in call.args]
                
                if isinstance(call.op, Function):
                    func_name = f"f_{obj._func_index:04d}"
                    _bind_dict = dict(zip(new_fn.params, new_args))
                    _new_fn = relay.bind(new_fn, _bind_dict)
                    _new_fn = run_opt_pass(_new_fn, relay.transform.DefuseOps())
                    obj.bind_dict[func_name] = _new_fn
                    obj._func_index += 1
                call = Call(new_fn, new_args, call.attrs, call.type_args, call.span)
                return call
        return Replace().visit(func)
calibrate_transform = CalibrateGraphTransform("test")
# partition_transform = PartitionGraphTransform()
with tvm.transform.PassContext(opt_level=3):
    calibrate_mod_t = calibrate_transform(calibrate_mod_f)
    # partition_mod_t = partition_transform(partition_mod_f)
# call = relay.Tuple(calibrate_transform.nodes)
# call = run_opt_pass(call, relay.transform.DefuseOps())
run_mod = relay.transform.ToANormalForm()(calibrate_mod_f)
from tvm.relay.expr import Var

@tvm.relay.transform.function_pass(opt_level=1)
class CalibrateGraphTransform:
    def __init__(self, compiler):
        self.reset()
        self.compiler = compiler
        
    def reset(self):
        self._func_index = 0
        self.bind_dict = {}
        self.nodes = []

    def transform_function(self, func, mod, ctx):
        obj = self
        class Replace(tvm.relay.ExprMutator):
            def visit_call(self, call):
                new_fn = self.visit(call.op)
                new_args = [self.visit(arg) for arg in call.args]
                # print(type(new_fn))
                
                if isinstance(new_fn, Var):
                    compiler = obj.compiler
                    func_name = f"f_{obj._func_index:04d}"
                    obj.nodes.append(call)
                    new_args = [compiler_begin(arg, compiler) for arg in new_args]
                    # new_fn = run_opt_pass(new_fn, relay.transform.DefuseOps())
                    # obj.bind_dict[func_name] = new_args
                    # _bind_dict = dict(zip(new_fn.params, new_args))
                    # new_fn = relay.bind(new_fn, _bind_dict)
                    
                    # if new_fn.attrs:
                    #     name = new_fn.attrs["PartitionedFromPattern"].replace("relay.op.annotation.simulated_quantize_", "").replace("annotation.cast_hint_", "")
                    #     if "conv" in name:
                    #         data = new_args[0]
                    #         old_data = new_fn.params[0]
                    #         body = new_fn.body
                    #         if data.op.name == "relay.op.annotation.simulated_quantize":
                    #             ...
                    new_fn = compiler_begin(new_fn, compiler)
                    # mod[func_name] = new_fn
                    # # # new_args = new_fn.params
                    # new_fn = mod.get_global_var(func_name)
                    # obj._func_index += 1
                else:
                    compiler = "default"
                call = Call(new_fn, new_args, call.attrs, call.type_args, call.span)
                return compiler_end(call, compiler)
        return Replace().visit(func)
            # def visit_let(self, let):
            #     new_var = self.visit(let.var)
            #     new_val = self.visit(let.value)
            #     new_body = self.visit(let.body)
            #     if new_var == let.var and new_val == let.value and new_body == let.body:
            #         new_let = let
            #     else:
            #         new_let = Let(new_var, new_val, new_body)
            #     if isinstance(let.value, Function):
            #         func_name = f"f_{obj._func_index:04d}"
            #         obj.nodes.append(let)
            #         # mod[func_name] = tvm.IRModule.from_expr(let.body)["main"]
            #         obj._func_index += 1
            #         # new_val, new_body = new_body, new_val
            #     return new_let
        return Replace().visit(func)
calibrate_transform = CalibrateGraphTransform("test")
with tvm.transform.PassContext(opt_level=3):
    calibrate_mod_t = calibrate_transform(run_mod)
nodes = calibrate_transform.nodes
node = nodes[0]
print(relay.transform.PartitionGraph()(calibrate_mod_t))
---------------------------------------------------------------------------
InternalError                             Traceback (most recent call last)
/media/pc/data/lxw/ai/tvm/xinetzone/tvm-book/doc/quantize/analysis.ipynb 单元格 19 line 1
----> <a href='vscode-notebook-cell://ssh-remote%2B10.16.11.3/media/pc/data/lxw/ai/tvm/xinetzone/tvm-book/doc/quantize/analysis.ipynb#X63sdnNjb2RlLXJlbW90ZQ%3D%3D?line=0'>1</a> print(relay.transform.PartitionGraph()(calibrate_mod_t))

File /media/pc/data/lxw/ai/tvm/xinetzone/__pypackages__/3.10/lib/tvm/ir/transform.py:238, in Pass.__call__(self, mod)
    224 def __call__(self, mod):
    225     """Execute the pass. Note that for sequential pass, the dependency among
    226     different passes will be resolved in the backend.
    227 
   (...)
    236         The updated module after applying this pass.
    237     """
--> 238     return _ffi_transform_api.RunPass(self, mod)

File /media/pc/data/lxw/ai/tvm/xinetzone/__pypackages__/3.10/lib/tvm/_ffi/_ctypes/packed_func.py:239, in PackedFuncBase.__call__(self, *args)
    227 ret_tcode = ctypes.c_int()
    228 if (
    229     _LIB.TVMFuncCall(
    230         self.handle,
   (...)
    237     != 0
    238 ):
--> 239     raise_last_ffi_error()
    240 _ = temp_args
    241 _ = args

File /media/pc/data/lxw/ai/tvm/xinetzone/__pypackages__/3.10/lib/tvm/_ffi/base.py:476, in raise_last_ffi_error()
    470 # The exception PyObject may contain a large amount of state,
    471 # including all stack frames that may be inspected in a later
    472 # PDB post-mortem.  Therefore, we must make sure to remove the
    473 # underlying PyObject* from the C++ side after we retrieve it.
    474 _LIB.TVMDropLastPythonError()
--> 476 raise py_err

InternalError: Traceback (most recent call last):
  104: tvm::runtime::PackedFuncObj::Extractor<tvm::runtime::PackedFuncSubObj<tvm::runtime::TypedPackedFunc<tvm::IRModule (tvm::transform::Pass, tvm::IRModule)>::AssignTypedLambda<tvm::transform::{lambda(tvm::transform::Pass, tvm::IRModule)#7}>(tvm::transform::{lambda(tvm::transform::Pass, tvm::IRModule)#7}, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >)::{lambda(tvm::runtime::TVMArgs const&, tvm::runtime::TVMRetValue*)#1}> >::Call(tvm::runtime::PackedFuncObj const*, tvm::runtime::TVMArgs, tvm::runtime::TVMRetValue*)
  103: tvm::transform::Pass::operator()(tvm::IRModule) const
  102: tvm::transform::Pass::operator()(tvm::IRModule, tvm::transform::PassContext const&) const
  101: tvm::transform::SequentialNode::operator()(tvm::IRModule, tvm::transform::PassContext const&) const
  100: tvm::transform::Pass::operator()(tvm::IRModule, tvm::transform::PassContext const&) const
  99: tvm::transform::ModulePassNode::operator()(tvm::IRModule, tvm::transform::PassContext const&) const
  98: _ZN3tvm7runtime13PackedFuncObj
  97: tvm::runtime::TypedPackedFunc<tvm::IRModule (tvm::IRModule, tvm::transform::PassContext)>::AssignTypedLambda<tvm::relay::transform::PartitionGraph(tvm::runtime::String, bool)::{lambda(tvm::IRModule, tvm::transform::PassContext)#3}>(tvm::relay::transform::PartitionGraph(tvm::runtime::String, bool)::{lambda(tvm::IRModule, tvm::transform::PassContext)#3})::{lambda(tvm::runtime::TVMArgs const&, tvm::runtime::TVMRetValue*)#1}::operator()(tvm::runtime::TVMArgs const&, tvm::runtime::TVMRetValue*) const
  96: tvm::relay::partitioning::Partitioner::Partition()
  95: tvm::relay::MixedModeMutator::VisitExpr(tvm::RelayExpr const&)
  94: void tvm::relay::ExpandDataflow<tvm::relay::MixedModeMutator::VisitExpr(tvm::RelayExpr const&)::{lambda(tvm::RelayExpr const&)#1}, tvm::relay::MixedModeMutator::VisitExpr(tvm::RelayExpr const&)::{lambda(tvm::RelayExpr const&)#2}, tvm::relay::ExpandDataflow<tvm::relay::MixedModeMutator::VisitExpr(tvm::RelayExpr const&)::{lambda(tvm::RelayExpr const&)#1}, tvm::relay::MixedModeMutator::VisitExpr(tvm::RelayExpr const&)::{lambda(tvm::RelayExpr const&)#2}>(tvm::RelayExpr, tvm::relay::MixedModeMutator::VisitExpr(tvm::RelayExpr const&)::{lambda(tvm::RelayExpr const&)#1}, tvm::relay::MixedModeMutator::VisitExpr(tvm::RelayExpr const&)::{lambda(tvm::RelayExpr const&)#2})::{lambda(tvm::RelayExpr const&)#1}>(tvm::RelayExpr, tvm::relay::MixedModeMutator::VisitExpr(tvm::RelayExpr const&)::{lambda(tvm::RelayExpr const&)#1}, tvm::relay::MixedModeMutator::VisitExpr(tvm::RelayExpr const&)::{lambda(tvm::RelayExpr const&)#2}, tvm::relay::ExpandDataflow<tvm::relay::MixedModeMutator::VisitExpr(tvm::RelayExpr const&)::{lambda(tvm::RelayExpr const&)#1}, tvm::relay::MixedModeMutator::VisitExpr(tvm::RelayExpr const&)::{lambda(tvm::RelayExpr const&)#2}>(tvm::RelayExpr, tvm::relay::MixedModeMutator::VisitExpr(tvm::RelayExpr const&)::{lambda(tvm::RelayExpr const&)#1}, tvm::relay::MixedModeMutator::VisitExpr(tvm::RelayExpr const&)::{lambda(tvm::RelayExpr const&)#2})::{lambda(tvm::RelayExpr const&)#1}) [clone .isra.0]
  93: tvm::relay::MixedModeMutator::VisitLeaf(tvm::RelayExpr const&)
  92: _ZN3tvm5relay16MixedModeMutator17DispatchVisitExprERKNS_9RelayExp
  91: tvm::relay::ExprMutator::VisitExpr(tvm::RelayExpr const&)
  90: _ZZN3tvm5relay11ExprFunctorIFNS_9RelayExprERKS2_EE10InitVTableEvENUlRKNS_7r
  89: tvm::relay::ExprMutator::VisitExpr_(tvm::relay::LetNode const*)
  88: tvm::relay::MixedModeMutator::VisitExpr(tvm::RelayExpr const&)
  87: void tvm::relay::ExpandDataflow<tvm::relay::MixedModeMutator::VisitExpr(tvm::RelayExpr const&)::{lambda(tvm::RelayExpr const&)#1}, tvm::relay::MixedModeMutator::VisitExpr(tvm::RelayExpr const&)::{lambda(tvm::RelayExpr const&)#2}, tvm::relay::ExpandDataflow<tvm::relay::MixedModeMutator::VisitExpr(tvm::RelayExpr const&)::{lambda(tvm::RelayExpr const&)#1}, tvm::relay::MixedModeMutator::VisitExpr(tvm::RelayExpr const&)::{lambda(tvm::RelayExpr const&)#2}>(tvm::RelayExpr, tvm::relay::MixedModeMutator::VisitExpr(tvm::RelayExpr const&)::{lambda(tvm::RelayExpr const&)#1}, tvm::relay::MixedModeMutator::VisitExpr(tvm::RelayExpr const&)::{lambda(tvm::RelayExpr const&)#2})::{lambda(tvm::RelayExpr const&)#1}>(tvm::RelayExpr, tvm::relay::MixedModeMutator::VisitExpr(tvm::RelayExpr const&)::{lambda(tvm::RelayExpr const&)#1}, tvm::relay::MixedModeMutator::VisitExpr(tvm::RelayExpr const&)::{lambda(tvm::RelayExpr const&)#2}, tvm::relay::ExpandDataflow<tvm::relay::MixedModeMutator::VisitExpr(tvm::RelayExpr const&)::{lambda(tvm::RelayExpr const&)#1}, tvm::relay::MixedModeMutator::VisitExpr(tvm::RelayExpr const&)::{lambda(tvm::RelayExpr const&)#2}>(tvm::RelayExpr, tvm::relay::MixedModeMutator::VisitExpr(tvm::RelayExpr const&)::{lambda(tvm::RelayExpr const&)#1}, tvm::relay::MixedModeMutator::VisitExpr(tvm::RelayExpr const&)::{lambda(tvm::RelayExpr const&)#2})::{lambda(tvm::RelayExpr const&)#1}) [clone .isra.0]
  86: tvm::relay::MixedModeMutator::VisitLeaf(tvm::RelayExpr const&)
  85: _ZN3tvm5relay16MixedModeMutator17DispatchVisitExprERKNS_9RelayExp
  84: tvm::relay::ExprMutator::VisitExpr(tvm::RelayExpr const&)
  83: _ZZN3tvm5relay11ExprFunctorIFNS_9RelayExprERKS2_EE10InitVTableEvENUlRKNS_7r
  82: tvm::relay::ExprMutator::VisitExpr_(tvm::relay::LetNode const*)
  81: tvm::relay::MixedModeMutator::VisitExpr(tvm::RelayExpr const&)
  80: void tvm::relay::ExpandDataflow<tvm::relay::MixedModeMutator::VisitExpr(tvm::RelayExpr const&)::{lambda(tvm::RelayExpr const&)#1}, tvm::relay::MixedModeMutator::VisitExpr(tvm::RelayExpr const&)::{lambda(tvm::RelayExpr const&)#2}, tvm::relay::ExpandDataflow<tvm::relay::MixedModeMutator::VisitExpr(tvm::RelayExpr const&)::{lambda(tvm::RelayExpr const&)#1}, tvm::relay::MixedModeMutator::VisitExpr(tvm::RelayExpr const&)::{lambda(tvm::RelayExpr const&)#2}>(tvm::RelayExpr, tvm::relay::MixedModeMutator::VisitExpr(tvm::RelayExpr const&)::{lambda(tvm::RelayExpr const&)#1}, tvm::relay::MixedModeMutator::VisitExpr(tvm::RelayExpr const&)::{lambda(tvm::RelayExpr const&)#2})::{lambda(tvm::RelayExpr const&)#1}>(tvm::RelayExpr, tvm::relay::MixedModeMutator::VisitExpr(tvm::RelayExpr const&)::{lambda(tvm::RelayExpr const&)#1}, tvm::relay::MixedModeMutator::VisitExpr(tvm::RelayExpr const&)::{lambda(tvm::RelayExpr const&)#2}, tvm::relay::ExpandDataflow<tvm::relay::MixedModeMutator::VisitExpr(tvm::RelayExpr const&)::{lambda(tvm::RelayExpr const&)#1}, tvm::relay::MixedModeMutator::VisitExpr(tvm::RelayExpr const&)::{lambda(tvm::RelayExpr const&)#2}>(tvm::RelayExpr, tvm::relay::MixedModeMutator::VisitExpr(tvm::RelayExpr const&)::{lambda(tvm::RelayExpr const&)#1}, tvm::relay::MixedModeMutator::VisitExpr(tvm::RelayExpr const&)::{lambda(tvm::RelayExpr const&)#2})::{lambda(tvm::RelayExpr const&)#1}) [clone .isra.0]
  79: tvm::relay::MixedModeMutator::VisitLeaf(tvm::RelayExpr const&)
  78: _ZN3tvm5relay16MixedModeMutator17DispatchVisitExprERKNS_9RelayExp
  77: tvm::relay::ExprMutator::VisitExpr(tvm::RelayExpr const&)
  76: _ZZN3tvm5relay11ExprFunctorIFNS_9RelayExprERKS2_EE10InitVTableEvENUlRKNS_7r
  75: tvm::relay::ExprMutator::VisitExpr_(tvm::relay::LetNode const*)
  74: tvm::relay::MixedModeMutator::VisitExpr(tvm::RelayExpr const&)
  73: void tvm::relay::ExpandDataflow<tvm::relay::MixedModeMutator::VisitExpr(tvm::RelayExpr const&)::{lambda(tvm::RelayExpr const&)#1}, tvm::relay::MixedModeMutator::VisitExpr(tvm::RelayExpr const&)::{lambda(tvm::RelayExpr const&)#2}, tvm::relay::ExpandDataflow<tvm::relay::MixedModeMutator::VisitExpr(tvm::RelayExpr const&)::{lambda(tvm::RelayExpr const&)#1}, tvm::relay::MixedModeMutator::VisitExpr(tvm::RelayExpr const&)::{lambda(tvm::RelayExpr const&)#2}>(tvm::RelayExpr, tvm::relay::MixedModeMutator::VisitExpr(tvm::RelayExpr const&)::{lambda(tvm::RelayExpr const&)#1}, tvm::relay::MixedModeMutator::VisitExpr(tvm::RelayExpr const&)::{lambda(tvm::RelayExpr const&)#2})::{lambda(tvm::RelayExpr const&)#1}>(tvm::RelayExpr, tvm::relay::MixedModeMutator::VisitExpr(tvm::RelayExpr const&)::{lambda(tvm::RelayExpr const&)#1}, tvm::relay::MixedModeMutator::VisitExpr(tvm::RelayExpr const&)::{lambda(tvm::RelayExpr const&)#2}, tvm::relay::ExpandDataflow<tvm::relay::MixedModeMutator::VisitExpr(tvm::RelayExpr const&)::{lambda(tvm::RelayExpr const&)#1}, tvm::relay::MixedModeMutator::VisitExpr(tvm::RelayExpr const&)::{lambda(tvm::RelayExpr const&)#2}>(tvm::RelayExpr, tvm::relay::MixedModeMutator::VisitExpr(tvm::RelayExpr const&)::{lambda(tvm::RelayExpr const&)#1}, tvm::relay::MixedModeMutator::VisitExpr(tvm::RelayExpr const&)::{lambda(tvm::RelayExpr const&)#2})::{lambda(tvm::RelayExpr const&)#1}) [clone .isra.0]
  72: tvm::relay::MixedModeMutator::VisitLeaf(tvm::RelayExpr const&)
  71: _ZN3tvm5relay16MixedModeMutator17DispatchVisitExprERKNS_9RelayExp
  70: tvm::relay::ExprMutator::VisitExpr(tvm::RelayExpr const&)
  69: _ZZN3tvm5relay11ExprFunctorIFNS_9RelayExprERKS2_EE10InitVTableEvENUlRKNS_7r
  68: tvm::relay::ExprMutator::VisitExpr_(tvm::relay::LetNode const*)
  67: tvm::relay::MixedModeMutator::VisitExpr(tvm::RelayExpr const&)
  66: void tvm::relay::ExpandDataflow<tvm::relay::MixedModeMutator::VisitExpr(tvm::RelayExpr const&)::{lambda(tvm::RelayExpr const&)#1}, tvm::relay::MixedModeMutator::VisitExpr(tvm::RelayExpr const&)::{lambda(tvm::RelayExpr const&)#2}, tvm::relay::ExpandDataflow<tvm::relay::MixedModeMutator::VisitExpr(tvm::RelayExpr const&)::{lambda(tvm::RelayExpr const&)#1}, tvm::relay::MixedModeMutator::VisitExpr(tvm::RelayExpr const&)::{lambda(tvm::RelayExpr const&)#2}>(tvm::RelayExpr, tvm::relay::MixedModeMutator::VisitExpr(tvm::RelayExpr const&)::{lambda(tvm::RelayExpr const&)#1}, tvm::relay::MixedModeMutator::VisitExpr(tvm::RelayExpr const&)::{lambda(tvm::RelayExpr const&)#2})::{lambda(tvm::RelayExpr const&)#1}>(tvm::RelayExpr, tvm::relay::MixedModeMutator::VisitExpr(tvm::RelayExpr const&)::{lambda(tvm::RelayExpr const&)#1}, tvm::relay::MixedModeMutator::VisitExpr(tvm::RelayExpr const&)::{lambda(tvm::RelayExpr const&)#2}, tvm::relay::ExpandDataflow<tvm::relay::MixedModeMutator::VisitExpr(tvm::RelayExpr const&)::{lambda(tvm::RelayExpr const&)#1}, tvm::relay::MixedModeMutator::VisitExpr(tvm::RelayExpr const&)::{lambda(tvm::RelayExpr const&)#2}>(tvm::RelayExpr, tvm::relay::MixedModeMutator::VisitExpr(tvm::RelayExpr const&)::{lambda(tvm::RelayExpr const&)#1}, tvm::relay::MixedModeMutator::VisitExpr(tvm::RelayExpr const&)::{lambda(tvm::RelayExpr const&)#2})::{lambda(tvm::RelayExpr const&)#1}) [clone .isra.0]
  65: tvm::relay::MixedModeMutator::VisitLeaf(tvm::RelayExpr const&)
  64: _ZN3tvm5relay16MixedModeMutator17DispatchVisitExprERKNS_9RelayExp
  63: tvm::relay::ExprMutator::VisitExpr(tvm::RelayExpr const&)
  62: _ZZN3tvm5relay11ExprFunctorIFNS_9RelayExprERKS2_EE10InitVTableEvENUlRKNS_7r
  61: tvm::relay::ExprMutator::VisitExpr_(tvm::relay::LetNode const*)
  60: tvm::relay::MixedModeMutator::VisitExpr(tvm::RelayExpr const&)
  59: void tvm::relay::ExpandDataflow<tvm::relay::MixedModeMutator::VisitExpr(tvm::RelayExpr const&)::{lambda(tvm::RelayExpr const&)#1}, tvm::relay::MixedModeMutator::VisitExpr(tvm::RelayExpr const&)::{lambda(tvm::RelayExpr const&)#2}, tvm::relay::ExpandDataflow<tvm::relay::MixedModeMutator::VisitExpr(tvm::RelayExpr const&)::{lambda(tvm::RelayExpr const&)#1}, tvm::relay::MixedModeMutator::VisitExpr(tvm::RelayExpr const&)::{lambda(tvm::RelayExpr const&)#2}>(tvm::RelayExpr, tvm::relay::MixedModeMutator::VisitExpr(tvm::RelayExpr const&)::{lambda(tvm::RelayExpr const&)#1}, tvm::relay::MixedModeMutator::VisitExpr(tvm::RelayExpr const&)::{lambda(tvm::RelayExpr const&)#2})::{lambda(tvm::RelayExpr const&)#1}>(tvm::RelayExpr, tvm::relay::MixedModeMutator::VisitExpr(tvm::RelayExpr const&)::{lambda(tvm::RelayExpr const&)#1}, tvm::relay::MixedModeMutator::VisitExpr(tvm::RelayExpr const&)::{lambda(tvm::RelayExpr const&)#2}, tvm::relay::ExpandDataflow<tvm::relay::MixedModeMutator::VisitExpr(tvm::RelayExpr const&)::{lambda(tvm::RelayExpr const&)#1}, tvm::relay::MixedModeMutator::VisitExpr(tvm::RelayExpr const&)::{lambda(tvm::RelayExpr const&)#2}>(tvm::RelayExpr, tvm::relay::MixedModeMutator::VisitExpr(tvm::RelayExpr const&)::{lambda(tvm::RelayExpr const&)#1}, tvm::relay::MixedModeMutator::VisitExpr(tvm::RelayExpr const&)::{lambda(tvm::RelayExpr const&)#2})::{lambda(tvm::RelayExpr const&)#1}) [clone .isra.0]
  58: tvm::relay::MixedModeMutator::VisitLeaf(tvm::RelayExpr const&)
  57: _ZN3tvm5relay16MixedModeMutator17DispatchVisitExprERKNS_9RelayExp
  56: tvm::relay::ExprMutator::VisitExpr(tvm::RelayExpr const&)
  55: _ZZN3tvm5relay11ExprFunctorIFNS_9RelayExprERKS2_EE10InitVTableEvENUlRKNS_7r
  54: tvm::relay::ExprMutator::VisitExpr_(tvm::relay::LetNode const*)
  53: tvm::relay::MixedModeMutator::VisitExpr(tvm::RelayExpr const&)
  52: void tvm::relay::ExpandDataflow<tvm::relay::MixedModeMutator::VisitExpr(tvm::RelayExpr const&)::{lambda(tvm::RelayExpr const&)#1}, tvm::relay::MixedModeMutator::VisitExpr(tvm::RelayExpr const&)::{lambda(tvm::RelayExpr const&)#2}, tvm::relay::ExpandDataflow<tvm::relay::MixedModeMutator::VisitExpr(tvm::RelayExpr const&)::{lambda(tvm::RelayExpr const&)#1}, tvm::relay::MixedModeMutator::VisitExpr(tvm::RelayExpr const&)::{lambda(tvm::RelayExpr const&)#2}>(tvm::RelayExpr, tvm::relay::MixedModeMutator::VisitExpr(tvm::RelayExpr const&)::{lambda(tvm::RelayExpr const&)#1}, tvm::relay::MixedModeMutator::VisitExpr(tvm::RelayExpr const&)::{lambda(tvm::RelayExpr const&)#2})::{lambda(tvm::RelayExpr const&)#1}>(tvm::RelayExpr, tvm::relay::MixedModeMutator::VisitExpr(tvm::RelayExpr const&)::{lambda(tvm::RelayExpr const&)#1}, tvm::relay::MixedModeMutator::VisitExpr(tvm::RelayExpr const&)::{lambda(tvm::RelayExpr const&)#2}, tvm::relay::ExpandDataflow<tvm::relay::MixedModeMutator::VisitExpr(tvm::RelayExpr const&)::{lambda(tvm::RelayExpr const&)#1}, tvm::relay::MixedModeMutator::VisitExpr(tvm::RelayExpr const&)::{lambda(tvm::RelayExpr const&)#2}>(tvm::RelayExpr, tvm::relay::MixedModeMutator::VisitExpr(tvm::RelayExpr const&)::{lambda(tvm::RelayExpr const&)#1}, tvm::relay::MixedModeMutator::VisitExpr(tvm::RelayExpr const&)::{lambda(tvm::RelayExpr const&)#2})::{lambda(tvm::RelayExpr const&)#1}) [clone .isra.0]
  51: tvm::relay::MixedModeMutator::VisitLeaf(tvm::RelayExpr const&)
  50: _ZN3tvm5relay16MixedModeMutator17DispatchVisitExprERKNS_9RelayExp
  49: tvm::relay::ExprMutator::VisitExpr(tvm::RelayExpr const&)
  48: _ZZN3tvm5relay11ExprFunctorIFNS_9RelayExprERKS2_EE10InitVTableEvENUlRKNS_7r
  47: tvm::relay::ExprMutator::VisitExpr_(tvm::relay::LetNode const*)
  46: tvm::relay::MixedModeMutator::VisitExpr(tvm::RelayExpr const&)
  45: void tvm::relay::ExpandDataflow<tvm::relay::MixedModeMutator::VisitExpr(tvm::RelayExpr const&)::{lambda(tvm::RelayExpr const&)#1}, tvm::relay::MixedModeMutator::VisitExpr(tvm::RelayExpr const&)::{lambda(tvm::RelayExpr const&)#2}, tvm::relay::ExpandDataflow<tvm::relay::MixedModeMutator::VisitExpr(tvm::RelayExpr const&)::{lambda(tvm::RelayExpr const&)#1}, tvm::relay::MixedModeMutator::VisitExpr(tvm::RelayExpr const&)::{lambda(tvm::RelayExpr const&)#2}>(tvm::RelayExpr, tvm::relay::MixedModeMutator::VisitExpr(tvm::RelayExpr const&)::{lambda(tvm::RelayExpr const&)#1}, tvm::relay::MixedModeMutator::VisitExpr(tvm::RelayExpr const&)::{lambda(tvm::RelayExpr const&)#2})::{lambda(tvm::RelayExpr const&)#1}>(tvm::RelayExpr, tvm::relay::MixedModeMutator::VisitExpr(tvm::RelayExpr const&)::{lambda(tvm::RelayExpr const&)#1}, tvm::relay::MixedModeMutator::VisitExpr(tvm::RelayExpr const&)::{lambda(tvm::RelayExpr const&)#2}, tvm::relay::ExpandDataflow<tvm::relay::MixedModeMutator::VisitExpr(tvm::RelayExpr const&)::{lambda(tvm::RelayExpr const&)#1}, tvm::relay::MixedModeMutator::VisitExpr(tvm::RelayExpr const&)::{lambda(tvm::RelayExpr const&)#2}>(tvm::RelayExpr, tvm::relay::MixedModeMutator::VisitExpr(tvm::RelayExpr const&)::{lambda(tvm::RelayExpr const&)#1}, tvm::relay::MixedModeMutator::VisitExpr(tvm::RelayExpr const&)::{lambda(tvm::RelayExpr const&)#2})::{lambda(tvm::RelayExpr const&)#1}) [clone .isra.0]
  44: tvm::relay::MixedModeMutator::VisitLeaf(tvm::RelayExpr const&)
  43: _ZN3tvm5relay16MixedModeMutator17DispatchVisitExprERKNS_9RelayExp
  42: tvm::relay::ExprMutator::VisitExpr(tvm::RelayExpr const&)
  41: _ZZN3tvm5relay11ExprFunctorIFNS_9RelayExprERKS2_EE10InitVTableEvENUlRKNS_7r
  40: tvm::relay::ExprMutator::VisitExpr_(tvm::relay::LetNode const*)
  39: tvm::relay::MixedModeMutator::VisitExpr(tvm::RelayExpr const&)
  38: void tvm::relay::ExpandDataflow<tvm::relay::MixedModeMutator::VisitExpr(tvm::RelayExpr const&)::{lambda(tvm::RelayExpr const&)#1}, tvm::relay::MixedModeMutator::VisitExpr(tvm::RelayExpr const&)::{lambda(tvm::RelayExpr const&)#2}, tvm::relay::ExpandDataflow<tvm::relay::MixedModeMutator::VisitExpr(tvm::RelayExpr const&)::{lambda(tvm::RelayExpr const&)#1}, tvm::relay::MixedModeMutator::VisitExpr(tvm::RelayExpr const&)::{lambda(tvm::RelayExpr const&)#2}>(tvm::RelayExpr, tvm::relay::MixedModeMutator::VisitExpr(tvm::RelayExpr const&)::{lambda(tvm::RelayExpr const&)#1}, tvm::relay::MixedModeMutator::VisitExpr(tvm::RelayExpr const&)::{lambda(tvm::RelayExpr const&)#2})::{lambda(tvm::RelayExpr const&)#1}>(tvm::RelayExpr, tvm::relay::MixedModeMutator::VisitExpr(tvm::RelayExpr const&)::{lambda(tvm::RelayExpr const&)#1}, tvm::relay::MixedModeMutator::VisitExpr(tvm::RelayExpr const&)::{lambda(tvm::RelayExpr const&)#2}, tvm::relay::ExpandDataflow<tvm::relay::MixedModeMutator::VisitExpr(tvm::RelayExpr const&)::{lambda(tvm::RelayExpr const&)#1}, tvm::relay::MixedModeMutator::VisitExpr(tvm::RelayExpr const&)::{lambda(tvm::RelayExpr const&)#2}>(tvm::RelayExpr, tvm::relay::MixedModeMutator::VisitExpr(tvm::RelayExpr const&)::{lambda(tvm::RelayExpr const&)#1}, tvm::relay::MixedModeMutator::VisitExpr(tvm::RelayExpr const&)::{lambda(tvm::RelayExpr const&)#2})::{lambda(tvm::RelayExpr const&)#1}) [clone .isra.0]
  37: tvm::relay::MixedModeMutator::VisitLeaf(tvm::RelayExpr const&)
  36: _ZN3tvm5relay16MixedModeMutator17DispatchVisitExprERKNS_9RelayExp
  35: tvm::relay::ExprMutator::VisitExpr(tvm::RelayExpr const&)
  34: _ZZN3tvm5relay11ExprFunctorIFNS_9RelayExprERKS2_EE10InitVTableEvENUlRKNS_7r
  33: tvm::relay::ExprMutator::VisitExpr_(tvm::relay::LetNode const*)
  32: tvm::relay::MixedModeMutator::VisitExpr(tvm::RelayExpr const&)
  31: void tvm::relay::ExpandDataflow<tvm::relay::MixedModeMutator::VisitExpr(tvm::RelayExpr const&)::{lambda(tvm::RelayExpr const&)#1}, tvm::relay::MixedModeMutator::VisitExpr(tvm::RelayExpr const&)::{lambda(tvm::RelayExpr const&)#2}, tvm::relay::ExpandDataflow<tvm::relay::MixedModeMutator::VisitExpr(tvm::RelayExpr const&)::{lambda(tvm::RelayExpr const&)#1}, tvm::relay::MixedModeMutator::VisitExpr(tvm::RelayExpr const&)::{lambda(tvm::RelayExpr const&)#2}>(tvm::RelayExpr, tvm::relay::MixedModeMutator::VisitExpr(tvm::RelayExpr const&)::{lambda(tvm::RelayExpr const&)#1}, tvm::relay::MixedModeMutator::VisitExpr(tvm::RelayExpr const&)::{lambda(tvm::RelayExpr const&)#2})::{lambda(tvm::RelayExpr const&)#1}>(tvm::RelayExpr, tvm::relay::MixedModeMutator::VisitExpr(tvm::RelayExpr const&)::{lambda(tvm::RelayExpr const&)#1}, tvm::relay::MixedModeMutator::VisitExpr(tvm::RelayExpr const&)::{lambda(tvm::RelayExpr const&)#2}, tvm::relay::ExpandDataflow<tvm::relay::MixedModeMutator::VisitExpr(tvm::RelayExpr const&)::{lambda(tvm::RelayExpr const&)#1}, tvm::relay::MixedModeMutator::VisitExpr(tvm::RelayExpr const&)::{lambda(tvm::RelayExpr const&)#2}>(tvm::RelayExpr, tvm::relay::MixedModeMutator::VisitExpr(tvm::RelayExpr const&)::{lambda(tvm::RelayExpr const&)#1}, tvm::relay::MixedModeMutator::VisitExpr(tvm::RelayExpr const&)::{lambda(tvm::RelayExpr const&)#2})::{lambda(tvm::RelayExpr const&)#1}) [clone .isra.0]
  30: tvm::relay::MixedModeMutator::VisitLeaf(tvm::RelayExpr const&)
  29: _ZN3tvm5relay16MixedModeMutator17DispatchVisitExprERKNS_9RelayExp
  28: tvm::relay::ExprMutator::VisitExpr(tvm::RelayExpr const&)
  27: _ZZN3tvm5relay11ExprFunctorIFNS_9RelayExprERKS2_EE10InitVTableEvENUlRKNS_7r
  26: tvm::relay::ExprMutator::VisitExpr_(tvm::relay::LetNode const*)
  25: tvm::relay::MixedModeMutator::VisitExpr(tvm::RelayExpr const&)
  24: void tvm::relay::ExpandDataflow<tvm::relay::MixedModeMutator::VisitExpr(tvm::RelayExpr const&)::{lambda(tvm::RelayExpr const&)#1}, tvm::relay::MixedModeMutator::VisitExpr(tvm::RelayExpr const&)::{lambda(tvm::RelayExpr const&)#2}, tvm::relay::ExpandDataflow<tvm::relay::MixedModeMutator::VisitExpr(tvm::RelayExpr const&)::{lambda(tvm::RelayExpr const&)#1}, tvm::relay::MixedModeMutator::VisitExpr(tvm::RelayExpr const&)::{lambda(tvm::RelayExpr const&)#2}>(tvm::RelayExpr, tvm::relay::MixedModeMutator::VisitExpr(tvm::RelayExpr const&)::{lambda(tvm::RelayExpr const&)#1}, tvm::relay::MixedModeMutator::VisitExpr(tvm::RelayExpr const&)::{lambda(tvm::RelayExpr const&)#2})::{lambda(tvm::RelayExpr const&)#1}>(tvm::RelayExpr, tvm::relay::MixedModeMutator::VisitExpr(tvm::RelayExpr const&)::{lambda(tvm::RelayExpr const&)#1}, tvm::relay::MixedModeMutator::VisitExpr(tvm::RelayExpr const&)::{lambda(tvm::RelayExpr const&)#2}, tvm::relay::ExpandDataflow<tvm::relay::MixedModeMutator::VisitExpr(tvm::RelayExpr const&)::{lambda(tvm::RelayExpr const&)#1}, tvm::relay::MixedModeMutator::VisitExpr(tvm::RelayExpr const&)::{lambda(tvm::RelayExpr const&)#2}>(tvm::RelayExpr, tvm::relay::MixedModeMutator::VisitExpr(tvm::RelayExpr const&)::{lambda(tvm::RelayExpr const&)#1}, tvm::relay::MixedModeMutator::VisitExpr(tvm::RelayExpr const&)::{lambda(tvm::RelayExpr const&)#2})::{lambda(tvm::RelayExpr const&)#1}) [clone .isra.0]
  23: tvm::relay::MixedModeMutator::VisitLeaf(tvm::RelayExpr const&)
  22: _ZN3tvm5relay16MixedModeMutator17DispatchVisitExprERKNS_9RelayExp
  21: tvm::relay::ExprMutator::VisitExpr(tvm::RelayExpr const&)
  20: _ZZN3tvm5relay11ExprFunctorIFNS_9RelayExprERKS2_EE10InitVTableEvENUlRKNS_7r
  19: tvm::relay::ExprMutator::VisitExpr_(tvm::relay::LetNode const*)
  18: tvm::relay::MixedModeMutator::VisitExpr(tvm::RelayExpr const&)
  17: void tvm::relay::ExpandDataflow<tvm::relay::MixedModeMutator::VisitExpr(tvm::RelayExpr const&)::{lambda(tvm::RelayExpr const&)#1}, tvm::relay::MixedModeMutator::VisitExpr(tvm::RelayExpr const&)::{lambda(tvm::RelayExpr const&)#2}, tvm::relay::ExpandDataflow<tvm::relay::MixedModeMutator::VisitExpr(tvm::RelayExpr const&)::{lambda(tvm::RelayExpr const&)#1}, tvm::relay::MixedModeMutator::VisitExpr(tvm::RelayExpr const&)::{lambda(tvm::RelayExpr const&)#2}>(tvm::RelayExpr, tvm::relay::MixedModeMutator::VisitExpr(tvm::RelayExpr const&)::{lambda(tvm::RelayExpr const&)#1}, tvm::relay::MixedModeMutator::VisitExpr(tvm::RelayExpr const&)::{lambda(tvm::RelayExpr const&)#2})::{lambda(tvm::RelayExpr const&)#1}>(tvm::RelayExpr, tvm::relay::MixedModeMutator::VisitExpr(tvm::RelayExpr const&)::{lambda(tvm::RelayExpr const&)#1}, tvm::relay::MixedModeMutator::VisitExpr(tvm::RelayExpr const&)::{lambda(tvm::RelayExpr const&)#2}, tvm::relay::ExpandDataflow<tvm::relay::MixedModeMutator::VisitExpr(tvm::RelayExpr const&)::{lambda(tvm::RelayExpr const&)#1}, tvm::relay::MixedModeMutator::VisitExpr(tvm::RelayExpr const&)::{lambda(tvm::RelayExpr const&)#2}>(tvm::RelayExpr, tvm::relay::MixedModeMutator::VisitExpr(tvm::RelayExpr const&)::{lambda(tvm::RelayExpr const&)#1}, tvm::relay::MixedModeMutator::VisitExpr(tvm::RelayExpr const&)::{lambda(tvm::RelayExpr const&)#2})::{lambda(tvm::RelayExpr const&)#1}) [clone .isra.0]
  16: tvm::relay::MixedModeMutator::VisitLeaf(tvm::RelayExpr const&)
  15: _ZN3tvm5relay16MixedModeMutator17DispatchVisitExprERKNS_9RelayExp
  14: tvm::relay::ExprMutator::VisitExpr(tvm::RelayExpr const&)
  13: _ZZN3tvm5relay11ExprFunctorIFNS_9RelayExprERKS2_EE10InitVTableEvENUlRKNS_7r
  12: tvm::relay::ExprMutator::VisitExpr_(tvm::relay::LetNode const*)
  11: tvm::relay::MixedModeMutator::VisitExpr(tvm::RelayExpr const&)
  10: void tvm::relay::ExpandDataflow<tvm::relay::MixedModeMutator::VisitExpr(tvm::RelayExpr const&)::{lambda(tvm::RelayExpr const&)#1}, tvm::relay::MixedModeMutator::VisitExpr(tvm::RelayExpr const&)::{lambda(tvm::RelayExpr const&)#2}, tvm::relay::ExpandDataflow<tvm::relay::MixedModeMutator::VisitExpr(tvm::RelayExpr const&)::{lambda(tvm::RelayExpr const&)#1}, tvm::relay::MixedModeMutator::VisitExpr(tvm::RelayExpr const&)::{lambda(tvm::RelayExpr const&)#2}>(tvm::RelayExpr, tvm::relay::MixedModeMutator::VisitExpr(tvm::RelayExpr const&)::{lambda(tvm::RelayExpr const&)#1}, tvm::relay::MixedModeMutator::VisitExpr(tvm::RelayExpr const&)::{lambda(tvm::RelayExpr const&)#2})::{lambda(tvm::RelayExpr const&)#1}>(tvm::RelayExpr, tvm::relay::MixedModeMutator::VisitExpr(tvm::RelayExpr const&)::{lambda(tvm::RelayExpr const&)#1}, tvm::relay::MixedModeMutator::VisitExpr(tvm::RelayExpr const&)::{lambda(tvm::RelayExpr const&)#2}, tvm::relay::ExpandDataflow<tvm::relay::MixedModeMutator::VisitExpr(tvm::RelayExpr const&)::{lambda(tvm::RelayExpr const&)#1}, tvm::relay::MixedModeMutator::VisitExpr(tvm::RelayExpr const&)::{lambda(tvm::RelayExpr const&)#2}>(tvm::RelayExpr, tvm::relay::MixedModeMutator::VisitExpr(tvm::RelayExpr const&)::{lambda(tvm::RelayExpr const&)#1}, tvm::relay::MixedModeMutator::VisitExpr(tvm::RelayExpr const&)::{lambda(tvm::RelayExpr const&)#2})::{lambda(tvm::RelayExpr const&)#1}) [clone .isra.0]
  9: tvm::relay::MixedModeMutator::VisitLeaf(tvm::RelayExpr const&)
  8: _ZN3tvm5relay16MixedModeMutator17DispatchVisitExprERKNS_9RelayExp
  7: tvm::relay::ExprMutator::VisitExpr(tvm::RelayExpr const&)
  6: _ZZN3tvm5relay11ExprFunctorIFNS_9RelayExprERKS2_EE10InitVTableEvENUlRKNS_7r
  5: tvm::relay::MixedModeMutator::VisitExpr_(tvm::relay::CallNode const*)
  4: tvm::relay::partitioning::Partitioner::Rewrite_(tvm::relay::CallNode const*, tvm::RelayExpr const&)
  3: tvm::relay::partitioning::Partitioner::CreateFunction(tvm::relay::AnnotatedRegion, tvm::relay::CallNode const*)
  2: tvm::relay::partitioning::Partitioner::CreateRegionCall(tvm::relay::AnnotatedRegion, tvm::runtime::Array<tvm::RelayExpr, void> const&, tvm::relay::CallNode const*)
  1: tvm::IRModuleNode::Add(tvm::GlobalVar const&, tvm::BaseFunc const&, bool)
  0: tvm::runtime::PackedFuncObj::Extractor<tvm::runtime::PackedFuncSubObj<tvm::runtime::TypedPackedFunc<void (tvm::IRModule const&, tvm::BaseFunc const&)>::AssignTypedLambda<tvm::relay::{lambda(tvm::IRModule const&, tvm::BaseFunc const&)#3}>(tvm::relay::{lambda(tvm::IRModule const&, tvm::BaseFunc const&)#3}, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >)::{lambda(tvm::runtime::TVMArgs const&, tvm::runtime::TVMRetValue*)#1}> >::Call(tvm::runtime::PackedFuncObj const*, tvm::runtime::TVMArgs, tvm::runtime::TVMRetValue*)
  File "/media/pc/data/lxw/ai/tvm/src/relay/ir/function.cc", line 156
InternalError: Check failed: fv.size() == 0 (1 vs. 0) : Function:
fn (%test_1_i0: Tensor[(1, 3, 224, 224), float32], %test_1_i1: Tensor[(32, 3, 3, 3), float32], %test_1_i2: Tensor[(32, 1, 1), float32], global_symbol="test_main_1", Primitive=1, Compiler="test", Inline=1) -> Tensor[(1, 32, 112, 112), float32] {
  free_var %test_0_i0: fn (Tensor[(1, 3, 224, 224), float32], Tensor[(32, 3, 3, 3), float32], Tensor[(32, 1, 1), float32]) -> Tensor[(1, 32, 112, 112), float32];
  %test_0_i0(%test_1_i0, %test_1_i1, %test_1_i2) /* ty=Tensor[(1, 32, 112, 112), float32] */
}
contains free variables: [Var(test_0_i0, ty=I.FuncType([], [I.TensorType([1, 3, 224, 224], "float32"), I.TensorType([32, 3, 3, 3], "float32"), I.TensorType([32, 1, 1], "float32")], I.TensorType([1, 32, 112, 112], "float32")))]
print(calibrate_mod_t)
def @main(%data: Tensor[(1, 3, 224, 224), float32] /* ty=Tensor[(1, 3, 224, 224), float32] span=aten::_convolution_0.data:0:0 */) -> Tensor[(1, 32, 112, 112), float32] {
  let %x_417: float32 /* ty=float32 */ = 0.0340509f /* ty=float32 */;
  let %x_418: float32 /* ty=float32 */ = -127f /* ty=float32 */;
  let %x_419: float32 /* ty=float32 */ = 127f /* ty=float32 */;
  %0 = relay.op.annotation.simulated_quantize(%data, %x_417, %x_418, %x_419, kind=1) /* ty=Tensor[(1, 3, 224, 224), float32] */;
  let %x_420: Tensor[(1, 3, 224, 224), float32] /* ty=Tensor[(1, 3, 224, 224), float32] */ = annotation.compiler_end(%0, compiler="default") /* ty=Tensor[(1, 3, 224, 224), float32] */;
  let %x_421: Tensor[(32, 3, 3, 3), float32] /* ty=Tensor[(32, 3, 3, 3), float32] */ = meta[relay.Constant][0] /* ty=Tensor[(32, 3, 3, 3), float32] */;
  let %x_422: float32 /* ty=float32 */ = 0.00283333f /* ty=float32 */;
  let %x_423: float32 /* ty=float32 */ = -127f /* ty=float32 */;
  let %x_424: float32 /* ty=float32 */ = 127f /* ty=float32 */;
  %1 = relay.op.annotation.simulated_quantize(%x_421, %x_422, %x_423, %x_424, kind=2) /* ty=Tensor[(32, 3, 3, 3), float32] */;
  let %x_425: Tensor[(32, 3, 3, 3), float32] /* ty=Tensor[(32, 3, 3, 3), float32] */ = annotation.compiler_end(%1, compiler="default") /* ty=Tensor[(32, 3, 3, 3), float32] */;
  let %x_426: Tensor[(32, 1, 1), float32] /* ty=Tensor[(32, 1, 1), float32] */ = meta[relay.Constant][1] /* ty=Tensor[(32, 1, 1), float32] */;
  let %x_439: fn (Tensor[(1, 3, 224, 224), float32], Tensor[(32, 3, 3, 3), float32], Tensor[(32, 1, 1), float32]) -> Tensor[(1, 32, 112, 112), float32] /* ty=fn (Tensor[(1, 3, 224, 224), float32], Tensor[(32, 3, 3, 3), float32], Tensor[(32, 1, 1), float32]) -> Tensor[(1, 32, 112, 112), float32] */ = fn (%FunctionVar_1_0: Tensor[(1, 3, 224, 224), float32] /* ty=Tensor[(1, 3, 224, 224), float32] */, %FunctionVar_1_1: Tensor[(32, 3, 3, 3), float32] /* ty=Tensor[(32, 3, 3, 3), float32] */, %FunctionVar_1_2: Tensor[(32, 1, 1), float32] /* ty=Tensor[(32, 1, 1), float32] */, PartitionedFromPattern="nn.conv2d_relay.op.annotation.simulated_quantize_add_clip_relay.op.annotation.simulated_quantize_annotation.cast_hint_", Composite="ccompiler.conv_add_activate") -> Tensor[(1, 32, 112, 112), float32] {
    %2 = nn.conv2d(%FunctionVar_1_0, %FunctionVar_1_1, strides=[2, 2], padding=[1, 1, 1, 1], channels=32, kernel_size=[3, 3]) /* ty=Tensor[(1, 32, 112, 112), float32] */;
    let %x_427: Tensor[(1, 32, 112, 112), float32] /* ty=Tensor[(1, 32, 112, 112), float32] */ = annotation.compiler_end(%2, compiler="default") /* ty=Tensor[(1, 32, 112, 112), float32] */;
    let %x_428: float32 /* ty=float32 */ = 0.00756057f /* ty=float32 */;
    let %x_429: float32 /* ty=float32 */ = -127f /* ty=float32 */;
    let %x_430: float32 /* ty=float32 */ = 127f /* ty=float32 */;
    %3 = relay.op.annotation.simulated_quantize(%FunctionVar_1_2, %x_428, %x_429, %x_430, kind=2) /* ty=Tensor[(32, 1, 1), float32] */;
    let %x_431: Tensor[(32, 1, 1), float32] /* ty=Tensor[(32, 1, 1), float32] */ = annotation.compiler_end(%3, compiler="default") /* ty=Tensor[(32, 1, 1), float32] */;
    %4 = add(%x_427, %x_431) /* ty=Tensor[(1, 32, 112, 112), float32] */;
    let %x_432: Tensor[(1, 32, 112, 112), float32] /* ty=Tensor[(1, 32, 112, 112), float32] */ = annotation.compiler_end(%4, compiler="default") /* ty=Tensor[(1, 32, 112, 112), float32] */;
    %5 = clip(%x_432, a_min=0f, a_max=6f) /* ty=Tensor[(1, 32, 112, 112), float32] */;
    let %x_433: Tensor[(1, 32, 112, 112), float32] /* ty=Tensor[(1, 32, 112, 112), float32] */ = annotation.compiler_end(%5, compiler="default") /* ty=Tensor[(1, 32, 112, 112), float32] */;
    let %x_434: float32 /* ty=float32 */ = 0.0150701f /* ty=float32 */;
    let %x_435: float32 /* ty=float32 */ = -127f /* ty=float32 */;
    let %x_436: float32 /* ty=float32 */ = 127f /* ty=float32 */;
    %6 = relay.op.annotation.simulated_quantize(%x_433, %x_434, %x_435, %x_436, kind=1) /* ty=Tensor[(1, 32, 112, 112), float32] */;
    let %x_437: Tensor[(1, 32, 112, 112), float32] /* ty=Tensor[(1, 32, 112, 112), float32] */ = annotation.compiler_end(%6, compiler="default") /* ty=Tensor[(1, 32, 112, 112), float32] */;
    %7 = annotation.cast_hint(%x_437, dtype="int8") /* ty=Tensor[(1, 32, 112, 112), float32] */;
    let %x_438: Tensor[(1, 32, 112, 112), float32] /* ty=Tensor[(1, 32, 112, 112), float32] */ = annotation.compiler_end(%7, compiler="default") /* ty=Tensor[(1, 32, 112, 112), float32] */;
    %x_438
  } /* ty=fn (Tensor[(1, 3, 224, 224), float32], Tensor[(32, 3, 3, 3), float32], Tensor[(32, 1, 1), float32]) -> Tensor[(1, 32, 112, 112), float32] */;
  %8 = annotation.compiler_begin(%x_420, compiler="test") /* ty=Tensor[(1, 3, 224, 224), float32] */;
  %9 = annotation.compiler_begin(%x_425, compiler="test") /* ty=Tensor[(32, 3, 3, 3), float32] */;
  %10 = annotation.compiler_begin(%x_426, compiler="test") /* ty=Tensor[(32, 1, 1), float32] */;
  %11 = annotation.compiler_begin(%x_439, compiler="test") /* ty=fn (Tensor[(1, 3, 224, 224), float32], Tensor[(32, 3, 3, 3), float32], Tensor[(32, 1, 1), float32]) -> Tensor[(1, 32, 112, 112), float32] */;
  %12 = %11(%8, %9, %10) /* ty=Tensor[(1, 32, 112, 112), float32] */;
  let %x_440: Tensor[(1, 32, 112, 112), float32] /* ty=Tensor[(1, 32, 112, 112), float32] */ = annotation.compiler_end(%12, compiler="test") /* ty=Tensor[(1, 32, 112, 112), float32] */;
  %13 = annotation.stop_fusion(%x_440) /* ty=Tensor[(1, 32, 112, 112), float32] */;
  let %x_441: Tensor[(1, 32, 112, 112), float32] /* ty=Tensor[(1, 32, 112, 112), float32] */ = annotation.compiler_end(%13, compiler="default") /* ty=Tensor[(1, 32, 112, 112), float32] */;
  let %x_442: Tensor[(32, 1, 3, 3), float32] /* ty=Tensor[(32, 1, 3, 3), float32] */ = meta[relay.Constant][2] /* ty=Tensor[(32, 1, 3, 3), float32] */;
  let %x_443: float32 /* ty=float32 */ = 0.117756f /* ty=float32 */;
  let %x_444: float32 /* ty=float32 */ = -127f /* ty=float32 */;
  let %x_445: float32 /* ty=float32 */ = 127f /* ty=float32 */;
  %14 = relay.op.annotation.simulated_quantize(%x_442, %x_443, %x_444, %x_445, kind=2) /* ty=Tensor[(32, 1, 3, 3), float32] */;
  let %x_446: Tensor[(32, 1, 3, 3), float32] /* ty=Tensor[(32, 1, 3, 3), float32] */ = annotation.compiler_end(%14, compiler="default") /* ty=Tensor[(32, 1, 3, 3), float32] */;
  let %x_447: Tensor[(32, 1, 1), float32] /* ty=Tensor[(32, 1, 1), float32] */ = meta[relay.Constant][3] /* ty=Tensor[(32, 1, 1), float32] */;
  let %x_460: fn (Tensor[(1, 32, 112, 112), float32], Tensor[(32, 1, 3, 3), float32], Tensor[(32, 1, 1), float32]) -> Tensor[(1, 32, 112, 112), float32] /* ty=fn (Tensor[(1, 32, 112, 112), float32], Tensor[(32, 1, 3, 3), float32], Tensor[(32, 1, 1), float32]) -> Tensor[(1, 32, 112, 112), float32] */ = fn (%FunctionVar_0_0: Tensor[(1, 32, 112, 112), float32] /* ty=Tensor[(1, 32, 112, 112), float32] */, %FunctionVar_0_1: Tensor[(32, 1, 3, 3), float32] /* ty=Tensor[(32, 1, 3, 3), float32] */, %FunctionVar_0_2: Tensor[(32, 1, 1), float32] /* ty=Tensor[(32, 1, 1), float32] */, PartitionedFromPattern="nn.conv2d_relay.op.annotation.simulated_quantize_add_clip_relay.op.annotation.simulated_quantize_annotation.cast_hint_", Composite="ccompiler.conv_add_activate") -> Tensor[(1, 32, 112, 112), float32] {
    %15 = nn.conv2d(%FunctionVar_0_0, %FunctionVar_0_1, padding=[1, 1, 1, 1], groups=32, channels=32, kernel_size=[3, 3]) /* ty=Tensor[(1, 32, 112, 112), float32] */;
    let %x_448: Tensor[(1, 32, 112, 112), float32] /* ty=Tensor[(1, 32, 112, 112), float32] */ = annotation.compiler_end(%15, compiler="default") /* ty=Tensor[(1, 32, 112, 112), float32] */;
    let %x_449: float32 /* ty=float32 */ = 0.0291522f /* ty=float32 */;
    let %x_450: float32 /* ty=float32 */ = -127f /* ty=float32 */;
    let %x_451: float32 /* ty=float32 */ = 127f /* ty=float32 */;
    %16 = relay.op.annotation.simulated_quantize(%FunctionVar_0_2, %x_449, %x_450, %x_451, kind=2) /* ty=Tensor[(32, 1, 1), float32] */;
    let %x_452: Tensor[(32, 1, 1), float32] /* ty=Tensor[(32, 1, 1), float32] */ = annotation.compiler_end(%16, compiler="default") /* ty=Tensor[(32, 1, 1), float32] */;
    %17 = add(%x_448, %x_452) /* ty=Tensor[(1, 32, 112, 112), float32] */;
    let %x_453: Tensor[(1, 32, 112, 112), float32] /* ty=Tensor[(1, 32, 112, 112), float32] */ = annotation.compiler_end(%17, compiler="default") /* ty=Tensor[(1, 32, 112, 112), float32] */;
    %18 = clip(%x_453, a_min=0f, a_max=6f) /* ty=Tensor[(1, 32, 112, 112), float32] */;
    let %x_454: Tensor[(1, 32, 112, 112), float32] /* ty=Tensor[(1, 32, 112, 112), float32] */ = annotation.compiler_end(%18, compiler="default") /* ty=Tensor[(1, 32, 112, 112), float32] */;
    let %x_455: float32 /* ty=float32 */ = 0.0460431f /* ty=float32 */;
    let %x_456: float32 /* ty=float32 */ = -127f /* ty=float32 */;
    let %x_457: float32 /* ty=float32 */ = 127f /* ty=float32 */;
    %19 = relay.op.annotation.simulated_quantize(%x_454, %x_455, %x_456, %x_457, kind=1) /* ty=Tensor[(1, 32, 112, 112), float32] */;
    let %x_458: Tensor[(1, 32, 112, 112), float32] /* ty=Tensor[(1, 32, 112, 112), float32] */ = annotation.compiler_end(%19, compiler="default") /* ty=Tensor[(1, 32, 112, 112), float32] */;
    %20 = annotation.cast_hint(%x_458, dtype="int8") /* ty=Tensor[(1, 32, 112, 112), float32] */;
    let %x_459: Tensor[(1, 32, 112, 112), float32] /* ty=Tensor[(1, 32, 112, 112), float32] */ = annotation.compiler_end(%20, compiler="default") /* ty=Tensor[(1, 32, 112, 112), float32] */;
    %x_459
  } /* ty=fn (Tensor[(1, 32, 112, 112), float32], Tensor[(32, 1, 3, 3), float32], Tensor[(32, 1, 1), float32]) -> Tensor[(1, 32, 112, 112), float32] */;
  %21 = annotation.compiler_begin(%x_441, compiler="test") /* ty=Tensor[(1, 32, 112, 112), float32] */;
  %22 = annotation.compiler_begin(%x_446, compiler="test") /* ty=Tensor[(32, 1, 3, 3), float32] */;
  %23 = annotation.compiler_begin(%x_447, compiler="test") /* ty=Tensor[(32, 1, 1), float32] */;
  %24 = annotation.compiler_begin(%x_460, compiler="test") /* ty=fn (Tensor[(1, 32, 112, 112), float32], Tensor[(32, 1, 3, 3), float32], Tensor[(32, 1, 1), float32]) -> Tensor[(1, 32, 112, 112), float32] */;
  %25 = %24(%21, %22, %23) /* ty=Tensor[(1, 32, 112, 112), float32] */;
  let %x_461: Tensor[(1, 32, 112, 112), float32] /* ty=Tensor[(1, 32, 112, 112), float32] */ = annotation.compiler_end(%25, compiler="test") /* ty=Tensor[(1, 32, 112, 112), float32] */;
  %26 = annotation.stop_fusion(%x_461) /* ty=Tensor[(1, 32, 112, 112), float32] */;
  let %x_462: Tensor[(1, 32, 112, 112), float32] /* ty=Tensor[(1, 32, 112, 112), float32] */ = annotation.compiler_end(%26, compiler="default") /* ty=Tensor[(1, 32, 112, 112), float32] */;
  %x_462
}
node.op
func_id = 0
call = calibrate_transform.nodes[func_id]
new_fn = call.op
new_args = new_fn.params
call = run_opt_pass(call, relay.transform.DefuseOps())
print(call)
new_fn = tvm.IRModule.from_expr(call)["main"]
call = Call(new_fn.body, new_fn.params, attrs=new_fn.attrs, type_args=new_fn.type_params, span=new_fn.span)
# call = run_opt_pass(call, relay.transform.DefuseOps())
# new_args = [relay.var(f"x_{func_id:03}_{ind:03d}") for ind, arg in enumerate(new_fn.params)]
# _bind_dict = dict(zip(new_fn.params, new_args))
# new_fn = relay.bind(new_fn, _bind_dict)
print(call)
g_var_names = []
for arg in calibrate_mod_t.get_global_vars():
    if arg.name_hint == "main":
        continue
    new_fn = calibrate_mod_t[arg]
    # 过滤不需要的函数
    name = new_fn.attrs["PartitionedFromPattern"].replace("relay.op.annotation.simulated_quantize_", "").replace("annotation.cast_hint_", "")
    if "squeeze" in name:
        continue
    g_var_names.append(arg.name_hint)
g_var_names.sort()
float_mod = tvm.IRModule()
for func_name in g_var_names:
    new_fn = partition_transform.bind_dict[func_name]
    float_mod[func_name] = new_fn

q_mod = tvm.IRModule()
for func_name in g_var_names:
    new_fn = calibrate_mod_t[func_name]
    new_fn = DefuseMutator(float_mod).visit(new_fn)
    q_mod[func_name] = new_fn
# partial_quant_outputs = []
# for func_name in tqdm(g_var_names):
#     new_fn = calibrate_mod_t[func_name]
#     new_fn = DefuseMutator(float_mod).visit(new_fn)
#     run_mod = tvm.IRModule.from_expr(new_fn)
#     # partial_quant_output = run_llvm_graph(
#     #     run_mod,
#     #     origin_params,
#     #     {"data": np.random.normal(size=input_shape)}
#     # )
#     # partial_quant_outputs.append(partial_quant_output)
#     break
float_mod_t = tvm.IRModule()
main_args = mod["main"].params
main_fns = []
for k, func_name in enumerate(g_var_names):
    new_fn = float_mod[func_name]
    new_args = [relay.var(f"x_{k:03}_{ind:03d}") for ind, arg in enumerate(new_fn.params)]
    _bind_dict = dict(zip(new_fn.params, new_args))
    new_fn = relay.bind(new_fn, _bind_dict)
    float_mod_t[func_name] = new_fn
    call = Call(new_fn, main_args, attrs=new_fn.attrs, type_args=new_fn.type_params, span=new_fn.span)
    main_fns.append(call)
new_fn = run_opt_pass(relay.Tuple(main_fns), relay.transform.DefuseOps())
float_mod_t = tvm.IRModule.from_expr(new_fn)
float_outputs = run_llvm_graph(
    float_mod_t,
    origin_params,
    {"data": np.random.normal(size=input_shape)}
)
partial_quant_outputs = run_llvm_graph(
    float_mod_t,
    origin_params,
    {"data": np.random.normal(size=input_shape)}
)
partial_quant_outputs = []

for func_name in tqdm(g_var_names):
    new_fn = calibrate_mod_t[func_name]
    new_params = transform.bind_params[func_name]
    _bind_dict = dict(zip(new_fn.params, new_params))
    new_fn = relay.bind(new_fn, _bind_dict)
    new_fn = DefuseTransform(partition_mod_t).visit(new_fn)
    new_fn = run_opt_pass(new_fn, relay.transform.DefuseOps())
    print(f"部分量化 {func_name}:\n{new_fn}")
    run_mod = tvm.IRModule.from_expr(new_fn)
    # 部分量化模型输出
    partial_quant_output = run_llvm_graph(
        run_mod,
        origin_params,
        {"data": np.random.normal(size=input_shape)}
    )
    partial_quant_outputs.append(partial_quant_output[0])
    # if func_name == "f_0002":
    #     break
partial_quant_outputs[0].shape