// automatically generated by the FlatBuffers compiler, do not modify


#ifndef FLATBUFFERS_GENERATED_TOSA_TOSA_H_
#define FLATBUFFERS_GENERATED_TOSA_TOSA_H_

#include "flatbuffers/flatbuffers.h"

namespace tosa {

struct PoolAttribute;
struct PoolAttributeBuilder;

struct ConvAttribute;
struct ConvAttributeBuilder;

struct TransposeConvAttribute;
struct TransposeConvAttributeBuilder;

struct PadAttribute;
struct PadAttributeBuilder;

struct AxisAttribute;
struct AxisAttributeBuilder;

struct ReshapeAttribute;
struct ReshapeAttributeBuilder;

struct SliceAttribute;
struct SliceAttributeBuilder;

struct TileAttribute;
struct TileAttributeBuilder;

struct ResizeAttribute;
struct ResizeAttributeBuilder;

struct ClampAttribute;
struct ClampAttributeBuilder;

struct RescaleAttribute;
struct RescaleAttributeBuilder;

struct MulAttribute;
struct MulAttributeBuilder;

struct ArithmeticRightShiftAttribute;
struct ArithmeticRightShiftAttributeBuilder;

struct CondIfAttribute;
struct CondIfAttributeBuilder;

struct WhileLoopAttribute;
struct WhileLoopAttributeBuilder;

struct TransposeAttribute;
struct TransposeAttributeBuilder;

struct TableAttribute;
struct TableAttributeBuilder;

struct UnaryQuantInfo;
struct UnaryQuantInfoBuilder;

struct ConvQuantInfo;
struct ConvQuantInfoBuilder;

struct MatMulQuantInfo;
struct MatMulQuantInfoBuilder;

struct PadQuantInfo;
struct PadQuantInfoBuilder;

struct Version;
struct VersionBuilder;

struct TosaTensor;
struct TosaTensorBuilder;

struct TosaOperator;
struct TosaOperatorBuilder;

struct TosaBasicBlock;
struct TosaBasicBlockBuilder;

struct TosaGraph;
struct TosaGraphBuilder;

enum DType {
  DType_UNKNOWN = 0,
  DType_BOOL = 1,
  DType_UINT8 = 2,
  DType_INT4 = 3,
  DType_INT8 = 4,
  DType_INT16 = 5,
  DType_INT32 = 6,
  DType_INT48 = 7,
  DType_FLOAT = 8,
  DType_MIN = DType_UNKNOWN,
  DType_MAX = DType_FLOAT
};

inline const DType (&EnumValuesDType())[9] {
  static const DType values[] = {
    DType_UNKNOWN,
    DType_BOOL,
    DType_UINT8,
    DType_INT4,
    DType_INT8,
    DType_INT16,
    DType_INT32,
    DType_INT48,
    DType_FLOAT
  };
  return values;
}

inline const char * const *EnumNamesDType() {
  static const char * const names[10] = {
    "UNKNOWN",
    "BOOL",
    "UINT8",
    "INT4",
    "INT8",
    "INT16",
    "INT32",
    "INT48",
    "FLOAT",
    nullptr
  };
  return names;
}

inline const char *EnumNameDType(DType e) {
  if (flatbuffers::IsOutRange(e, DType_UNKNOWN, DType_FLOAT)) return "";
  const size_t index = static_cast<size_t>(e);
  return EnumNamesDType()[index];
}

enum ResizeMode {
  ResizeMode_UNKNOWN = 0,
  ResizeMode_NEAREST = 1,
  ResizeMode_BILINEAR = 2,
  ResizeMode_MIN = ResizeMode_UNKNOWN,
  ResizeMode_MAX = ResizeMode_BILINEAR
};

inline const ResizeMode (&EnumValuesResizeMode())[3] {
  static const ResizeMode values[] = {
    ResizeMode_UNKNOWN,
    ResizeMode_NEAREST,
    ResizeMode_BILINEAR
  };
  return values;
}

inline const char * const *EnumNamesResizeMode() {
  static const char * const names[4] = {
    "UNKNOWN",
    "NEAREST",
    "BILINEAR",
    nullptr
  };
  return names;
}

inline const char *EnumNameResizeMode(ResizeMode e) {
  if (flatbuffers::IsOutRange(e, ResizeMode_UNKNOWN, ResizeMode_BILINEAR)) return "";
  const size_t index = static_cast<size_t>(e);
  return EnumNamesResizeMode()[index];
}

enum Op {
  Op_UNKNOWN = 0,
  Op_ARGMAX = 1,
  Op_AVG_POOL2D = 2,
  Op_CONV2D = 3,
  Op_CONV3D = 4,
  Op_DEPTHWISE_CONV2D = 5,
  Op_FULLY_CONNECTED = 6,
  Op_MATMUL = 7,
  Op_MAX_POOL2D = 8,
  Op_TRANSPOSE_CONV2D = 9,
  Op_CLAMP = 10,
  Op_RESERVED = 11,
  Op_SIGMOID = 12,
  Op_TANH = 13,
  Op_ADD = 14,
  Op_ARITHMETIC_RIGHT_SHIFT = 15,
  Op_BITWISE_AND = 16,
  Op_BITWISE_OR = 17,
  Op_BITWISE_XOR = 18,
  Op_INTDIV = 19,
  Op_LOGICAL_AND = 20,
  Op_LOGICAL_LEFT_SHIFT = 21,
  Op_LOGICAL_RIGHT_SHIFT = 22,
  Op_LOGICAL_OR = 23,
  Op_LOGICAL_XOR = 24,
  Op_MAXIMUM = 25,
  Op_MINIMUM = 26,
  Op_MUL = 27,
  Op_POW = 28,
  Op_SUB = 29,
  Op_TABLE = 30,
  Op_ABS = 31,
  Op_BITWISE_NOT = 32,
  Op_CEIL = 33,
  Op_CLZ = 34,
  Op_EXP = 35,
  Op_FLOOR = 36,
  Op_LOG = 37,
  Op_LOGICAL_NOT = 38,
  Op_NEGATE = 39,
  Op_RECIPROCAL = 40,
  Op_RSQRT = 41,
  Op_SELECT = 42,
  Op_EQUAL = 43,
  Op_GREATER = 44,
  Op_GREATER_EQUAL = 45,
  Op_REDUCE_ANY = 46,
  Op_REDUCE_ALL = 47,
  Op_REDUCE_MAX = 48,
  Op_REDUCE_MIN = 49,
  Op_REDUCE_PRODUCT = 50,
  Op_REDUCE_SUM = 51,
  Op_CONCAT = 52,
  Op_PAD = 53,
  Op_RESHAPE = 54,
  Op_REVERSE = 55,
  Op_SLICE = 56,
  Op_TILE = 57,
  Op_TRANSPOSE = 58,
  Op_GATHER = 59,
  Op_SCATTER = 60,
  Op_RESIZE = 61,
  Op_CAST = 62,
  Op_RESCALE = 63,
  Op_CONST = 64,
  Op_IDENTITY = 65,
  Op_CUSTOM = 66,
  Op_COND_IF = 67,
  Op_WHILE_LOOP = 68,
  Op_MIN = Op_UNKNOWN,
  Op_MAX = Op_WHILE_LOOP
};

inline const Op (&EnumValuesOp())[69] {
  static const Op values[] = {
    Op_UNKNOWN,
    Op_ARGMAX,
    Op_AVG_POOL2D,
    Op_CONV2D,
    Op_CONV3D,
    Op_DEPTHWISE_CONV2D,
    Op_FULLY_CONNECTED,
    Op_MATMUL,
    Op_MAX_POOL2D,
    Op_TRANSPOSE_CONV2D,
    Op_CLAMP,
    Op_RESERVED,
    Op_SIGMOID,
    Op_TANH,
    Op_ADD,
    Op_ARITHMETIC_RIGHT_SHIFT,
    Op_BITWISE_AND,
    Op_BITWISE_OR,
    Op_BITWISE_XOR,
    Op_INTDIV,
    Op_LOGICAL_AND,
    Op_LOGICAL_LEFT_SHIFT,
    Op_LOGICAL_RIGHT_SHIFT,
    Op_LOGICAL_OR,
    Op_LOGICAL_XOR,
    Op_MAXIMUM,
    Op_MINIMUM,
    Op_MUL,
    Op_POW,
    Op_SUB,
    Op_TABLE,
    Op_ABS,
    Op_BITWISE_NOT,
    Op_CEIL,
    Op_CLZ,
    Op_EXP,
    Op_FLOOR,
    Op_LOG,
    Op_LOGICAL_NOT,
    Op_NEGATE,
    Op_RECIPROCAL,
    Op_RSQRT,
    Op_SELECT,
    Op_EQUAL,
    Op_GREATER,
    Op_GREATER_EQUAL,
    Op_REDUCE_ANY,
    Op_REDUCE_ALL,
    Op_REDUCE_MAX,
    Op_REDUCE_MIN,
    Op_REDUCE_PRODUCT,
    Op_REDUCE_SUM,
    Op_CONCAT,
    Op_PAD,
    Op_RESHAPE,
    Op_REVERSE,
    Op_SLICE,
    Op_TILE,
    Op_TRANSPOSE,
    Op_GATHER,
    Op_SCATTER,
    Op_RESIZE,
    Op_CAST,
    Op_RESCALE,
    Op_CONST,
    Op_IDENTITY,
    Op_CUSTOM,
    Op_COND_IF,
    Op_WHILE_LOOP
  };
  return values;
}

inline const char * const *EnumNamesOp() {
  static const char * const names[70] = {
    "UNKNOWN",
    "ARGMAX",
    "AVG_POOL2D",
    "CONV2D",
    "CONV3D",
    "DEPTHWISE_CONV2D",
    "FULLY_CONNECTED",
    "MATMUL",
    "MAX_POOL2D",
    "TRANSPOSE_CONV2D",
    "CLAMP",
    "RESERVED",
    "SIGMOID",
    "TANH",
    "ADD",
    "ARITHMETIC_RIGHT_SHIFT",
    "BITWISE_AND",
    "BITWISE_OR",
    "BITWISE_XOR",
    "INTDIV",
    "LOGICAL_AND",
    "LOGICAL_LEFT_SHIFT",
    "LOGICAL_RIGHT_SHIFT",
    "LOGICAL_OR",
    "LOGICAL_XOR",
    "MAXIMUM",
    "MINIMUM",
    "MUL",
    "POW",
    "SUB",
    "TABLE",
    "ABS",
    "BITWISE_NOT",
    "CEIL",
    "CLZ",
    "EXP",
    "FLOOR",
    "LOG",
    "LOGICAL_NOT",
    "NEGATE",
    "RECIPROCAL",
    "RSQRT",
    "SELECT",
    "EQUAL",
    "GREATER",
    "GREATER_EQUAL",
    "REDUCE_ANY",
    "REDUCE_ALL",
    "REDUCE_MAX",
    "REDUCE_MIN",
    "REDUCE_PRODUCT",
    "REDUCE_SUM",
    "CONCAT",
    "PAD",
    "RESHAPE",
    "REVERSE",
    "SLICE",
    "TILE",
    "TRANSPOSE",
    "GATHER",
    "SCATTER",
    "RESIZE",
    "CAST",
    "RESCALE",
    "CONST",
    "IDENTITY",
    "CUSTOM",
    "COND_IF",
    "WHILE_LOOP",
    nullptr
  };
  return names;
}

inline const char *EnumNameOp(Op e) {
  if (flatbuffers::IsOutRange(e, Op_UNKNOWN, Op_WHILE_LOOP)) return "";
  const size_t index = static_cast<size_t>(e);
  return EnumNamesOp()[index];
}

enum Attribute {
  Attribute_NONE = 0,
  Attribute_PoolAttribute = 1,
  Attribute_ConvAttribute = 2,
  Attribute_TransposeConvAttribute = 3,
  Attribute_PadAttribute = 4,
  Attribute_AxisAttribute = 5,
  Attribute_ReshapeAttribute = 6,
  Attribute_SliceAttribute = 7,
  Attribute_TileAttribute = 8,
  Attribute_ResizeAttribute = 9,
  Attribute_ClampAttribute = 10,
  Attribute_RescaleAttribute = 11,
  Attribute_MulAttribute = 12,
  Attribute_ArithmeticRightShiftAttribute = 13,
  Attribute_CondIfAttribute = 14,
  Attribute_WhileLoopAttribute = 15,
  Attribute_TransposeAttribute = 16,
  Attribute_TableAttribute = 17,
  Attribute_MIN = Attribute_NONE,
  Attribute_MAX = Attribute_TableAttribute
};

inline const Attribute (&EnumValuesAttribute())[18] {
  static const Attribute values[] = {
    Attribute_NONE,
    Attribute_PoolAttribute,
    Attribute_ConvAttribute,
    Attribute_TransposeConvAttribute,
    Attribute_PadAttribute,
    Attribute_AxisAttribute,
    Attribute_ReshapeAttribute,
    Attribute_SliceAttribute,
    Attribute_TileAttribute,
    Attribute_ResizeAttribute,
    Attribute_ClampAttribute,
    Attribute_RescaleAttribute,
    Attribute_MulAttribute,
    Attribute_ArithmeticRightShiftAttribute,
    Attribute_CondIfAttribute,
    Attribute_WhileLoopAttribute,
    Attribute_TransposeAttribute,
    Attribute_TableAttribute
  };
  return values;
}

inline const char * const *EnumNamesAttribute() {
  static const char * const names[19] = {
    "NONE",
    "PoolAttribute",
    "ConvAttribute",
    "TransposeConvAttribute",
    "PadAttribute",
    "AxisAttribute",
    "ReshapeAttribute",
    "SliceAttribute",
    "TileAttribute",
    "ResizeAttribute",
    "ClampAttribute",
    "RescaleAttribute",
    "MulAttribute",
    "ArithmeticRightShiftAttribute",
    "CondIfAttribute",
    "WhileLoopAttribute",
    "TransposeAttribute",
    "TableAttribute",
    nullptr
  };
  return names;
}

inline const char *EnumNameAttribute(Attribute e) {
  if (flatbuffers::IsOutRange(e, Attribute_NONE, Attribute_TableAttribute)) return "";
  const size_t index = static_cast<size_t>(e);
  return EnumNamesAttribute()[index];
}

template<typename T> struct AttributeTraits {
  static const Attribute enum_value = Attribute_NONE;
};

template<> struct AttributeTraits<tosa::PoolAttribute> {
  static const Attribute enum_value = Attribute_PoolAttribute;
};

template<> struct AttributeTraits<tosa::ConvAttribute> {
  static const Attribute enum_value = Attribute_ConvAttribute;
};

template<> struct AttributeTraits<tosa::TransposeConvAttribute> {
  static const Attribute enum_value = Attribute_TransposeConvAttribute;
};

template<> struct AttributeTraits<tosa::PadAttribute> {
  static const Attribute enum_value = Attribute_PadAttribute;
};

template<> struct AttributeTraits<tosa::AxisAttribute> {
  static const Attribute enum_value = Attribute_AxisAttribute;
};

template<> struct AttributeTraits<tosa::ReshapeAttribute> {
  static const Attribute enum_value = Attribute_ReshapeAttribute;
};

template<> struct AttributeTraits<tosa::SliceAttribute> {
  static const Attribute enum_value = Attribute_SliceAttribute;
};

template<> struct AttributeTraits<tosa::TileAttribute> {
  static const Attribute enum_value = Attribute_TileAttribute;
};

template<> struct AttributeTraits<tosa::ResizeAttribute> {
  static const Attribute enum_value = Attribute_ResizeAttribute;
};

template<> struct AttributeTraits<tosa::ClampAttribute> {
  static const Attribute enum_value = Attribute_ClampAttribute;
};

template<> struct AttributeTraits<tosa::RescaleAttribute> {
  static const Attribute enum_value = Attribute_RescaleAttribute;
};

template<> struct AttributeTraits<tosa::MulAttribute> {
  static const Attribute enum_value = Attribute_MulAttribute;
};

template<> struct AttributeTraits<tosa::ArithmeticRightShiftAttribute> {
  static const Attribute enum_value = Attribute_ArithmeticRightShiftAttribute;
};

template<> struct AttributeTraits<tosa::CondIfAttribute> {
  static const Attribute enum_value = Attribute_CondIfAttribute;
};

template<> struct AttributeTraits<tosa::WhileLoopAttribute> {
  static const Attribute enum_value = Attribute_WhileLoopAttribute;
};

template<> struct AttributeTraits<tosa::TransposeAttribute> {
  static const Attribute enum_value = Attribute_TransposeAttribute;
};

template<> struct AttributeTraits<tosa::TableAttribute> {
  static const Attribute enum_value = Attribute_TableAttribute;
};

bool VerifyAttribute(flatbuffers::Verifier &verifier, const void *obj, Attribute type);
bool VerifyAttributeVector(flatbuffers::Verifier &verifier, const flatbuffers::Vector<flatbuffers::Offset<void>> *values, const flatbuffers::Vector<uint8_t> *types);

enum QuantInfo {
  QuantInfo_NONE = 0,
  QuantInfo_UnaryQuantInfo = 1,
  QuantInfo_ConvQuantInfo = 2,
  QuantInfo_MatMulQuantInfo = 3,
  QuantInfo_PadQuantInfo = 4,
  QuantInfo_MIN = QuantInfo_NONE,
  QuantInfo_MAX = QuantInfo_PadQuantInfo
};

inline const QuantInfo (&EnumValuesQuantInfo())[5] {
  static const QuantInfo values[] = {
    QuantInfo_NONE,
    QuantInfo_UnaryQuantInfo,
    QuantInfo_ConvQuantInfo,
    QuantInfo_MatMulQuantInfo,
    QuantInfo_PadQuantInfo
  };
  return values;
}

inline const char * const *EnumNamesQuantInfo() {
  static const char * const names[6] = {
    "NONE",
    "UnaryQuantInfo",
    "ConvQuantInfo",
    "MatMulQuantInfo",
    "PadQuantInfo",
    nullptr
  };
  return names;
}

inline const char *EnumNameQuantInfo(QuantInfo e) {
  if (flatbuffers::IsOutRange(e, QuantInfo_NONE, QuantInfo_PadQuantInfo)) return "";
  const size_t index = static_cast<size_t>(e);
  return EnumNamesQuantInfo()[index];
}

template<typename T> struct QuantInfoTraits {
  static const QuantInfo enum_value = QuantInfo_NONE;
};

template<> struct QuantInfoTraits<tosa::UnaryQuantInfo> {
  static const QuantInfo enum_value = QuantInfo_UnaryQuantInfo;
};

template<> struct QuantInfoTraits<tosa::ConvQuantInfo> {
  static const QuantInfo enum_value = QuantInfo_ConvQuantInfo;
};

template<> struct QuantInfoTraits<tosa::MatMulQuantInfo> {
  static const QuantInfo enum_value = QuantInfo_MatMulQuantInfo;
};

template<> struct QuantInfoTraits<tosa::PadQuantInfo> {
  static const QuantInfo enum_value = QuantInfo_PadQuantInfo;
};

bool VerifyQuantInfo(flatbuffers::Verifier &verifier, const void *obj, QuantInfo type);
bool VerifyQuantInfoVector(flatbuffers::Verifier &verifier, const flatbuffers::Vector<flatbuffers::Offset<void>> *values, const flatbuffers::Vector<uint8_t> *types);

struct PoolAttribute FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
  typedef PoolAttributeBuilder Builder;
  enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
    VT_PADDING = 4,
    VT_KERNEL = 6,
    VT_STRIDE = 8
  };
  const flatbuffers::Vector<int32_t> *padding() const {
    return GetPointer<const flatbuffers::Vector<int32_t> *>(VT_PADDING);
  }
  const flatbuffers::Vector<int32_t> *kernel() const {
    return GetPointer<const flatbuffers::Vector<int32_t> *>(VT_KERNEL);
  }
  const flatbuffers::Vector<int32_t> *stride() const {
    return GetPointer<const flatbuffers::Vector<int32_t> *>(VT_STRIDE);
  }
  bool Verify(flatbuffers::Verifier &verifier) const {
    return VerifyTableStart(verifier) &&
           VerifyOffset(verifier, VT_PADDING) &&
           verifier.VerifyVector(padding()) &&
           VerifyOffset(verifier, VT_KERNEL) &&
           verifier.VerifyVector(kernel()) &&
           VerifyOffset(verifier, VT_STRIDE) &&
           verifier.VerifyVector(stride()) &&
           verifier.EndTable();
  }
};

