gemini-code-assist[bot] commented on code in PR #19891:
URL: https://github.com/apache/tvm/pull/19891#discussion_r3476683681


##########
python/tvm/relax/frontend/onnx/onnx_frontend.py:
##########
@@ -441,7 +441,7 @@ def _impl_v1(cls, bb, inputs, attr, params):
 
 
 def _to_numpy(x):
-    if isinstance(x, relax.PrimValue):
+    if isinstance(x, tvm.tirx.PrimExpr):
         x = x.value
         if isinstance(x, tirx.IntImm | tirx.FloatImm):
             x = x.value

Review Comment:
   ![critical](https://www.gstatic.com/codereviewagent/critical.svg)
   
   In `_to_numpy`, `x = x.value` is called directly on `tvm.tirx.PrimExpr`. 
However, `PrimExpr` does not have a `.value` attribute (only `IntImm` and 
`FloatImm` do). This will raise an `AttributeError` for any non-constant 
`PrimExpr` (like `Var`), and is redundant/broken for constant `PrimExpr`s.
   
   We should check if `x` is an `IntImm` or `FloatImm` before accessing 
`.value`.
   
   ```suggestion
       if isinstance(x, tvm.tirx.PrimExpr):
           if isinstance(x, tirx.IntImm | tirx.FloatImm):
               return x.value
           return x
   ```



##########
python/tvm/relax/frontend/onnx/onnx_frontend.py:
##########
@@ -280,7 +280,7 @@ def get_prim_expr_list(
         return np_value.tolist()
     elif isinstance(inputs, relax.ShapeExpr):
         return inputs.values
-    elif isinstance(inputs, relax.PrimValue):
+    elif isinstance(inputs, tvm.tirx.PrimExpr):
         return [inputs.value.value]

Review Comment:
   ![critical](https://www.gstatic.com/codereviewagent/critical.svg)
   
   Since `inputs` is already a `tvm.tirx.PrimExpr`, accessing `inputs.value` 
will raise an `AttributeError` (as `PrimExpr` does not have a `.value` 
attribute unless it is an `IntImm` or `FloatImm`). Since the function 
`get_prim_expr_list` is intended to return a list of `PrimExpr`s, we should 
return `[inputs]` directly.
   
   ```suggestion
       elif isinstance(inputs, tvm.tirx.PrimExpr):
           return [inputs]
   ```



##########
python/tvm/relax/frontend/torch/base_fx_graph_translator.py:
##########
@@ -2142,19 +2150,19 @@ def _adjust(val):
                         return input_shape[axis]
                 return val
 
-            if isinstance(bound, relax.PrimValue):
+            if isinstance(bound, tirx.PrimExpr):
                 value = _adjust(bound.value)
-                return relax.PrimValue(value)
+                return relax.prim_value(value)

Review Comment:
   ![high](https://www.gstatic.com/codereviewagent/high-priority.svg)
   
   Since `bound` is already a `tirx.PrimExpr`, accessing `bound.value` will 
raise an `AttributeError`. We should pass `bound` directly to `_adjust`.
   
   ```suggestion
               if isinstance(bound, tirx.PrimExpr):
                   value = _adjust(bound)
                   return relax.prim_value(value)
   ```



##########
python/tvm/ir/expr.py:
##########
@@ -67,30 +62,29 @@ class GlobalVar(RelaxExpr):
     def __init__(self, name_hint: str):
         self.__init_handle_by_constructor__(_ffi_api.GlobalVar, name_hint)
 
-    def __call__(self, *args: RelaxExpr) -> BaseExpr:
+    def __call__(self, *args: Expr) -> Expr:
         """Call the global variable.
 
         Parameters
         ----------
-        args: List[RelaxExpr]
+        args: List[Expr]
             The arguments to the call.
 
         Returns
         -------
-        call: BaseExpr
+        call: Expr
             A call taking the variable as a function.
         """
         # pylint: disable=import-outside-toplevel
 
-        # TODO(@relax-team): replace with Relax base class after it's 
introduced
-        if all(isinstance(x, RelaxExpr) for x in args):
+        if all(isinstance(x, Number | PrimExpr) for x in args):
+            return tvm.tirx.call_tir(self, *args)
+
+        if all(isinstance(x, Expr) for x in args):
             from tvm import relax
 
             return relax.Call(self, args)

Review Comment:
   ![high](https://www.gstatic.com/codereviewagent/high-priority.svg)
   
   In `GlobalVar.__call__`, the check `all(isinstance(x, Number | PrimExpr) for 
x in args)` will incorrectly evaluate to `True` when `args` is empty (since 
`all([])` is `True` in Python). This causes nullary Relax function calls (e.g., 
`gv()`) to be incorrectly dispatched to `tvm.tirx.call_tir` instead of 
`relax.Call`.
   
   Adding a check to ensure `args` is not empty before dispatching to 
`call_tir` resolves this issue.
   
   ```suggestion
           if args and all(isinstance(x, Number | PrimExpr) for x in args):
               return tvm.tirx.call_tir(self, *args)
   
           if all(isinstance(x, Expr) for x in args):
               from tvm import relax
   
               return relax.Call(self, args)
   ```



##########
python/tvm/relax/expr.py:
##########
@@ -40,11 +40,40 @@
 # It is a workaround for mypy: 
https://github.com/python/mypy/issues/7866#issuecomment-549454370
 # This feature is not supported until python 3.10:
 # https://docs.python.org/3.10/whatsnew/3.10.html#pep-613-typealias
-Expr = tvm.ir.RelaxExpr
+Expr = tvm.ir.Expr
 Type = tvm.ir.Type  # pylint: disable=invalid-name
 GlobalVar = tvm.ir.GlobalVar
 
 
+def prim_value(value: PrimExpr | int | float, dtype: str | None = None) -> 
PrimExpr:
+    """Convert a Python scalar or primitive expression to ``PrimExpr``.
+
+    Parameters
+    ----------
+    value : PrimExpr | int | float
+        The value to convert.
+
+    dtype : Optional[str]
+        The dtype to use when converting Python numeric values.
+
+    Returns
+    -------
+    result : PrimExpr
+        The converted primitive expression.  Existing ``PrimExpr`` inputs are
+        returned unchanged.
+    """
+    if isinstance(value, PrimExpr):
+        return value
+    if isinstance(value, bool | int):
+        return tvm.tirx.IntImm(dtype or "int64", int(value))

Review Comment:
   ![medium](https://www.gstatic.com/codereviewagent/medium-priority.svg)
   
   Since `bool` is a subclass of `int` in Python, `isinstance(value, bool | 
int)` will match boolean values. If `dtype` is not specified, it will default 
to `"int64"`, converting `True`/`False` to `IntImm("int64", 1/0)` instead of 
`IntImm("bool", 1/0)`. This can cause type mismatches in operators expecting 
boolean conditions (like `assert_op` or `if`).
   
   Handling `bool` explicitly before `int` preserves the correct boolean type.
   
   ```suggestion
       if isinstance(value, bool):
           return tvm.tirx.IntImm(dtype or "bool", int(value))
       if isinstance(value, int):
           return tvm.tirx.IntImm(dtype or "int64", value)
   ```



##########
python/tvm/relax/frontend/onnx/onnx_frontend.py:
##########
@@ -478,15 +478,15 @@ def base_impl(cls, bb, inputs, attr, params):
             x = _to_numpy(inputs[0])
             y = _to_numpy(inputs[1])
             output = cls.numpy_op(x, y)  # pylint: disable=not-callable
-            if isinstance(x, relax.PrimValue) and isinstance(y, 
relax.PrimValue):
-                return relax.PrimValue(output.item())
+            if isinstance(x, tvm.tirx.PrimExpr) and isinstance(y, 
tvm.tirx.PrimExpr):
+                return relax.prim_value(output.item())

Review Comment:
   ![medium](https://www.gstatic.com/codereviewagent/medium-priority.svg)
   
   The check `isinstance(x, tvm.tirx.PrimExpr)` will always evaluate to `False` 
because `x` and `y` are Python scalars returned by `_to_numpy`. To correctly 
check if the original inputs were `PrimExpr`s, we should check `inputs[0]` and 
`inputs[1]` instead.
   
   ```suggestion
               if isinstance(inputs[0], tvm.tirx.PrimExpr) and 
isinstance(inputs[1], tvm.tirx.PrimExpr):
                   return relax.prim_value(output.item())
   ```



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to