// 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 MatMulAttribute;
struct MatMulAttributeBuilder;

struct FullyConnectedAttribute;
struct FullyConnectedAttributeBuilder;

struct NegateAttribute;
struct NegateAttributeBuilder;

struct CustomAttribute;
struct CustomAttributeBuilder;

struct FFTAttribute;
struct FFTAttributeBuilder;

struct Version;
struct VersionBuilder;

struct TosaTensor;
struct TosaTensorBuilder;

struct TosaOperator;
struct TosaOperatorBuilder;

struct TosaBasicBlock;
struct TosaBasicBlockBuilder;

struct TosaRegion;
struct TosaRegionBuilder;

struct TosaGraph;
struct TosaGraphBuilder;

enum DType : uint32_t {
  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_FP32 = 8,
  DType_UINT16 = 9,
  DType_FP16 = 10,
  DType_BF16 = 11,
  DType_MIN = DType_UNKNOWN,
  DType_MAX = DType_BF16
};

inline const DType (&EnumValuesDType())[12] {
  static const DType values[] = {
    DType_UNKNOWN,
    DType_BOOL,
    DType_UINT8,
    DType_INT4,
    DType_INT8,
    DType_INT16,
    DType_INT32,
    DType_INT48,
    DType_FP32,
    DType_UINT16,
    DType_FP16,
    DType_BF16
  };
  return values;
}

inline const char * const *EnumNamesDType() {
  static const char * const names[13] = {
    "UNKNOWN",
    "BOOL",
    "UINT8",
    "INT4",
    "INT8",
    "INT16",
    "INT32",
    "INT48",
    "FP32",
    "UINT16",
    "FP16",
    "BF16",
    nullptr
  };
  return names;
}

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

enum ResizeMode : uint32_t {
  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 : uint32_t {
  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_FFT2D = 69,
  Op_RFFT2D = 70,
  Op_MIN = Op_UNKNOWN,
  Op_MAX = Op_RFFT2D
};

inline const Op (&EnumValuesOp())[71] {
  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,
    Op_FFT2D,
    Op_RFFT2D
  };
  return values;
}

inline const char * const *EnumNamesOp() {
  static const char * const names[72] = {
    "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",
    "FFT2D",
    "RFFT2D",
    nullptr
  };
  return names;
}

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

enum Attribute : uint8_t {
  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_MatMulAttribute = 18,
  Attribute_FullyConnectedAttribute = 19,
  Attribute_NegateAttribute = 20,
  Attribute_CustomAttribute = 21,
  Attribute_FFTAttribute = 22,
  Attribute_MIN = Attribute_NONE,
  Attribute_MAX = Attribute_FFTAttribute
};

inline const Attribute (&EnumValuesAttribute())[23] {
  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,
    Attribute_MatMulAttribute,
    Attribute_FullyConnectedAttribute,
    Attribute_NegateAttribute,
    Attribute_CustomAttribute,
    Attribute_FFTAttribute
  };
  return values;
}

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

inline const char *EnumNameAttribute(Attribute e) {
  if (flatbuffers::IsOutRange(e, Attribute_NONE, Attribute_FFTAttribute)) 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;
};

template<> struct AttributeTraits<tosa::MatMulAttribute> {
  static const Attribute enum_value = Attribute_MatMulAttribute;
};

template<> struct AttributeTraits<tosa::FullyConnectedAttribute> {
  static const Attribute enum_value = Attribute_FullyConnectedAttribute;
};

template<> struct AttributeTraits<tosa::NegateAttribute> {
  static const Attribute enum_value = Attribute_NegateAttribute;
};

template<> struct AttributeTraits<tosa::CustomAttribute> {
  static const Attribute enum_value = Attribute_CustomAttribute;
};

template<> struct AttributeTraits<tosa::FFTAttribute> {
  static const Attribute enum_value = Attribute_FFTAttribute;
};

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);

struct PoolAttribute FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
  typedef PoolAttributeBuilder Builder;
  enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
    VT_PAD = 4,
    VT_KERNEL = 6,
    VT_STRIDE = 8,
    VT_INPUT_ZP = 10,
    VT_OUTPUT_ZP = 12,
    VT_ACCUM_DTYPE = 14
  };
  const flatbuffers::Vector<int32_t> *pad() const {
    return GetPointer<const flatbuffers::Vector<int32_t> *>(VT_PAD);
  }
  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);
  }
  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);
  }
  tosa::DType accum_dtype() const {
    return static_cast<tosa::DType>(GetField<uint32_t>(VT_ACCUM_DTYPE, 0));
  }
  bool Verify(flatbuffers::Verifier &verifier) const {
    return VerifyTableStart(verifier) &&
           VerifyOffset(verifier, VT_PAD) &&
           verifier.VerifyVector(pad()) &&
           VerifyOffset(verifier, VT_KERNEL) &&
           verifier.VerifyVector(kernel()) &&
           VerifyOffset(verifier, VT_STRIDE) &&
           verifier.VerifyVector(stride()) &&
           VerifyField<int32_t>(verifier, VT_INPUT_ZP, 4) &&
           VerifyField<int32_t>(verifier, VT_OUTPUT_ZP, 4) &&
           VerifyField<uint32_t>(verifier, VT_ACCUM_DTYPE, 4) &&
           verifier.EndTable();
  }
};