struct PoolAttributeBuilder {
  typedef PoolAttribute Table;
  flatbuffers::FlatBufferBuilder &fbb_;
  flatbuffers::uoffset_t start_;
  void add_padding(flatbuffers::Offset<flatbuffers::Vector<int32_t>> padding) {
    fbb_.AddOffset(PoolAttribute::VT_PADDING, padding);
  }
  void add_kernel(flatbuffers::Offset<flatbuffers::Vector<int32_t>> kernel) {
    fbb_.AddOffset(PoolAttribute::VT_KERNEL, kernel);
  }
  void add_stride(flatbuffers::Offset<flatbuffers::Vector<int32_t>> stride) {
    fbb_.AddOffset(PoolAttribute::VT_STRIDE, stride);
  }
  explicit PoolAttributeBuilder(flatbuffers::FlatBufferBuilder &_fbb)
        : fbb_(_fbb) {
    start_ = fbb_.StartTable();
  }
  PoolAttributeBuilder &operator=(const PoolAttributeBuilder &);
  flatbuffers::Offset<PoolAttribute> Finish() {
    const auto end = fbb_.EndTable(start_);
    auto o = flatbuffers::Offset<PoolAttribute>(end);
    return o;
  }
};

inline flatbuffers::Offset<PoolAttribute> CreatePoolAttribute(
    flatbuffers::FlatBufferBuilder &_fbb,
    flatbuffers::Offset<flatbuffers::Vector<int32_t>> padding = 0,
    flatbuffers::Offset<flatbuffers::Vector<int32_t>> kernel = 0,
    flatbuffers::Offset<flatbuffers::Vector<int32_t>> stride = 0) {
  PoolAttributeBuilder builder_(_fbb);
  builder_.add_stride(stride);
  builder_.add_kernel(kernel);
  builder_.add_padding(padding);
  return builder_.Finish();
}

inline flatbuffers::Offset<PoolAttribute> CreatePoolAttributeDirect(
    flatbuffers::FlatBufferBuilder &_fbb,
    const std::vector<int32_t> *padding = nullptr,
    const std::vector<int32_t> *kernel = nullptr,
    const std::vector<int32_t> *stride = nullptr) {
  auto padding__ = padding ? _fbb.CreateVector<int32_t>(*padding) : 0;
  auto kernel__ = kernel ? _fbb.CreateVector<int32_t>(*kernel) : 0;
  auto stride__ = stride ? _fbb.CreateVector<int32_t>(*stride) : 0;
  return tosa::CreatePoolAttribute(
      _fbb,
      padding__,
      kernel__,
      stride__);
}

struct ConvAttribute FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
  typedef ConvAttributeBuilder Builder;
  enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
    VT_PADDING = 4,
    VT_STRIDE = 6,
    VT_DILATION = 8
  };
  const flatbuffers::Vector<int32_t> *padding() const {
    return GetPointer<const flatbuffers::Vector<int32_t> *>(VT_PADDING);
  }
  const flatbuffers::Vector<int32_t> *stride() const {
    return GetPointer<const flatbuffers::Vector<int32_t> *>(VT_STRIDE);
  }
  const flatbuffers::Vector<int32_t> *dilation() const {
    return GetPointer<const flatbuffers::Vector<int32_t> *>(VT_DILATION);
  }
  bool Verify(flatbuffers::Verifier &verifier) const {
    return VerifyTableStart(verifier) &&
           VerifyOffset(verifier, VT_PADDING) &&
           verifier.VerifyVector(padding()) &&
           VerifyOffset(verifier, VT_STRIDE) &&
           verifier.VerifyVector(stride()) &&
           VerifyOffset(verifier, VT_DILATION) &&
           verifier.VerifyVector(dilation()) &&
           verifier.EndTable();
  }
};

struct ConvAttributeBuilder {
  typedef ConvAttribute Table;
  flatbuffers::FlatBufferBuilder &fbb_;
  flatbuffers::uoffset_t start_;
  void add_padding(flatbuffers::Offset<flatbuffers::Vector<int32_t>> padding) {
    fbb_.AddOffset(ConvAttribute::VT_PADDING, padding);
  }
  void add_stride(flatbuffers::Offset<flatbuffers::Vector<int32_t>> stride) {
    fbb_.AddOffset(ConvAttribute::VT_STRIDE, stride);
  }
  void add_dilation(flatbuffers::Offset<flatbuffers::Vector<int32_t>> dilation) {
    fbb_.AddOffset(ConvAttribute::VT_DILATION, dilation);
  }
  explicit ConvAttributeBuilder(flatbuffers::FlatBufferBuilder &_fbb)
        : fbb_(_fbb) {
    start_ = fbb_.StartTable();
  }
  ConvAttributeBuilder &operator=(const ConvAttributeBuilder &);
  flatbuffers::Offset<ConvAttribute> Finish() {
    const auto end = fbb_.EndTable(start_);
    auto o = flatbuffers::Offset<ConvAttribute>(end);
    return o;
  }
};

inline flatbuffers::Offset<ConvAttribute> CreateConvAttribute(
    flatbuffers::FlatBufferBuilder &_fbb,
    flatbuffers::Offset<flatbuffers::Vector<int32_t>> padding = 0,
    flatbuffers::Offset<flatbuffers::Vector<int32_t>> stride = 0,
    flatbuffers::Offset<flatbuffers::Vector<int32_t>> dilation = 0) {
  ConvAttributeBuilder builder_(_fbb);
  builder_.add_dilation(dilation);
  builder_.add_stride(stride);
  builder_.add_padding(padding);
  return builder_.Finish();
}

inline flatbuffers::Offset<ConvAttribute> CreateConvAttributeDirect(
    flatbuffers::FlatBufferBuilder &_fbb,
    const std::vector<int32_t> *padding = nullptr,
    const std::vector<int32_t> *stride = nullptr,
    const std::vector<int32_t> *dilation = nullptr) {
  auto padding__ = padding ? _fbb.CreateVector<int32_t>(*padding) : 0;
  auto stride__ = stride ? _fbb.CreateVector<int32_t>(*stride) : 0;
  auto dilation__ = dilation ? _fbb.CreateVector<int32_t>(*dilation) : 0;
  return tosa::CreateConvAttribute(
      _fbb,
      padding__,
      stride__,
      dilation__);
}

struct TransposeConvAttribute FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
  typedef TransposeConvAttributeBuilder Builder;
  enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
    VT_OUTPAD = 4,
    VT_STRIDE = 6,
    VT_DILATION = 8,
    VT_OUTPUT_SHAPE = 10
  };
  const flatbuffers::Vector<int32_t> *outpad() const {
    return GetPointer<const flatbuffers::Vector<int32_t> *>(VT_OUTPAD);
  }
  const flatbuffers::Vector<int32_t> *stride() const {
    return GetPointer<const flatbuffers::Vector<int32_t> *>(VT_STRIDE);
  }
  const flatbuffers::Vector<int32_t> *dilation() const {
    return GetPointer<const flatbuffers::Vector<int32_t> *>(VT_DILATION);
  }
  const flatbuffers::Vector<int32_t> *output_shape() const {
    return GetPointer<const flatbuffers::Vector<int32_t> *>(VT_OUTPUT_SHAPE);
  }
  bool Verify(flatbuffers::Verifier &verifier) const {
    return VerifyTableStart(verifier) &&
           VerifyOffset(verifier, VT_OUTPAD) &&
           verifier.VerifyVector(outpad()) &&
           VerifyOffset(verifier, VT_STRIDE) &&
           verifier.VerifyVector(stride()) &&
           VerifyOffset(verifier, VT_DILATION) &&
           verifier.VerifyVector(dilation()) &&
           VerifyOffset(verifier, VT_OUTPUT_SHAPE) &&
           verifier.VerifyVector(output_shape()) &&
           verifier.EndTable();
  }
};

struct TransposeConvAttributeBuilder {
  typedef TransposeConvAttribute Table;
  flatbuffers::FlatBufferBuilder &fbb_;
  flatbuffers::uoffset_t start_;
  void add_outpad(flatbuffers::Offset<flatbuffers::Vector<int32_t>> outpad) {
    fbb_.AddOffset(TransposeConvAttribute::VT_OUTPAD, outpad);
  }
  void add_stride(flatbuffers::Offset<flatbuffers::Vector<int32_t>> stride) {
    fbb_.AddOffset(TransposeConvAttribute::VT_STRIDE, stride);
  }
  void add_dilation(flatbuffers::Offset<flatbuffers::Vector<int32_t>> dilation) {
    fbb_.AddOffset(TransposeConvAttribute::VT_DILATION, dilation);
  }
  void add_output_shape(flatbuffers::Offset<flatbuffers::Vector<int32_t>> output_shape) {
    fbb_.AddOffset(TransposeConvAttribute::VT_OUTPUT_SHAPE, output_shape);
  }
  explicit TransposeConvAttributeBuilder(flatbuffers::FlatBufferBuilder &_fbb)
        : fbb_(_fbb) {
    start_ = fbb_.StartTable();
  }
  TransposeConvAttributeBuilder &operator=(const TransposeConvAttributeBuilder &);
  flatbuffers::Offset<TransposeConvAttribute> Finish() {
    const auto end = fbb_.EndTable(start_);
    auto o = flatbuffers::Offset<TransposeConvAttribute>(end);
    return o;
  }
};

