microsoft / onnxscript

ONNX Script enables developers to naturally author ONNX functions and models using a subset of Python.
https://onnxscript.ai/
MIT License
271 stars 52 forks source link

proper way to construct a tensor on the fly? #1560

Open vincentme opened 4 months ago

vincentme commented 4 months ago

My goal is to pad the image to the power of two. The following code works. But the way to construct pads pads = op.ConcatFromSequence(op.SequenceConstruct(zero, zero, padded_row, padded_col), axis = 0, new_axis=1) seems a bit cumbersome. Is this the proper way to construct a tensor on the fly? I tried the literal way # pads = [zero, zero, padded_row, padded_col], it does not work.

Thanks!

@script()
def pad_image(img_in):
    shape = op.Shape(img_in)
    next_row = find_next_power_of_two(shape[0])
    next_col = find_next_power_of_two(shape[1])

    zero = op.Constant(value=helper.make_tensor("int_zero", TensorProto.INT64, (), [0]))
    padded_row = next_row - shape[0]
    padded_col = next_col - shape[1]
    pads = op.ConcatFromSequence(op.SequenceConstruct(zero, zero, padded_row, padded_col), axis = 0, new_axis=1)
    # pads = [zero, zero, padded_row, padded_col]
    print(pads)

    img_padded = op.Pad(img_in, pads = pads, mode = 'reflect')
    return img_padded
justinchuby commented 4 months ago

Does op.Concat(zero, zero, padded_row, padded_col) work for you?

vincentme commented 4 months ago

Does op.Concat(zero, zero, padded_row, padded_col) work for you?

Thanks! Because these tensors are indeed scalars, so I have to unsqueeze them to 1D then concat, the following works. Not sure if this is a better way...

pads = op.Concat(op.Unsqueeze(zero, axes=[0]), op.Unsqueeze(zero, axes=[0]), op.Unsqueeze(pad_row, axes=[0]), op.Unsqueeze(pad_col, axes=[0]), axis = 0)

gramalingam commented 4 months ago

A naive question: how is this being run? I am a bit puzzled because this mixed-mode construction (interleaving script-time computation with onnx-construction) is doable in trace-mode, but not in script-mode.

Otherwise: nothing much to add to the existing discussion. If the shape is statically known, there may be other ways of doing this. But I assume you want to handle dynamic shapes here? So, Concat, as above, seems reasonable.

vincentme commented 4 months ago

A naive question: how is this being run? I am a bit puzzled because this mixed-mode construction (interleaving script-time computation with onnx-construction) is doable in trace-mode, but not in script-mode.

Otherwise: nothing much to add to the existing discussion. If the shape is statically known, there may be other ways of doing this. But I assume you want to handle dynamic shapes here? So, Concat, as above, seems reasonable.

Sorry, i am not quite understand your comments... The script or trace modes are the ones in pytorch export?

If so, my context is different. The goal is not convert from pytorch, but directly write algorithm(not necessary deep learning model) in onnxscript. As shown inthis example, one step is to pad the image to the power of two. The shape of the input image is dynamic, but the shape of the pads is of course fixed as (4,).