[Relay][PyTorch] When compiling PyTorch's fasterrcnn_resnet50_fpn_v2, I got `TVMError: if is not supported`

Hi there,

I’m trying to compile PyTorch’s fasterrcnn_resnet50_fpn_v2 model but I got TVMError: if is not supported error.

I checked the community discussion and found the below comment.

In the PR, there’s PyTorch frontend change so I’m guessing PyTorch is also supported.

Here’s the code and the output.

from tvm import relay
import tvm
import torch
from torchvision.models.detection import fasterrcnn_resnet50_fpn_v2, FasterRCNN_ResNet50_FPN_V2_Weights

weights = FasterRCNN_ResNet50_FPN_V2_Weights.DEFAULT
model = fasterrcnn_resnet50_fpn_v2(weights=weights, box_score_thresh=0.9)
model.eval()

class TraceWrapper(torch.nn.Module):
  def __init__(self, model):
    super().__init__()
    self.model = model

  def forward(self, x):
    out = self.model(x)[0]
    return out["boxes"], out["scores"], out["labels"]

input_shape = [1, 3, 224, 224]
input_data = torch.randn(input_shape, dtype=torch.float32)
wrapped_model = TraceWrapper(model).eval()
scripted_model = torch.jit.trace(wrapped_model, input_data)

input_name = "input0"
shape_list = [(input_name, input_data.shape)]
mod, params = relay.frontend.from_pytorch(scripted_model, shape_list)

target = tvm.target.Target("llvm")
with tvm.transform.PassContext(opt_level=3):
  lib = relay.build(mod, params=params, target=target)
