MLBEDSW-1498: Add Resize_Bilinear operator support

This patch adds support for the ResizeBilinear operator.

It is implemented using a 2x2 Nearest Neighbor upscale
followed by a 2x2 Average Pool.
Depending on the argument align_corners
the output is either of shape:
    - (2 * M, 2 * N) when align_corners == True, or
    - (2 * M - 1, 2 * N - 1) when align_corners == False
where (M, N) is the input shape.

The padding mode is SAME when align_corners == True
and VALID when align_corners == False.

The argument half_pixel_centers is out of scope and is
as of now ignored.

Note that only upscaling by a factor of 2 is supported.

Change-Id: Ia6d6d010c4f1bb13f5f839bc8d16872a626d9a3b
Signed-off-by: Dwight Lidman <dwight.lidman@arm.com>
diff --git a/ethosu/vela/tflite_reader.py b/ethosu/vela/tflite_reader.py
index 4456d5a..aa0ec4d 100644
--- a/ethosu/vela/tflite_reader.py
+++ b/ethosu/vela/tflite_reader.py
@@ -156,6 +156,22 @@
         if opt_serializer is not None:
             op.attrs = opt_serializer.deserialize(op_data.BuiltinOptions(), op_data.CustomOptionsAsNumpy())
 
+            if op_type.startswith("ResizeBilinear"):
+                upscaled_shape = [op.inputs[0].shape[1] * 2, op.inputs[0].shape[2] * 2]
+                out_shape = op.outputs[0].shape[1:3]
+                if not op.attrs['align_corners'] and out_shape == upscaled_shape:
+                    # this means the output is supposed to be a x2 upscale,
+                    # so we need to do SAME padding
+                    op.attrs.update({'padding': b'SAME'})
+                elif (op.attrs['align_corners']
+                    and out_shape == [upscaled_shape[0] - 1, upscaled_shape[1] - 1]):
+                    # here we can just run the avg pool without padding and
+                    # produce a (M * 2 - 1, N * 2 - 1) sized output
+                    op.attrs.update({'padding': b'VALID'})
+                else:
+                    assert False, "Only 2x upscaling is supported"
+                op.attrs.update({'filter_width': 2, 'filter_height': 2, 'stride_w': 1, 'stride_h': 1,})
+
             if "stride_w" in op.attrs:
                 op.attrs["strides"] = (1, op.attrs["stride_h"], op.attrs["stride_w"], 1)
             if "filter_width" in op.attrs: