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

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


The following commit(s) were added to refs/heads/main by this push:
     new d05715daed [TIR][TVMScript] Convert tir.op operands to PrimExpr 
(#15091)
d05715daed is described below

commit d05715daed9403bada37f814fc212bc34ac85453
Author: Eric Lunderberg <[email protected]>
AuthorDate: Thu Jun 15 14:54:37 2023 -0400

    [TIR][TVMScript] Convert tir.op operands to PrimExpr (#15091)
    
    Previously, some operations in `tvm.tir.op` required the operand to
    already be a `PrimExpr`, and raised an error if the operand was
    instead a python object.  This could cause failures round-trip through
    TVMScript, as int32 and float32 types are printed as literals in
    TVMScript, relying on automatic conversion to convert them back into
    `PrimExpr` objects.  For example, `T.expr2(T.int32(0))` is printed as
    `T.expr2(0)`, which then passes the python object `0` into
    `tvm.tir.op.expr2` when parsing the TVMScript.
    
    This commit updates the operations in `tvm.tir.op` to convert operands
    prior to accessing `operand.dtype`, avoiding the error and allowing
    these expressions to round-trip.
    
    This issue was first noticed in
    https://github.com/apache/tvm/pull/15076 for `T.ret(0)`, but applied
    to any operator that used the operand's dtype without first
    normalizing to `PrimExpr`.
---
 python/tvm/tir/op.py                              | 38 +++++++++++++++
 tests/python/unittest/test_tvmscript_roundtrip.py | 58 +++++++++++++++++++++++
 2 files changed, 96 insertions(+)

diff --git a/python/tvm/tir/op.py b/python/tvm/tir/op.py
index 098c13f04e..32c98efa69 100644
--- a/python/tvm/tir/op.py
+++ b/python/tvm/tir/op.py
@@ -1460,6 +1460,8 @@ def ret(val):
     ret : PrimExpr
         The return expression
     """
+
+    val = convert(val)
     return call_intrin(val.dtype, "tir.ret", val)
 
 
@@ -1645,6 +1647,7 @@ def exp(x):
     y : PrimExpr
         The result.
     """
+    x = convert(x)
     return call_intrin(x.dtype, "tir.exp", x)
 
 
@@ -1661,6 +1664,7 @@ def exp2(x):
     y : PrimExpr
         The result.
     """
+    x = convert(x)
     return call_intrin(x.dtype, "tir.exp2", x)
 
 
@@ -1677,6 +1681,7 @@ def exp10(x):
     y : PrimExpr
         The result.
     """
+    x = convert(x)
     return call_intrin(x.dtype, "tir.exp10", x)
 
 
@@ -1693,6 +1698,7 @@ def erf(x):
     y : PrimExpr
         The result.
     """
+    x = convert(x)
     return call_intrin(x.dtype, "tir.erf", x)
 
 
@@ -1709,6 +1715,7 @@ def tanh(x):
     y : PrimExpr
         The result.
     """
+    x = convert(x)
     return call_intrin(x.dtype, "tir.tanh", x)
 
 
@@ -1725,6 +1732,7 @@ def sigmoid(x):
     y : PrimExpr
         The result.
     """
+    x = convert(x)
     return call_intrin(x.dtype, "tir.sigmoid", x)
 
 
@@ -1741,6 +1749,7 @@ def log(x):
     y : PrimExpr
         The result.
     """
+    x = convert(x)
     return call_intrin(x.dtype, "tir.log", x)
 
 
@@ -1757,6 +1766,7 @@ def log2(x):
     y : PrimExpr
         The result.
     """
+    x = convert(x)
     return call_intrin(x.dtype, "tir.log2", x)
 
 
@@ -1773,6 +1783,7 @@ def log10(x):
     y : PrimExpr
         The result.
     """
+    x = convert(x)
     return call_intrin(x.dtype, "tir.log10", x)
 
 
@@ -1789,6 +1800,7 @@ def log1p(x):
     y : PrimExpr
         The result.
     """
+    x = convert(x)
     return call_intrin(x.dtype, "tir.log1p", x)
 
 
@@ -1805,6 +1817,7 @@ def tan(x):
     y : PrimExpr
         The result.
     """
+    x = convert(x)
     return call_intrin(x.dtype, "tir.tan", x)
 
 
@@ -1821,6 +1834,7 @@ def cos(x):
     y : PrimExpr
         The result.
     """
+    x = convert(x)
     return call_intrin(x.dtype, "tir.cos", x)
 
 
@@ -1837,6 +1851,7 @@ def cosh(x):
     y : PrimExpr
         The result.
     """
+    x = convert(x)
     return call_intrin(x.dtype, "tir.cosh", x)
 
 
@@ -1853,6 +1868,7 @@ def acos(x):
     y : PrimExpr
         The result.
     """
+    x = convert(x)
     return call_intrin(x.dtype, "tir.acos", x)
 
 
@@ -1869,6 +1885,7 @@ def acosh(x):
     y : PrimExpr
         The result.
     """
+    x = convert(x)
     return call_intrin(x.dtype, "tir.acosh", x)
 
 
@@ -1885,6 +1902,7 @@ def sin(x):
     y : PrimExpr
         The result.
     """
+    x = convert(x)
     return call_intrin(x.dtype, "tir.sin", x)
 
 
@@ -1901,6 +1919,7 @@ def sinh(x):
     y : PrimExpr
         The result.
     """
+    x = convert(x)
     return call_intrin(x.dtype, "tir.sinh", x)
 
 
@@ -1917,6 +1936,7 @@ def asin(x):
     y : PrimExpr
         The result.
     """
+    x = convert(x)
     return call_intrin(x.dtype, "tir.asin", x)
 
 
@@ -1933,6 +1953,7 @@ def asinh(x):
     y : PrimExpr
         The result.
     """
+    x = convert(x)
     return call_intrin(x.dtype, "tir.asinh", x)
 
 
@@ -1949,6 +1970,7 @@ def atan(x):
     y : PrimExpr
         The result.
     """
+    x = convert(x)
     return call_intrin(x.dtype, "tir.atan", x)
 
 
@@ -1965,6 +1987,7 @@ def atanh(x):
     y : PrimExpr
         The result.
     """
+    x = convert(x)
     return call_intrin(x.dtype, "tir.atanh", x)
 
 
@@ -1984,6 +2007,8 @@ def atan2(x1, x2):
     y : PrimExpr
         The result.
     """
+    x1 = convert(x1)
+    x2 = convert(x2)
     return call_intrin(x1.dtype, "tir.atan2", x1, x2)
 
 
@@ -2000,6 +2025,7 @@ def sqrt(x):
     y : PrimExpr
         The result.
     """
+    x = convert(x)
     return call_intrin(x.dtype, "tir.sqrt", x)
 
 
@@ -2016,6 +2042,7 @@ def rsqrt(x):
     y : PrimExpr
         The result.
     """
+    x = convert(x)
     return call_intrin(x.dtype, "tir.rsqrt", x)
 
 
@@ -2261,6 +2288,8 @@ def nextafter(x1, x2):
     y : PrimExpr
         The result.
     """
+    x1 = convert(x1)
+    x2 = convert(x2)
     return call_intrin(x1.dtype, "tir.nextafter", x1, x2)  # type: ignore
 
 
@@ -2280,6 +2309,8 @@ def hypot(x1, x2):
     y : PrimExpr
         The result.
     """
+    x1 = convert(x1)
+    x2 = convert(x2)
     return call_intrin(x1.dtype, "tir.hypot", x1, x2)  # type: ignore
 
 
@@ -2299,6 +2330,8 @@ def copysign(x1, x2):
     y : PrimExpr
         The result.
     """
+    x1 = convert(x1)
+    x2 = convert(x2)
     return call_intrin(x1.dtype, "tir.copysign", x1, x2)  # type: ignore
 
 
@@ -2318,6 +2351,8 @@ def ldexp(x1, x2):
     y : PrimExpr
         The result.
     """
+    x1 = convert(x1)
+    x2 = convert(x2)
     return call_intrin(x1.dtype, "tir.ldexp", x1, x2)  # type: ignore
 
 
@@ -2474,6 +2509,7 @@ def popcount(x):
     y : PrimExpr
         The result.
     """
+    x = convert(x)
     return call_intrin(x.dtype, "tir.popcount", x)
 
 
@@ -2605,6 +2641,8 @@ def fmod(x, y):
     z : PrimExpr
         The result.
     """
+    x = convert(x)
+    y = convert(y)
     return call_intrin(x.dtype, "tir.fmod", x, y)
 
 
diff --git a/tests/python/unittest/test_tvmscript_roundtrip.py 
b/tests/python/unittest/test_tvmscript_roundtrip.py
index 58be4e14d0..d36641dfc2 100644
--- a/tests/python/unittest/test_tvmscript_roundtrip.py
+++ b/tests/python/unittest/test_tvmscript_roundtrip.py
@@ -3882,6 +3882,62 @@ def subroutine_call_without_arguments():
     return mod
 
 
+def return_zero():
+    @T.prim_func
+    def func() -> T.int32:
+        T.ret(0)
+
+    return func
+
+
+def op_of_literal():
+    op_list = [
+        (T.exp, 0),
+        (T.exp2, 0),
+        (T.exp10, 0),
+        (T.erf, 0.0),
+        (T.tanh, 0.0),
+        (T.sigmoid, 0.0),
+        (T.log, 0.0),
+        (T.log2, 0.0),
+        (T.log1p, 0.0),
+        (T.tan, 0.0),
+        (T.cos, 0.0),
+        (T.acos, 0.0),
+        (T.acosh, 0.0),
+        (T.sin, 0.0),
+        (T.sinh, 0.0),
+        (T.asin, 0.0),
+        (T.asinh, 0.0),
+        (T.atan, 0.0),
+        (T.atanh, 0.0),
+        (T.atan2, (1.0, 0.0)),
+        (T.sqrt, 0.0),
+        (T.rsqrt, 1.0),
+        (T.nextafter, (0.0, 1.0)),
+        (T.hypot, (1.0, 1.0)),
+        (T.copysign, (1.0, 1.0)),
+        (T.popcount, 0),
+        (T.fmod, (1.0, 1.0)),
+    ]
+
+    def make_ir_generator(op, arg):
+        def inner():
+            call_expr = op(*arg) if isinstance(arg, tuple) else op(arg)
+
+            @T.prim_func
+            def func():
+                T.evaluate(call_expr)
+
+            return func
+
+        inner.__name__ = f"{op.__name__}_of_literal"
+        return inner
+
+    for op, arg in op_list:
+        yield make_ir_generator(op, arg)
+
+
 ir_generator = tvm.testing.parameter(
     launch_env_thread,
     opt_gemm_normalize,
@@ -3958,6 +4014,8 @@ ir_generator = tvm.testing.parameter(
     undefined_stride_in_decl_buffer,
     undefined_elem_offset_in_decl_buffer,
     subroutine_call_without_arguments,
+    return_zero,
+    *op_of_literal(),
 )
 
 

Reply via email to