// 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 ReshapeAttribute;
struct ReshapeAttributeBuilder;

struct SliceAttribute;
struct SliceAttributeBuilder;

struct TileAttribute;
struct TileAttributeBuilder;

struct ResizeAttribute;
struct ResizeAttributeBuilder;

struct ClampAttribute;
struct ClampAttributeBuilder;

struct RescaleAttribute;
struct RescaleAttributeBuilder;

struct MulAttribute;
struct MulAttributeBuilder;

struct ArithmeticRightShiftAttribute;
struct ArithmeticRightShiftAttributeBuilder;

struct CondIfAttribute;
struct CondIfAttributeBuilder;

struct WhileLoopAttribute;
struct WhileLoopAttributeBuilder;

struct TransposeAttribute;
struct TransposeAttributeBuilder;

struct TableAttribute;
struct TableAttributeBuilder;

struct MatMulAttribute;
struct MatMulAttributeBuilder;

struct FullyConnectedAttribute;
struct FullyConnectedAttributeBuilder;

struct NegateAttribute;
struct NegateAttributeBuilder;

struct CustomAttribute;
struct CustomAttributeBuilder;

struct FFTAttribute;
struct FFTAttributeBuilder;

struct 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_ReshapeAttribute = 6,
  Attribute_SliceAttribute = 7,
  Attribute_TileAttribute = 8,
  Attribute_ResizeAttribute = 9,
  Attribute_ClampAttribute = 10,
  Attribute_RescaleAttribute = 11,
  Attribute_MulAttribute = 12,
  Attribute_ArithmeticRightShiftAttribute = 13,
  Attribute_CondIfAttribute = 14,
  Attribute_WhileLoopAttribute = 15,
  Attribute_TransposeAttribute = 16,
  Attribute_TableAttribute = 17,
  Attribute_MatMulAttribute = 18,
  Attribute_FullyConnectedAttribute = 19,
  Attribute_NegateAttribute = 20,
  Attribute_CustomAttribute = 21,
  Attribute_FFTAttribute = 22,
  Attribute_RFFTAttribute = 23,
  Attribute_MIN = Attribute_NONE,
  Attribute_MAX = Attribute_RFFTAttribute
};

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

inline const char * const *EnumNamesAttribute() {
  static const char * const names[25] = {
    "NONE",
    "PoolAttribute",
    "ConvAttribute",
    "TransposeConvAttribute",
    "PadAttribute",
    "AxisAttribute",
    "ReshapeAttribute",
    "SliceAttribute",
    "TileAttribute",
    "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::ReshapeAttribute> {
  static const Attribute enum_value = Attribute_ReshapeAttribute;
};

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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_ACCUM_DTYPE = 14
  };
  const ::flatbuffers::Vector<int32_t> *pad() const {
    return GetPointer<const ::flatbuffers::Vector<int32_t> *>(VT_PAD);
  }
  const ::flatbuffers::Vector<int32_t> *kernel() const {
    return GetPointer<const ::flatbuffers::Vector<int32_t> *>(VT_KERNEL);
  }
  const ::flatbuffers::Vector<int32_t> *stride() const {
    return GetPointer<const ::flatbuffers::Vector<int32_t> *>(VT_STRIDE);
  }
  int32_t input_zp() const {
    return GetField<int32_t>(VT_INPUT_ZP, 0);
  }
  int32_t output_zp() const {
    return GetField<int32_t>(VT_OUTPUT_ZP, 0);
  }
  tosa::DType accum_dtype() const {
    return static_cast<tosa::DType>(GetField<uint32_t>(VT_ACCUM_DTYPE, 0));
  }
  bool Verify(::flatbuffers::Verifier &verifier) const {
    return VerifyTableStart(verifier) &&
           VerifyOffset(verifier, VT_PAD) &&
           verifier.VerifyVector(pad()) &&
           VerifyOffset(verifier, VT_KERNEL) &&
           verifier.VerifyVector(kernel()) &&
           VerifyOffset(verifier, VT_STRIDE) &&
           verifier.VerifyVector(stride()) &&
           VerifyField<int32_t>(verifier, VT_INPUT_ZP, 4) &&
           VerifyField<int32_t>(verifier, VT_OUTPUT_ZP, 4) &&
           VerifyField<uint32_t>(verifier, VT_ACCUM_DTYPE, 4) &&
           verifier.EndTable();
  }
};

