[Bug] [Relax][ONNX] MaxUnpool calls tolist on its output_shape expression

Open Beginner friendly
#20,888 0 comments 0 reactions 0 assignees View on GitHub

Maintainers usually reply within 1 day

Nobody has claimed this yet.

Assessment

Difficulty
2/5
Estimated time
1-3 hours
Newbie friendliness
72/100
Issue type
Bug
Clarity
Clearly specified
Activity status
Active
Tech stack
python
Domain
compilers

Research direction

Start in the MaxUnpool converter of the Relax ONNX frontend, where total_output_shape is taken from inputs[2] and .tolist() is called on it. Run the repro script with explicit_shape set to True to hit the GenericConst AttributeError. Done means the explicit output_shape case imports and matches the ReferenceEvaluator result [[[[5, 0], [0, 0]]]] for both the two-input and three-input models.

Written by the indexing model from the issue text.

Description

needs-triage type: bug
Expected behavior

Providing the optional constant output_shape=[1, 1, 2, 2] should preserve the result of the equivalent two-input MaxUnpool.

Actual behavior

The two-input model imports. Adding the same explicit output shape passes ONNX full checking and reference evaluation, then fails during import:

AttributeError: 'GenericConst' object has no attribute 'tolist'

The converter assigns inputs[2] to total_output_shape and calls .tolist() on that Relax expression.

Environment

TVM 0.28.dev0 (local build; build commit unavailable), Python 3.12.3, Linux x86_64; ONNX 1.22.0, NumPy 2.5.4.

Steps to reproduce

Run with python repro.py:

import numpy as np
import onnx
from onnx import TensorProto as T, helper as h, numpy_helper as nh
from onnx.reference import ReferenceEvaluator
from tvm.relax.frontend.onnx import from_onnx

x = np.array([[[[5.0]]]], dtype="float32")
for explicit_shape in [False, True]:
    initializers = [nh.from_array(np.zeros((1, 1, 1, 1), dtype="int64"), "indices")]
    inputs = ["x", "indices"]
    if explicit_shape:
        initializers.append(nh.from_array(np.array([1, 1, 2, 2], dtype="int64"), "shape"))
        inputs.append("shape")
    node = h.make_node("MaxUnpool", inputs, ["y"], kernel_shape=[2, 2], strides=[2, 2])
    model = h.make_model(h.make_graph([node], "unpool",
        [h.make_tensor_value_info("x", T.FLOAT, [1, 1, 1, 1])],
        [h.make_tensor_value_info("y", T.FLOAT, [1, 1, 2, 2])], initializers),
        opset_imports=[h.make_opsetid("", 18)], ir_version=10)
    onnx.checker.check_model(model, full_check=True)
    expected = np.array([[[[5, 0], [0, 0]]]], dtype="float32")
    np.testing.assert_array_equal(ReferenceEvaluator(model).run(None, {"x": x})[0], expected)
    try:
        from_onnx(model, keep_params_in_input=False)
        print("explicit_shape", explicit_shape, "imported")
    except Exception as error:
        print("explicit_shape", explicit_shape, type(error).__name__, str(error).splitlines()[-1])
Triage
  • needs-triage
Dominant language
Python
Stars
13.9k
Forks
4k
Avg merge
8h 10m
Merged PRs (30d)
186

Getting set up

This project ships no dev container, Dockerfile or contributing guide, so setting up is up to you: start from its README, and see our first-contribution guide for the general steps.

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

More from apache/tvm

All issues in apache/tvm

Similar issues

More Python issues

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.