// 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"

// Ensure the included flatbuffers.h is the same version as when this file was
// generated, otherwise it may not be compatible.
static_assert(FLATBUFFERS_VERSION_MAJOR == 23 &&
              FLATBUFFERS_VERSION_MINOR == 5 &&
              FLATBUFFERS_VERSION_REVISION == 26,
             "Non-compatible flatbuffers version included");

namespace tosa {

struct PoolAttribute;
struct PoolAttributeBuilder;

struct ConvAttribute;
struct ConvAttributeBuilder;

struct TransposeConvAttribute;
struct TransposeConvAttributeBuilder;

struct PadAttribute;
struct PadAttributeBuilder;

struct AxisAttribute;
struct AxisAttributeBuilder;

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 RFFTAttribute;
struct RFFTAttributeBuilder;

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_SHAPE = 12,
  DType_FP8E4M3 = 13,
  DType_FP8E5M2 = 14,
  DType_MIN = DType_UNKNOWN,
  DType_MAX = DType_FP8E5M2
};

inline const DType (&EnumValuesDType())[15] {
  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,
    DType_SHAPE,
    DType_FP8E4M3,
    DType_FP8E5M2
  };
  return values;
}

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

inline const char *EnumNameDType(DType e) {
  if (::flatbuffers::IsOutRange(e, DType_UNKNOWN, DType_FP8E5M2)) 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_ERF = 71,
  Op_DIM = 72,
  Op_CONST_SHAPE = 73,
  Op_CONCAT_SHAPE = 74,
  Op_ADD_SHAPE = 75,
  Op_SUB_SHAPE = 76,
  Op_MUL_SHAPE = 77,
  Op_DIV_SHAPE = 78,
  Op_COS = 79,
  Op_SIN = 80,
  Op_MIN = Op_UNKNOWN,
  Op_MAX = Op_SIN
};

inline const Op (&EnumValuesOp())[81] {
  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,
    Op_ERF,
    Op_DIM,
    Op_CONST_SHAPE,
    Op_CONCAT_SHAPE,
    Op_ADD_SHAPE,
    Op_SUB_SHAPE,
    Op_MUL_SHAPE,
    Op_DIV_SHAPE,
    Op_COS,
    Op_SIN
  };
  return values;
}

inline const char * const *EnumNamesOp() {
  static const char * const names[82] = {
    "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",
    "ERF",
    "DIM",
    "CONST_SHAPE",
    "CONCAT_SHAPE",
    "ADD_SHAPE",
    "SUB_SHAPE",
    "MUL_SHAPE",
    "DIV_SHAPE",
    "COS",
    "SIN",
    nullptr
  };
  return names;
}

inline const char *EnumNameOp(Op e) {
  if (::flatbuffers::IsOutRange(e, Op_UNKNOWN, Op_SIN)) 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_ResizeAttribute = 6,
  Attribute_ClampAttribute = 7,
  Attribute_RescaleAttribute = 8,
  Attribute_MulAttribute = 9,
  Attribute_ArithmeticRightShiftAttribute = 10,
  Attribute_CondIfAttribute = 11,
  Attribute_WhileLoopAttribute = 12,
  Attribute_TransposeAttribute = 13,
  Attribute_TableAttribute = 14,
  Attribute_MatMulAttribute = 15,
  Attribute_FullyConnectedAttribute = 16,
  Attribute_NegateAttribute = 17,
  Attribute_CustomAttribute = 18,
  Attribute_FFTAttribute = 19,
  Attribute_RFFTAttribute = 20,
  Attribute_MIN = Attribute_NONE,
  Attribute_MAX = Attribute_RFFTAttribute
};

inline const Attribute (&EnumValuesAttribute())[21] {
  static const Attribute values[] = {
    Attribute_NONE,
    Attribute_PoolAttribute,
    Attribute_ConvAttribute,
    Attribute_TransposeConvAttribute,
    Attribute_PadAttribute,
    Attribute_AxisAttribute,
    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,
    Attribute_RFFTAttribute
  };
  return values;
}

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

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