struct PoolAttributeBuilder {
  typedef PoolAttribute Table;
  flatbuffers::FlatBufferBuilder &fbb_;
  flatbuffers::uoffset_t start_;
  void add_pad(flatbuffers::Offset<flatbuffers::Vector<int32_t>> pad) {
    fbb_.AddOffset(PoolAttribute::VT_PAD, pad);
  }
  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);
  }
  void add_input_zp(int32_t input_zp) {
    fbb_.AddElement<int32_t>(PoolAttribute::VT_INPUT_ZP, input_zp, 0);
  }
  void add_output_zp(int32_t output_zp) {
    fbb_.AddElement<int32_t>(PoolAttribute::VT_OUTPUT_ZP, output_zp, 0);
  }
  void add_accum_dtype(tosa::DType accum_dtype) {
    fbb_.AddElement<uint32_t>(PoolAttribute::VT_ACCUM_DTYPE, static_cast<uint32_t>(accum_dtype), 0);
  }
  explicit PoolAttributeBuilder(flatbuffers::FlatBufferBuilder &_fbb)
        : fbb_(_fbb) {
    start_ = fbb_.StartTable();
  }
  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>> pad = 0,
    flatbuffers::Offset<flatbuffers::Vector<int32_t>> kernel = 0,
    flatbuffers::Offset<flatbuffers::Vector<int32_t>> stride = 0,
    int32_t input_zp = 0,
    int32_t output_zp = 0,
    tosa::DType accum_dtype = tosa::DType_UNKNOWN) {
  PoolAttributeBuilder builder_(_fbb);
  builder_.add_accum_dtype(accum_dtype);
  builder_.add_output_zp(output_zp);
  builder_.add_input_zp(input_zp);
  builder_.add_stride(stride);
  builder_.add_kernel(kernel);
  builder_.add_pad(pad);
  return builder_.Finish();
}

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

struct ConvAttribute FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
  typedef ConvAttributeBuilder Builder;
  enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
    VT_PAD = 4,
    VT_STRIDE = 6,
    VT_DILATION = 8,
    VT_INPUT_ZP = 10,
    VT_WEIGHT_ZP = 12
  };
  const flatbuffers::Vector<int32_t> *pad() const {
    return GetPointer<const flatbuffers::Vector<int32_t> *>(VT_PAD);
  }
  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);
  }
  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) &&
           VerifyOffset(verifier, VT_PAD) &&
           verifier.VerifyVector(pad()) &&
           VerifyOffset(verifier, VT_STRIDE) &&
           verifier.VerifyVector(stride()) &&
           VerifyOffset(verifier, VT_DILATION) &&
           verifier.VerifyVector(dilation()) &&
           VerifyField<int32_t>(verifier, VT_INPUT_ZP, 4) &&
           VerifyField<int32_t>(verifier, VT_WEIGHT_ZP, 4) &&
           verifier.EndTable();
  }
};

struct ConvAttributeBuilder {
  typedef ConvAttribute Table;
  flatbuffers::FlatBufferBuilder &fbb_;
  flatbuffers::uoffset_t start_;
  void add_pad(flatbuffers::Offset<flatbuffers::Vector<int32_t>> pad) {
    fbb_.AddOffset(ConvAttribute::VT_PAD, pad);
  }
  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);
  }
  void add_input_zp(int32_t input_zp) {
    fbb_.AddElement<int32_t>(ConvAttribute::VT_INPUT_ZP, input_zp, 0);
  }
  void add_weight_zp(int32_t weight_zp) {
    fbb_.AddElement<int32_t>(ConvAttribute::VT_WEIGHT_ZP, weight_zp, 0);
  }
  explicit ConvAttributeBuilder(flatbuffers::FlatBufferBuilder &_fbb)
        : fbb_(_fbb) {
    start_ = fbb_.StartTable();
  }
  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>> pad = 0,
    flatbuffers::Offset<flatbuffers::Vector<int32_t>> stride = 0,
    flatbuffers::Offset<flatbuffers::Vector<int32_t>> dilation = 0,
    int32_t input_zp = 0,
    int32_t weight_zp = 0) {
  ConvAttributeBuilder builder_(_fbb);
  builder_.add_weight_zp(weight_zp);
  builder_.add_input_zp(input_zp);
  builder_.add_dilation(dilation);
  builder_.add_stride(stride);
  builder_.add_pad(pad);
  return builder_.Finish();
}

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

