From 485a11d8cb67c8062c632f0987cd31cedbe93d6d Mon Sep 17 00:00:00 2001 From: James Ward Date: Fri, 5 Aug 2022 13:48:37 +0100 Subject: FP16 support in serialization * Allow serialization of fp16 data * Add package to support integrated half data-type (half_float::half), independent of native float: http://half.sourceforge.net/ * Allow passing of accumulate data-type in serialization Signed-off-by: James Ward Change-Id: I54357f02e3776d81958228f699ea5044f2014f4b --- python/serializer/tosa_serializer.py | 46 ++++++++++++++++++++++++++++++---- python/tosa/ConvAttribute.py | 12 ++++++++- python/tosa/DType.py | 1 + python/tosa/FullyConnectedAttribute.py | 12 ++++++++- python/tosa/MatMulAttribute.py | 12 ++++++++- python/tosa/PoolAttribute.py | 12 ++++++++- python/tosa/TransposeConvAttribute.py | 12 ++++++++- 7 files changed, 97 insertions(+), 10 deletions(-) (limited to 'python') diff --git a/python/serializer/tosa_serializer.py b/python/serializer/tosa_serializer.py index acec4b7..fb89563 100644 --- a/python/serializer/tosa_serializer.py +++ b/python/serializer/tosa_serializer.py @@ -58,6 +58,7 @@ DTypeNames = [ "INT48", "FLOAT", "UINT16", + "FP16", ] ByteMask = np.uint64(0xFF) @@ -145,7 +146,15 @@ class TosaSerializerAttribute(TosaSerializerUnion): def __init__(self): super().__init__() - def PoolAttribute(self, kernel, stride, pad, input_zp, output_zp): + def PoolAttribute( + self, + kernel, + stride, + pad, + input_zp, + output_zp, + accum_dtype, + ): from tosa import PoolAttribute as a, Attribute self.utype = Attribute.Attribute().PoolAttribute @@ -156,8 +165,9 @@ class TosaSerializerAttribute(TosaSerializerUnion): self.intvecs.append((a.AddStride, stride)) self.ints.append((a.AddInputZp, input_zp)) self.ints.append((a.AddOutputZp, output_zp)) + self.ints.append((a.AddAccumDtype, accum_dtype)) - def ConvAttribute(self, pad, stride, dilation, input_zp, weight_zp): + def ConvAttribute(self, pad, stride, dilation, input_zp, weight_zp, accum_dtype): from tosa import ConvAttribute as a, Attribute self.utype = Attribute.Attribute().ConvAttribute @@ -168,8 +178,11 @@ class TosaSerializerAttribute(TosaSerializerUnion): self.intvecs.append((a.AddDilation, dilation)) self.ints.append((a.AddInputZp, input_zp)) self.ints.append((a.AddWeightZp, weight_zp)) + self.ints.append((a.AddAccumDtype, accum_dtype)) - def TransposeConvAttribute(self, outpad, stride, output_shape, input_zp, weight_zp): + def TransposeConvAttribute( + self, outpad, stride, output_shape, input_zp, weight_zp, accum_dtype + ): from tosa import TransposeConvAttribute as a, Attribute self.utype = Attribute.Attribute().TransposeConvAttribute @@ -180,6 +193,7 @@ class TosaSerializerAttribute(TosaSerializerUnion): self.intvecs.append((a.AddOutputShape, output_shape)) self.ints.append((a.AddInputZp, input_zp)) self.ints.append((a.AddWeightZp, weight_zp)) + self.ints.append((a.AddAccumDtype, accum_dtype)) def PadAttribute(self, padding, pad_const_int, pad_const_fp): from tosa import PadAttribute as a, Attribute @@ -316,7 +330,7 @@ class TosaSerializerAttribute(TosaSerializerUnion): self.intvecs.append((a.AddTable, table)) - def MatMulAttribute(self, A_zp, B_zp): + def MatMulAttribute(self, A_zp, B_zp, accum_dtype): from tosa import MatMulAttribute as a, Attribute self.utype = Attribute.Attribute().MatMulAttribute @@ -324,8 +338,9 @@ class TosaSerializerAttribute(TosaSerializerUnion): self.ints.append((a.AddAZp, A_zp)) self.ints.append((a.AddBZp, B_zp)) + self.ints.append((a.AddAccumDtype, accum_dtype)) - def FullyConnectedAttribute(self, input_zp, weight_zp): + def FullyConnectedAttribute(self, input_zp, weight_zp, accum_dtype): from tosa import FullyConnectedAttribute as a, Attribute self.utype = Attribute.Attribute().FullyConnectedAttribute @@ -333,6 +348,7 @@ class TosaSerializerAttribute(TosaSerializerUnion): self.ints.append((a.AddInputZp, input_zp)) self.ints.append((a.AddWeightZp, weight_zp)) + self.ints.append((a.AddAccumDtype, accum_dtype)) def NegateAttribute(self, input1_zp, output_zp): from tosa import NegateAttribute as a, Attribute @@ -364,6 +380,8 @@ class TosaSerializerTensor: if dtype == DType.FLOAT: fntype = np.float32 + elif dtype == DType.FP16: + fntype = np.float16 else: fntype = int @@ -445,10 +463,18 @@ class TosaSerializerTensor: b4 = (val_u64 >> np.uint64(32)) & ByteMask b5 = (val_u64 >> np.uint64(40)) & ByteMask u8_data.extend([b0, b1, b2, b3, b4, b5]) + elif self.dtype == DType.FP16: + np_arr = np.array(self.data, dtype=np.float16) + u8_data.extend(np_arr.view(np.uint8)) elif self.dtype == DType.FLOAT: for val in self.data: b = struct.pack("!f", val) u8_data.extend([b[3], b[2], b[1], b[0]]) + elif self.dtype == TosaDType.DType: + # Serialize DType enum data as uint8 bytes + for val in self.data: + np_arr = np.array(self.data, dtype=np.uint32) + u8_data.extend(np_arr.view(np.uint8)) else: raise Exception( "unsupported data type {}".format(DTypeNames[self.dtype]) @@ -873,6 +899,7 @@ class TosaSerializer: ) ConvAttribute.AddInputZp = ConvAttribute.ConvAttributeAddInputZp ConvAttribute.AddWeightZp = ConvAttribute.ConvAttributeAddWeightZp + ConvAttribute.AddAccumDtype = ConvAttribute.ConvAttributeAddAccumDtype ConvAttribute.End = ConvAttribute.ConvAttributeEnd from tosa import FullyConnectedAttribute @@ -886,6 +913,9 @@ class TosaSerializer: FullyConnectedAttribute.AddWeightZp = ( FullyConnectedAttribute.FullyConnectedAttributeAddWeightZp ) + FullyConnectedAttribute.AddAccumDtype = ( + FullyConnectedAttribute.FullyConnectedAttributeAddAccumDtype + ) FullyConnectedAttribute.End = ( FullyConnectedAttribute.FullyConnectedAttributeEnd ) @@ -895,6 +925,7 @@ class TosaSerializer: MatMulAttribute.Start = MatMulAttribute.MatMulAttributeStart MatMulAttribute.AddAZp = MatMulAttribute.MatMulAttributeAddAZp MatMulAttribute.AddBZp = MatMulAttribute.MatMulAttributeAddBZp + MatMulAttribute.AddAccumDtype = MatMulAttribute.MatMulAttributeAddAccumDtype MatMulAttribute.End = MatMulAttribute.MatMulAttributeEnd from tosa import PoolAttribute @@ -910,6 +941,7 @@ class TosaSerializer: PoolAttribute.StartStrideVector = ( PoolAttribute.PoolAttributeStartStrideVector ) + PoolAttribute.AddAccumDtype = PoolAttribute.PoolAttributeAddAccumDtype PoolAttribute.AddInputZp = PoolAttribute.PoolAttributeAddInputZp PoolAttribute.AddOutputZp = PoolAttribute.PoolAttributeAddOutputZp PoolAttribute.End = PoolAttribute.PoolAttributeEnd @@ -944,6 +976,7 @@ class TosaSerializer: PoolAttribute.StartStrideVector = ( PoolAttribute.PoolAttributeStartStrideVector ) + PoolAttribute.AddAccumDtype = PoolAttribute.PoolAttributeAddAccumDtype PoolAttribute.AddInputZp = PoolAttribute.PoolAttributeAddInputZp PoolAttribute.AddOutputZp = PoolAttribute.PoolAttributeAddOutputZp PoolAttribute.End = PoolAttribute.PoolAttributeEnd @@ -1123,6 +1156,9 @@ class TosaSerializer: TransposeConvAttribute.AddWeightZp = ( TransposeConvAttribute.TransposeConvAttributeAddWeightZp ) + TransposeConvAttribute.AddAccumDtype = ( + TransposeConvAttribute.TransposeConvAttributeAddAccumDtype + ) TransposeConvAttribute.End = ( TransposeConvAttribute.TransposeConvAttributeEnd ) diff --git a/python/tosa/ConvAttribute.py b/python/tosa/ConvAttribute.py index fb22c7a..c06e8c7 100644 --- a/python/tosa/ConvAttribute.py +++ b/python/tosa/ConvAttribute.py @@ -123,7 +123,14 @@ class ConvAttribute(object): return self._tab.Get(flatbuffers.number_types.Int32Flags, o + self._tab.Pos) return 0 -def ConvAttributeStart(builder): builder.StartObject(5) + # ConvAttribute + def AccumDtype(self): + o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(14)) + if o != 0: + return self._tab.Get(flatbuffers.number_types.Uint32Flags, o + self._tab.Pos) + return 0 + +def ConvAttributeStart(builder): builder.StartObject(6) def Start(builder): return ConvAttributeStart(builder) def ConvAttributeAddPad(builder, pad): builder.PrependUOffsetTRelativeSlot(0, flatbuffers.number_types.UOffsetTFlags.py_type(pad), 0) @@ -150,6 +157,9 @@ def AddInputZp(builder, inputZp): def ConvAttributeAddWeightZp(builder, weightZp): builder.PrependInt32Slot(4, weightZp, 0) def AddWeightZp(builder, weightZp): return ConvAttributeAddWeightZp(builder, weightZp) +def ConvAttributeAddAccumDtype(builder, accumDtype): builder.PrependUint32Slot(5, accumDtype, 0) +def AddAccumDtype(builder, accumDtype): + return ConvAttributeAddAccumDtype(builder, accumDtype) def ConvAttributeEnd(builder): return builder.EndObject() def End(builder): return ConvAttributeEnd(builder) \ No newline at end of file diff --git a/python/tosa/DType.py b/python/tosa/DType.py index e6b41ed..27d28c4 100644 --- a/python/tosa/DType.py +++ b/python/tosa/DType.py @@ -13,3 +13,4 @@ class DType(object): INT48 = 7 FLOAT = 8 UINT16 = 9 + FP16 = 10 diff --git a/python/tosa/FullyConnectedAttribute.py b/python/tosa/FullyConnectedAttribute.py index 892b0da..546ec60 100644 --- a/python/tosa/FullyConnectedAttribute.py +++ b/python/tosa/FullyConnectedAttribute.py @@ -42,7 +42,14 @@ class FullyConnectedAttribute(object): return self._tab.Get(flatbuffers.number_types.Int32Flags, o + self._tab.Pos) return 0 -def FullyConnectedAttributeStart(builder): builder.StartObject(2) + # FullyConnectedAttribute + def AccumDtype(self): + o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(8)) + if o != 0: + return self._tab.Get(flatbuffers.number_types.Uint32Flags, o + self._tab.Pos) + return 0 + +def FullyConnectedAttributeStart(builder): builder.StartObject(3) def Start(builder): return FullyConnectedAttributeStart(builder) def FullyConnectedAttributeAddInputZp(builder, inputZp): builder.PrependInt32Slot(0, inputZp, 0) @@ -51,6 +58,9 @@ def AddInputZp(builder, inputZp): def FullyConnectedAttributeAddWeightZp(builder, weightZp): builder.PrependInt32Slot(1, weightZp, 0) def AddWeightZp(builder, weightZp): return FullyConnectedAttributeAddWeightZp(builder, weightZp) +def FullyConnectedAttributeAddAccumDtype(builder, accumDtype): builder.PrependUint32Slot(2, accumDtype, 0) +def AddAccumDtype(builder, accumDtype): + return FullyConnectedAttributeAddAccumDtype(builder, accumDtype) def FullyConnectedAttributeEnd(builder): return builder.EndObject() def End(builder): return FullyConnectedAttributeEnd(builder) \ No newline at end of file diff --git a/python/tosa/MatMulAttribute.py b/python/tosa/MatMulAttribute.py index b42ebfa..af6ba0b 100644 --- a/python/tosa/MatMulAttribute.py +++ b/python/tosa/MatMulAttribute.py @@ -42,7 +42,14 @@ class MatMulAttribute(object): return self._tab.Get(flatbuffers.number_types.Int32Flags, o + self._tab.Pos) return 0 -def MatMulAttributeStart(builder): builder.StartObject(2) + # MatMulAttribute + def AccumDtype(self): + o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(8)) + if o != 0: + return self._tab.Get(flatbuffers.number_types.Uint32Flags, o + self._tab.Pos) + return 0 + +def MatMulAttributeStart(builder): builder.StartObject(3) def Start(builder): return MatMulAttributeStart(builder) def MatMulAttributeAddAZp(builder, aZp): builder.PrependInt32Slot(0, aZp, 0) @@ -51,6 +58,9 @@ def AddAZp(builder, aZp): def MatMulAttributeAddBZp(builder, bZp): builder.PrependInt32Slot(1, bZp, 0) def AddBZp(builder, bZp): return MatMulAttributeAddBZp(builder, bZp) +def MatMulAttributeAddAccumDtype(builder, accumDtype): builder.PrependUint32Slot(2, accumDtype, 0) +def AddAccumDtype(builder, accumDtype): + return MatMulAttributeAddAccumDtype(builder, accumDtype) def MatMulAttributeEnd(builder): return builder.EndObject() def End(builder): return MatMulAttributeEnd(builder) \ No newline at end of file diff --git a/python/tosa/PoolAttribute.py b/python/tosa/PoolAttribute.py index 8256a6d..4307114 100644 --- a/python/tosa/PoolAttribute.py +++ b/python/tosa/PoolAttribute.py @@ -123,7 +123,14 @@ class PoolAttribute(object): return self._tab.Get(flatbuffers.number_types.Int32Flags, o + self._tab.Pos) return 0 -def PoolAttributeStart(builder): builder.StartObject(5) + # PoolAttribute + def AccumDtype(self): + o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(14)) + if o != 0: + return self._tab.Get(flatbuffers.number_types.Uint32Flags, o + self._tab.Pos) + return 0 + +def PoolAttributeStart(builder): builder.StartObject(6) def Start(builder): return PoolAttributeStart(builder) def PoolAttributeAddPad(builder, pad): builder.PrependUOffsetTRelativeSlot(0, flatbuffers.number_types.UOffsetTFlags.py_type(pad), 0) @@ -150,6 +157,9 @@ def AddInputZp(builder, inputZp): def PoolAttributeAddOutputZp(builder, outputZp): builder.PrependInt32Slot(4, outputZp, 0) def AddOutputZp(builder, outputZp): return PoolAttributeAddOutputZp(builder, outputZp) +def PoolAttributeAddAccumDtype(builder, accumDtype): builder.PrependUint32Slot(5, accumDtype, 0) +def AddAccumDtype(builder, accumDtype): + return PoolAttributeAddAccumDtype(builder, accumDtype) def PoolAttributeEnd(builder): return builder.EndObject() def End(builder): return PoolAttributeEnd(builder) \ No newline at end of file diff --git a/python/tosa/TransposeConvAttribute.py b/python/tosa/TransposeConvAttribute.py index a2824e2..1a6bbde 100644 --- a/python/tosa/TransposeConvAttribute.py +++ b/python/tosa/TransposeConvAttribute.py @@ -123,7 +123,14 @@ class TransposeConvAttribute(object): return self._tab.Get(flatbuffers.number_types.Int32Flags, o + self._tab.Pos) return 0 -def TransposeConvAttributeStart(builder): builder.StartObject(5) + # TransposeConvAttribute + def AccumDtype(self): + o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(14)) + if o != 0: + return self._tab.Get(flatbuffers.number_types.Uint32Flags, o + self._tab.Pos) + return 0 + +def TransposeConvAttributeStart(builder): builder.StartObject(6) def Start(builder): return TransposeConvAttributeStart(builder) def TransposeConvAttributeAddOutPad(builder, outPad): builder.PrependUOffsetTRelativeSlot(0, flatbuffers.number_types.UOffsetTFlags.py_type(outPad), 0) @@ -150,6 +157,9 @@ def AddInputZp(builder, inputZp): def TransposeConvAttributeAddWeightZp(builder, weightZp): builder.PrependInt32Slot(4, weightZp, 0) def AddWeightZp(builder, weightZp): return TransposeConvAttributeAddWeightZp(builder, weightZp) +def TransposeConvAttributeAddAccumDtype(builder, accumDtype): builder.PrependUint32Slot(5, accumDtype, 0) +def AddAccumDtype(builder, accumDtype): + return TransposeConvAttributeAddAccumDtype(builder, accumDtype) def TransposeConvAttributeEnd(builder): return builder.EndObject() def End(builder): return TransposeConvAttributeEnd(builder) \ No newline at end of file -- cgit v1.2.1