aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ethosu/vela/tflite_reader.py17
-rw-r--r--ethosu/vela/tflite_writer.py8
2 files changed, 15 insertions, 10 deletions
diff --git a/ethosu/vela/tflite_reader.py b/ethosu/vela/tflite_reader.py
index 85acb6b..e732f19 100644
--- a/ethosu/vela/tflite_reader.py
+++ b/ethosu/vela/tflite_reader.py
@@ -153,18 +153,21 @@ class TFLiteSubgraph:
self.virtual_outputs.append(tens)
if op.type.is_depthwise_conv2d_op() or op.type.is_conv2d_op() or op.type == Op.FullyConnected:
+ # Reshape and add bias for ops with constant weights
+ # Do not modify ops with dynamic data since they will run on CPU
if inputs[1].values is not None:
if op.type == Op.FullyConnected:
inputs[1] = clone_and_reshape_tensor(inputs[1], (1, 0), False)
else:
inputs[1] = clone_and_reshape_tensor(inputs[1], (1, 2, 3, 0), False)
- if op.type.needs_bias() and len(inputs) <= op_type.info.indices.biases[0]:
- # No Bias tensor
- inputs.append(None)
- if inputs[-1] and inputs[-1].values is not None:
- # Since bias tensor is used for both bias and scale,
- # a clone with a unique equivalence_id is needed.
- inputs[-1] = clone_and_reshape_tensor(inputs[-1], None, True)
+
+ if op.type.needs_bias() and len(inputs) <= op_type.info.indices.biases[0]:
+ # No Bias tensor
+ inputs.append(None)
+ if inputs[-1] and inputs[-1].values is not None:
+ # Since bias tensor is used for both bias and scale,
+ # a clone with a unique equivalence_id is needed.
+ inputs[-1] = clone_and_reshape_tensor(inputs[-1], None, True)
if opt_serializer is not None:
op.attrs = opt_serializer.deserialize(op_data)
diff --git a/ethosu/vela/tflite_writer.py b/ethosu/vela/tflite_writer.py
index 44ce711..d4e24a2 100644
--- a/ethosu/vela/tflite_writer.py
+++ b/ethosu/vela/tflite_writer.py
@@ -105,9 +105,11 @@ class TFLiteSerialiser:
if op.type.is_conv2d_op() or op.type.is_depthwise_conv2d_op() or op.type == Op.FullyConnected:
# Op is run on CPU, make sure the original weight and bias tensors are written back
# instead of the cloned/reshaped (see tflite_reader)
- for idx, inp in enumerate(op.inputs):
- if inp != op.ifm and inp is not None and inp.src_tensor is not None:
- op.inputs[idx] = inp.src_tensor
+ # Do nothing when values are None (dynamic weights)
+ if op.inputs[1].values is not None:
+ for idx, inp in enumerate(op.inputs):
+ if inp != op.ifm and inp is not None and inp.src_tensor is not None:
+ op.inputs[idx] = inp.src_tensor
# list of tuple(Op, string, op.version); the custom code is only used for 3rd party custom operators
self.operator_codes = sorted(set((op.type, op.attrs.get("custom_code", ""), op.version) for op in all_ops))