inline flatbuffers::Offset<TransposeConvAttribute> CreateTransposeConvAttribute(
    flatbuffers::FlatBufferBuilder &_fbb,
    flatbuffers::Offset<flatbuffers::Vector<int32_t>> outpad = 0,
    flatbuffers::Offset<flatbuffers::Vector<int32_t>> stride = 0,
    flatbuffers::Offset<flatbuffers::Vector<int32_t>> dilation = 0,
    flatbuffers::Offset<flatbuffers::Vector<int32_t>> output_shape = 0) {
  TransposeConvAttributeBuilder builder_(_fbb);
  builder_.add_output_shape(output_shape);
  builder_.add_dilation(dilation);
  builder_.add_stride(stride);
  builder_.add_outpad(outpad);
  return builder_.Finish();
}

inline flatbuffers::Offset<TransposeConvAttribute> CreateTransposeConvAttributeDirect(
    flatbuffers::FlatBufferBuilder &_fbb,
    const std::vector<int32_t> *outpad = nullptr,
    const std::vector<int32_t> *stride = nullptr,
    const std::vector<int32_t> *dilation = nullptr,
    const std::vector<int32_t> *output_shape = nullptr) {
  auto outpad__ = outpad ? _fbb.CreateVector<int32_t>(*outpad) : 0;
  auto stride__ = stride ? _fbb.CreateVector<int32_t>(*stride) : 0;
  auto dilation__ = dilation ? _fbb.CreateVector<int32_t>(*dilation) : 0;
  auto output_shape__ = output_shape ? _fbb.CreateVector<int32_t>(*output_shape) : 0;
  return tosa::CreateTransposeConvAttribute(
      _fbb,
      outpad__,
      stride__,
      dilation__,
      output_shape__);
}

struct PadAttribute FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
  typedef PadAttributeBuilder Builder;
  enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
    VT_PADDING = 4,
    VT_PAD_CONST_INT = 6,
    VT_PAD_CONST_FP = 8
  };
  const flatbuffers::Vector<int32_t> *padding() const {
    return GetPointer<const flatbuffers::Vector<int32_t> *>(VT_PADDING);
  }
  int32_t pad_const_int() const {
    return GetField<int32_t>(VT_PAD_CONST_INT, 0);
  }
  float pad_const_fp() const {
    return GetField<float>(VT_PAD_CONST_FP, 0.0f);
  }
  bool Verify(flatbuffers::Verifier &verifier) const {
    return VerifyTableStart(verifier) &&
           VerifyOffset(verifier, VT_PADDING) &&
           verifier.VerifyVector(padding()) &&
           VerifyField<int32_t>(verifier, VT_PAD_CONST_INT) &&
           VerifyField<float>(verifier, VT_PAD_CONST_FP) &&
           verifier.EndTable();
  }
};

struct PadAttributeBuilder {
  typedef PadAttribute Table;
  flatbuffers::FlatBufferBuilder &fbb_;
  flatbuffers::uoffset_t start_;
  void add_padding(flatbuffers::Offset<flatbuffers::Vector<int32_t>> padding) {
    fbb_.AddOffset(PadAttribute::VT_PADDING, padding);
  }
  void add_pad_const_int(int32_t pad_const_int) {
    fbb_.AddElement<int32_t>(PadAttribute::VT_PAD_CONST_INT, pad_const_int, 0);
  }
  void add_pad_const_fp(float pad_const_fp) {
    fbb_.AddElement<float>(PadAttribute::VT_PAD_CONST_FP, pad_const_fp, 0.0f);
  }
  explicit PadAttributeBuilder(flatbuffers::FlatBufferBuilder &_fbb)
        : fbb_(_fbb) {
    start_ = fbb_.StartTable();
  }
  PadAttributeBuilder &operator=(const PadAttributeBuilder &);
  flatbuffers::Offset<PadAttribute> Finish() {
    const auto end = fbb_.EndTable(start_);
    auto o = flatbuffers::Offset<PadAttribute>(end);
    return o;
  }
};

inline flatbuffers::Offset<PadAttribute> CreatePadAttribute(
    flatbuffers::FlatBufferBuilder &_fbb,
    flatbuffers::Offset<flatbuffers::Vector<int32_t>> padding = 0,
    int32_t pad_const_int = 0,
    float pad_const_fp = 0.0f) {
  PadAttributeBuilder builder_(_fbb);
  builder_.add_pad_const_fp(pad_const_fp);
  builder_.add_pad_const_int(pad_const_int);
  builder_.add_padding(padding);
  return builder_.Finish();
}

inline flatbuffers::Offset<PadAttribute> CreatePadAttributeDirect(
    flatbuffers::FlatBufferBuilder &_fbb,
    const std::vector<int32_t> *padding = nullptr,
    int32_t pad_const_int = 0,
    float pad_const_fp = 0.0f) {
  auto padding__ = padding ? _fbb.CreateVector<int32_t>(*padding) : 0;
  return tosa::CreatePadAttribute(
      _fbb,
      padding__,
      pad_const_int,
      pad_const_fp);
}

struct AxisAttribute FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
  typedef AxisAttributeBuilder Builder;
  enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
    VT_AXIS = 4
  };
  int32_t axis() const {
    return GetField<int32_t>(VT_AXIS, 0);
  }
  bool Verify(flatbuffers::Verifier &verifier) const {
    return VerifyTableStart(verifier) &&
           VerifyField<int32_t>(verifier, VT_AXIS) &&
           verifier.EndTable();
  }
};

struct AxisAttributeBuilder {
  typedef AxisAttribute Table;
  flatbuffers::FlatBufferBuilder &fbb_;
  flatbuffers::uoffset_t start_;
  void add_axis(int32_t axis) {
    fbb_.AddElement<int32_t>(AxisAttribute::VT_AXIS, axis, 0);
  }
  explicit AxisAttributeBuilder(flatbuffers::FlatBufferBuilder &_fbb)
        : fbb_(_fbb) {
    start_ = fbb_.StartTable();
  }
  AxisAttributeBuilder &operator=(const AxisAttributeBuilder &);
  flatbuffers::Offset<AxisAttribute> Finish() {
    const auto end = fbb_.EndTable(start_);
    auto o = flatbuffers::Offset<AxisAttribute>(end);
    return o;
  }
};

inline flatbuffers::Offset<AxisAttribute> CreateAxisAttribute(
    flatbuffers::FlatBufferBuilder &_fbb,
    int32_t axis = 0) {
  AxisAttributeBuilder builder_(_fbb);
  builder_.add_axis(axis);
  return builder_.Finish();
}

struct ReshapeAttribute FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
  typedef ReshapeAttributeBuilder Builder;
  enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
    VT_SHAPE = 4
  };
  const flatbuffers::Vector<int32_t> *shape() const {
    return GetPointer<const flatbuffers::Vector<int32_t> *>(VT_SHAPE);
  }
  bool Verify(flatbuffers::Verifier &verifier) const {
    return VerifyTableStart(verifier) &&
           VerifyOffset(verifier, VT_SHAPE) &&
           verifier.VerifyVector(shape()) &&
           verifier.EndTable();
  }
};

struct ReshapeAttributeBuilder {
  typedef ReshapeAttribute Table;
  flatbuffers::FlatBufferBuilder &fbb_;
  flatbuffers::uoffset_t start_;
  void add_shape(flatbuffers::Offset<flatbuffers::Vector<int32_t>> shape) {
    fbb_.AddOffset(ReshapeAttribute::VT_SHAPE, shape);
  }
  explicit ReshapeAttributeBuilder(flatbuffers::FlatBufferBuilder &_fbb)
        : fbb_(_fbb) {
    start_ = fbb_.StartTable();
  }
  ReshapeAttributeBuilder &operator=(const ReshapeAttributeBuilder &);
  flatbuffers::Offset<ReshapeAttribute> Finish() {
    const auto end = fbb_.EndTable(start_);
    auto o = flatbuffers::Offset<ReshapeAttribute>(end);
    return o;
  }
};

inline flatbuffers::Offset<ReshapeAttribute> CreateReshapeAttribute(
    flatbuffers::FlatBufferBuilder &_fbb,
    flatbuffers::Offset<flatbuffers::Vector<int32_t>> shape = 0) {
  ReshapeAttributeBuilder builder_(_fbb);
  builder_.add_shape(shape);
  return builder_.Finish();
}

inline flatbuffers::Offset<ReshapeAttribute> CreateReshapeAttributeDirect(
    flatbuffers::FlatBufferBuilder &_fbb,
    const std::vector<int32_t> *shape = nullptr) {
  auto shape__ = shape ? _fbb.CreateVector<int32_t>(*shape) : 0;
  return tosa::CreateReshapeAttribute(
      _fbb,
      shape__);
}

struct SliceAttribute FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
  typedef SliceAttributeBuilder Builder;
  enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
    VT_BEGIN = 4,
    VT_SIZE = 6
  };
  const flatbuffers::Vector<int32_t> *begin() const {
    return GetPointer<const flatbuffers::Vector<int32_t> *>(VT_BEGIN);
  }
  const flatbuffers::Vector<int32_t> *size() const {
    return GetPointer<const flatbuffers::Vector<int32_t> *>(VT_SIZE);
  }
  bool Verify(flatbuffers::Verifier &verifier) const {
    return VerifyTableStart(verifier) &&
           VerifyOffset(verifier, VT_BEGIN) &&
           verifier.VerifyVector(begin()) &&
           VerifyOffset(verifier, VT_SIZE) &&
           verifier.VerifyVector(size()) &&
           verifier.EndTable();
  }
};

struct SliceAttributeBuilder {
  typedef SliceAttribute Table;
  flatbuffers::FlatBufferBuilder &fbb_;
  flatbuffers::uoffset_t start_;
  void add_begin(flatbuffers::Offset<flatbuffers::Vector<int32_t>> begin) {
    fbb_.AddOffset(SliceAttribute::VT_BEGIN, begin);
  }
  void add_size(flatbuffers::Offset<flatbuffers::Vector<int32_t>> size) {
    fbb_.AddOffset(SliceAttribute::VT_SIZE, size);
  }
  explicit SliceAttributeBuilder(flatbuffers::FlatBufferBuilder &_fbb)
        : fbb_(_fbb) {
    start_ = fbb_.StartTable();
  }
  SliceAttributeBuilder &operator=(const SliceAttributeBuilder &);
  flatbuffers::Offset<SliceAttribute> Finish() {
    const auto end = fbb_.EndTable(start_);
    auto o = flatbuffers::Offset<SliceAttribute>(end);
    return o;
  }
};

inline flatbuffers::Offset<SliceAttribute> CreateSliceAttribute(
    flatbuffers::FlatBufferBuilder &_fbb,
    flatbuffers::Offset<flatbuffers::Vector<int32_t>> begin = 0,
    flatbuffers::Offset<flatbuffers::Vector<int32_t>> size = 0) {
  SliceAttributeBuilder builder_(_fbb);
  builder_.add_size(size);
  builder_.add_begin(begin);
  return builder_.Finish();
}

inline flatbuffers::Offset<SliceAttribute> CreateSliceAttributeDirect(
    flatbuffers::FlatBufferBuilder &_fbb,
    const std::vector<int32_t> *begin = nullptr,
    const std::vector<int32_t> *size = nullptr) {
  auto begin__ = begin ? _fbb.CreateVector<int32_t>(*begin) : 0;
  auto size__ = size ? _fbb.CreateVector<int32_t>(*size) : 0;
  return tosa::CreateSliceAttribute(
      _fbb,
      begin__,
      size__);
}

struct TileAttribute FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
  typedef TileAttributeBuilder Builder;
  enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
    VT_MULTIPLES = 4
  };
  const flatbuffers::Vector<int32_t> *multiples() const {
    return GetPointer<const flatbuffers::Vector<int32_t> *>(VT_MULTIPLES);
  }
  bool Verify(flatbuffers::Verifier &verifier) const {
    return VerifyTableStart(verifier) &&
           VerifyOffset(verifier, VT_MULTIPLES) &&
           verifier.VerifyVector(multiples()) &&
           verifier.EndTable();
  }
};

struct TileAttributeBuilder {
  typedef TileAttribute Table;
  flatbuffers::FlatBufferBuilder &fbb_;
  flatbuffers::uoffset_t start_;
  void add_multiples(flatbuffers::Offset<flatbuffers::Vector<int32_t>> multiples) {
    fbb_.AddOffset(TileAttribute::VT_MULTIPLES, multiples);
  }
  explicit TileAttributeBuilder(flatbuffers::FlatBufferBuilder &_fbb)
        : fbb_(_fbb) {
    start_ = fbb_.StartTable();
  }
  TileAttributeBuilder &operator=(const TileAttributeBuilder &);
  flatbuffers::Offset<TileAttribute> Finish() {
    const auto end = fbb_.EndTable(start_);
    auto o = flatbuffers::Offset<TileAttribute>(end);
    return o;
  }
};

inline flatbuffers::Offset<TileAttribute> CreateTileAttribute(
    flatbuffers::FlatBufferBuilder &_fbb,
    flatbuffers::Offset<flatbuffers::Vector<int32_t>> multiples = 0) {
  TileAttributeBuilder builder_(_fbb);
  builder_.add_multiples(multiples);
  return builder_.Finish();
}

inline flatbuffers::Offset<TileAttribute> CreateTileAttributeDirect(
    flatbuffers::FlatBufferBuilder &_fbb,
    const std::vector<int32_t> *multiples = nullptr) {
  auto multiples__ = multiples ? _fbb.CreateVector<int32_t>(*multiples) : 0;
  return tosa::CreateTileAttribute(
      _fbb,
      multiples__);
}

