From ca63db7b4f9ffd9e08f05fd22acf6d88a0815cd6 Mon Sep 17 00:00:00 2001 From: Kevin-Li-2025 <2242139@qq.com> Date: Sun, 28 Jun 2026 21:28:11 +0800 Subject: [PATCH 1/2] [Relax][VM] Improve unlowered operator diagnostics --- src/relax/backend/vm/codegen_vm.cc | 7 +++++-- src/relax/backend/vm/codegen_vm_tir.cc | 7 +++++-- tests/python/relax/test_vm_build.py | 24 ++++++++++++++++++++++++ 3 files changed, 34 insertions(+), 4 deletions(-) diff --git a/src/relax/backend/vm/codegen_vm.cc b/src/relax/backend/vm/codegen_vm.cc index e9fda4a0a8f3..1e9e930c6eec 100644 --- a/src/relax/backend/vm/codegen_vm.cc +++ b/src/relax/backend/vm/codegen_vm.cc @@ -157,8 +157,11 @@ class CodeGenVM : public ExprFunctor { } else { // every "normal" operator is lowered to a global var in the IRModule. The Attrs for those // ops are handled in a pass when lowering them to TIR. - TVM_FFI_THROW(InternalError) << "CodeGenVM cannot handle this intrinsic now:\n" - << call_node->op; + TVM_FFI_THROW(InternalError) + << "CodeGenVM cannot emit this Relax operator directly. " + << "Run the appropriate lowering pass, or route the operator to an external " + << "codegen before VM codegen.\nOffending call:\n" + << call; } } else { EmitNormalCall(call, dst_reg); diff --git a/src/relax/backend/vm/codegen_vm_tir.cc b/src/relax/backend/vm/codegen_vm_tir.cc index a2852116fa0d..d88b08163fbe 100644 --- a/src/relax/backend/vm/codegen_vm_tir.cc +++ b/src/relax/backend/vm/codegen_vm_tir.cc @@ -246,8 +246,11 @@ class CodeGenVMTIR : public ExprFunctor(const Expr&)> { } else { // every "normal" operator is lowered to a global var in the IRModule. The Attrs for those // ops are handled in a pass when lowering them to TIR. - TVM_FFI_THROW(InternalError) << "CodeGenVMTIR cannot handle this intrinsic now:\n" - << call_node->op; + TVM_FFI_THROW(InternalError) + << "CodeGenVMTIR cannot emit this Relax operator directly. " + << "Run the appropriate lowering pass, or route the operator to an external " + << "codegen before VM codegen.\nOffending call:\n" + << call; } } else { EmitNormalCall(call, dst_reg); diff --git a/tests/python/relax/test_vm_build.py b/tests/python/relax/test_vm_build.py index 538388cc47d9..062e8742d6ed 100644 --- a/tests/python/relax/test_vm_build.py +++ b/tests/python/relax/test_vm_build.py @@ -84,6 +84,30 @@ def foo(x: R.Tensor((3, 4), "float32"), y: R.Tensor((3, 4), "float32")): tvm.testing.assert_allclose(inp2.numpy(), inp1.numpy(), rtol=1e-7, atol=1e-7) +def test_vm_compile_unlowered_operator_error(exec_mode): + @tvm.script.ir_module + class Conv2dTranspose: + @R.function + def main( + x: R.Tensor((1, 4, 4, 1), "float32"), + w: R.Tensor((1, 2, 3, 3), "float32"), + ): + gv = R.nn.conv2d_transpose( + x, + w, + data_layout="NHWC", + kernel_layout="IOHW", + ) + return gv + + mod = relax.transform.LegalizeOps()(Conv2dTranspose) + with pytest.raises( + tvm.error.InternalError, + match=r"(?s)Offending call:.*relax\.nn\.conv2d_transpose.*data_layout.*NHWC", + ): + relax.build(mod, target="llvm", exec_mode=exec_mode) + + def test_match_check(exec_mode): @tvm.script.ir_module class TestMatchCheck: From 005f50b501a21e770fee6b64793787b18d372adf Mon Sep 17 00:00:00 2001 From: Kevin-Li-2025 <2242139@qq.com> Date: Tue, 30 Jun 2026 06:54:00 +0800 Subject: [PATCH 2/2] test: accept TVMScript shorthand in VM diagnostic --- tests/python/relax/test_vm_build.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/python/relax/test_vm_build.py b/tests/python/relax/test_vm_build.py index 062e8742d6ed..f34ddf39b789 100644 --- a/tests/python/relax/test_vm_build.py +++ b/tests/python/relax/test_vm_build.py @@ -103,7 +103,7 @@ def main( mod = relax.transform.LegalizeOps()(Conv2dTranspose) with pytest.raises( tvm.error.InternalError, - match=r"(?s)Offending call:.*relax\.nn\.conv2d_transpose.*data_layout.*NHWC", + match=r"(?s)Offending call:.*(?:R|relax)\.nn\.conv2d_transpose.*data_layout.*NHWC", ): relax.build(mod, target="llvm", exec_mode=exec_mode)