template<> struct AttributeTraits<tosa::RFFTAttribute> {
  static const Attribute enum_value = Attribute_RFFTAttribute;
};

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_ACC_TYPE = 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 acc_type() const {
    return static_cast<tosa::DType>(GetField<uint32_t>(VT_ACC_TYPE, 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_ACC_TYPE, 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_acc_type(tosa::DType acc_type) {
    fbb_.AddElement<uint32_t>(PoolAttribute::VT_ACC_TYPE, static_cast<uint32_t>(acc_type), 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 acc_type = tosa::DType_UNKNOWN) {
  PoolAttributeBuilder builder_(_fbb);
  builder_.add_acc_type(acc_type);
  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 acc_type = 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,
      acc_type);
}

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,
    VT_LOCAL_BOUND = 14
  };
  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 local_bound() const {
    return GetField<uint8_t>(VT_LOCAL_BOUND, 0) != 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) &&
           VerifyField<uint8_t>(verifier, VT_LOCAL_BOUND, 1) &&
           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);
  }
  void add_local_bound(bool local_bound) {
    fbb_.AddElement<uint8_t>(ConvAttribute::VT_LOCAL_BOUND, static_cast<uint8_t>(local_bound), 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,
    bool local_bound = false) {
  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);
  builder_.add_local_bound(local_bound);
  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,
    bool local_bound = false) {
  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,
      local_bound);
}

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,
    VT_LOCAL_BOUND = 14
  };
  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 local_bound() const {
    return GetField<uint8_t>(VT_LOCAL_BOUND, 0) != 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) &&
           VerifyField<uint8_t>(verifier, VT_LOCAL_BOUND, 1) &&
           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);
  }
  void add_local_bound(bool local_bound) {
    fbb_.AddElement<uint8_t>(TransposeConvAttribute::VT_LOCAL_BOUND, static_cast<uint8_t>(local_bound), 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,
    bool local_bound = false) {
  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);
  builder_.add_local_bound(local_bound);
  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,
    bool local_bound = false) {
  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,
      local_bound);
}

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 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,
    VT_INPUT_UNSIGNED = 18,
    VT_OUTPUT_UNSIGNED = 20
  };
  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 input_unsigned() const {
    return GetField<uint8_t>(VT_INPUT_UNSIGNED, 0) != 0;
  }
  bool output_unsigned() const {
    return GetField<uint8_t>(VT_OUTPUT_UNSIGNED, 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) &&
           VerifyField<uint8_t>(verifier, VT_INPUT_UNSIGNED, 1) &&
           VerifyField<uint8_t>(verifier, VT_OUTPUT_UNSIGNED, 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);
  }
  void add_input_unsigned(bool input_unsigned) {
    fbb_.AddElement<uint8_t>(RescaleAttribute::VT_INPUT_UNSIGNED, static_cast<uint8_t>(input_unsigned), 0);
  }
  void add_output_unsigned(bool output_unsigned) {
    fbb_.AddElement<uint8_t>(RescaleAttribute::VT_OUTPUT_UNSIGNED, static_cast<uint8_t>(output_unsigned), 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,
    bool input_unsigned = false,
    bool output_unsigned = 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_output_unsigned(output_unsigned);
  builder_.add_input_unsigned(input_unsigned);
  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,
    bool input_unsigned = false,
    bool output_unsigned = 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,
      input_unsigned,
      output_unsigned);
}

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_GRAPH = 4,
    VT_ELSE_GRAPH = 6
  };
  const ::flatbuffers::String *then_graph() const {
    return GetPointer<const ::flatbuffers::String *>(VT_THEN_GRAPH);
  }
  const ::flatbuffers::String *else_graph() const {
    return GetPointer<const ::flatbuffers::String *>(VT_ELSE_GRAPH);
  }
  bool Verify(::flatbuffers::Verifier &verifier) const {
    return VerifyTableStart(verifier) &&
           VerifyOffset(verifier, VT_THEN_GRAPH) &&
           verifier.VerifyString(then_graph()) &&
           VerifyOffset(verifier, VT_ELSE_GRAPH) &&
           verifier.VerifyString(else_graph()) &&
           verifier.EndTable();
  }
};

struct CondIfAttributeBuilder {
  typedef CondIfAttribute Table;
  ::flatbuffers::FlatBufferBuilder &fbb_;
  ::flatbuffers::uoffset_t start_;
  void add_then_graph(::flatbuffers::Offset<::flatbuffers::String> then_graph) {
    fbb_.AddOffset(CondIfAttribute::VT_THEN_GRAPH, then_graph);
  }
  void add_else_graph(::flatbuffers::Offset<::flatbuffers::String> else_graph) {
    fbb_.AddOffset(CondIfAttribute::VT_ELSE_GRAPH, else_graph);
  }
  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_graph = 0,
    ::flatbuffers::Offset<::flatbuffers::String> else_graph = 0) {
  CondIfAttributeBuilder builder_(_fbb);
  builder_.add_else_graph(else_graph);
  builder_.add_then_graph(then_graph);
  return builder_.Finish();
}