struct PoolAttributeBuilder {
  typedef PoolAttribute Table;
  ::flatbuffers::FlatBufferBuilder &fbb_;
  ::flatbuffers::uoffset_t start_;
  void add_pad(::flatbuffers::Offset<::flatbuffers::Vector<int32_t>> pad) {
    fbb_.AddOffset(PoolAttribute::VT_PAD, pad);
  }
  void add_kernel(::flatbuffers::Offset<::flatbuffers::Vector<int32_t>> kernel) {
    fbb_.AddOffset(PoolAttribute::VT_KERNEL, kernel);
  }
  void add_stride(::flatbuffers::Offset<::flatbuffers::Vector<int32_t>> stride) {
    fbb_.AddOffset(PoolAttribute::VT_STRIDE, stride);
  }
  void add_input_zp(int32_t input_zp) {
    fbb_.AddElement<int32_t>(PoolAttribute::VT_INPUT_ZP, input_zp, 0);
  }
  void add_output_zp(int32_t output_zp) {
    fbb_.AddElement<int32_t>(PoolAttribute::VT_OUTPUT_ZP, output_zp, 0);
  }
  void add_accum_dtype(tosa::DType accum_dtype) {
    fbb_.AddElement<uint32_t>(PoolAttribute::VT_ACCUM_DTYPE, static_cast<uint32_t>(accum_dtype), 0);
  }
  explicit PoolAttributeBuilder(::flatbuffers::FlatBufferBuilder &_fbb)
        : fbb_(_fbb) {
    start_ = fbb_.StartTable();
  }
  ::flatbuffers::Offset<PoolAttribute> Finish() {
    const auto end = fbb_.EndTable(start_);
    auto o = ::flatbuffers::Offset<PoolAttribute>(end);
    return o;
  }
};

inline ::flatbuffers::Offset<PoolAttribute> CreatePoolAttribute(
    ::flatbuffers::FlatBufferBuilder &_fbb,
    ::flatbuffers::Offset<::flatbuffers::Vector<int32_t>> pad = 0,
    ::flatbuffers::Offset<::flatbuffers::Vector<int32_t>> kernel = 0,
    ::flatbuffers::Offset<::flatbuffers::Vector<int32_t>> stride = 0,
    int32_t input_zp = 0,
    int32_t output_zp = 0,
    tosa::DType accum_dtype = tosa::DType_UNKNOWN) {
  PoolAttributeBuilder builder_(_fbb);
  builder_.add_accum_dtype(accum_dtype);
  builder_.add_output_zp(output_zp);
  builder_.add_input_zp(input_zp);
  builder_.add_stride(stride);
  builder_.add_kernel(kernel);
  builder_.add_pad(pad);
  return builder_.Finish();
}

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

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

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

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

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

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

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

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

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

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

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

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

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

struct ResizeAttribute FLATBUFFERS_FINAL_CLASS : private ::flatbuffers::Table {
  typedef ResizeAttributeBuilder Builder;
  enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
    VT_SCALE = 4,
    VT_OFFSET = 6,
    VT_BORDER = 8,
    VT_MODE = 10
  };
  const ::flatbuffers::Vector<int16_t> *scale() const {
    return GetPointer<const ::flatbuffers::Vector<int16_t> *>(VT_SCALE);
  }
  const ::flatbuffers::Vector<int16_t> *offset() const {
    return GetPointer<const ::flatbuffers::Vector<int16_t> *>(VT_OFFSET);
  }
  const ::flatbuffers::Vector<int16_t> *border() const {
    return GetPointer<const ::flatbuffers::Vector<int16_t> *>(VT_BORDER);
  }
  tosa::ResizeMode mode() const {
    return static_cast<tosa::ResizeMode>(GetField<uint32_t>(VT_MODE, 0));
  }
  bool Verify(::flatbuffers::Verifier &verifier) const {
    return VerifyTableStart(verifier) &&
           VerifyOffset(verifier, VT_SCALE) &&
           verifier.VerifyVector(scale()) &&
           VerifyOffset(verifier, VT_OFFSET) &&
           verifier.VerifyVector(offset()) &&
           VerifyOffset(verifier, VT_BORDER) &&
           verifier.VerifyVector(border()) &&
           VerifyField<uint32_t>(verifier, VT_MODE, 4) &&
           verifier.EndTable();
  }
};