struct TransposeConvAttribute FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
  typedef TransposeConvAttributeBuilder Builder;
  enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
    VT_OUT_PAD = 4,
    VT_STRIDE = 6,
    VT_OUTPUT_SHAPE = 8,
    VT_INPUT_ZP = 10,
    VT_WEIGHT_ZP = 12
  };
  const flatbuffers::Vector<int32_t> *out_pad() const {
    return GetPointer<const flatbuffers::Vector<int32_t> *>(VT_OUT_PAD);
  }
  const flatbuffers::Vector<int32_t> *stride() const {
    return GetPointer<const flatbuffers::Vector<int32_t> *>(VT_STRIDE);
  }
  const flatbuffers::Vector<int32_t> *output_shape() const {
    return GetPointer<const flatbuffers::Vector<int32_t> *>(VT_OUTPUT_SHAPE);
  }
  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) &&
           VerifyOffset(verifier, VT_OUT_PAD) &&
           verifier.VerifyVector(out_pad()) &&
           VerifyOffset(verifier, VT_STRIDE) &&
           verifier.VerifyVector(stride()) &&
           VerifyOffset(verifier, VT_OUTPUT_SHAPE) &&
           verifier.VerifyVector(output_shape()) &&
           VerifyField<int32_t>(verifier, VT_INPUT_ZP, 4) &&
           VerifyField<int32_t>(verifier, VT_WEIGHT_ZP, 4) &&
           verifier.EndTable();
  }
};

struct TransposeConvAttributeBuilder {
  typedef TransposeConvAttribute Table;
  flatbuffers::FlatBufferBuilder &fbb_;
  flatbuffers::uoffset_t start_;
  void add_out_pad(flatbuffers::Offset<flatbuffers::Vector<int32_t>> out_pad) {
    fbb_.AddOffset(TransposeConvAttribute::VT_OUT_PAD, out_pad);
  }
  void add_stride(flatbuffers::Offset<flatbuffers::Vector<int32_t>> stride) {
    fbb_.AddOffset(TransposeConvAttribute::VT_STRIDE, stride);
  }
  void add_output_shape(flatbuffers::Offset<flatbuffers::Vector<int32_t>> output_shape) {
    fbb_.AddOffset(TransposeConvAttribute::VT_OUTPUT_SHAPE, output_shape);
  }
  void add_input_zp(int32_t input_zp) {
    fbb_.AddElement<int32_t>(TransposeConvAttribute::VT_INPUT_ZP, input_zp, 0);
  }
  void add_weight_zp(int32_t weight_zp) {
    fbb_.AddElement<int32_t>(TransposeConvAttribute::VT_WEIGHT_ZP, weight_zp, 0);
  }
  explicit TransposeConvAttributeBuilder(flatbuffers::FlatBufferBuilder &_fbb)
        : fbb_(_fbb) {
    start_ = fbb_.StartTable();
  }
  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>> out_pad = 0,
    flatbuffers::Offset<flatbuffers::Vector<int32_t>> stride = 0,
    flatbuffers::Offset<flatbuffers::Vector<int32_t>> output_shape = 0,
    int32_t input_zp = 0,
    int32_t weight_zp = 0) {
  TransposeConvAttributeBuilder builder_(_fbb);
  builder_.add_weight_zp(weight_zp);
  builder_.add_input_zp(input_zp);
  builder_.add_output_shape(output_shape);
  builder_.add_stride(stride);
  builder_.add_out_pad(out_pad);
  return builder_.Finish();
}

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

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);
  }
  const flatbuffers::Vector<uint8_t> *pad_const_fp() const {
    return GetPointer<const flatbuffers::Vector<uint8_t> *>(VT_PAD_CONST_FP);
  }
  bool Verify(flatbuffers::Verifier &verifier) const {
    return VerifyTableStart(verifier) &&
           VerifyOffset(verifier, VT_PADDING) &&
           verifier.VerifyVector(padding()) &&
           VerifyField<int32_t>(verifier, VT_PAD_CONST_INT, 4) &&
           VerifyOffset(verifier, VT_PAD_CONST_FP) &&
           verifier.VerifyVector(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(flatbuffers::Offset<flatbuffers::Vector<uint8_t>> pad_const_fp) {
    fbb_.AddOffset(PadAttribute::VT_PAD_CONST_FP, pad_const_fp);
  }
  explicit PadAttributeBuilder(flatbuffers::FlatBufferBuilder &_fbb)
        : fbb_(_fbb) {
    start_ = fbb_.StartTable();
  }
  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,
    flatbuffers::Offset<flatbuffers::Vector<uint8_t>> pad_const_fp = 0) {
  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,
    const std::vector<uint8_t> *pad_const_fp = nullptr) {
  auto padding__ = padding ? _fbb.CreateVector<int32_t>(*padding) : 0;
  if (pad_const_fp) { _fbb.ForceVectorAlignment(pad_const_fp->size(), sizeof(uint8_t), 8); }
  auto pad_const_fp__ = pad_const_fp ? _fbb.CreateVector<uint8_t>(*pad_const_fp) : 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, 4) &&
           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();
  }
  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_NEW_SHAPE = 4
  };
  const flatbuffers::Vector<int32_t> *new_shape() const {
    return GetPointer<const flatbuffers::Vector<int32_t> *>(VT_NEW_SHAPE);
  }
  bool Verify(flatbuffers::Verifier &verifier) const {
    return VerifyTableStart(verifier) &&
           VerifyOffset(verifier, VT_NEW_SHAPE) &&
           verifier.VerifyVector(new_shape()) &&
           verifier.EndTable();
  }
};