inline ::flatbuffers::Offset<CondIfAttribute> CreateCondIfAttributeDirect(
    ::flatbuffers::FlatBufferBuilder &_fbb,
    const char *then_graph = nullptr,
    const char *else_graph = nullptr) {
  auto then_graph__ = then_graph ? _fbb.CreateString(then_graph) : 0;
  auto else_graph__ = else_graph ? _fbb.CreateString(else_graph) : 0;
  return tosa::CreateCondIfAttribute(
      _fbb,
      then_graph__,
      else_graph__);
}

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

struct WhileLoopAttributeBuilder {
  typedef WhileLoopAttribute Table;
  ::flatbuffers::FlatBufferBuilder &fbb_;
  ::flatbuffers::uoffset_t start_;
  void add_cond_graph(::flatbuffers::Offset<::flatbuffers::String> cond_graph) {
    fbb_.AddOffset(WhileLoopAttribute::VT_COND_GRAPH, cond_graph);
  }
  void add_body_graph(::flatbuffers::Offset<::flatbuffers::String> body_graph) {
    fbb_.AddOffset(WhileLoopAttribute::VT_BODY_GRAPH, body_graph);
  }
  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_graph = 0,
    ::flatbuffers::Offset<::flatbuffers::String> body_graph = 0) {
  WhileLoopAttributeBuilder builder_(_fbb);
  builder_.add_body_graph(body_graph);
  builder_.add_cond_graph(cond_graph);
  return builder_.Finish();
}

inline ::flatbuffers::Offset<WhileLoopAttribute> CreateWhileLoopAttributeDirect(
    ::flatbuffers::FlatBufferBuilder &_fbb,
    const char *cond_graph = nullptr,
    const char *body_graph = nullptr) {
  auto cond_graph__ = cond_graph ? _fbb.CreateString(cond_graph) : 0;
  auto body_graph__ = body_graph ? _fbb.CreateString(body_graph) : 0;
  return tosa::CreateWhileLoopAttribute(
      _fbb,
      cond_graph__,
      body_graph__);
}

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_OPERATOR_NAME = 4,
    VT_DOMAIN_NAME = 6,
    VT_IMPLEMENTATION_ATTRS = 8
  };
  const ::flatbuffers::String *operator_name() const {
    return GetPointer<const ::flatbuffers::String *>(VT_OPERATOR_NAME);
  }
  const ::flatbuffers::String *domain_name() const {
    return GetPointer<const ::flatbuffers::String *>(VT_DOMAIN_NAME);
  }
  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_OPERATOR_NAME) &&
           verifier.VerifyString(operator_name()) &&
           VerifyOffset(verifier, VT_DOMAIN_NAME) &&
           verifier.VerifyString(domain_name()) &&
           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_operator_name(::flatbuffers::Offset<::flatbuffers::String> operator_name) {
    fbb_.AddOffset(CustomAttribute::VT_OPERATOR_NAME, operator_name);
  }
  void add_domain_name(::flatbuffers::Offset<::flatbuffers::String> domain_name) {
    fbb_.AddOffset(CustomAttribute::VT_DOMAIN_NAME, domain_name);
  }
  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> operator_name = 0,
    ::flatbuffers::Offset<::flatbuffers::String> domain_name = 0,
    ::flatbuffers::Offset<::flatbuffers::Vector<uint8_t>> implementation_attrs = 0) {
  CustomAttributeBuilder builder_(_fbb);
  builder_.add_implementation_attrs(implementation_attrs);
  builder_.add_domain_name(domain_name);
  builder_.add_operator_name(operator_name);
  return builder_.Finish();
}

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

