[translate ONNX to Relax]AttributeError: <class 'tvm.relax.expr.Call'> has no attribute data

When I perform a transformation on an ONNX node, I encounter the following error. I checked the input of this Mul operation, and it looks like this.

According to the code, the input here needs to be of type relax.PrimValue, but the actual input is indeed tvm.relax.expr.Call. I would like to ask how to resolve this error. Thank you very much.

the error is:\

Traceback (most recent call last):
  File "/lpai/code/llava_tvm/debug.py", line 39, in <module>
    relax_mod = from_onnx(onnx_model, shape_dict=encoder_shape_dyna, dtype_dict=dtype_dict, keep_params_in_input=True)
  File "/lpai/tvm/python/tvm/relax/frontend/onnx/onnx_frontend.py", line 3703, in from_onnx
    return g.from_onnx(graph, opset)
  File "/lpai/tvm/python/tvm/relax/frontend/onnx/onnx_frontend.py", line 3320, in from_onnx
    self._construct_nodes(graph)
  File "/lpai/tvm/python/tvm/relax/frontend/onnx/onnx_frontend.py", line 3504, in _construct_nodes
    op = self._convert_operator(op_name, inputs, attr, self.opset)
  File "/lpai/tvm/python/tvm/relax/frontend/onnx/onnx_frontend.py", line 3609, in _convert_operator
    sym = op_function(self.bb, inputs, attrs, [self._nodes, self._params])
  File "/lpai/tvm/python/tvm/relax/frontend/onnx/onnx_frontend.py", line 381, in _impl_v7
    return cls.base_impl(bb, inputs, attr, params)
  File "/lpai/tvm/python/tvm/relax/frontend/onnx/onnx_frontend.py", line 344, in base_impl
    x = _to_numpy(inputs[0])
  File "/lpai/tvm/python/tvm/relax/frontend/onnx/onnx_frontend.py", line 324, in _to_numpy
    return x.data.numpy()
  File "/lpai/tvm/python/tvm/runtime/object.py", line 75, in __getattr__
    raise AttributeError(f"{type(self)} has no attribute {name}") from None
AttributeError: <class 'tvm.relax.expr.Call'> has no attribute data

I’ve encountered this problem as well, and I believe the main issue is that the TVM frontend doesn’t support dynamic shapes for the ReduceSum operator in ONNX.

Thank you for your response. I hadn’t noticed this before, but I think you have a point. I attempted to forcibly modify the logic with the following code to make it work here, but many issues arose afterward. I think I should take a different approach to handle this ONNX model. :joy: class BinaryBase(OnnxOpConverter): “”“Converts an onnx BinaryBase node into an equivalent Relax expression.”""

    numpy_op: Callable = None
    relax_op: Callable = None

    @classmethod
    def base_impl(cls, bb, inputs, attr, params):
        """Base implementation for binary operations."""
        if cls.numpy_op is None or cls.relax_op is None:
            raise ValueError("Numpy and Relax operators must be defined for BinaryBase.")
        if (len(inputs) == 2 and isinstance(inputs[0], relax.expr.Call) and isinstance(inputs[1], relax.PrimValue)):
            # import pdb; pdb.set_trace()
            x = inputs[0]
            y = inputs[1]
            if isinstance(y, relax.expr.Var):
                return cls.relax_op(x, y)
            if isinstance(y.value, (tir.IntImm, tir.FloatImm)):
                y = relax.const(y.value.value, dtype=x.struct_info.dtype)
                return cls.relax_op(x, y)

            return cls.relax_op(x, y)

        if all([isinstance(inp, relax.Constant) for inp in inputs]):
            output = cls.numpy_op(  # pylint: disable=not-callable
                inputs[0].data.numpy(), inputs[1].data.numpy()
            )
            return relax.const(output, inputs[0].struct_info.dtype)
        if any([isinstance(inp, relax.PrimValue) for inp in inputs]):
            x = _to_numpy(inputs[0])
            y = _to_numpy(inputs[1])
            return relax.PrimValue(cls.numpy_op(x, y))  # pylint: disable=not-callable

        return cls.relax_op(inputs[0], inputs[1])  # pylint: disable=not-callable