struct ResizeAttributeBuilder {
  typedef ResizeAttribute Table;
  ::flatbuffers::FlatBufferBuilder &fbb_;
  ::flatbuffers::uoffset_t start_;
  void add_scale(::flatbuffers::Offset<::flatbuffers::Vector<int16_t>> scale) {
    fbb_.AddOffset(ResizeAttribute::VT_SCALE, scale);
  }
  void add_offset(::flatbuffers::Offset<::flatbuffers::Vector<int16_t>> offset) {
    fbb_.AddOffset(ResizeAttribute::VT_OFFSET, offset);
  }
  void add_border(::flatbuffers::Offset<::flatbuffers::Vector<int16_t>> border) {
    fbb_.AddOffset(ResizeAttribute::VT_BORDER, border);
  }
  void add_mode(tosa::ResizeMode mode) {
    fbb_.AddElement<uint32_t>(ResizeAttribute::VT_MODE, static_cast<uint32_t>(mode), 0);
  }
  explicit ResizeAttributeBuilder(::flatbuffers::FlatBufferBuilder &_fbb)
        : fbb_(_fbb) {
    start_ = fbb_.StartTable();
  }
  ::flatbuffers::Offset<ResizeAttribute> Finish() {
    const auto end = fbb_.EndTable(start_);
    auto o = ::flatbuffers::Offset<ResizeAttribute>(end);
    return o;
  }
};

inline ::flatbuffers::Offset<ResizeAttribute> CreateResizeAttribute(
    ::flatbuffers::FlatBufferBuilder &_fbb,
    ::flatbuffers::Offset<::flatbuffers::Vector<int16_t>> scale = 0,
    ::flatbuffers::Offset<::flatbuffers::Vector<int16_t>> offset = 0,
    ::flatbuffers::Offset<::flatbuffers::Vector<int16_t>> border = 0,
    tosa::ResizeMode mode = tosa::ResizeMode_UNKNOWN) {
  ResizeAttributeBuilder builder_(_fbb);
  builder_.add_mode(mode);
  builder_.add_border(border);
  builder_.add_offset(offset);
  builder_.add_scale(scale);
  return builder_.Finish();
}

inline ::flatbuffers::Offset<ResizeAttribute> CreateResizeAttributeDirect(
    ::flatbuffers::FlatBufferBuilder &_fbb,
    const std::vector<int16_t> *scale = nullptr,
    const std::vector<int16_t> *offset = nullptr,
    const std::vector<int16_t> *border = nullptr,
    tosa::ResizeMode mode = tosa::ResizeMode_UNKNOWN) {
  auto scale__ = scale ? _fbb.CreateVector<int16_t>(*scale) : 0;
  auto offset__ = offset ? _fbb.CreateVector<int16_t>(*offset) : 0;
  auto border__ = border ? _fbb.CreateVector<int16_t>(*border) : 0;
  return tosa::CreateResizeAttribute(
      _fbb,
      scale__,
      offset__,
      border__,
      mode);
}

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

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

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

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

struct RescaleAttribute FLATBUFFERS_FINAL_CLASS : private ::flatbuffers::Table {
  typedef RescaleAttributeBuilder Builder;
  enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
    VT_INPUT_ZP = 4,
    VT_OUTPUT_ZP = 6,
    VT_MULTIPLIER = 8,
    VT_SHIFT = 10,
    VT_SCALE32 = 12,
    VT_DOUBLE_ROUND = 14,
    VT_PER_CHANNEL = 16,
    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_BRANCH = 4,
    VT_ELSE_BRANCH = 6
  };
  const ::flatbuffers::String *then_branch() const {
    return GetPointer<const ::flatbuffers::String *>(VT_THEN_BRANCH);
  }
  const ::flatbuffers::String *else_branch() const {
    return GetPointer<const ::flatbuffers::String *>(VT_ELSE_BRANCH);
  }
  bool Verify(::flatbuffers::Verifier &verifier) const {
    return VerifyTableStart(verifier) &&
           VerifyOffset(verifier, VT_THEN_BRANCH) &&
           verifier.VerifyString(then_branch()) &&
           VerifyOffset(verifier, VT_ELSE_BRANCH) &&
           verifier.VerifyString(else_branch()) &&
           verifier.EndTable();
  }
};

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