struct ResizeAttribute FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
  typedef ResizeAttributeBuilder Builder;
  enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
    VT_OUTPUT_SIZE = 4,
    VT_STRIDE = 6,
    VT_OFFSET = 8,
    VT_SHIFT = 10,
    VT_STRIDE_FP = 12,
    VT_OFFSET_FP = 14,
    VT_MODE = 16
  };
  const flatbuffers::Vector<int32_t> *output_size() const {
    return GetPointer<const flatbuffers::Vector<int32_t> *>(VT_OUTPUT_SIZE);
  }
  const flatbuffers::Vector<int32_t> *stride() const {
    return GetPointer<const flatbuffers::Vector<int32_t> *>(VT_STRIDE);
  }
  const flatbuffers::Vector<int32_t> *offset() const {
    return GetPointer<const flatbuffers::Vector<int32_t> *>(VT_OFFSET);
  }
  int32_t shift() const {
    return GetField<int32_t>(VT_SHIFT, 0);
  }
  const flatbuffers::Vector<float> *stride_fp() const {
    return GetPointer<const flatbuffers::Vector<float> *>(VT_STRIDE_FP);
  }
  const flatbuffers::Vector<float> *offset_fp() const {
    return GetPointer<const flatbuffers::Vector<float> *>(VT_OFFSET_FP);
  }
  tosa::ResizeMode mode() const {
    return static_cast<tosa::ResizeMode>(GetField<uint32_t>(VT_MODE, 0));
  }
  bool Verify(flatbuffers::Verifier &verifier) const {
    return VerifyTableStart(verifier) &&
           VerifyOffset(verifier, VT_OUTPUT_SIZE) &&
           verifier.VerifyVector(output_size()) &&
           VerifyOffset(verifier, VT_STRIDE) &&
           verifier.VerifyVector(stride()) &&
           VerifyOffset(verifier, VT_OFFSET) &&
           verifier.VerifyVector(offset()) &&
           VerifyField<int32_t>(verifier, VT_SHIFT) &&
           VerifyOffset(verifier, VT_STRIDE_FP) &&
           verifier.VerifyVector(stride_fp()) &&
           VerifyOffset(verifier, VT_OFFSET_FP) &&
           verifier.VerifyVector(offset_fp()) &&
           VerifyField<uint32_t>(verifier, VT_MODE) &&
           verifier.EndTable();
  }
};

struct ResizeAttributeBuilder {
  typedef ResizeAttribute Table;
  flatbuffers::FlatBufferBuilder &fbb_;
  flatbuffers::uoffset_t start_;
  void add_output_size(flatbuffers::Offset<flatbuffers::Vector<int32_t>> output_size) {
    fbb_.AddOffset(ResizeAttribute::VT_OUTPUT_SIZE, output_size);
  }
  void add_stride(flatbuffers::Offset<flatbuffers::Vector<int32_t>> stride) {
    fbb_.AddOffset(ResizeAttribute::VT_STRIDE, stride);
  }
  void add_offset(flatbuffers::Offset<flatbuffers::Vector<int32_t>> offset) {
    fbb_.AddOffset(ResizeAttribute::VT_OFFSET, offset);
  }
  void add_shift(int32_t shift) {
    fbb_.AddElement<int32_t>(ResizeAttribute::VT_SHIFT, shift, 0);
  }
  void add_stride_fp(flatbuffers::Offset<flatbuffers::Vector<float>> stride_fp) {
    fbb_.AddOffset(ResizeAttribute::VT_STRIDE_FP, stride_fp);
  }
  void add_offset_fp(flatbuffers::Offset<flatbuffers::Vector<float>> offset_fp) {
    fbb_.AddOffset(ResizeAttribute::VT_OFFSET_FP, offset_fp);
  }
  void add_mode(tosa::ResizeMode mode) {
    fbb_.AddElement<uint32_t>(ResizeAttribute::VT_MODE, static_cast<uint32_t>(mode), 0);
  }
  explicit ResizeAttributeBuilder(flatbuffers::FlatBufferBuilder &_fbb)
        : fbb_(_fbb) {
    start_ = fbb_.StartTable();
  }
  ResizeAttributeBuilder &operator=(const ResizeAttributeBuilder &);
  flatbuffers::Offset<ResizeAttribute> Finish() {
    const auto end = fbb_.EndTable(start_);
    auto o = flatbuffers::Offset<ResizeAttribute>(end);
    return o;
  }
};

inline flatbuffers::Offset<ResizeAttribute> CreateResizeAttribute(
    flatbuffers::FlatBufferBuilder &_fbb,
    flatbuffers::Offset<flatbuffers::Vector<int32_t>> output_size = 0,
    flatbuffers::Offset<flatbuffers::Vector<int32_t>> stride = 0,
    flatbuffers::Offset<flatbuffers::Vector<int32_t>> offset = 0,
    int32_t shift = 0,
    flatbuffers::Offset<flatbuffers::Vector<float>> stride_fp = 0,
    flatbuffers::Offset<flatbuffers::Vector<float>> offset_fp = 0,
    tosa::ResizeMode mode = tosa::ResizeMode_UNKNOWN) {
  ResizeAttributeBuilder builder_(_fbb);
  builder_.add_mode(mode);
  builder_.add_offset_fp(offset_fp);
  builder_.add_stride_fp(stride_fp);
  builder_.add_shift(shift);
  builder_.add_offset(offset);
  builder_.add_stride(stride);
  builder_.add_output_size(output_size);
  return builder_.Finish();
}

inline flatbuffers::Offset<ResizeAttribute> CreateResizeAttributeDirect(
    flatbuffers::FlatBufferBuilder &_fbb,
    const std::vector<int32_t> *output_size = nullptr,
    const std::vector<int32_t> *stride = nullptr,
    const std::vector<int32_t> *offset = nullptr,
    int32_t shift = 0,
    const std::vector<float> *stride_fp = nullptr,
    const std::vector<float> *offset_fp = nullptr,
    tosa::ResizeMode mode = tosa::ResizeMode_UNKNOWN) {
  auto output_size__ = output_size ? _fbb.CreateVector<int32_t>(*output_size) : 0;
  auto stride__ = stride ? _fbb.CreateVector<int32_t>(*stride) : 0;
  auto offset__ = offset ? _fbb.CreateVector<int32_t>(*offset) : 0;
  auto stride_fp__ = stride_fp ? _fbb.CreateVector<float>(*stride_fp) : 0;
  auto offset_fp__ = offset_fp ? _fbb.CreateVector<float>(*offset_fp) : 0;
  return tosa::CreateResizeAttribute(
      _fbb,
      output_size__,
      stride__,
      offset__,
      shift,
      stride_fp__,
      offset_fp__,
      mode);
}

struct ClampAttribute FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
  typedef ClampAttributeBuilder Builder;
  enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
    VT_MIN_INT = 4,
    VT_MAX_INT = 6,
    VT_MIN_FP = 8,
    VT_MAX_FP = 10
  };
  int32_t min_int() const {
    return GetField<int32_t>(VT_MIN_INT, 0);
  }
  int32_t max_int() const {
    return GetField<int32_t>(VT_MAX_INT, 0);
  }
  float min_fp() const {
    return GetField<float>(VT_MIN_FP, 0.0f);
  }
  float max_fp() const {
    return GetField<float>(VT_MAX_FP, 0.0f);
  }
  bool Verify(flatbuffers::Verifier &verifier) const {
    return VerifyTableStart(verifier) &&
           VerifyField<int32_t>(verifier, VT_MIN_INT) &&
           VerifyField<int32_t>(verifier, VT_MAX_INT) &&
           VerifyField<float>(verifier, VT_MIN_FP) &&
           VerifyField<float>(verifier, VT_MAX_FP) &&
           verifier.EndTable();
  }
};

struct ClampAttributeBuilder {
  typedef ClampAttribute Table;
  flatbuffers::FlatBufferBuilder &fbb_;
  flatbuffers::uoffset_t start_;
  void add_min_int(int32_t min_int) {
    fbb_.AddElement<int32_t>(ClampAttribute::VT_MIN_INT, min_int, 0);
  }
  void add_max_int(int32_t max_int) {
    fbb_.AddElement<int32_t>(ClampAttribute::VT_MAX_INT, max_int, 0);
  }
  void add_min_fp(float min_fp) {
    fbb_.AddElement<float>(ClampAttribute::VT_MIN_FP, min_fp, 0.0f);
  }
  void add_max_fp(float max_fp) {
    fbb_.AddElement<float>(ClampAttribute::VT_MAX_FP, max_fp, 0.0f);
  }
  explicit ClampAttributeBuilder(flatbuffers::FlatBufferBuilder &_fbb)
        : fbb_(_fbb) {
    start_ = fbb_.StartTable();
  }
  ClampAttributeBuilder &operator=(const ClampAttributeBuilder &);
  flatbuffers::Offset<ClampAttribute> Finish() {
    const auto end = fbb_.EndTable(start_);
    auto o = flatbuffers::Offset<ClampAttribute>(end);
    return o;
  }
};

inline flatbuffers::Offset<ClampAttribute> CreateClampAttribute(
    flatbuffers::FlatBufferBuilder &_fbb,
    int32_t min_int = 0,
    int32_t max_int = 0,
    float min_fp = 0.0f,
    float max_fp = 0.0f) {
  ClampAttributeBuilder builder_(_fbb);
  builder_.add_max_fp(max_fp);
  builder_.add_min_fp(min_fp);
  builder_.add_max_int(max_int);
  builder_.add_min_int(min_int);
  return builder_.Finish();
}

struct RescaleAttribute FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
  typedef RescaleAttributeBuilder Builder;
  enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
    VT_INPUT_ZP = 4,
    VT_OUTPUT_ZP = 6,
    VT_MULTIPLIER = 8,
    VT_SHIFT = 10,
    VT_SCALE32 = 12,
    VT_DOUBLE_ROUND = 14,
    VT_PER_CHANNEL = 16
  };
  int32_t input_zp() const {
    return GetField<int32_t>(VT_INPUT_ZP, 0);
  }
  int32_t output_zp() const {
    return GetField<int32_t>(VT_OUTPUT_ZP, 0);
  }
  const flatbuffers::Vector<int32_t> *multiplier() const {
    return GetPointer<const flatbuffers::Vector<int32_t> *>(VT_MULTIPLIER);
  }
  const flatbuffers::Vector<int32_t> *shift() const {
    return GetPointer<const flatbuffers::Vector<int32_t> *>(VT_SHIFT);
  }
  bool scale32() const {
    return GetField<uint8_t>(VT_SCALE32, 0) != 0;
  }
  bool double_round() const {
    return GetField<uint8_t>(VT_DOUBLE_ROUND, 0) != 0;
  }
  bool per_channel() const {
    return GetField<uint8_t>(VT_PER_CHANNEL, 0) != 0;
  }
  bool Verify(flatbuffers::Verifier &verifier) const {
    return VerifyTableStart(verifier) &&
           VerifyField<int32_t>(verifier, VT_INPUT_ZP) &&
           VerifyField<int32_t>(verifier, VT_OUTPUT_ZP) &&
           VerifyOffset(verifier, VT_MULTIPLIER) &&
           verifier.VerifyVector(multiplier()) &&
           VerifyOffset(verifier, VT_SHIFT) &&
           verifier.VerifyVector(shift()) &&
           VerifyField<uint8_t>(verifier, VT_SCALE32) &&
           VerifyField<uint8_t>(verifier, VT_DOUBLE_ROUND) &&
           VerifyField<uint8_t>(verifier, VT_PER_CHANNEL) &&
           verifier.EndTable();
  }
};

struct RescaleAttributeBuilder {
  typedef RescaleAttribute Table;
  flatbuffers::FlatBufferBuilder &fbb_;
  flatbuffers::uoffset_t start_;
  void add_input_zp(int32_t input_zp) {
    fbb_.AddElement<int32_t>(RescaleAttribute::VT_INPUT_ZP, input_zp, 0);
  }
  void add_output_zp(int32_t output_zp) {
    fbb_.AddElement<int32_t>(RescaleAttribute::VT_OUTPUT_ZP, output_zp, 0);
  }
  void add_multiplier(flatbuffers::Offset<flatbuffers::Vector<int32_t>> multiplier) {
    fbb_.AddOffset(RescaleAttribute::VT_MULTIPLIER, multiplier);
  }
  void add_shift(flatbuffers::Offset<flatbuffers::Vector<int32_t>> shift) {
    fbb_.AddOffset(RescaleAttribute::VT_SHIFT, shift);
  }
  void add_scale32(bool scale32) {
    fbb_.AddElement<uint8_t>(RescaleAttribute::VT_SCALE32, static_cast<uint8_t>(scale32), 0);
  }
  void add_double_round(bool double_round) {
    fbb_.AddElement<uint8_t>(RescaleAttribute::VT_DOUBLE_ROUND, static_cast<uint8_t>(double_round), 0);
  }
  void add_per_channel(bool per_channel) {
    fbb_.AddElement<uint8_t>(RescaleAttribute::VT_PER_CHANNEL, static_cast<uint8_t>(per_channel), 0);
  }
  explicit RescaleAttributeBuilder(flatbuffers::FlatBufferBuilder &_fbb)
        : fbb_(_fbb) {
    start_ = fbb_.StartTable();
  }
  RescaleAttributeBuilder &operator=(const RescaleAttributeBuilder &);
  flatbuffers::Offset<RescaleAttribute> Finish() {
    const auto end = fbb_.EndTable(start_);
    auto o = flatbuffers::Offset<RescaleAttribute>(end);
    return o;
  }
};

inline flatbuffers::Offset<RescaleAttribute> CreateRescaleAttribute(
    flatbuffers::FlatBufferBuilder &_fbb,
    int32_t input_zp = 0,
    int32_t output_zp = 0,
    flatbuffers::Offset<flatbuffers::Vector<int32_t>> multiplier = 0,
    flatbuffers::Offset<flatbuffers::Vector<int32_t>> shift = 0,
    bool scale32 = false,
    bool double_round = false,
    bool per_channel = false) {
  RescaleAttributeBuilder builder_(_fbb);
  builder_.add_shift(shift);
  builder_.add_multiplier(multiplier);
  builder_.add_output_zp(output_zp);
  builder_.add_input_zp(input_zp);
  builder_.add_per_channel(per_channel);
  builder_.add_double_round(double_round);
  builder_.add_scale32(scale32);
  return builder_.Finish();
}

inline flatbuffers::Offset<RescaleAttribute> CreateRescaleAttributeDirect(
    flatbuffers::FlatBufferBuilder &_fbb,
    int32_t input_zp = 0,
    int32_t output_zp = 0,
    const std::vector<int32_t> *multiplier = nullptr,
    const std::vector<int32_t> *shift = nullptr,
    bool scale32 = false,
    bool double_round = false,
    bool per_channel = false) {
  auto multiplier__ = multiplier ? _fbb.CreateVector<int32_t>(*multiplier) : 0;
  auto shift__ = shift ? _fbb.CreateVector<int32_t>(*shift) : 0;
  return tosa::CreateRescaleAttribute(
      _fbb,
      input_zp,
      output_zp,
      multiplier__,
      shift__,
      scale32,
      double_round,
      per_channel);
}