struct ReshapeAttributeBuilder {
  typedef ReshapeAttribute Table;
  flatbuffers::FlatBufferBuilder &fbb_;
  flatbuffers::uoffset_t start_;
  void add_new_shape(flatbuffers::Offset<flatbuffers::Vector<int32_t>> new_shape) {
    fbb_.AddOffset(ReshapeAttribute::VT_NEW_SHAPE, new_shape);
  }
  explicit ReshapeAttributeBuilder(flatbuffers::FlatBufferBuilder &_fbb)
        : fbb_(_fbb) {
    start_ = fbb_.StartTable();
  }
  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>> new_shape = 0) {
  ReshapeAttributeBuilder builder_(_fbb);
  builder_.add_new_shape(new_shape);
  return builder_.Finish();
}

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

struct SliceAttribute FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
  typedef SliceAttributeBuilder Builder;
  enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
    VT_START = 4,
    VT_SIZE = 6
  };
  const flatbuffers::Vector<int32_t> *start() const {
    return GetPointer<const flatbuffers::Vector<int32_t> *>(VT_START);
  }
  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_START) &&
           verifier.VerifyVector(start()) &&
           VerifyOffset(verifier, VT_SIZE) &&
           verifier.VerifyVector(size()) &&
           verifier.EndTable();
  }
};

struct SliceAttributeBuilder {
  typedef SliceAttribute Table;
  flatbuffers::FlatBufferBuilder &fbb_;
  flatbuffers::uoffset_t start_;
  void add_start(flatbuffers::Offset<flatbuffers::Vector<int32_t>> start) {
    fbb_.AddOffset(SliceAttribute::VT_START, start);
  }
  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();
  }
  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>> start = 0,
    flatbuffers::Offset<flatbuffers::Vector<int32_t>> size = 0) {
  SliceAttributeBuilder builder_(_fbb);
  builder_.add_size(size);
  builder_.add_start(start);
  return builder_.Finish();
}

inline flatbuffers::Offset<SliceAttribute> CreateSliceAttributeDirect(
    flatbuffers::FlatBufferBuilder &_fbb,
    const std::vector<int32_t> *start = nullptr,
    const std::vector<int32_t> *size = nullptr) {
  auto start__ = start ? _fbb.CreateVector<int32_t>(*start) : 0;
  auto size__ = size ? _fbb.CreateVector<int32_t>(*size) : 0;
  return tosa::CreateSliceAttribute(
      _fbb,
      start__,
      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();
  }
  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_SCALE = 4,
    VT_OFFSET = 6,
    VT_BORDER = 8,
    VT_MODE = 10
  };
  const flatbuffers::Vector<int16_t> *scale() const {
    return GetPointer<const flatbuffers::Vector<int16_t> *>(VT_SCALE);
  }
  const flatbuffers::Vector<int16_t> *offset() const {
    return GetPointer<const flatbuffers::Vector<int16_t> *>(VT_OFFSET);
  }
  const flatbuffers::Vector<int16_t> *border() const {
    return GetPointer<const flatbuffers::Vector<int16_t> *>(VT_BORDER);
  }
  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_SCALE) &&
           verifier.VerifyVector(scale()) &&
           VerifyOffset(verifier, VT_OFFSET) &&
           verifier.VerifyVector(offset()) &&
           VerifyOffset(verifier, VT_BORDER) &&
           verifier.VerifyVector(border()) &&
           VerifyField<uint32_t>(verifier, VT_MODE, 4) &&
           verifier.EndTable();
  }
};

struct ResizeAttributeBuilder {
  typedef ResizeAttribute Table;
  flatbuffers::FlatBufferBuilder &fbb_;
  flatbuffers::uoffset_t start_;
  void add_scale(flatbuffers::Offset<flatbuffers::Vector<int16_t>> scale) {
    fbb_.AddOffset(ResizeAttribute::VT_SCALE, scale);
  }
  void add_offset(flatbuffers::Offset<flatbuffers::Vector<int16_t>> offset) {
    fbb_.AddOffset(ResizeAttribute::VT_OFFSET, offset);
  }
  void add_border(flatbuffers::Offset<flatbuffers::Vector<int16_t>> border) {
    fbb_.AddOffset(ResizeAttribute::VT_BORDER, border);
  }
  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();
  }
  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<int16_t>> scale = 0,
    flatbuffers::Offset<flatbuffers::Vector<int16_t>> offset = 0,
    flatbuffers::Offset<flatbuffers::Vector<int16_t>> border = 0,
    tosa::ResizeMode mode = tosa::ResizeMode_UNKNOWN) {
  ResizeAttributeBuilder builder_(_fbb);
  builder_.add_mode(mode);
  builder_.add_border(border);
  builder_.add_offset(offset);
  builder_.add_scale(scale);
  return builder_.Finish();
}

