The GitHub Actions job "Lint" on tvm.git/fix/relax-torch-division-dtype has failed. Run started by GitHub user hiyufan (triggered by hiyufan).
Head commit for run: 49d7915ce41a2d7e0e30016ba4ffdc853720a32b / Chen Yufan <[email protected]> [Fix][Relax][Frontend][Torch] Follow torch's dtype rules for the division family Three converters disagreed with torch on what a division returns: - `div.Tensor` / `div.Scalar` went through the generic `_binary_op`, which keeps the promoted dtype. torch's true division always yields a floating result, so `int64 / 2` and `int64 / int64` are float32 there and were an integer quotient here: `[3, 4, 5] / 2` came back as int64 `[1, 2, 2]` instead of float32 `[1.5, 2, 2.5]`. - `div.Tensor_mode` (which `x // 2` and `torch.div(x, 2, rounding_mode=...)` decompose to) built its scalar constant with `relax.const(inp_2)` and no dtype, i.e. int32, so every float tensor and every non-int32 integer tensor failed the same-dtype check: `x // 2` raised `TypeError` for float32 and int64 inputs alike. The int32 case passed only because relax.const's default dtype happens to be int32. - `reciprocal.default`, which `scalar / x` decomposes to, divided `const(1, x.dtype)` by x, so `2 / int_tensor` was an integer quotient as well. The converter was duplicated in both translators; there is now one in the base class. The two promotion closures inside `_binary_op` become methods (`_promote_binary_operands`, `_promote_scalar_operand`) so the division converters share them, and `_true_division_operands` adds the one rule true division has on top of `torch.result_type`: an integral or bool pair is cast to the default float dtype. `div.Tensor` / `div.Scalar` dispatch to a new `_true_divide`; `_div` promotes its operands the same way and then keeps the promoted dtype for `floor` and `trunc`. Integer division in relax truncates toward zero, so `trunc` on an integer pair is a plain divide; `floor` is `floor_divide`; floats go through divide + trunc as before. int64 [3, 4, 5] / 2 torch float32 [1.5, 2.0, 2.5] before int64 [1, 2, 2] bool [T, T, F] / 2 torch float32 [0.5, 0.5, 0.0] before bool 2 / int64 [3, 4, 5] torch float32 [0.67, 0.5, 0.4] before int64 [0, 0, 0] int64 [-7, -3, 3, 7] // 2 torch int64 [-4, -2, 1, 3] before TypeError float32 x // 2 torch float32 before TypeError torch.div(x, 2, "trunc") torch int64 [-3, -1, 1, 3] before TypeError Same 864-program sweep as the previous commit (18 binary ops x 8 dtypes x 6 Python scalars, built with relax.build(llvm), result dtype and values compared with torch), measured against that commit as the base: base 645 matched 52 wrong dtype or values 132 raised after 799 matched 0 wrong 30 raised no case fails after this change that did not fail before it; 154 repaired The 30 left are the same pre-existing edges as before: relax rejecting arithmetic on a bool tensor with a bool scalar, a uint8 tensor against a negative scalar (torch wraps, relax.const raises), and `x ** True` on an integer tensor. Tests: an IR-level check that `int64 / 2` casts both operands to float32 before the divide; numeric checks of `x / s`, `s / x`, `x / (x + 1)` and `torch.reciprocal(x)` over int64, int32, uint8 and bool tensors; and `x // 2`, `torch.div(..., "floor")`, `torch.div(..., "trunc")` and a tensor divisor on `[-7, -3, 3, 7]` for int64, int32 and float32, where the negative inputs separate floor from trunc. 8 of 9 fail against the previous head; the int32 rounding-mode case passes there for the int32-default reason above and pins that it keeps working. Report URL: https://github.com/apache/tvm/actions/runs/35198860598 With regards, GitHub Actions via GitBox --------------------------------------------------------------------- To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]