struct MulAttribute FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
  typedef MulAttributeBuilder Builder;
  enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
    VT_SHIFT = 4
  };
  int32_t shift() const {
    return GetField<int32_t>(VT_SHIFT, 0);
  }
  bool Verify(flatbuffers::Verifier &verifier) const {
    return VerifyTableStart(verifier) &&
           VerifyField<int32_t>(verifier, VT_SHIFT) &&
           verifier.EndTable();
  }
};

struct MulAttributeBuilder {
  typedef MulAttribute Table;
  flatbuffers::FlatBufferBuilder &fbb_;
  flatbuffers::uoffset_t start_;
  void add_shift(int32_t shift) {
    fbb_.AddElement<int32_t>(MulAttribute::VT_SHIFT, shift, 0);
  }
  explicit MulAttributeBuilder(flatbuffers::FlatBufferBuilder &_fbb)
        : fbb_(_fbb) {
    start_ = fbb_.StartTable();
  }
  MulAttributeBuilder &operator=(const MulAttributeBuilder &);
  flatbuffers::Offset<MulAttribute> Finish() {
    const auto end = fbb_.EndTable(start_);
    auto o = flatbuffers::Offset<MulAttribute>(end);
    return o;
  }
};

inline flatbuffers::Offset<MulAttribute> CreateMulAttribute(
    flatbuffers::FlatBufferBuilder &_fbb,
    int32_t shift = 0) {
  MulAttributeBuilder builder_(_fbb);
  builder_.add_shift(shift);
  return builder_.Finish();
}

struct ArithmeticRightShiftAttribute FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
  typedef ArithmeticRightShiftAttributeBuilder Builder;
  enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
    VT_ROUND = 4
  };
  bool round() const {
    return GetField<uint8_t>(VT_ROUND, 0) != 0;
  }
  bool Verify(flatbuffers::Verifier &verifier) const {
    return VerifyTableStart(verifier) &&
           VerifyField<uint8_t>(verifier, VT_ROUND) &&
           verifier.EndTable();
  }
};

struct ArithmeticRightShiftAttributeBuilder {
  typedef ArithmeticRightShiftAttribute Table;
  flatbuffers::FlatBufferBuilder &fbb_;
  flatbuffers::uoffset_t start_;
  void add_round(bool round) {
    fbb_.AddElement<uint8_t>(ArithmeticRightShiftAttribute::VT_ROUND, static_cast<uint8_t>(round), 0);
  }
  explicit ArithmeticRightShiftAttributeBuilder(flatbuffers::FlatBufferBuilder &_fbb)
        : fbb_(_fbb) {
    start_ = fbb_.StartTable();
  }
  ArithmeticRightShiftAttributeBuilder &operator=(const ArithmeticRightShiftAttributeBuilder &);
  flatbuffers::Offset<ArithmeticRightShiftAttribute> Finish() {
    const auto end = fbb_.EndTable(start_);
    auto o = flatbuffers::Offset<ArithmeticRightShiftAttribute>(end);
    return o;
  }
};

inline flatbuffers::Offset<ArithmeticRightShiftAttribute> CreateArithmeticRightShiftAttribute(
    flatbuffers::FlatBufferBuilder &_fbb,
    bool round = false) {
  ArithmeticRightShiftAttributeBuilder builder_(_fbb);
  builder_.add_round(round);
  return builder_.Finish();
}

struct CondIfAttribute FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
  typedef CondIfAttributeBuilder Builder;
  enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
    VT_THEN_BRANCH = 4,
    VT_ELSE_BRANCH = 6
  };
  const flatbuffers::String *then_branch() const {
    return GetPointer<const flatbuffers::String *>(VT_THEN_BRANCH);
  }
  const flatbuffers::String *else_branch() const {
    return GetPointer<const flatbuffers::String *>(VT_ELSE_BRANCH);
  }
  bool Verify(flatbuffers::Verifier &verifier) const {
    return VerifyTableStart(verifier) &&
           VerifyOffset(verifier, VT_THEN_BRANCH) &&
           verifier.VerifyString(then_branch()) &&
           VerifyOffset(verifier, VT_ELSE_BRANCH) &&
           verifier.VerifyString(else_branch()) &&
           verifier.EndTable();
  }
};

struct CondIfAttributeBuilder {
  typedef CondIfAttribute Table;
  flatbuffers::FlatBufferBuilder &fbb_;
  flatbuffers::uoffset_t start_;
  void add_then_branch(flatbuffers::Offset<flatbuffers::String> then_branch) {
    fbb_.AddOffset(CondIfAttribute::VT_THEN_BRANCH, then_branch);
  }
  void add_else_branch(flatbuffers::Offset<flatbuffers::String> else_branch) {
    fbb_.AddOffset(CondIfAttribute::VT_ELSE_BRANCH, else_branch);
  }
  explicit CondIfAttributeBuilder(flatbuffers::FlatBufferBuilder &_fbb)
        : fbb_(_fbb) {
    start_ = fbb_.StartTable();
  }
  CondIfAttributeBuilder &operator=(const CondIfAttributeBuilder &);
  flatbuffers::Offset<CondIfAttribute> Finish() {
    const auto end = fbb_.EndTable(start_);
    auto o = flatbuffers::Offset<CondIfAttribute>(end);
    return o;
  }
};

inline flatbuffers::Offset<CondIfAttribute> CreateCondIfAttribute(
    flatbuffers::FlatBufferBuilder &_fbb,
    flatbuffers::Offset<flatbuffers::String> then_branch = 0,
    flatbuffers::Offset<flatbuffers::String> else_branch = 0) {
  CondIfAttributeBuilder builder_(_fbb);
  builder_.add_else_branch(else_branch);
  builder_.add_then_branch(then_branch);
  return builder_.Finish();
}

inline flatbuffers::Offset<CondIfAttribute> CreateCondIfAttributeDirect(
    flatbuffers::FlatBufferBuilder &_fbb,
    const char *then_branch = nullptr,
    const char *else_branch = nullptr) {
  auto then_branch__ = then_branch ? _fbb.CreateString(then_branch) : 0;
  auto else_branch__ = else_branch ? _fbb.CreateString(else_branch) : 0;
  return tosa::CreateCondIfAttribute(
      _fbb,
      then_branch__,
      else_branch__);
}

struct WhileLoopAttribute FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
  typedef WhileLoopAttributeBuilder Builder;
  enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
    VT_COND_BRANCH = 4,
    VT_BODY_BRANCH = 6
  };
  const flatbuffers::String *cond_branch() const {
    return GetPointer<const flatbuffers::String *>(VT_COND_BRANCH);
  }
  const flatbuffers::String *body_branch() const {
    return GetPointer<const flatbuffers::String *>(VT_BODY_BRANCH);
  }
  bool Verify(flatbuffers::Verifier &verifier) const {
    return VerifyTableStart(verifier) &&
           VerifyOffset(verifier, VT_COND_BRANCH) &&
           verifier.VerifyString(cond_branch()) &&
           VerifyOffset(verifier, VT_BODY_BRANCH) &&
           verifier.VerifyString(body_branch()) &&
           verifier.EndTable();
  }
};

struct WhileLoopAttributeBuilder {
  typedef WhileLoopAttribute Table;
  flatbuffers::FlatBufferBuilder &fbb_;
  flatbuffers::uoffset_t start_;
  void add_cond_branch(flatbuffers::Offset<flatbuffers::String> cond_branch) {
    fbb_.AddOffset(WhileLoopAttribute::VT_COND_BRANCH, cond_branch);
  }
  void add_body_branch(flatbuffers::Offset<flatbuffers::String> body_branch) {
    fbb_.AddOffset(WhileLoopAttribute::VT_BODY_BRANCH, body_branch);
  }
  explicit WhileLoopAttributeBuilder(flatbuffers::FlatBufferBuilder &_fbb)
        : fbb_(_fbb) {
    start_ = fbb_.StartTable();
  }
  WhileLoopAttributeBuilder &operator=(const WhileLoopAttributeBuilder &);
  flatbuffers::Offset<WhileLoopAttribute> Finish() {
    const auto end = fbb_.EndTable(start_);
    auto o = flatbuffers::Offset<WhileLoopAttribute>(end);
    return o;
  }
};

inline flatbuffers::Offset<WhileLoopAttribute> CreateWhileLoopAttribute(
    flatbuffers::FlatBufferBuilder &_fbb,
    flatbuffers::Offset<flatbuffers::String> cond_branch = 0,
    flatbuffers::Offset<flatbuffers::String> body_branch = 0) {
  WhileLoopAttributeBuilder builder_(_fbb);
  builder_.add_body_branch(body_branch);
  builder_.add_cond_branch(cond_branch);
  return builder_.Finish();
}

inline flatbuffers::Offset<WhileLoopAttribute> CreateWhileLoopAttributeDirect(
    flatbuffers::FlatBufferBuilder &_fbb,
    const char *cond_branch = nullptr,
    const char *body_branch = nullptr) {
  auto cond_branch__ = cond_branch ? _fbb.CreateString(cond_branch) : 0;
  auto body_branch__ = body_branch ? _fbb.CreateString(body_branch) : 0;
  return tosa::CreateWhileLoopAttribute(
      _fbb,
      cond_branch__,
      body_branch__);
}

struct TransposeAttribute FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
  typedef TransposeAttributeBuilder Builder;
  enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
    VT_PERM = 4
  };
  const flatbuffers::Vector<int32_t> *perm() const {
    return GetPointer<const flatbuffers::Vector<int32_t> *>(VT_PERM);
  }
  bool Verify(flatbuffers::Verifier &verifier) const {
    return VerifyTableStart(verifier) &&
           VerifyOffset(verifier, VT_PERM) &&
           verifier.VerifyVector(perm()) &&
           verifier.EndTable();
  }
};

struct TransposeAttributeBuilder {
  typedef TransposeAttribute Table;
  flatbuffers::FlatBufferBuilder &fbb_;
  flatbuffers::uoffset_t start_;
  void add_perm(flatbuffers::Offset<flatbuffers::Vector<int32_t>> perm) {
    fbb_.AddOffset(TransposeAttribute::VT_PERM, perm);
  }
  explicit TransposeAttributeBuilder(flatbuffers::FlatBufferBuilder &_fbb)
        : fbb_(_fbb) {
    start_ = fbb_.StartTable();
  }
  TransposeAttributeBuilder &operator=(const TransposeAttributeBuilder &);
  flatbuffers::Offset<TransposeAttribute> Finish() {
    const auto end = fbb_.EndTable(start_);
    auto o = flatbuffers::Offset<TransposeAttribute>(end);
    return o;
  }
};

inline flatbuffers::Offset<TransposeAttribute> CreateTransposeAttribute(
    flatbuffers::FlatBufferBuilder &_fbb,
    flatbuffers::Offset<flatbuffers::Vector<int32_t>> perm = 0) {
  TransposeAttributeBuilder builder_(_fbb);
  builder_.add_perm(perm);
  return builder_.Finish();
}

inline flatbuffers::Offset<TransposeAttribute> CreateTransposeAttributeDirect(
    flatbuffers::FlatBufferBuilder &_fbb,
    const std::vector<int32_t> *perm = nullptr) {
  auto perm__ = perm ? _fbb.CreateVector<int32_t>(*perm) : 0;
  return tosa::CreateTransposeAttribute(
      _fbb,
      perm__);
}

struct TableAttribute FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
  typedef TableAttributeBuilder Builder;
  enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
    VT_TABLE = 4
  };
  const flatbuffers::Vector<int32_t> *table() const {
    return GetPointer<const flatbuffers::Vector<int32_t> *>(VT_TABLE);
  }
  bool Verify(flatbuffers::Verifier &verifier) const {
    return VerifyTableStart(verifier) &&
           VerifyOffset(verifier, VT_TABLE) &&
           verifier.VerifyVector(table()) &&
           verifier.EndTable();
  }
};

struct TableAttributeBuilder {
  typedef TableAttribute Table;
  flatbuffers::FlatBufferBuilder &fbb_;
  flatbuffers::uoffset_t start_;
  void add_table(flatbuffers::Offset<flatbuffers::Vector<int32_t>> table) {
    fbb_.AddOffset(TableAttribute::VT_TABLE, table);
  }
  explicit TableAttributeBuilder(flatbuffers::FlatBufferBuilder &_fbb)
        : fbb_(_fbb) {
    start_ = fbb_.StartTable();
  }
  TableAttributeBuilder &operator=(const TableAttributeBuilder &);
  flatbuffers::Offset<TableAttribute> Finish() {
    const auto end = fbb_.EndTable(start_);
    auto o = flatbuffers::Offset<TableAttribute>(end);
    return o;
  }
};

inline flatbuffers::Offset<TableAttribute> CreateTableAttribute(
    flatbuffers::FlatBufferBuilder &_fbb,
    flatbuffers::Offset<flatbuffers::Vector<int32_t>> table = 0) {
  TableAttributeBuilder builder_(_fbb);
  builder_.add_table(table);
  return builder_.Finish();
}

inline flatbuffers::Offset<TableAttribute> CreateTableAttributeDirect(
    flatbuffers::FlatBufferBuilder &_fbb,
    const std::vector<int32_t> *table = nullptr) {
  auto table__ = table ? _fbb.CreateVector<int32_t>(*table) : 0;
  return tosa::CreateTableAttribute(
      _fbb,
      table__);
}

struct UnaryQuantInfo FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
  typedef UnaryQuantInfoBuilder Builder;
  enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
    VT_INPUT_ZP = 4,
    VT_OUTPUT_ZP = 6
  };
  int32_t input_zp() const {
    return GetField<int32_t>(VT_INPUT_ZP, 0);
  }
  int32_t output_zp() const {
    return GetField<int32_t>(VT_OUTPUT_ZP, 0);
  }
  bool Verify(flatbuffers::Verifier &verifier) const {
    return VerifyTableStart(verifier) &&
           VerifyField<int32_t>(verifier, VT_INPUT_ZP) &&
           VerifyField<int32_t>(verifier, VT_OUTPUT_ZP) &&
           verifier.EndTable();
  }
};

struct UnaryQuantInfoBuilder {
  typedef UnaryQuantInfo Table;
  flatbuffers::FlatBufferBuilder &fbb_;
  flatbuffers::uoffset_t start_;
  void add_input_zp(int32_t input_zp) {
    fbb_.AddElement<int32_t>(UnaryQuantInfo::VT_INPUT_ZP, input_zp, 0);
  }
  void add_output_zp(int32_t output_zp) {
    fbb_.AddElement<int32_t>(UnaryQuantInfo::VT_OUTPUT_ZP, output_zp, 0);
  }
  explicit UnaryQuantInfoBuilder(flatbuffers::FlatBufferBuilder &_fbb)
        : fbb_(_fbb) {
    start_ = fbb_.StartTable();
  }
  UnaryQuantInfoBuilder &operator=(const UnaryQuantInfoBuilder &);
  flatbuffers::Offset<UnaryQuantInfo> Finish() {
    const auto end = fbb_.EndTable(start_);
    auto o = flatbuffers::Offset<UnaryQuantInfo>(end);
    return o;
  }
};