inline flatbuffers::Offset<ResizeAttribute> CreateResizeAttributeDirect(
    flatbuffers::FlatBufferBuilder &_fbb,
    const std::vector<int16_t> *scale = nullptr,
    const std::vector<int16_t> *offset = nullptr,
    const std::vector<int16_t> *border = nullptr,
    tosa::ResizeMode mode = tosa::ResizeMode_UNKNOWN) {
  auto scale__ = scale ? _fbb.CreateVector<int16_t>(*scale) : 0;
  auto offset__ = offset ? _fbb.CreateVector<int16_t>(*offset) : 0;
  auto border__ = border ? _fbb.CreateVector<int16_t>(*border) : 0;
  return tosa::CreateResizeAttribute(
      _fbb,
      scale__,
      offset__,
      border__,
      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);
  }
  const flatbuffers::Vector<uint8_t> *min_fp() const {
    return GetPointer<const flatbuffers::Vector<uint8_t> *>(VT_MIN_FP);
  }
  const flatbuffers::Vector<uint8_t> *max_fp() const {
    return GetPointer<const flatbuffers::Vector<uint8_t> *>(VT_MAX_FP);
  }
  bool Verify(flatbuffers::Verifier &verifier) const {
    return VerifyTableStart(verifier) &&
           VerifyField<int32_t>(verifier, VT_MIN_INT, 4) &&
           VerifyField<int32_t>(verifier, VT_MAX_INT, 4) &&
           VerifyOffset(verifier, VT_MIN_FP) &&
           verifier.VerifyVector(min_fp()) &&
           VerifyOffset(verifier, VT_MAX_FP) &&
           verifier.VerifyVector(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(flatbuffers::Offset<flatbuffers::Vector<uint8_t>> min_fp) {
    fbb_.AddOffset(ClampAttribute::VT_MIN_FP, min_fp);
  }
  void add_max_fp(flatbuffers::Offset<flatbuffers::Vector<uint8_t>> max_fp) {
    fbb_.AddOffset(ClampAttribute::VT_MAX_FP, max_fp);
  }
  explicit ClampAttributeBuilder(flatbuffers::FlatBufferBuilder &_fbb)
        : fbb_(_fbb) {
    start_ = fbb_.StartTable();
  }
  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,
    flatbuffers::Offset<flatbuffers::Vector<uint8_t>> min_fp = 0,
    flatbuffers::Offset<flatbuffers::Vector<uint8_t>> max_fp = 0) {
  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();
}

inline flatbuffers::Offset<ClampAttribute> CreateClampAttributeDirect(
    flatbuffers::FlatBufferBuilder &_fbb,
    int32_t min_int = 0,
    int32_t max_int = 0,
    const std::vector<uint8_t> *min_fp = nullptr,
    const std::vector<uint8_t> *max_fp = nullptr) {
  if (min_fp) { _fbb.ForceVectorAlignment(min_fp->size(), sizeof(uint8_t), 8); }
  auto min_fp__ = min_fp ? _fbb.CreateVector<uint8_t>(*min_fp) : 0;
  if (max_fp) { _fbb.ForceVectorAlignment(max_fp->size(), sizeof(uint8_t), 8); }
  auto max_fp__ = max_fp ? _fbb.CreateVector<uint8_t>(*max_fp) : 0;
  return tosa::CreateClampAttribute(
      _fbb,
      min_int,
      max_int,
      min_fp__,
      max_fp__);
}

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, 4) &&
           VerifyField<int32_t>(verifier, VT_OUTPUT_ZP, 4) &&
           VerifyOffset(verifier, VT_MULTIPLIER) &&
           verifier.VerifyVector(multiplier()) &&
           VerifyOffset(verifier, VT_SHIFT) &&
           verifier.VerifyVector(shift()) &&
           VerifyField<uint8_t>(verifier, VT_SCALE32, 1) &&
           VerifyField<uint8_t>(verifier, VT_DOUBLE_ROUND, 1) &&
           VerifyField<uint8_t>(verifier, VT_PER_CHANNEL, 1) &&
           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();
  }
  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, 4) &&
           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();
  }
  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, 1) &&
           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();
  }
  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();
  }
  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();
  }
  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_PERMS = 4
  };
  const flatbuffers::Vector<int32_t> *perms() const {
    return GetPointer<const flatbuffers::Vector<int32_t> *>(VT_PERMS);
  }
  bool Verify(flatbuffers::Verifier &verifier) const {
    return VerifyTableStart(verifier) &&
           VerifyOffset(verifier, VT_PERMS) &&
           verifier.VerifyVector(perms()) &&
           verifier.EndTable();
  }
};

struct TransposeAttributeBuilder {
  typedef TransposeAttribute Table;
  flatbuffers::FlatBufferBuilder &fbb_;
  flatbuffers::uoffset_t start_;
  void add_perms(flatbuffers::Offset<flatbuffers::Vector<int32_t>> perms) {
    fbb_.AddOffset(TransposeAttribute::VT_PERMS, perms);
  }
  explicit TransposeAttributeBuilder(flatbuffers::FlatBufferBuilder &_fbb)
        : fbb_(_fbb) {
    start_ = fbb_.StartTable();
  }
  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>> perms = 0) {
  TransposeAttributeBuilder builder_(_fbb);
  builder_.add_perms(perms);
  return builder_.Finish();
}

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

struct TableAttribute FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
  typedef TableAttributeBuilder Builder;
  enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
    VT_TABLE = 4
  };
  const flatbuffers::Vector<int16_t> *table() const {
    return GetPointer<const flatbuffers::Vector<int16_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<int16_t>> table) {
    fbb_.AddOffset(TableAttribute::VT_TABLE, table);
  }
  explicit TableAttributeBuilder(flatbuffers::FlatBufferBuilder &_fbb)
        : fbb_(_fbb) {
    start_ = fbb_.StartTable();
  }
  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<int16_t>> table = 0) {
  TableAttributeBuilder builder_(_fbb);
  builder_.add_table(table);
  return builder_.Finish();
}

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

