Skip to content

[Fix][Relax] Honor ONNX Reshape zero semantics - #20161

Open
tandede wants to merge 3 commits into
apache:mainfrom
tandede:fix/onnx-reshape-zero-semantics
Open

[Fix][Relax] Honor ONNX Reshape zero semantics#20161
tandede wants to merge 3 commits into
apache:mainfrom
tandede:fix/onnx-reshape-zero-semantics

Conversation

@tandede

@tandede tandede commented Aug 19, 2026

Copy link
Copy Markdown

ONNX Reshape uses zero entries to copy the corresponding input dimension by default. The Relax importer currently constant-folds those shapes through NumPy without applying that rule, so a valid shape such as [0, 3] fails for a (2, 3) tensor. Conversely, when allowzero=1, passing the zero through relax.op.reshape invokes Relax's own zero-copy convention instead of preserving the literal zero dimension.

This change normalizes copied dimensions before constant folding when allowzero is disabled. When it is enabled, the shape tensor is materialized as a symbolic ShapeExpr, preserving literal zero dimensions without applying Relax's zero-copy shortcut.

The regression tests cover both the default all-constant path and an executable allowzero=1 model with a (0, 2) output.

Fixes #20151

Testing:

pre-commit run --files python/tvm/relax/frontend/onnx/onnx_frontend.py tests/python/relax/test_frontend_onnx.py
pytest -q tests/python/relax/test_frontend_onnx.py -k reshape
pytest -q -n 4 tests/python/relax/test_frontend_onnx.py -k 'not test_clip_v13'

The first two commands pass, and the broad run reports 493 passed, 9 skipped, and 4 xfailed. Running the entire file also reports three test_clip_v13 failures that reproduce unchanged on a clean main worktree in the same environment.

ONNX Reshape copies the corresponding input dimension for zero entries unless allowzero is enabled. Normalize those entries before constant folding, and materialize allowzero shapes without triggering Relax reshape zero-copy semantics. Add regression coverage for both cases.

@tlopex tlopex left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

allowzero only changes zero semantics, but this branch also bypasses -1 inference. A valid non-constant (3, 4) input with shape [-1, 2] and allowzero=1 reaches runtime with a literal -1 and fails with std::bad_alloc. Please keep the normal reshape path when no literal zero is present and add a regression test.

@tandede

tandede commented Aug 23, 2026

Copy link
Copy Markdown
Author

allowzero only changes zero semantics, but this branch also bypasses -1 inference. A valid non-constant (3, 4) input with shape [-1, 2] and allowzero=1 reaches runtime with a literal -1 and fails with std::bad_alloc. Please keep the normal reshape path when no literal zero is present and add a regression test.

Thanks for catching this. You’re right that allowzero should only change the interpretation when the target shape actually contains a literal zero; it should not bypass normal -1 inference.

I narrowed the special path to constant target shapes containing zero. With allowzero=1 and [-1, 2], a non-constant (3, 4) input now follows the normal reshape path and produces (6, 2).

I added the requested regression test and pushed the update in d20b94e. All five Reshape-related tests and the changed-file pre-commit checks pass.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug][Relax][Frontend][ONNX] Reshape mishandles 0 in shape: constant-fold path breaks 0-copy semantics (default allowzero=0); allowzero=1 ignored

2 participants