inline flatbuffers::Offset<UnaryQuantInfo> CreateUnaryQuantInfo(
    flatbuffers::FlatBufferBuilder &_fbb,
    int32_t input_zp = 0,
    int32_t output_zp = 0) {
  UnaryQuantInfoBuilder builder_(_fbb);
  builder_.add_output_zp(output_zp);
  builder_.add_input_zp(input_zp);
  return builder_.Finish();
}

struct ConvQuantInfo FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
  typedef ConvQuantInfoBuilder Builder;
  enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
    VT_INPUT_ZP = 4,
    VT_WEIGHT_ZP = 6
  };
  int32_t input_zp() const {
    return GetField<int32_t>(VT_INPUT_ZP, 0);
  }
  int32_t weight_zp() const {
    return GetField<int32_t>(VT_WEIGHT_ZP, 0);
  }
  bool Verify(flatbuffers::Verifier &verifier) const {
    return VerifyTableStart(verifier) &&
           VerifyField<int32_t>(verifier, VT_INPUT_ZP) &&
           VerifyField<int32_t>(verifier, VT_WEIGHT_ZP) &&
           verifier.EndTable();
  }
};

struct ConvQuantInfoBuilder {
  typedef ConvQuantInfo Table;
  flatbuffers::FlatBufferBuilder &fbb_;
  flatbuffers::uoffset_t start_;
  void add_input_zp(int32_t input_zp) {
    fbb_.AddElement<int32_t>(ConvQuantInfo::VT_INPUT_ZP, input_zp, 0);
  }
  void add_weight_zp(int32_t weight_zp) {
    fbb_.AddElement<int32_t>(ConvQuantInfo::VT_WEIGHT_ZP, weight_zp, 0);
  }
  explicit ConvQuantInfoBuilder(flatbuffers::FlatBufferBuilder &_fbb)
        : fbb_(_fbb) {
    start_ = fbb_.StartTable();
  }
  ConvQuantInfoBuilder &operator=(const ConvQuantInfoBuilder &);
  flatbuffers::Offset<ConvQuantInfo> Finish() {
    const auto end = fbb_.EndTable(start_);
    auto o = flatbuffers::Offset<ConvQuantInfo>(end);
    return o;
  }
};

inline flatbuffers::Offset<ConvQuantInfo> CreateConvQuantInfo(
    flatbuffers::FlatBufferBuilder &_fbb,
    int32_t input_zp = 0,
    int32_t weight_zp = 0) {
  ConvQuantInfoBuilder builder_(_fbb);
  builder_.add_weight_zp(weight_zp);
  builder_.add_input_zp(input_zp);
  return builder_.Finish();
}

struct MatMulQuantInfo FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
  typedef MatMulQuantInfoBuilder Builder;
  enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
    VT_A_ZP = 4,
    VT_B_ZP = 6
  };
  int32_t a_zp() const {
    return GetField<int32_t>(VT_A_ZP, 0);
  }
  int32_t b_zp() const {
    return GetField<int32_t>(VT_B_ZP, 0);
  }
  bool Verify(flatbuffers::Verifier &verifier) const {
    return VerifyTableStart(verifier) &&
           VerifyField<int32_t>(verifier, VT_A_ZP) &&
           VerifyField<int32_t>(verifier, VT_B_ZP) &&
           verifier.EndTable();
  }
};

struct MatMulQuantInfoBuilder {
  typedef MatMulQuantInfo Table;
  flatbuffers::FlatBufferBuilder &fbb_;
  flatbuffers::uoffset_t start_;
  void add_a_zp(int32_t a_zp) {
    fbb_.AddElement<int32_t>(MatMulQuantInfo::VT_A_ZP, a_zp, 0);
  }
  void add_b_zp(int32_t b_zp) {
    fbb_.AddElement<int32_t>(MatMulQuantInfo::VT_B_ZP, b_zp, 0);
  }
  explicit MatMulQuantInfoBuilder(flatbuffers::FlatBufferBuilder &_fbb)
        : fbb_(_fbb) {
    start_ = fbb_.StartTable();
  }
  MatMulQuantInfoBuilder &operator=(const MatMulQuantInfoBuilder &);
  flatbuffers::Offset<MatMulQuantInfo> Finish() {
    const auto end = fbb_.EndTable(start_);
    auto o = flatbuffers::Offset<MatMulQuantInfo>(end);
    return o;
  }
};

inline flatbuffers::Offset<MatMulQuantInfo> CreateMatMulQuantInfo(
    flatbuffers::FlatBufferBuilder &_fbb,
    int32_t a_zp = 0,
    int32_t b_zp = 0) {
  MatMulQuantInfoBuilder builder_(_fbb);
  builder_.add_b_zp(b_zp);
  builder_.add_a_zp(a_zp);
  return builder_.Finish();
}

struct PadQuantInfo FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
  typedef PadQuantInfoBuilder Builder;
  enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
    VT_INPUT_ZP = 4
  };
  int32_t input_zp() const {
    return GetField<int32_t>(VT_INPUT_ZP, 0);
  }
  bool Verify(flatbuffers::Verifier &verifier) const {
    return VerifyTableStart(verifier) &&
           VerifyField<int32_t>(verifier, VT_INPUT_ZP) &&
           verifier.EndTable();
  }
};

struct PadQuantInfoBuilder {
  typedef PadQuantInfo Table;
  flatbuffers::FlatBufferBuilder &fbb_;
  flatbuffers::uoffset_t start_;
  void add_input_zp(int32_t input_zp) {
    fbb_.AddElement<int32_t>(PadQuantInfo::VT_INPUT_ZP, input_zp, 0);
  }
  explicit PadQuantInfoBuilder(flatbuffers::FlatBufferBuilder &_fbb)
        : fbb_(_fbb) {
    start_ = fbb_.StartTable();
  }
  PadQuantInfoBuilder &operator=(const PadQuantInfoBuilder &);
  flatbuffers::Offset<PadQuantInfo> Finish() {
    const auto end = fbb_.EndTable(start_);
    auto o = flatbuffers::Offset<PadQuantInfo>(end);
    return o;
  }
};

inline flatbuffers::Offset<PadQuantInfo> CreatePadQuantInfo(
    flatbuffers::FlatBufferBuilder &_fbb,
    int32_t input_zp = 0) {
  PadQuantInfoBuilder builder_(_fbb);
  builder_.add_input_zp(input_zp);
  return builder_.Finish();
}

struct Version FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
  typedef VersionBuilder Builder;
  enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
    VT__MAJOR = 4,
    VT__MINOR = 6,
    VT__PATCH = 8,
    VT__DRAFT = 10
  };
  int32_t _major() const {
    return GetField<int32_t>(VT__MAJOR, 0);
  }
  int32_t _minor() const {
    return GetField<int32_t>(VT__MINOR, 23);
  }
  int32_t _patch() const {
    return GetField<int32_t>(VT__PATCH, 0);
  }
  bool _draft() const {
    return GetField<uint8_t>(VT__DRAFT, 0) != 0;
  }
  bool Verify(flatbuffers::Verifier &verifier) const {
    return VerifyTableStart(verifier) &&
           VerifyField<int32_t>(verifier, VT__MAJOR) &&
           VerifyField<int32_t>(verifier, VT__MINOR) &&
           VerifyField<int32_t>(verifier, VT__PATCH) &&
           VerifyField<uint8_t>(verifier, VT__DRAFT) &&
           verifier.EndTable();
  }
};

struct VersionBuilder {
  typedef Version Table;
  flatbuffers::FlatBufferBuilder &fbb_;
  flatbuffers::uoffset_t start_;
  void add__major(int32_t _major) {
    fbb_.AddElement<int32_t>(Version::VT__MAJOR, _major, 0);
  }
  void add__minor(int32_t _minor) {
    fbb_.AddElement<int32_t>(Version::VT__MINOR, _minor, 23);
  }
  void add__patch(int32_t _patch) {
    fbb_.AddElement<int32_t>(Version::VT__PATCH, _patch, 0);
  }
  void add__draft(bool _draft) {
    fbb_.AddElement<uint8_t>(Version::VT__DRAFT, static_cast<uint8_t>(_draft), 0);
  }
  explicit VersionBuilder(flatbuffers::FlatBufferBuilder &_fbb)
        : fbb_(_fbb) {
    start_ = fbb_.StartTable();
  }
  VersionBuilder &operator=(const VersionBuilder &);
  flatbuffers::Offset<Version> Finish() {
    const auto end = fbb_.EndTable(start_);
    auto o = flatbuffers::Offset<Version>(end);
    return o;
  }
};

inline flatbuffers::Offset<Version> CreateVersion(
    flatbuffers::FlatBufferBuilder &_fbb,
    int32_t _major = 0,
    int32_t _minor = 23,
    int32_t _patch = 0,
    bool _draft = false) {
  VersionBuilder builder_(_fbb);
  builder_.add__patch(_patch);
  builder_.add__minor(_minor);
  builder_.add__major(_major);
  builder_.add__draft(_draft);
  return builder_.Finish();
}

struct TosaTensor FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
  typedef TosaTensorBuilder Builder;
  enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
    VT_NAME = 4,
    VT_SHAPE = 6,
    VT_TYPE = 8,
    VT_DATA = 10
  };
  const flatbuffers::String *name() const {
    return GetPointer<const flatbuffers::String *>(VT_NAME);
  }
  const flatbuffers::Vector<int32_t> *shape() const {
    return GetPointer<const flatbuffers::Vector<int32_t> *>(VT_SHAPE);
  }
  tosa::DType type() const {
    return static_cast<tosa::DType>(GetField<uint32_t>(VT_TYPE, 0));
  }
  const flatbuffers::Vector<uint8_t> *data() const {
    return GetPointer<const flatbuffers::Vector<uint8_t> *>(VT_DATA);
  }
  bool Verify(flatbuffers::Verifier &verifier) const {
    return VerifyTableStart(verifier) &&
           VerifyOffset(verifier, VT_NAME) &&
           verifier.VerifyString(name()) &&
           VerifyOffset(verifier, VT_SHAPE) &&
           verifier.VerifyVector(shape()) &&
           VerifyField<uint32_t>(verifier, VT_TYPE) &&
           VerifyOffset(verifier, VT_DATA) &&
           verifier.VerifyVector(data()) &&
           verifier.EndTable();
  }
};

struct TosaTensorBuilder {
  typedef TosaTensor Table;
  flatbuffers::FlatBufferBuilder &fbb_;
  flatbuffers::uoffset_t start_;
  void add_name(flatbuffers::Offset<flatbuffers::String> name) {
    fbb_.AddOffset(TosaTensor::VT_NAME, name);
  }
  void add_shape(flatbuffers::Offset<flatbuffers::Vector<int32_t>> shape) {
    fbb_.AddOffset(TosaTensor::VT_SHAPE, shape);
  }
  void add_type(tosa::DType type) {
    fbb_.AddElement<uint32_t>(TosaTensor::VT_TYPE, static_cast<uint32_t>(type), 0);
  }
  void add_data(flatbuffers::Offset<flatbuffers::Vector<uint8_t>> data) {
    fbb_.AddOffset(TosaTensor::VT_DATA, data);
  }
  explicit TosaTensorBuilder(flatbuffers::FlatBufferBuilder &_fbb)
        : fbb_(_fbb) {
    start_ = fbb_.StartTable();
  }
  TosaTensorBuilder &operator=(const TosaTensorBuilder &);
  flatbuffers::Offset<TosaTensor> Finish() {
    const auto end = fbb_.EndTable(start_);
    auto o = flatbuffers::Offset<TosaTensor>(end);
    return o;
  }
};

inline flatbuffers::Offset<TosaTensor> CreateTosaTensor(
    flatbuffers::FlatBufferBuilder &_fbb,
    flatbuffers::Offset<flatbuffers::String> name = 0,
    flatbuffers::Offset<flatbuffers::Vector<int32_t>> shape = 0,
    tosa::DType type = tosa::DType_UNKNOWN,
    flatbuffers::Offset<flatbuffers::Vector<uint8_t>> data = 0) {
  TosaTensorBuilder builder_(_fbb);
  builder_.add_data(data);
  builder_.add_type(type);
  builder_.add_shape(shape);
  builder_.add_name(name);
  return builder_.Finish();
}

inline flatbuffers::Offset<TosaTensor> CreateTosaTensorDirect(
    flatbuffers::FlatBufferBuilder &_fbb,
    const char *name = nullptr,
    const std::vector<int32_t> *shape = nullptr,
    tosa::DType type = tosa::DType_UNKNOWN,
    const std::vector<uint8_t> *data = nullptr) {
  auto name__ = name ? _fbb.CreateString(name) : 0;
  auto shape__ = shape ? _fbb.CreateVector<int32_t>(*shape) : 0;
  if (data) { _fbb.ForceVectorAlignment(data->size(), sizeof(uint8_t), 8); }
  auto data__ = data ? _fbb.CreateVector<uint8_t>(*data) : 0;
  return tosa::CreateTosaTensor(
      _fbb,
      name__,
      shape__,
      type,
      data__);
}