struct MatMulAttribute FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
  typedef MatMulAttributeBuilder 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, 4) &&
           VerifyField<int32_t>(verifier, VT_B_ZP, 4) &&
           verifier.EndTable();
  }
};

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

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

struct FullyConnectedAttribute FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
  typedef FullyConnectedAttributeBuilder 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, 4) &&
           VerifyField<int32_t>(verifier, VT_WEIGHT_ZP, 4) &&
           verifier.EndTable();
  }
};

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

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

struct NegateAttribute FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
  typedef NegateAttributeBuilder Builder;
  enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
    VT_INPUT1_ZP = 4,
    VT_OUTPUT_ZP = 6
  };
  int32_t input1_zp() const {
    return GetField<int32_t>(VT_INPUT1_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_INPUT1_ZP, 4) &&
           VerifyField<int32_t>(verifier, VT_OUTPUT_ZP, 4) &&
           verifier.EndTable();
  }
};

struct NegateAttributeBuilder {
  typedef NegateAttribute Table;
  flatbuffers::FlatBufferBuilder &fbb_;
  flatbuffers::uoffset_t start_;
  void add_input1_zp(int32_t input1_zp) {
    fbb_.AddElement<int32_t>(NegateAttribute::VT_INPUT1_ZP, input1_zp, 0);
  }
  void add_output_zp(int32_t output_zp) {
    fbb_.AddElement<int32_t>(NegateAttribute::VT_OUTPUT_ZP, output_zp, 0);
  }
  explicit NegateAttributeBuilder(flatbuffers::FlatBufferBuilder &_fbb)
        : fbb_(_fbb) {
    start_ = fbb_.StartTable();
  }
  flatbuffers::Offset<NegateAttribute> Finish() {
    const auto end = fbb_.EndTable(start_);
    auto o = flatbuffers::Offset<NegateAttribute>(end);
    return o;
  }
};

inline flatbuffers::Offset<NegateAttribute> CreateNegateAttribute(
    flatbuffers::FlatBufferBuilder &_fbb,
    int32_t input1_zp = 0,
    int32_t output_zp = 0) {
  NegateAttributeBuilder builder_(_fbb);
  builder_.add_output_zp(output_zp);
  builder_.add_input1_zp(input1_zp);
  return builder_.Finish();
}

struct CustomAttribute FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
  typedef CustomAttributeBuilder Builder;
  enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
    VT_IDENTIFIER = 4,
    VT_CONFIG = 6,
    VT_IMPLEMENTATION_ATTRS = 8
  };
  const flatbuffers::String *identifier() const {
    return GetPointer<const flatbuffers::String *>(VT_IDENTIFIER);
  }
  const flatbuffers::String *config() const {
    return GetPointer<const flatbuffers::String *>(VT_CONFIG);
  }
  const flatbuffers::Vector<uint8_t> *implementation_attrs() const {
    return GetPointer<const flatbuffers::Vector<uint8_t> *>(VT_IMPLEMENTATION_ATTRS);
  }
  bool Verify(flatbuffers::Verifier &verifier) const {
    return VerifyTableStart(verifier) &&
           VerifyOffset(verifier, VT_IDENTIFIER) &&
           verifier.VerifyString(identifier()) &&
           VerifyOffset(verifier, VT_CONFIG) &&
           verifier.VerifyString(config()) &&
           VerifyOffset(verifier, VT_IMPLEMENTATION_ATTRS) &&
           verifier.VerifyVector(implementation_attrs()) &&
           verifier.EndTable();
  }
};

struct CustomAttributeBuilder {
  typedef CustomAttribute Table;
  flatbuffers::FlatBufferBuilder &fbb_;
  flatbuffers::uoffset_t start_;
  void add_identifier(flatbuffers::Offset<flatbuffers::String> identifier) {
    fbb_.AddOffset(CustomAttribute::VT_IDENTIFIER, identifier);
  }
  void add_config(flatbuffers::Offset<flatbuffers::String> config) {
    fbb_.AddOffset(CustomAttribute::VT_CONFIG, config);
  }
  void add_implementation_attrs(flatbuffers::Offset<flatbuffers::Vector<uint8_t>> implementation_attrs) {
    fbb_.AddOffset(CustomAttribute::VT_IMPLEMENTATION_ATTRS, implementation_attrs);
  }
  explicit CustomAttributeBuilder(flatbuffers::FlatBufferBuilder &_fbb)
        : fbb_(_fbb) {
    start_ = fbb_.StartTable();
  }
  flatbuffers::Offset<CustomAttribute> Finish() {
    const auto end = fbb_.EndTable(start_);
    auto o = flatbuffers::Offset<CustomAttribute>(end);
    return o;
  }
};

inline flatbuffers::Offset<CustomAttribute> CreateCustomAttribute(
    flatbuffers::FlatBufferBuilder &_fbb,
    flatbuffers::Offset<flatbuffers::String> identifier = 0,
    flatbuffers::Offset<flatbuffers::String> config = 0,
    flatbuffers::Offset<flatbuffers::Vector<uint8_t>> implementation_attrs = 0) {
  CustomAttributeBuilder builder_(_fbb);
  builder_.add_implementation_attrs(implementation_attrs);
  builder_.add_config(config);
  builder_.add_identifier(identifier);
  return builder_.Finish();
}