One or more operators have not been tuned. Please tune your model for better performance. Use DEBUG logging level to see more details.
Traceback (most recent call last):
  File "/home/ubuntu/workspace/sandbox/tvm_/frontend/objectdetection.py", line 32, in <module>
    lib = relay.build(mod, params=params, target=target)
  File "/home/ubuntu/workspace/sandbox/.dep/tvm/python/tvm/relay/build_module.py", line 364, in build
    graph_json, runtime_mod, params = bld_mod.build(
  File "/home/ubuntu/workspace/sandbox/.dep/tvm/python/tvm/relay/build_module.py", line 161, in build
    self._build(
  File "/home/ubuntu/workspace/sandbox/.dep/tvm/python/tvm/_ffi/_ctypes/packed_func.py", line 239, in __call__
    raise_last_ffi_error()
  File "/home/ubuntu/workspace/sandbox/.dep/tvm/python/tvm/_ffi/base.py", line 481, in raise_last_ffi_error
    raise py_err
tvm._ffi.base.TVMError: Traceback (most recent call last):
  110: tvm::runtime::PackedFuncObj::Extractor<tvm::runtime::PackedFuncSubObj<tvm::relay::backend::RelayBuildModule::GetFunction(tvm::runtime::String const&, tvm::runtime::ObjectPtr<tvm::runtime::Object> const&)::{lambda(tvm::runtime::TVMArgs, tvm::runtime::TVMRetValue*)#3}> >::Call(tvm::runtime::PackedFuncObj const*, tvm::runtime::TVMArgs, tvm::runtime::TVMRetValue*)
  109: tvm::relay::backend::RelayBuildModule::BuildRelay(tvm::IRModule, tvm::runtime::String const&)
  108: void tvm::relay::backend::ExecutorCodegen::CallFunc<tvm::IRModule, tvm::relay::Function, tvm::runtime::String>(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, tvm::IRModule, tvm::relay::Function, tvm::runtime::String)
  107: tvm::runtime::PackedFuncObj::Extractor<tvm::runtime::PackedFuncSubObj<tvm::relay::backend::GraphExecutorCodegenModule::GetFunction(tvm::runtime::String const&, tvm::runtime::ObjectPtr<tvm::runtime::Object> const&)::{lambda(tvm::runtime::TVMArgs, tvm::runtime::TVMRetValue*)#2}> >::Call(tvm::runtime::PackedFuncObj const*, tvm::runtime::TVMArgs, tvm::runtime::TVMRetValue*)
  106: tvm::relay::backend::GraphExecutorCodegen::Codegen(tvm::IRModule, tvm::relay::Function, tvm::runtime::String)
  105: tvm::relay::GraphPlanMemory(tvm::relay::Function const&)
  104: tvm::relay::StorageAllocator::Plan(tvm::relay::Function const&)
  103: tvm::relay::ExprVisitor::VisitExpr(tvm::RelayExpr const&)
  102: tvm::relay::transform::DeviceAwareExprVisitor::VisitExpr_(tvm::relay::FunctionNode const*)
  101: tvm::relay::StorageAllocaBaseVisitor::DeviceAwareVisitExpr_(tvm::relay::FunctionNode const*)
  100: tvm::relay::StorageAllocaBaseVisitor::GetToken(tvm::RelayExpr const&)
  99: tvm::relay::ExprVisitor::VisitExpr(tvm::RelayExpr const&)
  98: tvm::relay::transform::DeviceAwareExprVisitor::VisitExpr_(tvm::relay::LetNode const*)
  97: tvm::relay::StorageAllocaBaseVisitor::PreVisitLetBinding_(tvm::relay::Var const&, tvm::RelayExpr const&)
  96: tvm::relay::StorageAllocaBaseVisitor::GetToken(tvm::RelayExpr const&)
  95: tvm::relay::ExprVisitor::VisitExpr(tvm::RelayExpr const&)
  94: tvm::relay::transform::DeviceAwareExprVisitor::VisitExpr_(tvm::relay::CallNode const*)
  93: tvm::relay::ExprVisitor::VisitExpr(tvm::RelayExpr const&)
  92: tvm::relay::transform::DeviceAwareExprVisitor::VisitExpr_(tvm::relay::CallNode const*)
  91: tvm::relay::StorageAllocaInit::DeviceAwareVisitExpr_(tvm::relay::CallNode const*)
  90: tvm::relay::StorageAllocaBaseVisitor::GetToken(tvm::RelayExpr const&)
  89: tvm::relay::ExprVisitor::VisitExpr(tvm::RelayExpr const&)
  88: tvm::relay::transform::DeviceAwareExprVisitor::VisitExpr_(tvm::relay::CallNode const*)
  87: tvm::relay::StorageAllocaInit::DeviceAwareVisitExpr_(tvm::relay::CallNode const*)
  86: tvm::relay::StorageAllocaBaseVisitor::GetToken(tvm::RelayExpr const&)
  85: tvm::relay::ExprVisitor::VisitExpr(tvm::RelayExpr const&)
  84: tvm::relay::transform::DeviceAwareExprVisitor::VisitExpr_(tvm::relay::CallNode const*)
  83: tvm::relay::StorageAllocaInit::DeviceAwareVisitExpr_(tvm::relay::CallNode const*)
  82: tvm::relay::StorageAllocaBaseVisitor::GetToken(tvm::RelayExpr const&)
  81: tvm::relay::ExprVisitor::VisitExpr(tvm::RelayExpr const&)
  80: tvm::relay::transform::DeviceAwareExprVisitor::VisitExpr_(tvm::relay::CallNode const*)
  79: tvm::relay::StorageAllocaInit::DeviceAwareVisitExpr_(tvm::relay::CallNode const*)
  78: tvm::relay::StorageAllocaBaseVisitor::GetToken(tvm::RelayExpr const&)
  77: tvm::relay::ExprVisitor::VisitExpr(tvm::RelayExpr const&)
  76: tvm::relay::transform::DeviceAwareExprVisitor::VisitExpr_(tvm::relay::CallNode const*)
  75: tvm::relay::StorageAllocaInit::DeviceAwareVisitExpr_(tvm::relay::CallNode const*)
  74: tvm::relay::StorageAllocaBaseVisitor::GetToken(tvm::RelayExpr const&)
  73: tvm::relay::ExprVisitor::VisitExpr(tvm::RelayExpr const&)
  72: tvm::relay::transform::DeviceAwareExprVisitor::VisitExpr_(tvm::relay::CallNode const*)
  71: tvm::relay::StorageAllocaInit::DeviceAwareVisitExpr_(tvm::relay::CallNode const*)
  70: tvm::relay::StorageAllocaBaseVisitor::GetToken(tvm::RelayExpr const&)
  69: tvm::relay::ExprVisitor::VisitExpr(tvm::RelayExpr const&)
  68: tvm::relay::transform::DeviceAwareExprVisitor::VisitExpr_(tvm::relay::CallNode const*)
  67: tvm::relay::StorageAllocaInit::DeviceAwareVisitExpr_(tvm::relay::CallNode const*)
  66: tvm::relay::StorageAllocaBaseVisitor::GetToken(tvm::RelayExpr const&)
  65: tvm::relay::ExprVisitor::VisitExpr(tvm::RelayExpr const&)
  64: tvm::relay::transform::DeviceAwareExprVisitor::VisitExpr_(tvm::relay::CallNode const*)
  63: tvm::relay::StorageAllocaInit::DeviceAwareVisitExpr_(tvm::relay::CallNode const*)
  62: tvm::relay::StorageAllocaBaseVisitor::GetToken(tvm::RelayExpr const&)
  61: tvm::relay::ExprVisitor::VisitExpr(tvm::RelayExpr const&)
  60: tvm::relay::transform::DeviceAwareExprVisitor::VisitExpr_(tvm::relay::CallNode const*)
  59: tvm::relay::StorageAllocaInit::DeviceAwareVisitExpr_(tvm::relay::CallNode const*)
  58: tvm::relay::StorageAllocaBaseVisitor::GetToken(tvm::RelayExpr const&)
  57: tvm::relay::ExprVisitor::VisitExpr(tvm::RelayExpr const&)
  56: tvm::relay::transform::DeviceAwareExprVisitor::VisitExpr_(tvm::relay::CallNode const*)
  55: tvm::relay::StorageAllocaInit::DeviceAwareVisitExpr_(tvm::relay::CallNode const*)
  54: tvm::relay::StorageAllocaBaseVisitor::GetToken(tvm::RelayExpr const&)
  53: tvm::relay::ExprVisitor::VisitExpr(tvm::RelayExpr const&)
  52: tvm::relay::transform::DeviceAwareExprVisitor::VisitExpr_(tvm::relay::CallNode const*)
  51: tvm::relay::StorageAllocaInit::DeviceAwareVisitExpr_(tvm::relay::CallNode const*)
  50: tvm::relay::StorageAllocaBaseVisitor::GetToken(tvm::RelayExpr const&)
  49: tvm::relay::ExprVisitor::VisitExpr(tvm::RelayExpr const&)
  48: tvm::relay::transform::DeviceAwareExprVisitor::VisitExpr_(tvm::relay::CallNode const*)
  47: tvm::relay::StorageAllocaInit::DeviceAwareVisitExpr_(tvm::relay::CallNode const*)
  46: tvm::relay::StorageAllocaBaseVisitor::GetToken(tvm::RelayExpr const&)
  45: tvm::relay::ExprVisitor::VisitExpr(tvm::RelayExpr const&)
  44: tvm::relay::transform::DeviceAwareExprVisitor::VisitExpr_(tvm::relay::CallNode const*)
  43: tvm::relay::StorageAllocaInit::DeviceAwareVisitExpr_(tvm::relay::CallNode const*)
  42: tvm::relay::StorageAllocaBaseVisitor::GetToken(tvm::RelayExpr const&)
  41: tvm::relay::ExprVisitor::VisitExpr(tvm::RelayExpr const&)
  40: tvm::relay::transform::DeviceAwareExprVisitor::VisitExpr_(tvm::relay::CallNode const*)
  39: tvm::relay::StorageAllocaInit::DeviceAwareVisitExpr_(tvm::relay::CallNode const*)
  38: tvm::relay::StorageAllocaBaseVisitor::GetToken(tvm::RelayExpr const&)
  37: tvm::relay::ExprVisitor::VisitExpr(tvm::RelayExpr const&)
  36: tvm::relay::transform::DeviceAwareExprVisitor::VisitExpr_(tvm::relay::CallNode const*)
  35: tvm::relay::StorageAllocaInit::DeviceAwareVisitExpr_(tvm::relay::CallNode const*)
  34: tvm::relay::StorageAllocaBaseVisitor::GetToken(tvm::RelayExpr const&)
  33: tvm::relay::ExprVisitor::VisitExpr(tvm::RelayExpr const&)
  32: tvm::relay::transform::DeviceAwareExprVisitor::VisitExpr_(tvm::relay::CallNode const*)
  31: tvm::relay::StorageAllocaInit::DeviceAwareVisitExpr_(tvm::relay::CallNode const*)
  30: tvm::relay::StorageAllocaBaseVisitor::GetToken(tvm::RelayExpr const&)
  29: tvm::relay::ExprVisitor::VisitExpr(tvm::RelayExpr const&)
  28: tvm::relay::transform::DeviceAwareExprVisitor::VisitExpr_(tvm::relay::CallNode const*)
  27: tvm::relay::StorageAllocaInit::DeviceAwareVisitExpr_(tvm::relay::CallNode const*)
  26: tvm::relay::StorageAllocaBaseVisitor::GetToken(tvm::RelayExpr const&)
  25: tvm::relay::ExprVisitor::VisitExpr(tvm::RelayExpr const&)
  24: tvm::relay::transform::DeviceAwareExprVisitor::VisitExpr_(tvm::relay::CallNode const*)
  23: tvm::relay::StorageAllocaInit::DeviceAwareVisitExpr_(tvm::relay::CallNode const*)
  22: tvm::relay::StorageAllocaBaseVisitor::GetToken(tvm::RelayExpr const&)
  21: tvm::relay::ExprVisitor::VisitExpr(tvm::RelayExpr const&)
  20: tvm::relay::transform::DeviceAwareExprVisitor::VisitExpr_(tvm::relay::CallNode const*)
  19: tvm::relay::StorageAllocaInit::DeviceAwareVisitExpr_(tvm::relay::CallNode const*)
  18: tvm::relay::StorageAllocaBaseVisitor::GetToken(tvm::RelayExpr const&)
  17: tvm::relay::ExprVisitor::VisitExpr(tvm::RelayExpr const&)
  16: tvm::relay::transform::DeviceAwareExprVisitor::VisitExpr_(tvm::relay::CallNode const*)
  15: tvm::relay::StorageAllocaInit::DeviceAwareVisitExpr_(tvm::relay::CallNode const*)
  14: tvm::relay::StorageAllocaBaseVisitor::GetToken(tvm::RelayExpr const&)
  13: tvm::relay::ExprVisitor::VisitExpr(tvm::RelayExpr const&)
  12: tvm::relay::transform::DeviceAwareExprVisitor::VisitExpr_(tvm::relay::CallNode const*)
  11: tvm::relay::StorageAllocaInit::DeviceAwareVisitExpr_(tvm::relay::CallNode const*)
  10: tvm::relay::StorageAllocaBaseVisitor::GetToken(tvm::RelayExpr const&)
  9: tvm::relay::ExprVisitor::VisitExpr(tvm::RelayExpr const&)
  8: tvm::relay::transform::DeviceAwareExprVisitor::VisitExpr_(tvm::relay::CallNode const*)
  7: tvm::relay::StorageAllocaInit::DeviceAwareVisitExpr_(tvm::relay::CallNode const*)
  6: tvm::relay::StorageAllocaBaseVisitor::GetToken(tvm::RelayExpr const&)
  5: tvm::relay::ExprVisitor::VisitExpr(tvm::RelayExpr const&)
  4: tvm::relay::transform::DeviceAwareExprVisitor::VisitExpr_(tvm::relay::CallNode const*)
  3: tvm::relay::StorageAllocaInit::DeviceAwareVisitExpr_(tvm::relay::CallNode const*)
  2: tvm::relay::StorageAllocaBaseVisitor::GetToken(tvm::RelayExpr const&)
  1: tvm::relay::ExprVisitor::VisitExpr(tvm::RelayExpr const&)
  0: _ZN3tvm5relay24StorageAllocaBaseVisitor10VisitExpr_EPKNS0_6If
  File "/home/ubuntu/workspace/sandbox/.dep/tvm/src/relay/backend/graph_plan_memory.cc", line 110
TVMError: if is not supported.

Ah, I misunderstood the comment. The if is only supported on the VM Executor.

Changing

  lib = relay.build(mod, params=params, target=target)

to

  vm_exec = relay.vm.compile(mod, target, params=params)

worked fine.