struct FFTAttribute FLATBUFFERS_FINAL_CLASS : private ::flatbuffers::Table {
  typedef FFTAttributeBuilder Builder;
  enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
    VT_INVERSE = 4,
    VT_LOCAL_BOUND = 6
  };
  bool inverse() const {
    return GetField<uint8_t>(VT_INVERSE, 0) != 0;
  }
  bool local_bound() const {
    return GetField<uint8_t>(VT_LOCAL_BOUND, 0) != 0;
  }
  bool Verify(::flatbuffers::Verifier &verifier) const {
    return VerifyTableStart(verifier) &&
           VerifyField<uint8_t>(verifier, VT_INVERSE, 1) &&
           VerifyField<uint8_t>(verifier, VT_LOCAL_BOUND, 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);
  }
  void add_local_bound(bool local_bound) {
    fbb_.AddElement<uint8_t>(FFTAttribute::VT_LOCAL_BOUND, static_cast<uint8_t>(local_bound), 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,
    bool local_bound = false) {
  FFTAttributeBuilder builder_(_fbb);
  builder_.add_local_bound(local_bound);
  builder_.add_inverse(inverse);
  return builder_.Finish();
}

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

struct RFFTAttributeBuilder {
  typedef RFFTAttribute Table;
  ::flatbuffers::FlatBufferBuilder &fbb_;
  ::flatbuffers::uoffset_t start_;
  void add_local_bound(bool local_bound) {
    fbb_.AddElement<uint8_t>(RFFTAttribute::VT_LOCAL_BOUND, static_cast<uint8_t>(local_bound), 0);
  }
  explicit RFFTAttributeBuilder(::flatbuffers::FlatBufferBuilder &_fbb)
        : fbb_(_fbb) {
    start_ = fbb_.StartTable();
  }
  ::flatbuffers::Offset<RFFTAttribute> Finish() {
    const auto end = fbb_.EndTable(start_);
    auto o = ::flatbuffers::Offset<RFFTAttribute>(end);
    return o;
  }
};

inline ::flatbuffers::Offset<RFFTAttribute> CreateRFFTAttribute(
    ::flatbuffers::FlatBufferBuilder &_fbb,
    bool local_bound = false) {
  RFFTAttributeBuilder builder_(_fbb);
  builder_.add_local_bound(local_bound);
  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, -1);
  }
  int32_t _minor() const {
    return GetField<int32_t>(VT__MINOR, -1);
  }
  int32_t _patch() const {
    return GetField<int32_t>(VT__PATCH, -1);
  }
  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, -1);
  }
  void add__minor(int32_t _minor) {
    fbb_.AddElement<int32_t>(Version::VT__MINOR, _minor, -1);
  }
  void add__patch(int32_t _patch) {
    fbb_.AddElement<int32_t>(Version::VT__PATCH, _patch, -1);
  }
  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 = -1,
    int32_t _minor = -1,
    int32_t _patch = -1,
    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,
    VT_VARIABLE = 12,
    VT_IS_UNRANKED = 14,
    VT_VARIABLE_NAME = 16
  };
  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 variable() const {
    return GetField<uint8_t>(VT_VARIABLE, 0) != 0;
  }
  bool is_unranked() const {
    return GetField<uint8_t>(VT_IS_UNRANKED, 0) != 0;
  }
  const ::flatbuffers::String *variable_name() const {
    return GetPointer<const ::flatbuffers::String *>(VT_VARIABLE_NAME);
  }
  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()) &&
           VerifyField<uint8_t>(verifier, VT_VARIABLE, 1) &&
           VerifyField<uint8_t>(verifier, VT_IS_UNRANKED, 1) &&
           VerifyOffset(verifier, VT_VARIABLE_NAME) &&
           verifier.VerifyString(variable_name()) &&
           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);
  }
  void add_variable(bool variable) {
    fbb_.AddElement<uint8_t>(TosaTensor::VT_VARIABLE, static_cast<uint8_t>(variable), 0);
  }
  void add_is_unranked(bool is_unranked) {
    fbb_.AddElement<uint8_t>(TosaTensor::VT_IS_UNRANKED, static_cast<uint8_t>(is_unranked), 0);
  }
  void add_variable_name(::flatbuffers::Offset<::flatbuffers::String> variable_name) {
    fbb_.AddOffset(TosaTensor::VT_VARIABLE_NAME, variable_name);
  }
  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,
    bool variable = false,
    bool is_unranked = false,
    ::flatbuffers::Offset<::flatbuffers::String> variable_name = 0) {
  TosaTensorBuilder builder_(_fbb);
  builder_.add_variable_name(variable_name);
  builder_.add_data(data);
  builder_.add_type(type);
  builder_.add_shape(shape);
  builder_.add_name(name);
  builder_.add_is_unranked(is_unranked);
  builder_.add_variable(variable);
  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,
    bool variable = false,
    bool is_unranked = false,
    const char *variable_name = 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;
  auto variable_name__ = variable_name ? _fbb.CreateString(variable_name) : 0;
  return tosa::CreateTosaTensor(
      _fbb,
      name__,
      shape__,
      type,
      data__,
      variable,
      is_unranked,
      variable_name__);
}

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::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 tosa::RFFTAttribute *attribute_as_RFFTAttribute() const {
    return attribute_type() == tosa::Attribute_RFFTAttribute ? static_cast<const tosa::RFFTAttribute *>(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::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();
}

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

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) &&
           VerifyOffsetRequired(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);
    fbb_.Required(o, TosaGraph::VT_VERSION);
    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_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);
    }
    case Attribute_RFFTAttribute: {
      auto ptr = reinterpret_cast<const tosa::RFFTAttribute *>(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_
