aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ethosu/vela/graph_optimiser.py4
-rw-r--r--ethosu/vela/pass_packing.py2
-rw-r--r--ethosu/vela/register_command_stream_generator.py10
-rw-r--r--ethosu/vela/supported_operators.py2
-rw-r--r--ethosu/vela/tflite_reader.py16
5 files changed, 30 insertions, 4 deletions
diff --git a/ethosu/vela/graph_optimiser.py b/ethosu/vela/graph_optimiser.py
index b29a3823..fdd6fc61 100644
--- a/ethosu/vela/graph_optimiser.py
+++ b/ethosu/vela/graph_optimiser.py
@@ -283,7 +283,7 @@ def add_padding_fields(op, arch):
if "Conv" in op.type:
kernel_size = op.inputs[1].shape[:2]
input_shape = op.inputs[0].shape
- elif "Pool" in op.type:
+ elif "Pool" in op.type or "ResizeBilinear" == op.type:
kernel_size = op.attrs["ksize"][1:3]
input_shape = op.inputs[0].shape
elif op.type == "ExtractImagePatches":
@@ -314,7 +314,7 @@ fc_op = set(
)
)
depthwise_op = set(("DepthwiseConv2dNative", "DepthwiseConv2dBiasAct",))
-pool_op = set(("AvgPool", "MaxPool", "QuantizedAvgPool", "QuantizedMaxPool", "AvgPoolAct", "MaxPoolAct"))
+pool_op = set(("AvgPool", "MaxPool", "QuantizedAvgPool", "QuantizedMaxPool", "AvgPoolAct", "MaxPoolAct", "ResizeBilinear",))
elementwise_op = set(("AddAct", "MulAct", "SubAct", "Maximum", "Minimum", "LeakyRelu", "Abs"))
activation_ops = set(("Relu", "Relu6", "ReluN1To1", "Sigmoid", "Tanh"))
memory_only_ops = set(("Reshape",))
diff --git a/ethosu/vela/pass_packing.py b/ethosu/vela/pass_packing.py
index bae81517..1ad5b4f7 100644
--- a/ethosu/vela/pass_packing.py
+++ b/ethosu/vela/pass_packing.py
@@ -67,6 +67,8 @@ mac_main_ops = set(
"MaxPool",
"AvgPoolAct",
"MaxPoolAct",
+ # deconvolution
+ "ResizeBilinear",
)
)
diff --git a/ethosu/vela/register_command_stream_generator.py b/ethosu/vela/register_command_stream_generator.py
index 460cf016..7a4faa80 100644
--- a/ethosu/vela/register_command_stream_generator.py
+++ b/ethosu/vela/register_command_stream_generator.py
@@ -401,6 +401,8 @@ def generate_register_command_stream(nng, sg, arch, verbose=False):
use_global_scale = False
# Specifies type of rounding to be used.
rounding_mode = rounding.TFL
+ if primary_op.type == 'ResizeBilinear':
+ rounding_mode = rounding.TRUNCATE
fmf = primary_op.attrs.get("fused_memory_function", None)
faf = primary_op.attrs.get("fused_activation_function", None)
@@ -537,7 +539,11 @@ def generate_register_command_stream(nng, sg, arch, verbose=False):
emit.cmd0_with_param(cmd0.NPU_SET_ACC_FORMAT, acc_format_map[shared_buffer.use_accumulator_element])
- emit.cmd0_with_param(cmd0.NPU_SET_IFM_UPSCALE, 0)
+ if primary_op.type == 'ResizeBilinear':
+ # perform nearest neighbor upscale
+ emit.cmd0_with_param(cmd0.NPU_SET_IFM_UPSCALE, 1)
+ else:
+ emit.cmd0_with_param(cmd0.NPU_SET_IFM_UPSCALE, 0)
if npu_block_type in set(
(NpuBlockType.ConvolutionMxN, NpuBlockType.ConvolutionDepthWise, NpuBlockType.Pooling)
@@ -579,7 +585,7 @@ def generate_register_command_stream(nng, sg, arch, verbose=False):
valid_padding = sum(explicit_padding) == 0
- if primary_op.type in set(("AvgPool", "AvgPoolAct")) and valid_padding:
+ if primary_op.type in set(("AvgPool", "AvgPoolAct", "ResizeBilinear")) and valid_padding:
# For valid padding vela has to output scaling values
if faf == "Sigmoid" or faf == "Tanh":
rescale = 0x3000 * cmd.ifm_tensor.quantization.scale_f32
diff --git a/ethosu/vela/supported_operators.py b/ethosu/vela/supported_operators.py
index 1a25887f..7334fe25 100644
--- a/ethosu/vela/supported_operators.py
+++ b/ethosu/vela/supported_operators.py
@@ -44,6 +44,8 @@ class SupportedOperators:
| self.fc_vector_products
# RNN/LSTM/GRU
| set(("BlockLSTM"))
+ # deconvolution
+ | set(("ResizeBilinear",))
)
self.unary_elem_wise_main_ops = set(("LeakyRelu", "Abs"))
self.binary_elem_wise_main_ops = set(
diff --git a/ethosu/vela/tflite_reader.py b/ethosu/vela/tflite_reader.py
index 4456d5a0..aa0ec4d8 100644
--- a/ethosu/vela/tflite_reader.py
+++ b/ethosu/vela/tflite_reader.py
@@ -156,6 +156,22 @@ class TFLiteSubgraph:
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: