This is an automated email from the ASF dual-hosted git repository.

lunderberg pushed a commit to branch unity
in repository https://gitbox.apache.org/repos/asf/tvm.git


The following commit(s) were added to refs/heads/unity by this push:
     new 1af82ad666 [Unity] Validate struct info in relax::Call constructor 
(#16311)
1af82ad666 is described below

commit 1af82ad6660314f9f42f8cde2a4696af6ed94ef7
Author: Eric Lunderberg <[email protected]>
AuthorDate: Wed Jan 3 09:50:36 2024 -0600

    [Unity] Validate struct info in relax::Call constructor (#16311)
    
    * [Unity] Validate struct info in relax::Call constructor
    
    All operations called by a `relax::Call` node must have a
    `FuncStructInfo`.  Prior to this commit, an invalid struct info would
    be caught by the `BlockBuilder` during normalization.  This delay
    between the invalid `relax::Call` being constructed and the invalid
    `relax::Call` being detected makes debugging difficult.
    This commit adds an additional check during the `relax::Call`
    constructor, to provide earlier error detection.
    
    * Updated unit test to avoid using Tensor as callable function
---
 src/relax/ir/expr.cc               |  6 ++++++
 tests/python/relax/test_expr.py    | 20 ++++++++++++++++++++
 tests/python/relax/test_op_misc.py | 14 ++++++++++++--
 3 files changed, 38 insertions(+), 2 deletions(-)

diff --git a/src/relax/ir/expr.cc b/src/relax/ir/expr.cc
index 00ad252ec4..1bc7267af6 100644
--- a/src/relax/ir/expr.cc
+++ b/src/relax/ir/expr.cc
@@ -36,6 +36,12 @@ Id::Id(String name_hint) {
 }
 
 Call::Call(Expr op, Array<Expr> args, Attrs attrs, Array<StructInfo> 
sinfo_args, Span span) {
+  CHECK(!op->struct_info_.defined() || 
op->struct_info_->IsInstance<FuncStructInfoNode>())
+      << "ValueError: "
+      << "Call expects its operator to have FuncStructInfo, "
+      << "but operator " << op << ", which was called with arguments " << args
+      << ", has struct info " << op->struct_info_;
+
   ObjectPtr<CallNode> n = make_object<CallNode>();
   n->op = std::move(op);
   n->args = std::move(args);
diff --git a/tests/python/relax/test_expr.py b/tests/python/relax/test_expr.py
index fbd37b307e..af1bc851be 100644
--- a/tests/python/relax/test_expr.py
+++ b/tests/python/relax/test_expr.py
@@ -271,5 +271,25 @@ def test_datatype_imm():
     _check_json_roundtrip(d0)
 
 
+def test_call():
+    dtype = rx.PrimStructInfo("int32")
+    func = rx.Var("func", rx.FuncStructInfo([dtype], dtype))
+    arg = rx.Var("arg", dtype)
+    call = rx.Call(func, [arg])
+    assert call.op.same_as(func)
+    assert len(call.args) == 1
+    assert call.args[0].same_as(arg)
+
+
+def test_call_raises_error_for_invalid_function():
+    """relax::Call requires the function to have FuncStructInfo"""
+    dtype = rx.PrimStructInfo("int32")
+    func = rx.Var("func", dtype)
+    arg = rx.Var("arg", dtype)
+
+    with pytest.raises(ValueError):
+        rx.Call(func, [arg])
+
+
 if __name__ == "__main__":
     tvm.testing.main()
diff --git a/tests/python/relax/test_op_misc.py 
b/tests/python/relax/test_op_misc.py
index 2bbc18af6b..f786b89043 100644
--- a/tests/python/relax/test_op_misc.py
+++ b/tests/python/relax/test_op_misc.py
@@ -66,6 +66,16 @@ def test_implicit_op():
     m, n = tvm.tir.Var("m", "int64"), tvm.tir.Var("n", "int64")
     x = rx.Var("x", R.Tensor([m, n], "float32"))
     y = rx.Var("y", R.Tensor([m, n], "float32"))
+    func = rx.Var(
+        "func",
+        R.Callable(
+            [R.Tensor([m, n], "float32")],
+            R.Callable(
+                [R.Tensor([m, n], "float32")],
+                R.Tuple,
+            ),
+        ),
+    )
 
     def _check_call(expr, op_name: str):
         assert isinstance(expr, rx.Call)
@@ -94,9 +104,9 @@ def test_implicit_op():
     _check_call(x.astype("float32"), "astype")
 
     # Call
-    call_expr = x(y)(y)
+    call_expr = func(y)(y)
     assert isinstance(call_expr.op, rx.Call)
-    assert call_expr.op.op == x
+    assert call_expr.op.op == func
 
     # GetTupleItem
     ## Eager get item for tuple

Reply via email to