struct CustomAttribute FLATBUFFERS_FINAL_CLASS : private ::flatbuffers::Table {
  typedef CustomAttributeBuilder Builder;
  enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
    VT_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::ReshapeAttribute *attribute_as_ReshapeAttribute() const {
    return attribute_type() == tosa::Attribute_ReshapeAttribute ? static_cast<const tosa::ReshapeAttribute *>(attribute()) : nullptr;
  }
  const tosa::SliceAttribute *attribute_as_SliceAttribute() const {
    return attribute_type() == tosa::Attribute_SliceAttribute ? static_cast<const tosa::SliceAttribute *>(attribute()) : nullptr;
  }
  const tosa::TileAttribute *attribute_as_TileAttribute() const {
    return attribute_type() == tosa::Attribute_TileAttribute ? static_cast<const tosa::TileAttribute *>(attribute()) : nullptr;
  }
  const tosa::ResizeAttribute *attribute_as_ResizeAttribute() const {
    return attribute_type() == tosa::Attribute_ResizeAttribute ? static_cast<const tosa::ResizeAttribute *>(attribute()) : nullptr;
  }
  const tosa::ClampAttribute *attribute_as_ClampAttribute() const {
    return attribute_type() == tosa::Attribute_ClampAttribute ? static_cast<const tosa::ClampAttribute *>(attribute()) : nullptr;
  }
  const tosa::RescaleAttribute *attribute_as_RescaleAttribute() const {
    return attribute_type() == tosa::Attribute_RescaleAttribute ? static_cast<const tosa::RescaleAttribute *>(attribute()) : nullptr;
  }
  const tosa::MulAttribute *attribute_as_MulAttribute() const {
    return attribute_type() == tosa::Attribute_MulAttribute ? static_cast<const tosa::MulAttribute *>(attribute()) : nullptr;
  }
  const tosa::ArithmeticRightShiftAttribute *attribute_as_ArithmeticRightShiftAttribute() const {
    return attribute_type() == tosa::Attribute_ArithmeticRightShiftAttribute ? static_cast<const tosa::ArithmeticRightShiftAttribute *>(attribute()) : nullptr;
  }
  const tosa::CondIfAttribute *attribute_as_CondIfAttribute() const {
    return attribute_type() == tosa::Attribute_CondIfAttribute ? static_cast<const tosa::CondIfAttribute *>(attribute()) : nullptr;
  }
  const tosa::WhileLoopAttribute *attribute_as_WhileLoopAttribute() const {
    return attribute_type() == tosa::Attribute_WhileLoopAttribute ? static_cast<const tosa::WhileLoopAttribute *>(attribute()) : nullptr;
  }
  const tosa::TransposeAttribute *attribute_as_TransposeAttribute() const {
    return attribute_type() == tosa::Attribute_TransposeAttribute ? static_cast<const tosa::TransposeAttribute *>(attribute()) : nullptr;
  }
  const tosa::TableAttribute *attribute_as_TableAttribute() const {
    return attribute_type() == tosa::Attribute_TableAttribute ? static_cast<const tosa::TableAttribute *>(attribute()) : nullptr;
  }
  const tosa::MatMulAttribute *attribute_as_MatMulAttribute() const {
    return attribute_type() == tosa::Attribute_MatMulAttribute ? static_cast<const tosa::MatMulAttribute *>(attribute()) : nullptr;
  }
  const tosa::FullyConnectedAttribute *attribute_as_FullyConnectedAttribute() const {
    return attribute_type() == tosa::Attribute_FullyConnectedAttribute ? static_cast<const tosa::FullyConnectedAttribute *>(attribute()) : nullptr;
  }
  const tosa::NegateAttribute *attribute_as_NegateAttribute() const {
    return attribute_type() == tosa::Attribute_NegateAttribute ? static_cast<const tosa::NegateAttribute *>(attribute()) : nullptr;
  }
  const tosa::CustomAttribute *attribute_as_CustomAttribute() const {
    return attribute_type() == tosa::Attribute_CustomAttribute ? static_cast<const tosa::CustomAttribute *>(attribute()) : nullptr;
  }
  const tosa::FFTAttribute *attribute_as_FFTAttribute() const {
    return attribute_type() == tosa::Attribute_FFTAttribute ? static_cast<const tosa::FFTAttribute *>(attribute()) : nullptr;
  }
  const 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::ReshapeAttribute *TosaOperator::attribute_as<tosa::ReshapeAttribute>() const {
  return attribute_as_ReshapeAttribute();
}

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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_ReshapeAttribute: {
      auto ptr = reinterpret_cast<const tosa::ReshapeAttribute *>(obj);
      return verifier.VerifyTable(ptr);
    }
    case Attribute_SliceAttribute: {
      auto ptr = reinterpret_cast<const tosa::SliceAttribute *>(obj);
      return verifier.VerifyTable(ptr);
    }
    case Attribute_TileAttribute: {
      auto ptr = reinterpret_cast<const tosa::TileAttribute *>(obj);
      return verifier.VerifyTable(ptr);
    }
    case Attribute_ResizeAttribute: {
      auto ptr = reinterpret_cast<const tosa::ResizeAttribute *>(obj);
      return verifier.VerifyTable(ptr);
    }
    case Attribute_ClampAttribute: {
      auto ptr = reinterpret_cast<const tosa::ClampAttribute *>(obj);
      return verifier.VerifyTable(ptr);
    }
    case Attribute_RescaleAttribute: {
      auto ptr = reinterpret_cast<const tosa::RescaleAttribute *>(obj);
      return verifier.VerifyTable(ptr);
    }
    case Attribute_MulAttribute: {
      auto ptr = reinterpret_cast<const tosa::MulAttribute *>(obj);
      return verifier.VerifyTable(ptr);
    }
    case Attribute_ArithmeticRightShiftAttribute: {
      auto ptr = reinterpret_cast<const tosa::ArithmeticRightShiftAttribute *>(obj);
      return verifier.VerifyTable(ptr);
    }
    case Attribute_CondIfAttribute: {
      auto ptr = reinterpret_cast<const tosa::CondIfAttribute *>(obj);
      return verifier.VerifyTable(ptr);
    }
    case Attribute_WhileLoopAttribute: {
      auto ptr = reinterpret_cast<const tosa::WhileLoopAttribute *>(obj);
      return verifier.VerifyTable(ptr);
    }
    case Attribute_TransposeAttribute: {
      auto ptr = reinterpret_cast<const tosa::TransposeAttribute *>(obj);
      return verifier.VerifyTable(ptr);
    }
    case Attribute_TableAttribute: {
      auto ptr = reinterpret_cast<const tosa::TableAttribute *>(obj);
      return verifier.VerifyTable(ptr);
    }
    case Attribute_MatMulAttribute: {
      auto ptr = reinterpret_cast<const tosa::MatMulAttribute *>(obj);
      return verifier.VerifyTable(ptr);
    }
    case Attribute_FullyConnectedAttribute: {
      auto ptr = reinterpret_cast<const tosa::FullyConnectedAttribute *>(obj);
      return verifier.VerifyTable(ptr);
    }
    case Attribute_NegateAttribute: {
      auto ptr = reinterpret_cast<const tosa::NegateAttribute *>(obj);
      return verifier.VerifyTable(ptr);
    }
    case Attribute_CustomAttribute: {
      auto ptr = reinterpret_cast<const tosa::CustomAttribute *>(obj);
      return verifier.VerifyTable(ptr);
    }
    case Attribute_FFTAttribute: {
      auto ptr = reinterpret_cast<const tosa::FFTAttribute *>(obj);
      return verifier.VerifyTable(ptr);
    }
    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_