struct TosaOperator FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
  typedef TosaOperatorBuilder Builder;
  enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
    VT_OP = 4,
    VT_ATTRIBUTE_TYPE = 6,
    VT_ATTRIBUTE = 8,
    VT_INPUTS = 10,
    VT_OUTPUTS = 12,
    VT_QUANT_INFO_TYPE = 14,
    VT_QUANT_INFO = 16
  };
  tosa::Op op() const {
    return static_cast<tosa::Op>(GetField<uint32_t>(VT_OP, 0));
  }
  tosa::Attribute attribute_type() const {
    return static_cast<tosa::Attribute>(GetField<uint8_t>(VT_ATTRIBUTE_TYPE, 0));
  }
  const void *attribute() const {
    return GetPointer<const void *>(VT_ATTRIBUTE);
  }
  template<typename T> const T *attribute_as() const;
  const tosa::PoolAttribute *attribute_as_PoolAttribute() const {
    return attribute_type() == tosa::Attribute_PoolAttribute ? static_cast<const tosa::PoolAttribute *>(attribute()) : nullptr;
  }
  const tosa::ConvAttribute *attribute_as_ConvAttribute() const {
    return attribute_type() == tosa::Attribute_ConvAttribute ? static_cast<const tosa::ConvAttribute *>(attribute()) : nullptr;
  }
  const tosa::TransposeConvAttribute *attribute_as_TransposeConvAttribute() const {
    return attribute_type() == tosa::Attribute_TransposeConvAttribute ? static_cast<const tosa::TransposeConvAttribute *>(attribute()) : nullptr;
  }
  const tosa::PadAttribute *attribute_as_PadAttribute() const {
    return attribute_type() == tosa::Attribute_PadAttribute ? static_cast<const tosa::PadAttribute *>(attribute()) : nullptr;
  }
  const tosa::AxisAttribute *attribute_as_AxisAttribute() const {
    return attribute_type() == tosa::Attribute_AxisAttribute ? static_cast<const tosa::AxisAttribute *>(attribute()) : nullptr;
  }
  const tosa::ReshapeAttribute *attribute_as_ReshapeAttribute() const {
    return attribute_type() == tosa::Attribute_ReshapeAttribute ? static_cast<const tosa::ReshapeAttribute *>(attribute()) : nullptr;
  }
  const tosa::SliceAttribute *attribute_as_SliceAttribute() const {
    return attribute_type() == tosa::Attribute_SliceAttribute ? static_cast<const tosa::SliceAttribute *>(attribute()) : nullptr;
  }
  const tosa::TileAttribute *attribute_as_TileAttribute() const {
    return attribute_type() == tosa::Attribute_TileAttribute ? static_cast<const tosa::TileAttribute *>(attribute()) : nullptr;
  }
  const tosa::ResizeAttribute *attribute_as_ResizeAttribute() const {
    return attribute_type() == tosa::Attribute_ResizeAttribute ? static_cast<const tosa::ResizeAttribute *>(attribute()) : nullptr;
  }
  const tosa::ClampAttribute *attribute_as_ClampAttribute() const {
    return attribute_type() == tosa::Attribute_ClampAttribute ? static_cast<const tosa::ClampAttribute *>(attribute()) : nullptr;
  }
  const tosa::RescaleAttribute *attribute_as_RescaleAttribute() const {
    return attribute_type() == tosa::Attribute_RescaleAttribute ? static_cast<const tosa::RescaleAttribute *>(attribute()) : nullptr;
  }
  const tosa::MulAttribute *attribute_as_MulAttribute() const {
    return attribute_type() == tosa::Attribute_MulAttribute ? static_cast<const tosa::MulAttribute *>(attribute()) : nullptr;
  }
  const tosa::ArithmeticRightShiftAttribute *attribute_as_ArithmeticRightShiftAttribute() const {
    return attribute_type() == tosa::Attribute_ArithmeticRightShiftAttribute ? static_cast<const tosa::ArithmeticRightShiftAttribute *>(attribute()) : nullptr;
  }
  const tosa::CondIfAttribute *attribute_as_CondIfAttribute() const {
    return attribute_type() == tosa::Attribute_CondIfAttribute ? static_cast<const tosa::CondIfAttribute *>(attribute()) : nullptr;
  }
  const tosa::WhileLoopAttribute *attribute_as_WhileLoopAttribute() const {
    return attribute_type() == tosa::Attribute_WhileLoopAttribute ? static_cast<const tosa::WhileLoopAttribute *>(attribute()) : nullptr;
  }
  const tosa::TransposeAttribute *attribute_as_TransposeAttribute() const {
    return attribute_type() == tosa::Attribute_TransposeAttribute ? static_cast<const tosa::TransposeAttribute *>(attribute()) : nullptr;
  }
  const tosa::TableAttribute *attribute_as_TableAttribute() const {
    return attribute_type() == tosa::Attribute_TableAttribute ? static_cast<const tosa::TableAttribute *>(attribute()) : nullptr;
  }
  const flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>> *inputs() const {
    return GetPointer<const flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>> *>(VT_INPUTS);
  }
  const flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>> *outputs() const {
    return GetPointer<const flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>> *>(VT_OUTPUTS);
  }
  tosa::QuantInfo quant_info_type() const {
    return static_cast<tosa::QuantInfo>(GetField<uint8_t>(VT_QUANT_INFO_TYPE, 0));
  }
  const void *quant_info() const {
    return GetPointer<const void *>(VT_QUANT_INFO);
  }
  template<typename T> const T *quant_info_as() const;
  const tosa::UnaryQuantInfo *quant_info_as_UnaryQuantInfo() const {
    return quant_info_type() == tosa::QuantInfo_UnaryQuantInfo ? static_cast<const tosa::UnaryQuantInfo *>(quant_info()) : nullptr;
  }
  const tosa::ConvQuantInfo *quant_info_as_ConvQuantInfo() const {
    return quant_info_type() == tosa::QuantInfo_ConvQuantInfo ? static_cast<const tosa::ConvQuantInfo *>(quant_info()) : nullptr;
  }
  const tosa::MatMulQuantInfo *quant_info_as_MatMulQuantInfo() const {
    return quant_info_type() == tosa::QuantInfo_MatMulQuantInfo ? static_cast<const tosa::MatMulQuantInfo *>(quant_info()) : nullptr;
  }
  const tosa::PadQuantInfo *quant_info_as_PadQuantInfo() const {
    return quant_info_type() == tosa::QuantInfo_PadQuantInfo ? static_cast<const tosa::PadQuantInfo *>(quant_info()) : nullptr;
  }
  bool Verify(flatbuffers::Verifier &verifier) const {
    return VerifyTableStart(verifier) &&
           VerifyField<uint32_t>(verifier, VT_OP) &&
           VerifyField<uint8_t>(verifier, VT_ATTRIBUTE_TYPE) &&
           VerifyOffset(verifier, VT_ATTRIBUTE) &&
           VerifyAttribute(verifier, attribute(), attribute_type()) &&
           VerifyOffset(verifier, VT_INPUTS) &&
           verifier.VerifyVector(inputs()) &&
           verifier.VerifyVectorOfStrings(inputs()) &&
           VerifyOffset(verifier, VT_OUTPUTS) &&
           verifier.VerifyVector(outputs()) &&
           verifier.VerifyVectorOfStrings(outputs()) &&
           VerifyField<uint8_t>(verifier, VT_QUANT_INFO_TYPE) &&
           VerifyOffset(verifier, VT_QUANT_INFO) &&
           VerifyQuantInfo(verifier, quant_info(), quant_info_type()) &&
           verifier.EndTable();
  }
};

template<> inline const tosa::PoolAttribute *TosaOperator::attribute_as<tosa::PoolAttribute>() const {
  return attribute_as_PoolAttribute();
}

template<> inline const tosa::ConvAttribute *TosaOperator::attribute_as<tosa::ConvAttribute>() const {
  return attribute_as_ConvAttribute();
}

template<> inline const tosa::TransposeConvAttribute *TosaOperator::attribute_as<tosa::TransposeConvAttribute>() const {
  return attribute_as_TransposeConvAttribute();
}

template<> inline const tosa::PadAttribute *TosaOperator::attribute_as<tosa::PadAttribute>() const {
  return attribute_as_PadAttribute();
}

template<> inline const tosa::AxisAttribute *TosaOperator::attribute_as<tosa::AxisAttribute>() const {
  return attribute_as_AxisAttribute();
}

template<> inline const tosa::ReshapeAttribute *TosaOperator::attribute_as<tosa::ReshapeAttribute>() const {
  return attribute_as_ReshapeAttribute();
}

template<> inline const tosa::SliceAttribute *TosaOperator::attribute_as<tosa::SliceAttribute>() const {
  return attribute_as_SliceAttribute();
}

template<> inline const tosa::TileAttribute *TosaOperator::attribute_as<tosa::TileAttribute>() const {
  return attribute_as_TileAttribute();
}

template<> inline const tosa::ResizeAttribute *TosaOperator::attribute_as<tosa::ResizeAttribute>() const {
  return attribute_as_ResizeAttribute();
}

template<> inline const tosa::ClampAttribute *TosaOperator::attribute_as<tosa::ClampAttribute>() const {
  return attribute_as_ClampAttribute();
}

template<> inline const tosa::RescaleAttribute *TosaOperator::attribute_as<tosa::RescaleAttribute>() const {
  return attribute_as_RescaleAttribute();
}

template<> inline const tosa::MulAttribute *TosaOperator::attribute_as<tosa::MulAttribute>() const {
  return attribute_as_MulAttribute();
}

template<> inline const tosa::ArithmeticRightShiftAttribute *TosaOperator::attribute_as<tosa::ArithmeticRightShiftAttribute>() const {
  return attribute_as_ArithmeticRightShiftAttribute();
}

template<> inline const tosa::CondIfAttribute *TosaOperator::attribute_as<tosa::CondIfAttribute>() const {
  return attribute_as_CondIfAttribute();
}

template<> inline const tosa::WhileLoopAttribute *TosaOperator::attribute_as<tosa::WhileLoopAttribute>() const {
  return attribute_as_WhileLoopAttribute();
}

template<> inline const tosa::TransposeAttribute *TosaOperator::attribute_as<tosa::TransposeAttribute>() const {
  return attribute_as_TransposeAttribute();
}

template<> inline const tosa::TableAttribute *TosaOperator::attribute_as<tosa::TableAttribute>() const {
  return attribute_as_TableAttribute();
}

template<> inline const tosa::UnaryQuantInfo *TosaOperator::quant_info_as<tosa::UnaryQuantInfo>() const {
  return quant_info_as_UnaryQuantInfo();
}

template<> inline const tosa::ConvQuantInfo *TosaOperator::quant_info_as<tosa::ConvQuantInfo>() const {
  return quant_info_as_ConvQuantInfo();
}

template<> inline const tosa::MatMulQuantInfo *TosaOperator::quant_info_as<tosa::MatMulQuantInfo>() const {
  return quant_info_as_MatMulQuantInfo();
}

template<> inline const tosa::PadQuantInfo *TosaOperator::quant_info_as<tosa::PadQuantInfo>() const {
  return quant_info_as_PadQuantInfo();
}

struct TosaOperatorBuilder {
  typedef TosaOperator Table;
  flatbuffers::FlatBufferBuilder &fbb_;
  flatbuffers::uoffset_t start_;
  void add_op(tosa::Op op) {
    fbb_.AddElement<uint32_t>(TosaOperator::VT_OP, static_cast<uint32_t>(op), 0);
  }
  void add_attribute_type(tosa::Attribute attribute_type) {
    fbb_.AddElement<uint8_t>(TosaOperator::VT_ATTRIBUTE_TYPE, static_cast<uint8_t>(attribute_type), 0);
  }
  void add_attribute(flatbuffers::Offset<void> attribute) {
    fbb_.AddOffset(TosaOperator::VT_ATTRIBUTE, attribute);
  }
  void add_inputs(flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>>> inputs) {
    fbb_.AddOffset(TosaOperator::VT_INPUTS, inputs);
  }
  void add_outputs(flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>>> outputs) {
    fbb_.AddOffset(TosaOperator::VT_OUTPUTS, outputs);
  }
  void add_quant_info_type(tosa::QuantInfo quant_info_type) {
    fbb_.AddElement<uint8_t>(TosaOperator::VT_QUANT_INFO_TYPE, static_cast<uint8_t>(quant_info_type), 0);
  }
  void add_quant_info(flatbuffers::Offset<void> quant_info) {
    fbb_.AddOffset(TosaOperator::VT_QUANT_INFO, quant_info);
  }
  explicit TosaOperatorBuilder(flatbuffers::FlatBufferBuilder &_fbb)
        : fbb_(_fbb) {
    start_ = fbb_.StartTable();
  }
  TosaOperatorBuilder &operator=(const TosaOperatorBuilder &);
  flatbuffers::Offset<TosaOperator> Finish() {
    const auto end = fbb_.EndTable(start_);
    auto o = flatbuffers::Offset<TosaOperator>(end);
    return o;
  }
};

inline flatbuffers::Offset<TosaOperator> CreateTosaOperator(
    flatbuffers::FlatBufferBuilder &_fbb,
    tosa::Op op = tosa::Op_UNKNOWN,
    tosa::Attribute attribute_type = tosa::Attribute_NONE,
    flatbuffers::Offset<void> attribute = 0,
    flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>>> inputs = 0,
    flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>>> outputs = 0,
    tosa::QuantInfo quant_info_type = tosa::QuantInfo_NONE,
    flatbuffers::Offset<void> quant_info = 0) {
  TosaOperatorBuilder builder_(_fbb);
  builder_.add_quant_info(quant_info);
  builder_.add_outputs(outputs);
  builder_.add_inputs(inputs);
  builder_.add_attribute(attribute);
  builder_.add_op(op);
  builder_.add_quant_info_type(quant_info_type);
  builder_.add_attribute_type(attribute_type);
  return builder_.Finish();
}

inline flatbuffers::Offset<TosaOperator> CreateTosaOperatorDirect(
    flatbuffers::FlatBufferBuilder &_fbb,
    tosa::Op op = tosa::Op_UNKNOWN,
    tosa::Attribute attribute_type = tosa::Attribute_NONE,
    flatbuffers::Offset<void> attribute = 0,
    const std::vector<flatbuffers::Offset<flatbuffers::String>> *inputs = nullptr,
    const std::vector<flatbuffers::Offset<flatbuffers::String>> *outputs = nullptr,
    tosa::QuantInfo quant_info_type = tosa::QuantInfo_NONE,
    flatbuffers::Offset<void> quant_info = 0) {
  auto inputs__ = inputs ? _fbb.CreateVector<flatbuffers::Offset<flatbuffers::String>>(*inputs) : 0;
  auto outputs__ = outputs ? _fbb.CreateVector<flatbuffers::Offset<flatbuffers::String>>(*outputs) : 0;
  return tosa::CreateTosaOperator(
      _fbb,
      op,
      attribute_type,
      attribute,
      inputs__,
      outputs__,
      quant_info_type,
      quant_info);
}

