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

   ### Expected behavior
   
   A valid ONNX `Reshape` node should follow the ONNX spec's 0-dimension 
semantics:
   
   - With default `allowzero=0` (and opset < 14), a `0` in `shape` means "copy 
the corresponding dimension from the input". For constant `data` with shape 
`(2, 3)` and `shape = [0, 3]`, the output must be `(2, 3)`, unchanged.
   - With `allowzero=1` (opset ≥ 14), a `0` in `shape` is a literal zero 
dimension. For input `(2, 0)` and `shape = [0, 2]`, the output must be `(0, 2)`.
   
   Both models pass `onnx.checker` and run correctly in onnxruntime and 
`onnx.reference`.
   
   ### Actual behavior
   
   `tvm.relax.frontend.onnx.from_onnx` mishandles both cases:
   
   1. **Constant-fold path** (`Reshape._impl_v13`, 
`python/tvm/relax/frontend/onnx/onnx_frontend.py:979-981`): when both `data` 
and `shape` are constants, the frontend calls `np.reshape(data, shape)`, which 
treats `0` as a literal zero element (numpy semantics) instead of "copy dim 
from input" (ONNX default). A fully-constant model `data=(2,3)`, `shape=[0,3]` 
(default `allowzero=0`) — which onnxruntime and `onnx.reference` both accept 
and return `(2,3)` — raises:
   
      ```
      ValueError: cannot reshape array of size 6 into shape (0,3)
      ```
   
   2. **`allowzero` attribute ignored** (`Reshape._impl_v13`, 
`python/tvm/relax/frontend/onnx/onnx_frontend.py:968-985`): the converter never 
reads `attr["allowzero"]`. It always passes `0`-copy semantics to 
`relax.op.reshape`. A valid empty-tensor model `data=(2,0)`, `shape=[0,2]`, 
`allowzero=1` (opset 14) — which onnxruntime and `onnx.reference` return 
`(0,2)` — is rejected:
   
      ```
      InternalError: Reshape expects the new shape to be convertible from the 
old shape. However, the old shape ...
      ```
   
   Both are valid, runnable ONNX models.
   
   ### Environment
   
   - OS: Linux
   - TVM: v0.24.dev0 (main branch, commit `262c6d2e0`, built 2026-02-11)
   - Python: 3.11
   - onnx: 1.20.1
   - onnxruntime: 1.24.1
   
   ### Steps to reproduce
   
   ```python
   """Repro: ONNX Reshape 0-dim semantics mishandled by TVM relax frontend."""
   import numpy as np
   import onnx, onnxruntime
   from onnx import helper, TensorProto
   from onnx.reference import ReferenceEvaluator
   from tvm.relax.frontend.onnx import from_onnx
   
   
   def build(data_shape, shape_vals, data_const, out_shape, allowzero=None, 
opset=13):
       inits, inputs = [], []
       if data_const:
           d = (np.arange(int(np.prod(data_shape))).reshape(data_shape) + 
1).astype("float32")
           inits.append(helper.make_tensor("data", TensorProto.FLOAT, 
list(data_shape), d.flatten().tolist()))
       else:
           inputs.append(helper.make_tensor_value_info("data", 
TensorProto.FLOAT, list(data_shape)))
       inits.append(helper.make_tensor("shape", TensorProto.INT64, 
[len(shape_vals)], list(shape_vals)))
       node = helper.make_node("Reshape", ["data", "shape"], ["Y"])
       if allowzero is not None:
           node.attribute.append(helper.make_attribute("allowzero", allowzero))
       graph = helper.make_graph(
           [node], "g", inputs,
           [helper.make_tensor_value_info("Y", TensorProto.FLOAT, 
list(out_shape))], inits)
       model = helper.make_model(graph, opset_imports=[helper.make_opsetid("", 
opset)])
       model.ir_version = 8
       return model
   
   
   def try_tvm(m, shape_dict, label):
       try:
           from_onnx(m, shape_dict=shape_dict)
           print(f"{label} TVM: OK")
       except Exception as e:
           print(f"{label} TVM: {type(e).__name__}: {e}")
   
   
   # (1) Constant path, default allowzero=0: 0 must copy the input dim
   m1 = build((2, 3), [0, 3], data_const=True, out_shape=(2, 3))
   onnx.checker.check_model(m1)                                    # valid ONNX 
model
   print("m1 onnxruntime:", 
onnxruntime.InferenceSession(m1.SerializeToString()).run(None, {})[0].shape)
   print("m1 onnx.reference:", ReferenceEvaluator(m1).run(None, {})[0].shape)
   try_tvm(m1, {}, "m1")                                           # TVM rejects
   
   # (2) allowzero=1 (opset 14): 0 is a literal zero dim
   m2 = build((2, 0), [0, 2], data_const=False, out_shape=(0, 2), allowzero=1, 
opset=14)
   onnx.checker.check_model(m2)                                    # valid ONNX 
model
   x = np.zeros((2, 0), dtype="float32")
   print("m2 onnxruntime:", 
onnxruntime.InferenceSession(m2.SerializeToString()).run(None, {"data": 
x})[0].shape)
   print("m2 onnx.reference:", ReferenceEvaluator(m2).run(None, {"data": 
x})[0].shape)
   try_tvm(m2, {"data": [2, 0]}, "m2")                             # TVM rejects
   ```
   
   Actual output:
   
   ```
   m1 onnxruntime: (2, 3)
   m1 onnx.reference: (2, 3)
   Error converting operator Reshape, with inputs: 
[metadata["relax.expr.Constant"][0], metadata["relax.expr.Constant"][0]]
   m1 TVM: ValueError: cannot reshape array of size 6 into shape (0,3)
     File "tvm/relax/frontend/onnx/onnx_frontend.py", line 980, in _impl_v13
       out = _np.reshape(data.data.numpy(), new_shape.data.numpy().tolist())
   
   m2 onnxruntime: (0, 2)
   m2 onnx.reference: (0, 2)
   Error converting operator Reshape, with inputs: [data, 
metadata["relax.expr.Constant"][0]]
   m2 TVM: InternalError: Reshape expects the new shape to be convertible from 
the old shape. However, the old shape is R.shape([2, 0]), with product 
T.int64(0), while the new shape is R.shape([2, 2]), with product T.int64(4)
   ```
   
   ### Triage
   
   * needs-triage
   * bug
   * relax
   * frontend/onnx
   


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