siyiweigeHEW opened a new issue, #20227:
URL: https://github.com/apache/tvm/issues/20227

   ### Expected behavior
   
   A model whose `flatten` uses invalid dims (`start_dim > end_dim`) is 
rejected by PyTorch itself at execution time:
   
   ```python
   torch.flatten(x, 2, 1)      # RuntimeError: flatten() has invalid args: 
start_dim cannot come after end_dim
   torch.nn.Flatten(2, 1)(x)   # same
   ```
   
   `torch.fx.symbolic_trace` does **not** execute the model and does **not** 
validate `flatten` dims (the check only fires on execution), so such a graph is 
perfectly traceable:
   
   ```python
   import torch
   gm = torch.fx.symbolic_trace(torch.nn.Flatten(2, 1))   # succeeds
   ```
   
   When such a graph is passed to the TVM torch frontend, the conversion should 
reject the invalid `flatten` with a clear error message (matching torch's 
`RuntimeError` / `ValueError`), not crash with an internal implementation 
detail.
   
   ### Actual behavior
   
   `tvm.relax.frontend.torch.from_fx` (via `TorchFXImporter`) dispatches the 
`flatten` node to `_flatten` → `_flatten_impl` 
(`python/tvm/relax/frontend/torch/base_fx_graph_translator.py:1771-1787`), 
which computes the flattened extent as:
   
   ```python
   flattened = reduce(lambda x, y: x * y, [shape[i] for i in range(start_dim, 
end_dim + 1)])
   ```
   
   For `start_dim=2, end_dim=1` on a 3-D tensor, `range(2, 2)` is empty, so 
`functools.reduce` is called over an empty iterable with no initial value and 
raises:
   
   ```
   TypeError: reduce() of empty iterable with no initial value
   ```
   
   The same crash is reachable both from a raw `torch.flatten(x, 2, 1)` call in 
the traced module and from `torch.nn.Flatten(start_dim=2, end_dim=1)`. A legal 
`flatten(1, 2)` converts and runs correctly (`(2, 12)`).
   
   ### Environment
   
   - OS: Linux
   - TVM: v0.24.dev0 (main branch, commit `262c6d2e0`, built 2026-02-11)
   - Python: 3.11
   - torch: 2.10.0+cu128
   
   ### Steps to reproduce
   
   ```python
   import torch
   from tvm.relax.frontend.torch import from_fx
   
   
   # Variant 1: raw torch.flatten with invalid dims
   class BadFlatten(torch.nn.Module):
       def forward(self, x):
           return torch.flatten(x, 2, 1)
   
   
   # Variant 2: nn.Flatten with start_dim > end_dim
   class BadFlattenModule(torch.nn.Module):
       def __init__(self):
           super().__init__()
           self.flatten = torch.nn.Flatten(start_dim=2, end_dim=1)
   
       def forward(self, x):
           return self.flatten(x)
   
   
   x = torch.randn(2, 3, 4)
   
   # torch reference: both are rejected on execution
   for name, m in [("torch.flatten(x,2,1)", BadFlatten()), ("nn.Flatten(2,1)", 
BadFlattenModule())]:
       try:
           m(x)
           print(f"torch native {name}: OK")
       except Exception as e:
           print(f"torch native {name}: {type(e).__name__}: {e}")
   
   # TVM: symbolic_trace succeeds (no validation), from_fx crashes
   for gm in (torch.fx.symbolic_trace(BadFlatten().eval()),
              torch.fx.symbolic_trace(BadFlattenModule().eval())):
       try:
           from_fx(gm, input_info=[((2, 3, 4), "float32")])
           print("from_fx: OK")
       except Exception as e:
           print(f"from_fx: {type(e).__name__}: {e}")
   ```
   
   Actual output:
   
   ```
   torch native torch.flatten(x,2,1): RuntimeError: flatten() has invalid args: 
start_dim cannot come after end_dim
   torch native nn.Flatten(2,1): RuntimeError: flatten() has invalid args: 
start_dim cannot come after end_dim
   from_fx: TypeError: reduce() of empty iterable with no initial value
   from_fx: TypeError: reduce() of empty iterable with no initial value
   ```
   
   Full traceback (single variant):
   
   ```
     File "tvm/relax/frontend/torch/fx_translator.py", line 1256, in from_fx
       return 
TorchFXImporter(default_image_layout=default_image_layout).from_fx(
     File "tvm/relax/frontend/torch/fx_translator.py", line 1134, in from_fx
       self.env[node] = self.convert_map[func_name](node)
     File "tvm/relax/frontend/torch/base_fx_graph_translator.py", line 1787, in 
_flatten
       return self._flatten_impl(x, start_dim, end_dim)
     File "tvm/relax/frontend/torch/base_fx_graph_translator.py", line 1775, in 
_flatten_impl
       flattened = reduce(lambda x, y: x * y, [shape[i] for i in 
range(start_dim, end_dim + 1)])
     TypeError: reduce() of empty iterable with no initial value
   ```
   
   ### Notes / suggested fix
   
   - Root cause: `_flatten_impl` does not validate that `start_dim <= end_dim` 
after negative-index normalization. On an empty `range` it hits 
`functools.reduce` with no initial value.
   - Suggest validating the dims and raising a clear error (e.g. matching 
torch's `"flatten() has invalid args: start_dim cannot come after end_dim"`), 
or equivalently guarding the empty-range case.
   - Scope: this affects the `from_fx` / `TorchFXImporter` entry point (where 
`flatten` is dispatched to `_flatten`). The `from_exported_program` path is not 
affected: the module-level `from_exported_program` runs 
`exported_program.run_decompositions()` by default 
(`python/tvm/relax/frontend/torch/exported_program_translator.py:1841-1842`), 
which decomposes `aten.flatten.using_ints` into `aten.view` (shape computed at 
decompose time), so `_flatten_impl` is never reached there.
   
   ### Triage
   
   * needs-triage
   * bug
   * relax
   * frontend/torch
   


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