diff options
author | wilisa01 <william.isaksson@arm.com> | 2023-04-13 17:05:09 +0000 |
---|---|---|
committer | Fredrik Svedberg <fredrik.svedberg@arm.com> | 2023-05-04 08:45:46 +0000 |
commit | 0a7d5ee98dfc8c881372bc5a50be37aed209c30e (patch) | |
tree | 7b88b1cc4bae5fa835f16f0c0d51fe7d4e14a7af /ethosu | |
parent | 50550d60121a3ca39b086d643163e7c74ccee837 (diff) | |
download | ethos-u-vela-0a7d5ee98dfc8c881372bc5a50be37aed209c30e.tar.gz |
MLBEDSW-7504: Vela does not keep op version number
We now read operator code version, store it in operator and write it out
to optimized file.
Signed-off-by: wilisa01 <william.isaksson@arm.com>
Change-Id: Idba672531d2e2a0203a85d3ffca9cf65ace85b47
Diffstat (limited to 'ethosu')
-rw-r--r-- | ethosu/vela/operation.py | 4 | ||||
-rw-r--r-- | ethosu/vela/test/test_tflite_reader.py | 24 | ||||
-rw-r--r-- | ethosu/vela/tflite_reader.py | 5 | ||||
-rw-r--r-- | ethosu/vela/tflite_writer.py | 12 |
4 files changed, 26 insertions, 19 deletions
diff --git a/ethosu/vela/operation.py b/ethosu/vela/operation.py index 69596522..161b17fd 100644 --- a/ethosu/vela/operation.py +++ b/ethosu/vela/operation.py @@ -471,6 +471,7 @@ class Operation: "type", "_original_type", "name", + "version", "op_index", "attrs", "inputs", @@ -504,6 +505,7 @@ class Operation: self.type = op_type self._original_type = op_type # the original type of the operation. once set this shouldn't be changed self.name = name + self.version = 1 # Used to track original operator version. self.attrs: Dict[str, Any] = {} self.inputs: List[Optional[Tensor]] = [] self.outputs: List[Tensor] = [] @@ -549,7 +551,7 @@ class Operation: # maintain the original type, in cases where the type was changed to something different res._original_type = self._original_type - + res.version = self.version res.attrs = dict(self.attrs) res.inputs = list(self.inputs) res.outputs = list(self.outputs) diff --git a/ethosu/vela/test/test_tflite_reader.py b/ethosu/vela/test/test_tflite_reader.py index 871545e4..d1a8ee67 100644 --- a/ethosu/vela/test/test_tflite_reader.py +++ b/ethosu/vela/test/test_tflite_reader.py @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: Copyright 2020-2021 Arm Limited and/or its affiliates <open-source-office@arm.com> +# SPDX-FileCopyrightText: Copyright 2020-2021, 2023 Arm Limited and/or its affiliates <open-source-office@arm.com> # # SPDX-License-Identifier: Apache-2.0 # @@ -46,25 +46,25 @@ class TestTFLiteSubgraph: assert output == expected parse_op_testdata = [ - # op_type, opt_serializer, indices, inputs, output, expected - (Op.FullyConnected, None, TFLITE_IFM_WEIGHTS_BIAS_INDICES, [0, 1, 2], 3, 3), # FC - (Op.FullyConnected, None, TFLITE_IFM_WEIGHTS_BIAS_INDICES, [0, 1, -1], 3, 3), # FC disabled Bias - (Op.FullyConnected, None, TFLITE_IFM_WEIGHTS_BIAS_INDICES, [0, 1], 3, 3), # FC no Bias - (Op.Conv2DBias, None, TFLITE_IFM_WEIGHTS_BIAS_INDICES, [2, 1, 3], 0, 3), # Conv2D - (Op.Conv2DBackpropInput, None, TFLITE_CONV2D_BACKPROP_INDICES, [0, 1, 2, 3], 4, 4), # TransposeConv - (Op.Conv2DBackpropInput, None, TFLITE_CONV2D_BACKPROP_INDICES, [0, 1, 2], 4, 4), # TransposeConv no Bias + # op_type, opt_serializer, indices, version, inputs, output, expected + (Op.FullyConnected, None, TFLITE_IFM_WEIGHTS_BIAS_INDICES, 1, [0, 1, 2], 3, 3), # FC + (Op.FullyConnected, None, TFLITE_IFM_WEIGHTS_BIAS_INDICES, 1, [0, 1, -1], 3, 3), # FC disabled Bias + (Op.FullyConnected, None, TFLITE_IFM_WEIGHTS_BIAS_INDICES, 5, [0, 1], 3, 3), # FC no Bias + (Op.Conv2DBias, None, TFLITE_IFM_WEIGHTS_BIAS_INDICES, 5, [2, 1, 3], 0, 3), # Conv2D + (Op.Conv2DBackpropInput, None, TFLITE_CONV2D_BACKPROP_INDICES, 5, [0, 1, 2, 3], 4, 4), # TransposeConv + (Op.Conv2DBackpropInput, None, TFLITE_CONV2D_BACKPROP_INDICES, 5, [0, 1, 2], 4, 4), # TransposeConv no Bias pytest.param( - Op.Conv2DBias, None, TFLITE_IFM_WEIGHTS_BIAS_INDICES, [0, -1, 1], 3, 3, marks=pytest.mark.xfail + Op.Conv2DBias, None, TFLITE_IFM_WEIGHTS_BIAS_INDICES, 5, [0, -1, 1], 3, 3, marks=pytest.mark.xfail ), # Conv2D no Weights ] - @pytest.mark.parametrize("op_type, opt_serializer, indices, inputs, output, expected", parse_op_testdata) - def test_parse_operator(self, op_type, opt_serializer, indices, inputs, output, expected): + @pytest.mark.parametrize("op_type, opt_serializer, indices, version, inputs, output, expected", parse_op_testdata) + def test_parse_operator(self, op_type, opt_serializer, indices, version, inputs, output, expected): with patch.object(TFLiteSubgraph, "__init__", lambda self, graph, subraph: None): # Mock a TFLiteSubGraph sg = TFLiteSubgraph(None, None) sg.graph = MagicMock() - sg.graph.operator_codes = [(op_type, opt_serializer, "", indices)] + sg.graph.operator_codes = [(op_type, opt_serializer, "", indices, version)] # Mock a couple of tensors sg.tensors = [MagicMock() for _ in range(5)] diff --git a/ethosu/vela/tflite_reader.py b/ethosu/vela/tflite_reader.py index 061f3626..85acb6b8 100644 --- a/ethosu/vela/tflite_reader.py +++ b/ethosu/vela/tflite_reader.py @@ -117,7 +117,7 @@ class TFLiteSubgraph: return tens def parse_operator(self, op_index, op_data): - op_type, opt_serializer, custom_code, indices = self.graph.operator_codes[op_data.OpcodeIndex()] + op_type, opt_serializer, custom_code, indices, version = self.graph.operator_codes[op_data.OpcodeIndex()] inputs = [self.tensors[idx] if idx != -1 else None for idx in op_data.InputsAsNumpy()] outputs = [self.tensors[idx] if idx != -1 else None for idx in op_data.OutputsAsNumpy()] intermediates = [] @@ -130,6 +130,7 @@ class TFLiteSubgraph: inputs = align_tensor_indices_to_nng(op_type, indices, inputs) op = Operation(op_type, name) op.op_index = op_index + op.version = version op.inputs = inputs op.outputs = outputs op.intermediates = intermediates @@ -338,7 +339,7 @@ class TFLiteGraph: custom_code = None if c == BuiltinOperator.CUSTOM: custom_code = decode_str(code.CustomCode()) - return op_type, ser, custom_code, indices + return op_type, ser, custom_code, indices, code.Version() def read_tflite(filename, batch_size, feed_dict, output_node_names, initialisation_nodes): diff --git a/ethosu/vela/tflite_writer.py b/ethosu/vela/tflite_writer.py index 2e7345ce..8c03f051 100644 --- a/ethosu/vela/tflite_writer.py +++ b/ethosu/vela/tflite_writer.py @@ -108,8 +108,8 @@ class TFLiteSerialiser: if inp is not None and inp.src_tensor is not None: op.inputs[idx] = inp.src_tensor - # list of tuple(Op, string); the custom code is only used for 3rd party custom operators - self.operator_codes = sorted(set((op.type, op.attrs.get("custom_code", "")) for op in all_ops)) + # 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)) self.operator_code_map = {} def align_nng_inputs_to_tflite(self, op): @@ -176,7 +176,7 @@ class TFLiteSerialiser: return buffer_map - def serialise_operator_code(self, idx, op_type, custom_code): + def serialise_operator_code(self, idx, op_type, custom_code, version): builder = self.builder custom_code_offset = None if op_type == Op.Custom: @@ -207,6 +207,7 @@ class TFLiteSerialiser: OperatorCode.OperatorCodeStart(builder) OperatorCode.OperatorCodeAddDeprecatedBuiltinCode(builder, tf_code if tf_code < 127 else 127) OperatorCode.OperatorCodeAddBuiltinCode(builder, tf_code) + OperatorCode.OperatorCodeAddVersion(builder, version) if custom_code_offset is not None: OperatorCode.OperatorCodeAddCustomCode(builder, custom_code_offset) @@ -455,7 +456,10 @@ class TFLiteSerialiser: def serialise_model(self): builder = self.builder operator_code_offset = self.write_offset_vector( - [self.serialise_operator_code(idx, optype, code) for idx, (optype, code) in enumerate(self.operator_codes)] + [ + self.serialise_operator_code(idx, optype, code, version) + for idx, (optype, code, version) in enumerate(self.operator_codes) + ] ) description = builder.CreateString("Vela Optimised") |