tvm.error.OpNotImplemented: The following operators are not supported for frontend ONNX: Expand

I try to convert a pretrained pytorch model into TVM. But it failed.
So can anyone give me some help?

1 Like

you can add the codes in the file: /tvm/python/tvm/relay/frontend/onnx.py

class Expand(OnnxOpConverter):
""" Operator converter for Expand.
"""
@classmethod
def _impl_v1(cls, inputs, attr, params):
    if not isinstance(inputs, list) or len(inputs) < 2:
        raise ValueError("Expect minimum 2 inputs")
    axis = attr.get('axis', 0)
    return _op.expand_dims(inputs[0], axis=axis)

in function _get_convert_map() add the code:

'Expand': Expand.get_converter(opset),

Thanks for your reply. I will try it later.

@Fighting-JJ did you get this resolved? Looking at the operator definition for Expand, it seems like it is more similar to NNVMā€™s expand_like. However, expand_like isnā€™t supported in Relay. Looks like we may need to do some work.

I also found this case. In Relay, there is no expand op so we need to implement. Does anyone has a plan to do? Iā€™m going to try but I havenā€™t add a op to Relay so, It would need time.

@tkclimb that would be very helpful!

For my dummy implementation, Iā€™ve been using this:

class Expand(OnnxOpConverter):
    """Operator converter for Expand
    """
    @classmethod
    def _impl_v8(cls, inputs, attr, params):
        new_shape = infer_value_simulated(inputs[1], params).asnumpy()
        return _op.reshape(inputs[0], new_shape)

I am not sure if this will cover all cases, though.

Update: my implementation actually looks just like Reshapeā€™s _impl_v5. Maybe we can use that for now :slight_smile:

@jonso Thanks for your replay. Iā€™m wondering if the behavior of ONNX Expand is different from the tvm.op.reshape because the ONNX Expand behaves almost like broadcast, which sometimes repeatedly copy the input data by following the given shape. What do you think??

Agree :slight_smile: maybe we can use Relayā€™s broadcast_to.

@tkclimb, according to the ONNX docs:

Also, this operator is similar to numpy.broadcast_to(input, shape), but the major difference is numpy.broadcast_to() does not allow shape to be smaller than input.size()

Maybe we can have a starter implementation that uses broadcast_to and throws if shape is smaller than input.size(). In the future, if thereā€™s need for it, we can add support for shape smaller than input.size(). What do you think?

@jonso That alternative sounds nice! As I understand the ONNX Expand op, it also seems not allowed for the output to be smaller than the input (the name itself indicates it perhaps), doesnā€™t it? Anyway, I will try to use topi.broadcast_to that you suggested. Many thanks :ok_hand:

@jonso I added expand to onnx frontend in the following WIP pull request.

could you check this out?