inline flatbuffers::Offset<CustomAttribute> CreateCustomAttributeDirect(
    flatbuffers::FlatBufferBuilder &_fbb,
    const char *identifier = nullptr,
    const char *config = nullptr,
    const std::vector<uint8_t> *implementation_attrs = nullptr) {
  auto identifier__ = identifier ? _fbb.CreateString(identifier) : 0;
  auto config__ = config ? _fbb.CreateString(config) : 0;
  auto implementation_attrs__ = implementation_attrs ? _fbb.CreateVector<uint8_t>(*implementation_attrs) : 0;
  return tosa::CreateCustomAttribute(
      _fbb,
      identifier__,
      config__,
      implementation_attrs__);
}

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

struct FFTAttributeBuilder {
  typedef FFTAttribute Table;
  flatbuffers::FlatBufferBuilder &fbb_;
  flatbuffers::uoffset_t start_;
  void add_inverse(bool inverse) {
    fbb_.AddElement<uint8_t>(FFTAttribute::VT_INVERSE, static_cast<uint8_t>(inverse), 0);
  }
  explicit FFTAttributeBuilder(flatbuffers::FlatBufferBuilder &_fbb)
        : fbb_(_fbb) {
    start_ = fbb_.StartTable();
  }
  flatbuffers::Offset<FFTAttribute> Finish() {
    const auto end = fbb_.EndTable(start_);
    auto o = flatbuffers::Offset<FFTAttribute>(end);
    return o;
  }
};

inline flatbuffers::Offset<FFTAttribute> CreateFFTAttribute(
    flatbuffers::FlatBufferBuilder &_fbb,
    bool inverse = false) {
  FFTAttributeBuilder builder_(_fbb);
  builder_.add_inverse(inverse);
  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, 51);
  }
  int32_t _patch() const {
    return GetField<int32_t>(VT__PATCH, 0);
  }
  bool _draft() const {
    return GetField<uint8_t>(VT__DRAFT, 1) != 0;
  }
  bool Verify(flatbuffers::Verifier &verifier) const {
    return VerifyTableStart(verifier) &&
           VerifyField<int32_t>(verifier, VT__MAJOR, 4) &&
           VerifyField<int32_t>(verifier, VT__MINOR, 4) &&
           VerifyField<int32_t>(verifier, VT__PATCH, 4) &&
           VerifyField<uint8_t>(verifier, VT__DRAFT, 1) &&
           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, 51);
  }
  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), 1);
  }
  explicit VersionBuilder(flatbuffers::FlatBufferBuilder &_fbb)
        : fbb_(_fbb) {
    start_ = fbb_.StartTable();
  }
  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 = 51,
    int32_t _patch = 0,
    bool _draft = true) {
  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, 4) &&
           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();
  }
  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
  };
  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 tosa::MatMulAttribute *attribute_as_MatMulAttribute() const {
    return attribute_type() == tosa::Attribute_MatMulAttribute ? static_cast<const tosa::MatMulAttribute *>(attribute()) : nullptr;
  }
  const tosa::FullyConnectedAttribute *attribute_as_FullyConnectedAttribute() const {
    return attribute_type() == tosa::Attribute_FullyConnectedAttribute ? static_cast<const tosa::FullyConnectedAttribute *>(attribute()) : nullptr;
  }
  const tosa::NegateAttribute *attribute_as_NegateAttribute() const {
    return attribute_type() == tosa::Attribute_NegateAttribute ? static_cast<const tosa::NegateAttribute *>(attribute()) : nullptr;
  }
  const tosa::CustomAttribute *attribute_as_CustomAttribute() const {
    return attribute_type() == tosa::Attribute_CustomAttribute ? static_cast<const tosa::CustomAttribute *>(attribute()) : nullptr;
  }
  const tosa::FFTAttribute *attribute_as_FFTAttribute() const {
    return attribute_type() == tosa::Attribute_FFTAttribute ? static_cast<const tosa::FFTAttribute *>(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);
  }
  bool Verify(flatbuffers::Verifier &verifier) const {
    return VerifyTableStart(verifier) &&
           VerifyField<uint32_t>(verifier, VT_OP, 4) &&
           VerifyField<uint8_t>(verifier, VT_ATTRIBUTE_TYPE, 1) &&
           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()) &&
           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::MatMulAttribute *TosaOperator::attribute_as<tosa::MatMulAttribute>() const {
  return attribute_as_MatMulAttribute();
}

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

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

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

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

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);
  }
  explicit TosaOperatorBuilder(flatbuffers::FlatBufferBuilder &_fbb)
        : fbb_(_fbb) {
    start_ = fbb_.StartTable();
  }
  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) {
  TosaOperatorBuilder builder_(_fbb);
  builder_.add_outputs(outputs);
  builder_.add_inputs(inputs);
  builder_.add_attribute(attribute);
  builder_.add_op(op);
  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) {
  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__);
}

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();
  }
  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 TosaRegion FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
  typedef TosaRegionBuilder Builder;
  enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
    VT_NAME = 4,
    VT_BLOCKS = 6
  };
  const flatbuffers::String *name() const {
    return GetPointer<const flatbuffers::String *>(VT_NAME);
  }
  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_NAME) &&
           verifier.VerifyString(name()) &&
           VerifyOffset(verifier, VT_BLOCKS) &&
           verifier.VerifyVector(blocks()) &&
           verifier.VerifyVectorOfTables(blocks()) &&
           verifier.EndTable();
  }
};

