# automatically generated by the FlatBuffers compiler, do not modify

# namespace: tosa

import flatbuffers
from flatbuffers.compat import import_numpy
np = import_numpy()

class TransposeConvAttribute(object):
    __slots__ = ['_tab']

    @classmethod
    def GetRootAs(cls, buf, offset=0):
        n = flatbuffers.encode.Get(flatbuffers.packer.uoffset, buf, offset)
        x = TransposeConvAttribute()
        x.Init(buf, n + offset)
        return x

    @classmethod
    def GetRootAsTransposeConvAttribute(cls, buf, offset=0):
        """This method is deprecated. Please switch to GetRootAs."""
        return cls.GetRootAs(buf, offset)
    @classmethod
    def TransposeConvAttributeBufferHasIdentifier(cls, buf, offset, size_prefixed=False):
        return flatbuffers.util.BufferHasIdentifier(buf, offset, b"\x54\x4F\x53\x41", size_prefixed=size_prefixed)

    # TransposeConvAttribute
    def Init(self, buf, pos):
        self._tab = flatbuffers.table.Table(buf, pos)

    # TransposeConvAttribute
    def OutPad(self, j):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(4))
        if o != 0:
            a = self._tab.Vector(o)
            return self._tab.Get(flatbuffers.number_types.Int32Flags, a + flatbuffers.number_types.UOffsetTFlags.py_type(j * 4))
        return 0

    # TransposeConvAttribute
    def OutPadAsNumpy(self):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(4))
        if o != 0:
            return self._tab.GetVectorAsNumpy(flatbuffers.number_types.Int32Flags, o)
        return 0

    # TransposeConvAttribute
    def OutPadLength(self):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(4))
        if o != 0:
            return self._tab.VectorLen(o)
        return 0

    # TransposeConvAttribute
    def OutPadIsNone(self):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(4))
        return o == 0

    # TransposeConvAttribute
    def Stride(self, j):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(6))
        if o != 0:
            a = self._tab.Vector(o)
            return self._tab.Get(flatbuffers.number_types.Int32Flags, a + flatbuffers.number_types.UOffsetTFlags.py_type(j * 4))
        return 0

    # TransposeConvAttribute
    def StrideAsNumpy(self):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(6))
        if o != 0:
            return self._tab.GetVectorAsNumpy(flatbuffers.number_types.Int32Flags, o)
        return 0

    # TransposeConvAttribute
    def StrideLength(self):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(6))
        if o != 0:
            return self._tab.VectorLen(o)
        return 0

    # TransposeConvAttribute
    def StrideIsNone(self):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(6))
        return o == 0

    # TransposeConvAttribute
    def OutputShape(self, j):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(8))
        if o != 0:
            a = self._tab.Vector(o)
            return self._tab.Get(flatbuffers.number_types.Int32Flags, a + flatbuffers.number_types.UOffsetTFlags.py_type(j * 4))
        return 0

    # TransposeConvAttribute
    def OutputShapeAsNumpy(self):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(8))
        if o != 0:
            return self._tab.GetVectorAsNumpy(flatbuffers.number_types.Int32Flags, o)
        return 0

    # TransposeConvAttribute
    def OutputShapeLength(self):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(8))
        if o != 0:
            return self._tab.VectorLen(o)
        return 0

    # TransposeConvAttribute
    def OutputShapeIsNone(self):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(8))
        return o == 0

    # TransposeConvAttribute
    def InputZp(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

    # TransposeConvAttribute
    def WeightZp(self):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(12))
        if o != 0:
            return self._tab.Get(flatbuffers.number_types.Int32Flags, o + self._tab.Pos)
        return 0

def TransposeConvAttributeStart(builder):
    builder.StartObject(5)

def Start(builder):
    TransposeConvAttributeStart(builder)

def TransposeConvAttributeAddOutPad(builder, outPad):
    builder.PrependUOffsetTRelativeSlot(0, flatbuffers.number_types.UOffsetTFlags.py_type(outPad), 0)

def AddOutPad(builder, outPad):
    TransposeConvAttributeAddOutPad(builder, outPad)

def TransposeConvAttributeStartOutPadVector(builder, numElems):
    return builder.StartVector(4, numElems, 4)

def StartOutPadVector(builder, numElems: int) -> int:
    return TransposeConvAttributeStartOutPadVector(builder, numElems)

def TransposeConvAttributeAddStride(builder, stride):
    builder.PrependUOffsetTRelativeSlot(1, flatbuffers.number_types.UOffsetTFlags.py_type(stride), 0)

def AddStride(builder, stride):
    TransposeConvAttributeAddStride(builder, stride)

def TransposeConvAttributeStartStrideVector(builder, numElems):
    return builder.StartVector(4, numElems, 4)

def StartStrideVector(builder, numElems: int) -> int:
    return TransposeConvAttributeStartStrideVector(builder, numElems)

def TransposeConvAttributeAddOutputShape(builder, outputShape):
    builder.PrependUOffsetTRelativeSlot(2, flatbuffers.number_types.UOffsetTFlags.py_type(outputShape), 0)

def AddOutputShape(builder, outputShape):
    TransposeConvAttributeAddOutputShape(builder, outputShape)

def TransposeConvAttributeStartOutputShapeVector(builder, numElems):
    return builder.StartVector(4, numElems, 4)

def StartOutputShapeVector(builder, numElems: int) -> int:
    return TransposeConvAttributeStartOutputShapeVector(builder, numElems)

def TransposeConvAttributeAddInputZp(builder, inputZp):
    builder.PrependInt32Slot(3, inputZp, 0)

def AddInputZp(builder, inputZp):
    TransposeConvAttributeAddInputZp(builder, inputZp)

def TransposeConvAttributeAddWeightZp(builder, weightZp):
    builder.PrependInt32Slot(4, weightZp, 0)

def AddWeightZp(builder, weightZp):
    TransposeConvAttributeAddWeightZp(builder, weightZp)

def TransposeConvAttributeEnd(builder):
    return builder.EndObject()

def End(builder):
    return TransposeConvAttributeEnd(builder)