struct TosaBasicBlock FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
  typedef TosaBasicBlockBuilder Builder;
  enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
    VT_NAME = 4,
    VT_OPERATORS = 6,
    VT_TENSORS = 8,
    VT_INPUTS = 10,
    VT_OUTPUTS = 12
  };
  const flatbuffers::String *name() const {
    return GetPointer<const flatbuffers::String *>(VT_NAME);
  }
  const flatbuffers::Vector<flatbuffers::Offset<tosa::TosaOperator>> *operators() const {
    return GetPointer<const flatbuffers::Vector<flatbuffers::Offset<tosa::TosaOperator>> *>(VT_OPERATORS);
  }
  const flatbuffers::Vector<flatbuffers::Offset<tosa::TosaTensor>> *tensors() const {
    return GetPointer<const flatbuffers::Vector<flatbuffers::Offset<tosa::TosaTensor>> *>(VT_TENSORS);
  }
  const flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>> *inputs() const {
    return GetPointer<const flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>> *>(VT_INPUTS);
  }
  const flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>> *outputs() const {
    return GetPointer<const flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>> *>(VT_OUTPUTS);
  }
  bool Verify(flatbuffers::Verifier &verifier) const {
    return VerifyTableStart(verifier) &&
           VerifyOffset(verifier, VT_NAME) &&
           verifier.VerifyString(name()) &&
           VerifyOffset(verifier, VT_OPERATORS) &&
           verifier.VerifyVector(operators()) &&
           verifier.VerifyVectorOfTables(operators()) &&
           VerifyOffset(verifier, VT_TENSORS) &&
           verifier.VerifyVector(tensors()) &&
           verifier.VerifyVectorOfTables(tensors()) &&
           VerifyOffset(verifier, VT_INPUTS) &&
           verifier.VerifyVector(inputs()) &&
           verifier.VerifyVectorOfStrings(inputs()) &&
           VerifyOffset(verifier, VT_OUTPUTS) &&
           verifier.VerifyVector(outputs()) &&
           verifier.VerifyVectorOfStrings(outputs()) &&
           verifier.EndTable();
  }
};

struct TosaBasicBlockBuilder {
  typedef TosaBasicBlock Table;
  flatbuffers::FlatBufferBuilder &fbb_;
  flatbuffers::uoffset_t start_;
  void add_name(flatbuffers::Offset<flatbuffers::String> name) {
    fbb_.AddOffset(TosaBasicBlock::VT_NAME, name);
  }
  void add_operators(flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<tosa::TosaOperator>>> operators) {
    fbb_.AddOffset(TosaBasicBlock::VT_OPERATORS, operators);
  }
  void add_tensors(flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<tosa::TosaTensor>>> tensors) {
    fbb_.AddOffset(TosaBasicBlock::VT_TENSORS, tensors);
  }
  void add_inputs(flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>>> inputs) {
    fbb_.AddOffset(TosaBasicBlock::VT_INPUTS, inputs);
  }
  void add_outputs(flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>>> outputs) {
    fbb_.AddOffset(TosaBasicBlock::VT_OUTPUTS, outputs);
  }
  explicit TosaBasicBlockBuilder(flatbuffers::FlatBufferBuilder &_fbb)
        : fbb_(_fbb) {
    start_ = fbb_.StartTable();
  }
  TosaBasicBlockBuilder &operator=(const TosaBasicBlockBuilder &);
  flatbuffers::Offset<TosaBasicBlock> Finish() {
    const auto end = fbb_.EndTable(start_);
    auto o = flatbuffers::Offset<TosaBasicBlock>(end);
    return o;
  }
};

inline flatbuffers::Offset<TosaBasicBlock> CreateTosaBasicBlock(
    flatbuffers::FlatBufferBuilder &_fbb,
    flatbuffers::Offset<flatbuffers::String> name = 0,
    flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<tosa::TosaOperator>>> operators = 0,
    flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<tosa::TosaTensor>>> tensors = 0,
    flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>>> inputs = 0,
    flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>>> outputs = 0) {
  TosaBasicBlockBuilder builder_(_fbb);
  builder_.add_outputs(outputs);
  builder_.add_inputs(inputs);
  builder_.add_tensors(tensors);
  builder_.add_operators(operators);
  builder_.add_name(name);
  return builder_.Finish();
}

inline flatbuffers::Offset<TosaBasicBlock> CreateTosaBasicBlockDirect(
    flatbuffers::FlatBufferBuilder &_fbb,
    const char *name = nullptr,
    const std::vector<flatbuffers::Offset<tosa::TosaOperator>> *operators = nullptr,
    const std::vector<flatbuffers::Offset<tosa::TosaTensor>> *tensors = nullptr,
    const std::vector<flatbuffers::Offset<flatbuffers::String>> *inputs = nullptr,
    const std::vector<flatbuffers::Offset<flatbuffers::String>> *outputs = nullptr) {
  auto name__ = name ? _fbb.CreateString(name) : 0;
  auto operators__ = operators ? _fbb.CreateVector<flatbuffers::Offset<tosa::TosaOperator>>(*operators) : 0;
  auto tensors__ = tensors ? _fbb.CreateVector<flatbuffers::Offset<tosa::TosaTensor>>(*tensors) : 0;
  auto inputs__ = inputs ? _fbb.CreateVector<flatbuffers::Offset<flatbuffers::String>>(*inputs) : 0;
  auto outputs__ = outputs ? _fbb.CreateVector<flatbuffers::Offset<flatbuffers::String>>(*outputs) : 0;
  return tosa::CreateTosaBasicBlock(
      _fbb,
      name__,
      operators__,
      tensors__,
      inputs__,
      outputs__);
}

struct TosaGraph FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
  typedef TosaGraphBuilder Builder;
  enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
    VT_VERSION = 4,
    VT_BLOCKS = 6
  };
  const tosa::Version *version() const {
    return GetPointer<const tosa::Version *>(VT_VERSION);
  }
  const flatbuffers::Vector<flatbuffers::Offset<tosa::TosaBasicBlock>> *blocks() const {
    return GetPointer<const flatbuffers::Vector<flatbuffers::Offset<tosa::TosaBasicBlock>> *>(VT_BLOCKS);
  }
  bool Verify(flatbuffers::Verifier &verifier) const {
    return VerifyTableStart(verifier) &&
           VerifyOffset(verifier, VT_VERSION) &&
           verifier.VerifyTable(version()) &&
           VerifyOffset(verifier, VT_BLOCKS) &&
           verifier.VerifyVector(blocks()) &&
           verifier.VerifyVectorOfTables(blocks()) &&
           verifier.EndTable();
  }
};

struct TosaGraphBuilder {
  typedef TosaGraph Table;
  flatbuffers::FlatBufferBuilder &fbb_;
  flatbuffers::uoffset_t start_;
  void add_version(flatbuffers::Offset<tosa::Version> version) {
    fbb_.AddOffset(TosaGraph::VT_VERSION, version);
  }
  void add_blocks(flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<tosa::TosaBasicBlock>>> blocks) {
    fbb_.AddOffset(TosaGraph::VT_BLOCKS, blocks);
  }
  explicit TosaGraphBuilder(flatbuffers::FlatBufferBuilder &_fbb)
        : fbb_(_fbb) {
    start_ = fbb_.StartTable();
  }
  TosaGraphBuilder &operator=(const TosaGraphBuilder &);
  flatbuffers::Offset<TosaGraph> Finish() {
    const auto end = fbb_.EndTable(start_);
    auto o = flatbuffers::Offset<TosaGraph>(end);
    return o;
  }
};

inline flatbuffers::Offset<TosaGraph> CreateTosaGraph(
    flatbuffers::FlatBufferBuilder &_fbb,
    flatbuffers::Offset<tosa::Version> version = 0,
    flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<tosa::TosaBasicBlock>>> blocks = 0) {
  TosaGraphBuilder builder_(_fbb);
  builder_.add_blocks(blocks);
  builder_.add_version(version);
  return builder_.Finish();
}

inline flatbuffers::Offset<TosaGraph> CreateTosaGraphDirect(
    flatbuffers::FlatBufferBuilder &_fbb,
    flatbuffers::Offset<tosa::Version> version = 0,
    const std::vector<flatbuffers::Offset<tosa::TosaBasicBlock>> *blocks = nullptr) {
  auto blocks__ = blocks ? _fbb.CreateVector<flatbuffers::Offset<tosa::TosaBasicBlock>>(*blocks) : 0;
  return tosa::CreateTosaGraph(
      _fbb,
      version,
      blocks__);
}

inline bool VerifyAttribute(flatbuffers::Verifier &verifier, const void *obj, Attribute type) {
  switch (type) {
    case Attribute_NONE: {
      return true;
    }
    case Attribute_PoolAttribute: {
      auto ptr = reinterpret_cast<const tosa::PoolAttribute *>(obj);
      return verifier.VerifyTable(ptr);
    }
    case Attribute_ConvAttribute: {
      auto ptr = reinterpret_cast<const tosa::ConvAttribute *>(obj);
      return verifier.VerifyTable(ptr);
    }
    case Attribute_TransposeConvAttribute: {
      auto ptr = reinterpret_cast<const tosa::TransposeConvAttribute *>(obj);
      return verifier.VerifyTable(ptr);
    }
    case Attribute_PadAttribute: {
      auto ptr = reinterpret_cast<const tosa::PadAttribute *>(obj);
      return verifier.VerifyTable(ptr);
    }
    case Attribute_AxisAttribute: {
      auto ptr = reinterpret_cast<const tosa::AxisAttribute *>(obj);
      return verifier.VerifyTable(ptr);
    }
    case Attribute_ReshapeAttribute: {
      auto ptr = reinterpret_cast<const tosa::ReshapeAttribute *>(obj);
      return verifier.VerifyTable(ptr);
    }
    case Attribute_SliceAttribute: {
      auto ptr = reinterpret_cast<const tosa::SliceAttribute *>(obj);
      return verifier.VerifyTable(ptr);
    }
    case Attribute_TileAttribute: {
      auto ptr = reinterpret_cast<const tosa::TileAttribute *>(obj);
      return verifier.VerifyTable(ptr);
    }
    case Attribute_ResizeAttribute: {
      auto ptr = reinterpret_cast<const tosa::ResizeAttribute *>(obj);
      return verifier.VerifyTable(ptr);
    }
    case Attribute_ClampAttribute: {
      auto ptr = reinterpret_cast<const tosa::ClampAttribute *>(obj);
      return verifier.VerifyTable(ptr);
    }
    case Attribute_RescaleAttribute: {
      auto ptr = reinterpret_cast<const tosa::RescaleAttribute *>(obj);
      return verifier.VerifyTable(ptr);
    }
    case Attribute_MulAttribute: {
      auto ptr = reinterpret_cast<const tosa::MulAttribute *>(obj);
      return verifier.VerifyTable(ptr);
    }
    case Attribute_ArithmeticRightShiftAttribute: {
      auto ptr = reinterpret_cast<const tosa::ArithmeticRightShiftAttribute *>(obj);
      return verifier.VerifyTable(ptr);
    }
    case Attribute_CondIfAttribute: {
      auto ptr = reinterpret_cast<const tosa::CondIfAttribute *>(obj);
      return verifier.VerifyTable(ptr);
    }
    case Attribute_WhileLoopAttribute: {
      auto ptr = reinterpret_cast<const tosa::WhileLoopAttribute *>(obj);
      return verifier.VerifyTable(ptr);
    }
    case Attribute_TransposeAttribute: {
      auto ptr = reinterpret_cast<const tosa::TransposeAttribute *>(obj);
      return verifier.VerifyTable(ptr);
    }
    case Attribute_TableAttribute: {
      auto ptr = reinterpret_cast<const tosa::TableAttribute *>(obj);
      return verifier.VerifyTable(ptr);
    }
    default: return true;
  }
}

inline bool VerifyAttributeVector(flatbuffers::Verifier &verifier, const flatbuffers::Vector<flatbuffers::Offset<void>> *values, const flatbuffers::Vector<uint8_t> *types) {
  if (!values || !types) return !values && !types;
  if (values->size() != types->size()) return false;
  for (flatbuffers::uoffset_t i = 0; i < values->size(); ++i) {
    if (!VerifyAttribute(
        verifier,  values->Get(i), types->GetEnum<Attribute>(i))) {
      return false;
    }
  }
  return true;
}

inline bool VerifyQuantInfo(flatbuffers::Verifier &verifier, const void *obj, QuantInfo type) {
  switch (type) {
    case QuantInfo_NONE: {
      return true;
    }
    case QuantInfo_UnaryQuantInfo: {
      auto ptr = reinterpret_cast<const tosa::UnaryQuantInfo *>(obj);
      return verifier.VerifyTable(ptr);
    }
    case QuantInfo_ConvQuantInfo: {
      auto ptr = reinterpret_cast<const tosa::ConvQuantInfo *>(obj);
      return verifier.VerifyTable(ptr);
    }
    case QuantInfo_MatMulQuantInfo: {
      auto ptr = reinterpret_cast<const tosa::MatMulQuantInfo *>(obj);
      return verifier.VerifyTable(ptr);
    }
    case QuantInfo_PadQuantInfo: {
      auto ptr = reinterpret_cast<const tosa::PadQuantInfo *>(obj);
      return verifier.VerifyTable(ptr);
    }
    default: return true;
  }
}

inline bool VerifyQuantInfoVector(flatbuffers::Verifier &verifier, const flatbuffers::Vector<flatbuffers::Offset<void>> *values, const flatbuffers::Vector<uint8_t> *types) {
  if (!values || !types) return !values && !types;
  if (values->size() != types->size()) return false;
  for (flatbuffers::uoffset_t i = 0; i < values->size(); ++i) {
    if (!VerifyQuantInfo(
        verifier,  values->Get(i), types->GetEnum<QuantInfo>(i))) {
      return false;
    }
  }
  return true;
}

inline const tosa::TosaGraph *GetTosaGraph(const void *buf) {
  return flatbuffers::GetRoot<tosa::TosaGraph>(buf);
}

inline const tosa::TosaGraph *GetSizePrefixedTosaGraph(const void *buf) {
  return flatbuffers::GetSizePrefixedRoot<tosa::TosaGraph>(buf);
}

inline const char *TosaGraphIdentifier() {
  return "TOSA";
}

inline bool TosaGraphBufferHasIdentifier(const void *buf) {
  return flatbuffers::BufferHasIdentifier(
      buf, TosaGraphIdentifier());
}

inline bool VerifyTosaGraphBuffer(
    flatbuffers::Verifier &verifier) {
  return verifier.VerifyBuffer<tosa::TosaGraph>(TosaGraphIdentifier());
}

inline bool VerifySizePrefixedTosaGraphBuffer(
    flatbuffers::Verifier &verifier) {
  return verifier.VerifySizePrefixedBuffer<tosa::TosaGraph>(TosaGraphIdentifier());
}

inline const char *TosaGraphExtension() {
  return "tosa";
}

inline void FinishTosaGraphBuffer(
    flatbuffers::FlatBufferBuilder &fbb,
    flatbuffers::Offset<tosa::TosaGraph> root) {
  fbb.Finish(root, TosaGraphIdentifier());
}

inline void FinishSizePrefixedTosaGraphBuffer(
    flatbuffers::FlatBufferBuilder &fbb,
    flatbuffers::Offset<tosa::TosaGraph> root) {
  fbb.FinishSizePrefixed(root, TosaGraphIdentifier());
}

}  // namespace tosa

#endif  // FLATBUFFERS_GENERATED_TOSA_TOSA_H_