struct TosaRegionBuilder {
  typedef TosaRegion Table;
  flatbuffers::FlatBufferBuilder &fbb_;
  flatbuffers::uoffset_t start_;
  void add_name(flatbuffers::Offset<flatbuffers::String> name) {
    fbb_.AddOffset(TosaRegion::VT_NAME, name);
  }
  void add_blocks(flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<tosa::TosaBasicBlock>>> blocks) {
    fbb_.AddOffset(TosaRegion::VT_BLOCKS, blocks);
  }
  explicit TosaRegionBuilder(flatbuffers::FlatBufferBuilder &_fbb)
        : fbb_(_fbb) {
    start_ = fbb_.StartTable();
  }
  flatbuffers::Offset<TosaRegion> Finish() {
    const auto end = fbb_.EndTable(start_);
    auto o = flatbuffers::Offset<TosaRegion>(end);
    return o;
  }
};

inline flatbuffers::Offset<TosaRegion> CreateTosaRegion(
    flatbuffers::FlatBufferBuilder &_fbb,
    flatbuffers::Offset<flatbuffers::String> name = 0,
    flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<tosa::TosaBasicBlock>>> blocks = 0) {
  TosaRegionBuilder builder_(_fbb);
  builder_.add_blocks(blocks);
  builder_.add_name(name);
  return builder_.Finish();
}

inline flatbuffers::Offset<TosaRegion> CreateTosaRegionDirect(
    flatbuffers::FlatBufferBuilder &_fbb,
    const char *name = nullptr,
    const std::vector<flatbuffers::Offset<tosa::TosaBasicBlock>> *blocks = nullptr) {
  auto name__ = name ? _fbb.CreateString(name) : 0;
  auto blocks__ = blocks ? _fbb.CreateVector<flatbuffers::Offset<tosa::TosaBasicBlock>>(*blocks) : 0;
  return tosa::CreateTosaRegion(
      _fbb,
      name__,
      blocks__);
}

struct TosaGraph FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
  typedef TosaGraphBuilder Builder;
  enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
    VT_VERSION = 4,
    VT_REGIONS = 6
  };
  const tosa::Version *version() const {
    return GetPointer<const tosa::Version *>(VT_VERSION);
  }
  const flatbuffers::Vector<flatbuffers::Offset<tosa::TosaRegion>> *regions() const {
    return GetPointer<const flatbuffers::Vector<flatbuffers::Offset<tosa::TosaRegion>> *>(VT_REGIONS);
  }
  bool Verify(flatbuffers::Verifier &verifier) const {
    return VerifyTableStart(verifier) &&
           VerifyOffset(verifier, VT_VERSION) &&
           verifier.VerifyTable(version()) &&
           VerifyOffset(verifier, VT_REGIONS) &&
           verifier.VerifyVector(regions()) &&
           verifier.VerifyVectorOfTables(regions()) &&
           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_regions(flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<tosa::TosaRegion>>> regions) {
    fbb_.AddOffset(TosaGraph::VT_REGIONS, regions);
  }
  explicit TosaGraphBuilder(flatbuffers::FlatBufferBuilder &_fbb)
        : fbb_(_fbb) {
    start_ = fbb_.StartTable();
  }
  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::TosaRegion>>> regions = 0) {
  TosaGraphBuilder builder_(_fbb);
  builder_.add_regions(regions);
  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::TosaRegion>> *regions = nullptr) {
  auto regions__ = regions ? _fbb.CreateVector<flatbuffers::Offset<tosa::TosaRegion>>(*regions) : 0;
  return tosa::CreateTosaGraph(
      _fbb,
      version,
      regions__);
}

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);
    }
    case Attribute_MatMulAttribute: {
      auto ptr = reinterpret_cast<const tosa::MatMulAttribute *>(obj);
      return verifier.VerifyTable(ptr);
    }
    case Attribute_FullyConnectedAttribute: {
      auto ptr = reinterpret_cast<const tosa::FullyConnectedAttribute *>(obj);
      return verifier.VerifyTable(ptr);
    }
    case Attribute_NegateAttribute: {
      auto ptr = reinterpret_cast<const tosa::NegateAttribute *>(obj);
      return verifier.VerifyTable(ptr);
    }
    case Attribute_CustomAttribute: {
      auto ptr = reinterpret_cast<const tosa::CustomAttribute *>(obj);
      return verifier.VerifyTable(ptr);
    }
    case Attribute_FFTAttribute: {
      auto ptr = reinterpret_cast<const tosa::FFTAttribute *>(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 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 SizePrefixedTosaGraphBufferHasIdentifier(const void *buf) {
  return flatbuffers::BufferHasIdentifier(
      buf, TosaGraphIdentifier(), true);
}

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_
