From 42abec185a95ac8d5f2b32d541f587b3cd306e75 Mon Sep 17 00:00:00 2001 From: Tim Hall Date: Thu, 4 Feb 2021 21:31:57 +0000 Subject: MLBEDSW-3771: Updated to TF 2.4 flatbuffer schema Updated tflite loader and mappings from tensorflow 2.3 to tensorflow 2.4 Signed-off-by: Tim Hall Change-Id: I55884000ee139baf639bb0377008e0534f72fe94 --- README.md | 4 +- ethosu/vela/operation.py | 1 + ethosu/vela/tflite/BuiltinOperator.py | 2 + ethosu/vela/tflite/BuiltinOptions.py | 1 + ethosu/vela/tflite/CumsumOptions.py | 38 ++++++++++++++++ ethosu/vela/tflite/Model.py | 24 +++++++++- ethosu/vela/tflite/OperatorCode.py | 14 ++++-- ethosu/vela/tflite/SignatureDef.py | 82 +++++++++++++++++++++++++++++++++++ ethosu/vela/tflite/TensorMap.py | 38 ++++++++++++++++ ethosu/vela/tflite_mapping.py | 3 ++ ethosu/vela/tflite_reader.py | 2 + ethosu/vela/tflite_writer.py | 1 + setup.py | 2 +- 13 files changed, 206 insertions(+), 6 deletions(-) create mode 100644 ethosu/vela/tflite/CumsumOptions.py create mode 100644 ethosu/vela/tflite/SignatureDef.py create mode 100644 ethosu/vela/tflite/TensorMap.py diff --git a/README.md b/README.md index 586885c3..81bb0a08 100644 --- a/README.md +++ b/README.md @@ -25,7 +25,9 @@ compiled model. ## TensorFlow Support -Vela supports TensorFlow 2.3.0 +* Vela 2.1.0 to current supports TensorFlow 2.4 +* Vela 2.0.0 to 2.0.1 supports TensorFlow 2.3 +* Vela 0.1.0 to 1.2.0 supports TensorFlow 2.1 ## Environment diff --git a/ethosu/vela/operation.py b/ethosu/vela/operation.py index 963d9e69..09371b7a 100644 --- a/ethosu/vela/operation.py +++ b/ethosu/vela/operation.py @@ -145,6 +145,7 @@ class Op(Enum): ) Conv2DBias = OperatorInfo(block_type=NpuBlockType.ConvolutionMxN, indices=IFM_WEIGHTS_BIAS_INDICES) Cos = OperatorInfo() + Cumsum = OperatorInfo() Custom = OperatorInfo() # Custom 3rd party operator, only used in CPU subgraphs CustomNpuOp = OperatorInfo() # NPU custom operator, only used in CPU subgraphs DMA = OperatorInfo() diff --git a/ethosu/vela/tflite/BuiltinOperator.py b/ethosu/vela/tflite/BuiltinOperator.py index fb23155c..73fed9b6 100644 --- a/ethosu/vela/tflite/BuiltinOperator.py +++ b/ethosu/vela/tflite/BuiltinOperator.py @@ -130,4 +130,6 @@ class BuiltinOperator(object): DENSIFY = 124 SEGMENT_SUM = 125 BATCH_MATMUL = 126 + PLACEHOLDER_FOR_GREATER_OP_CODES = 127 + CUMSUM = 128 diff --git a/ethosu/vela/tflite/BuiltinOptions.py b/ethosu/vela/tflite/BuiltinOptions.py index 6f0aab0a..6be2d43a 100644 --- a/ethosu/vela/tflite/BuiltinOptions.py +++ b/ethosu/vela/tflite/BuiltinOptions.py @@ -105,4 +105,5 @@ class BuiltinOptions(object): DensifyOptions = 99 SegmentSumOptions = 100 BatchMatMulOptions = 101 + CumsumOptions = 102 diff --git a/ethosu/vela/tflite/CumsumOptions.py b/ethosu/vela/tflite/CumsumOptions.py new file mode 100644 index 00000000..33e086ef --- /dev/null +++ b/ethosu/vela/tflite/CumsumOptions.py @@ -0,0 +1,38 @@ +# automatically generated by the FlatBuffers compiler, do not modify + +# namespace: tflite + +import flatbuffers + +class CumsumOptions(object): + __slots__ = ['_tab'] + + @classmethod + def GetRootAsCumsumOptions(cls, buf, offset): + n = flatbuffers.encode.Get(flatbuffers.packer.uoffset, buf, offset) + x = CumsumOptions() + x.Init(buf, n + offset) + return x + + # CumsumOptions + def Init(self, buf, pos): + self._tab = flatbuffers.table.Table(buf, pos) + + # CumsumOptions + def Exclusive(self): + o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(4)) + if o != 0: + return bool(self._tab.Get(flatbuffers.number_types.BoolFlags, o + self._tab.Pos)) + return False + + # CumsumOptions + def Reverse(self): + o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(6)) + if o != 0: + return bool(self._tab.Get(flatbuffers.number_types.BoolFlags, o + self._tab.Pos)) + return False + +def CumsumOptionsStart(builder): builder.StartObject(2) +def CumsumOptionsAddExclusive(builder, exclusive): builder.PrependBoolSlot(0, exclusive, 0) +def CumsumOptionsAddReverse(builder, reverse): builder.PrependBoolSlot(1, reverse, 0) +def CumsumOptionsEnd(builder): return builder.EndObject() diff --git a/ethosu/vela/tflite/Model.py b/ethosu/vela/tflite/Model.py index cc9991ba..52aac021 100644 --- a/ethosu/vela/tflite/Model.py +++ b/ethosu/vela/tflite/Model.py @@ -134,7 +134,27 @@ class Model(object): return self._tab.VectorLen(o) return 0 -def ModelStart(builder): builder.StartObject(7) + # Model + def SignatureDefs(self, j): + o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(18)) + if o != 0: + x = self._tab.Vector(o) + x += flatbuffers.number_types.UOffsetTFlags.py_type(j) * 4 + x = self._tab.Indirect(x) + from .SignatureDef import SignatureDef + obj = SignatureDef() + obj.Init(self._tab.Bytes, x) + return obj + return None + + # Model + def SignatureDefsLength(self): + o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(18)) + if o != 0: + return self._tab.VectorLen(o) + return 0 + +def ModelStart(builder): builder.StartObject(8) def ModelAddVersion(builder, version): builder.PrependUint32Slot(0, version, 0) def ModelAddOperatorCodes(builder, operatorCodes): builder.PrependUOffsetTRelativeSlot(1, flatbuffers.number_types.UOffsetTFlags.py_type(operatorCodes), 0) def ModelStartOperatorCodesVector(builder, numElems): return builder.StartVector(4, numElems, 4) @@ -147,4 +167,6 @@ def ModelAddMetadataBuffer(builder, metadataBuffer): builder.PrependUOffsetTRela def ModelStartMetadataBufferVector(builder, numElems): return builder.StartVector(4, numElems, 4) def ModelAddMetadata(builder, metadata): builder.PrependUOffsetTRelativeSlot(6, flatbuffers.number_types.UOffsetTFlags.py_type(metadata), 0) def ModelStartMetadataVector(builder, numElems): return builder.StartVector(4, numElems, 4) +def ModelAddSignatureDefs(builder, signatureDefs): builder.PrependUOffsetTRelativeSlot(7, flatbuffers.number_types.UOffsetTFlags.py_type(signatureDefs), 0) +def ModelStartSignatureDefsVector(builder, numElems): return builder.StartVector(4, numElems, 4) def ModelEnd(builder): return builder.EndObject() diff --git a/ethosu/vela/tflite/OperatorCode.py b/ethosu/vela/tflite/OperatorCode.py index dd525f53..5a0ba2a4 100644 --- a/ethosu/vela/tflite/OperatorCode.py +++ b/ethosu/vela/tflite/OperatorCode.py @@ -19,7 +19,7 @@ class OperatorCode(object): self._tab = flatbuffers.table.Table(buf, pos) # OperatorCode - def BuiltinCode(self): + def DeprecatedBuiltinCode(self): o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(4)) if o != 0: return self._tab.Get(flatbuffers.number_types.Int8Flags, o + self._tab.Pos) @@ -39,8 +39,16 @@ class OperatorCode(object): return self._tab.Get(flatbuffers.number_types.Int32Flags, o + self._tab.Pos) return 1 -def OperatorCodeStart(builder): builder.StartObject(3) -def OperatorCodeAddBuiltinCode(builder, builtinCode): builder.PrependInt8Slot(0, builtinCode, 0) + # OperatorCode + def BuiltinCode(self): + o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(10)) + if o != 0: + return self._tab.Get(flatbuffers.number_types.Int32Flags, o + self._tab.Pos) + return 0 + +def OperatorCodeStart(builder): builder.StartObject(4) +def OperatorCodeAddDeprecatedBuiltinCode(builder, deprecatedBuiltinCode): builder.PrependInt8Slot(0, deprecatedBuiltinCode, 0) def OperatorCodeAddCustomCode(builder, customCode): builder.PrependUOffsetTRelativeSlot(1, flatbuffers.number_types.UOffsetTFlags.py_type(customCode), 0) def OperatorCodeAddVersion(builder, version): builder.PrependInt32Slot(2, version, 1) +def OperatorCodeAddBuiltinCode(builder, builtinCode): builder.PrependInt32Slot(3, builtinCode, 0) def OperatorCodeEnd(builder): return builder.EndObject() diff --git a/ethosu/vela/tflite/SignatureDef.py b/ethosu/vela/tflite/SignatureDef.py new file mode 100644 index 00000000..149f8fc6 --- /dev/null +++ b/ethosu/vela/tflite/SignatureDef.py @@ -0,0 +1,82 @@ +# automatically generated by the FlatBuffers compiler, do not modify + +# namespace: tflite + +import flatbuffers + +class SignatureDef(object): + __slots__ = ['_tab'] + + @classmethod + def GetRootAsSignatureDef(cls, buf, offset): + n = flatbuffers.encode.Get(flatbuffers.packer.uoffset, buf, offset) + x = SignatureDef() + x.Init(buf, n + offset) + return x + + # SignatureDef + def Init(self, buf, pos): + self._tab = flatbuffers.table.Table(buf, pos) + + # SignatureDef + def Inputs(self, j): + o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(4)) + if o != 0: + x = self._tab.Vector(o) + x += flatbuffers.number_types.UOffsetTFlags.py_type(j) * 4 + x = self._tab.Indirect(x) + from .TensorMap import TensorMap + obj = TensorMap() + obj.Init(self._tab.Bytes, x) + return obj + return None + + # SignatureDef + def InputsLength(self): + o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(4)) + if o != 0: + return self._tab.VectorLen(o) + return 0 + + # SignatureDef + def Outputs(self, j): + o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(6)) + if o != 0: + x = self._tab.Vector(o) + x += flatbuffers.number_types.UOffsetTFlags.py_type(j) * 4 + x = self._tab.Indirect(x) + from .TensorMap import TensorMap + obj = TensorMap() + obj.Init(self._tab.Bytes, x) + return obj + return None + + # SignatureDef + def OutputsLength(self): + o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(6)) + if o != 0: + return self._tab.VectorLen(o) + return 0 + + # SignatureDef + def MethodName(self): + o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(8)) + if o != 0: + return self._tab.String(o + self._tab.Pos) + return None + + # SignatureDef + def Key(self): + o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(10)) + if o != 0: + return self._tab.String(o + self._tab.Pos) + return None + +def SignatureDefStart(builder): builder.StartObject(4) +def SignatureDefAddInputs(builder, inputs): builder.PrependUOffsetTRelativeSlot(0, flatbuffers.number_types.UOffsetTFlags.py_type(inputs), 0) +def SignatureDefStartInputsVector(builder, numElems): return builder.StartVector(4, numElems, 4) +def SignatureDefAddOutputs(builder, outputs): builder.PrependUOffsetTRelativeSlot(1, flatbuffers.number_types.UOffsetTFlags.py_type(outputs), 0) +def SignatureDefStartOutputsVector(builder, numElems): return builder.StartVector(4, numElems, 4) +def SignatureDefAddMethodName(builder, methodName): builder.PrependUOffsetTRelativeSlot(2, flatbuffers.number_types.UOffsetTFlags.py_type(methodName), 0) +def SignatureDefAddKey(builder, key): builder.PrependUOffsetTRelativeSlot(3, flatbuffers.number_types.UOffsetTFlags.py_type(key), 0) +def SignatureDefEnd(builder): return builder.EndObject() diff --git a/ethosu/vela/tflite/TensorMap.py b/ethosu/vela/tflite/TensorMap.py new file mode 100644 index 00000000..e9b036d9 --- /dev/null +++ b/ethosu/vela/tflite/TensorMap.py @@ -0,0 +1,38 @@ +# automatically generated by the FlatBuffers compiler, do not modify + +# namespace: tflite + +import flatbuffers + +class TensorMap(object): + __slots__ = ['_tab'] + + @classmethod + def GetRootAsTensorMap(cls, buf, offset): + n = flatbuffers.encode.Get(flatbuffers.packer.uoffset, buf, offset) + x = TensorMap() + x.Init(buf, n + offset) + return x + + # TensorMap + def Init(self, buf, pos): + self._tab = flatbuffers.table.Table(buf, pos) + + # TensorMap + def Name(self): + o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(4)) + if o != 0: + return self._tab.String(o + self._tab.Pos) + return None + + # TensorMap + def TensorIndex(self): + o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(6)) + if o != 0: + return self._tab.Get(flatbuffers.number_types.Uint32Flags, o + self._tab.Pos) + return 0 + +def TensorMapStart(builder): builder.StartObject(2) +def TensorMapAddName(builder, name): builder.PrependUOffsetTRelativeSlot(0, flatbuffers.number_types.UOffsetTFlags.py_type(name), 0) +def TensorMapAddTensorIndex(builder, tensorIndex): builder.PrependUint32Slot(1, tensorIndex, 0) +def TensorMapEnd(builder): return builder.EndObject() diff --git a/ethosu/vela/tflite_mapping.py b/ethosu/vela/tflite_mapping.py index 6fcbb95b..c1e45c0c 100644 --- a/ethosu/vela/tflite_mapping.py +++ b/ethosu/vela/tflite_mapping.py @@ -40,6 +40,7 @@ from .tflite import ConcatEmbeddingsOptions from .tflite import ConcatenationOptions from .tflite import Conv2DOptions from .tflite import CosOptions +from .tflite import CumsumOptions from .tflite import DensifyOptions from .tflite import DepthToSpaceOptions from .tflite import DepthwiseConv2DOptions @@ -278,6 +279,7 @@ builtin_options_map = { BuiltinOptions.SelectV2Options: SelectV2Options.SelectV2Options, BuiltinOptions.WhileOptions: WhileOptions.WhileOptions, BuiltinOptions.BatchMatMulOptions: BatchMatMulOptions.BatchMatMulOptions, + BuiltinOptions.CumsumOptions: CumsumOptions.CumsumOptions, } builtin_options_inv_map = inverse_map(builtin_options_map) @@ -690,6 +692,7 @@ builtin_operator_map = { BuiltinOperator.DENSIFY: (Op.Densify, OptionsSerializer("DensifyOptions")), BuiltinOperator.SEGMENT_SUM: (Op.SegmentSum, OptionsSerializer("SegmentSumOptions")), BuiltinOperator.BATCH_MATMUL: (Op.BatchMatMul, OptionsSerializer("BatchMatMulOptions", ("adj_x", "adj_y"))), + BuiltinOperator.CUMSUM: (Op.Cumsum, OptionsSerializer("CumsumOptions", ("exclusive", "reverse"))), BuiltinOperator.CUSTOM: (Op.Custom, CustomOptionsSerializer()), } diff --git a/ethosu/vela/tflite_reader.py b/ethosu/vela/tflite_reader.py index 45397c2b..ae99c339 100644 --- a/ethosu/vela/tflite_reader.py +++ b/ethosu/vela/tflite_reader.py @@ -266,6 +266,8 @@ class TFLiteGraph: def parse_operator_code(self, code): c = code.BuiltinCode() + if c == 0: + c = code.DeprecatedBuiltinCode() if c not in builtin_operator_map: raise InputFileError( self.name, f"The input file contains operator code '{c}' which is currently not supported" diff --git a/ethosu/vela/tflite_writer.py b/ethosu/vela/tflite_writer.py index 82a063ff..e190a746 100644 --- a/ethosu/vela/tflite_writer.py +++ b/ethosu/vela/tflite_writer.py @@ -193,6 +193,7 @@ class TFLiteSerialiser: self.operator_code_map[op_type] = (idx, tf_code, opt_serializer) OperatorCode.OperatorCodeStart(builder) + OperatorCode.OperatorCodeAddDeprecatedBuiltinCode(builder, tf_code if tf_code < 127 else 127) OperatorCode.OperatorCodeAddBuiltinCode(builder, tf_code) if custom_code_offset is not None: OperatorCode.OperatorCodeAddCustomCode(builder, custom_code_offset) diff --git a/setup.py b/setup.py index c62944af..f67d42e7 100644 --- a/setup.py +++ b/setup.py @@ -78,7 +78,7 @@ setup( packages=find_namespace_packages(include=["ethosu.*"]), python_requires="~=3.6", # We support only 3.6+ install_requires=[ - "flatbuffers==1.11.0", + "flatbuffers==1.12.0", "numpy>=1.16.6", "numpy>=1.16.6,<1.19.4 ; platform_system=='Windows'", "lxml>=4.5.1", -- cgit v1.2.1