hiyufan opened a new pull request, #20254:
URL: https://github.com/apache/tvm/pull/20254

   ### Problem
   
   `torch.sort` and `torch.argsort` return `int64` indices. The Relax PyTorch 
frontend emits `int32` for them.
   
   `relax.op.argsort` defaults to `dtype="int32"`, and both call sites in 
`base_fx_graph_translator.py` take that default:
   
   ```python
   # _argsort
   return self.block_builder.emit(relax.op.argsort(x, dim, descending))
   
   # _sort
   indices = self.block_builder.emit(relax.op.argsort(x, dim, descending))
   ```
   
   To be precise about the scope: the sorted values and the index *values* are 
already correct. Only the index dtype diverges from PyTorch.
   
   ### Why this looks like an oversight rather than a deliberate choice
   
   `relax.op.topk` has the same `dtype="int32"` default, and `_topk` in this 
very file explicitly overrides it:
   
   ```python
   relax.op.topk(x, k=k, axis=dim, largest=largest, ret_type="both", 
dtype="int64")
   ```
   
   So the frontend already establishes that the relax-level default has to be 
overridden to match PyTorch. Every index-producing torch op the frontend 
supports comes out as `int64` — except `sort` and `argsort`:
   
   | torch op | torch index dtype | frontend before this PR |
   | --- | --- | --- |
   | `torch.sort` | `int64` | **`int32`** |
   | `torch.argsort` | `int64` | **`int32`** |
   | `torch.topk` | `int64` | `int64` (explicit `dtype=`) |
   | `torch.argmax` / `torch.argmin` | `int64` | `int64` |
   | `torch.max(dim=)` / `torch.median(dim=)` | `int64` | `int64` |
   | `torch.bucketize` | `int64` | `int64` |
   
   A single imported graph that uses both `topk` and `sort` therefore carries 
two different index dtypes for the same kind of value.
   
   ### Reproduce
   
   ```python
   import torch
   from torch import nn
   from tvm.relax.frontend.torch import from_exported_program
   
   
   def relax_dtypes(fn, x):
       class M(nn.Module):
           def forward(self, t):
               return fn(t)
   
       ep = torch.export.export(M().eval(), (x,))
       return [str(f.dtype) for f in 
from_exported_program(ep)["main"].ret_ty.fields]
   
   
   x = torch.randn(3, 4)
   print("sort   ", relax_dtypes(lambda t: torch.sort(t, dim=1), x))
   print("argsort", relax_dtypes(lambda t: torch.argsort(t, dim=1), x))
   print("topk   ", relax_dtypes(lambda t: torch.topk(t, 2, dim=1), x))
   ```
   
   Before / after:
   
   ```
                    before                        after
   sort     ['float32', 'int32']          ['float32', 'int64']
   argsort  ['int32']                     ['int64']
   topk     ['float32', 'int64']          ['float32', 'int64']
   ```
   
   ### Fix
   
   Pass `dtype="int64"` at both `relax.op.argsort` call sites, matching what 
`_topk` already does.
   
   ### Verification
   
   Built with LLVM and ran the imported graph through the VM against PyTorch on 
`sort(dim=1)`, `sort(descending=True)`, `sort(dim=0)` and `argsort(dim=1)`:
   
   - before: values equal, indices equal, **index dtype `int32` vs torch 
`int64`**
   - after: values equal, indices equal, index dtype `int64` — matches torch on 
every case
   
   Test suites, `tests/python/relax/test_frontend_from_fx.py` + 
`tests/python/relax/test_frontend_from_exported_program.py`:
   
   - clean `main`: 24 failed, 412 passed, 3 skipped
   - with this change: 24 failed, **413** passed, 3 skipped
   
   The 24 failures are pre-existing on `main` in my environment (`test_dtypes` 
and friends) and are identical before and after; the one additional pass is the 
new `test_sort`.
   
   `ruff format --check` and `ruff check` are clean on the touched files.
   
   ### Tests
   
   - Updated the expected IR in `test_argsort` (both frontend test files) and 
`test_sort` (`test_frontend_from_fx.py`) — these had the `int32` result written 
into them.
   - Added `test_sort` to `test_frontend_from_exported_program.py`; that path 
had no coverage for `torch.sort`.
   
   ---
   
   This change was prepared with AI assistance (Claude). I have reviewed and 
verified it, and can speak to it in review.
   


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