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]

Reply via email to