Lunderberg commented on PR #15983:
URL: https://github.com/apache/tvm/pull/15983#issuecomment-1799131469

   This arose when writing unit tests for access of a relax tuple.  I expected 
the following unit test to pass on `unity` HEAD.
   
   ```python
   import tvm.testing
   from tvm.script import relax as R
   
   exec_mode = tvm.testing.parameter("bytecode", "compiled")
   
   def test_vm_tuple_get_item(exec_mode):
       @R.function(private=True)
       def func(arg: R.Tuple([R.Prim("int64"), R.Prim("float32")])):
           return arg[0]
   
       mod = tvm.IRModule({"main": func})
   
       target = tvm.target.Target("llvm", host="llvm")
       ex = tvm.relax.build(mod, target, exec_mode=exec_mode)
       vm = tvm.relax.VirtualMachine(ex, tvm.cpu())
   
       res = vm["main"]((17, 42.5))
       assert res == 17
   ```
   
   The error occurs with the following steps:
   
   1. When passed an argument, python tuples are converted to `tvm.ir.Array`.
   2. In order to use `tvm.ir.Array`, the arguments must be converted to 
`ObjectRef` subclasses.  This converts `(17, 42.5)` into `tvm.ir.Array([ 
T.int64(17), T.float32(42.5) ])`.
   3. The tuple is accessed with a relax VM builtin, and `T.int64(17)` is 
stored in a relax VM register.
   4. The `T.int64(17)` is type-checked as a `R.prim('int64')`, which uses 
`TVMPODValue_::operator int64_t`.
   5. The call to `operator int64_t` fails, as it is an `IntImm`, and uses 
`TVMArgTypeCode::kTVMObjectHandle` and not `TVMArgTypeCode::kTVMArgInt`.
   
   Any of these steps could be broken in order to avoid the error.  
Fundamentally, the error occurs because we apply an automatic conversion (`int` 
to `IntImm`), but do not automatically apply the reverse conversion (`IntImm` 
to `int`).  I believe that this PR, which changes step (5), is the best 
resolution.  Avoiding the error by updating any of the other steps has 
drawbacks as described below.
   
   1. Change the FFI conversion of python tuples to a runtime-only type, rather 
than `tvm.ir.Array`.  This would cause breakage for any FFI call that uses 
`Array` at compile-time.
   2. Change the internal type of `tvm.ir.Array` from `ObjectRef` to 
`TVMArgValue`.  This would allow FFI conversions from python tuples to `Array`, 
but would break the usage of those `Array` objects.
   3. Change the return of the `tuple_getitem` builtin to convert from `IntImm` 
to `int` when providing a `TVMRetValue`.  Possible, but would drop the dtype 
information that may be required for later type-checks.
   4. Change the type-checking of `R.Prim` in the VM to check for `IntImm`.  
This would avoid the error in this case, but this function is used for 
type-checking before calling external `PackedFunc` instances.  Those calls 
would throw the same error at a later point.
   5. Change the `operator int64_t` implementation to check for an `IntImm`.  
That is the change implemented in this PR, and handles any such conversion 
required.
   
   > Given the implementation complexity
   
   Can you explain what you mean here?  This doesn't seem any more complex than 
the argument handling that we already do for FFI compatibility purposes.


-- 
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]

Reply via email to