{tir.const(1), tir.const(True)} throws ValueError

Hi folks, I’m a newbie of TVM and these days I was playing with TIR. When I enter the code below in the Python interpreter, it throws ValueError. It’s strange to me since I was just constructing a set…

>>> from tvm import tir
>>> {tir.const(1), tir.const(True)}

I’d appreciate any help :slight_smile:

I think it’s concerned with the implementation of __eq__. Since both tir.const(1) and tir.const(True) have the __hash__ value, 1, the set construction logic would use __eq__ to see if the two objects are the same. Here’s the error message:

~tvm/python/tvm/tir/expr.py in __nonzero__(self)
    171     def __nonzero__(self):
    172         raise ValueError(
--> 173             "Cannot use and / or / not operator to Expr, hint: "
    174             + "use tvm.tir.all / tvm.tir.any instead"
    175         )

ValueError: Cannot use and / or / not operator to Expr, hint: use tvm.tir.all / tvm.tir.any instead

After some inspection, I guess I could elaborate on the steps leading to this issue:

  • During the construction of s, the __hash__ of int_1 and bool_t are compared, which are both 1.
  • Since they have the same hash value, Python needs to further consider whether the two objects are the same before finishing set construction, which in turn concerns the __eq__ operator.
  • __eq__ of tir.IntImm calls _ffi_api._OpEQ, which returns a tir.EQ(int_1, bool_t) given that constant folding doesn’t happen.
  • Python wants to convert the this tir.EQ to bool, which calls __bool__ of tir.EQ that inherits __bool__ of tir.ExprOp, which calls __nonzero__, which finally raises ValueError.

I’m not sure whether this problem can be solved through simple fix since it involves the design of the operator sugar of TIR in Python-level.

Interesting finding. I have been reading related C++ codebase and made a PR to fix this. [TIR] enhance tir signed-unsigned cast by ganler · Pull Request #8706 · apache/tvm · GitHub

1 Like