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


#ifndef FLATBUFFERS_GENERATED_TOSA_TOSA_H_
#define FLATBUFFERS_GENERATED_TOSA_TOSA_H_

#include "flatbuffers/flatbuffers.h"

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

namespace tosa {

struct PoolAttribute;
struct PoolAttributeBuilder;

struct ConvAttribute;
struct ConvAttributeBuilder;

struct TransposeConvAttribute;
struct TransposeConvAttributeBuilder;

struct PadAttribute;
struct PadAttributeBuilder;

struct AxisAttribute;
struct AxisAttributeBuilder;

struct ResizeAttribute;
struct ResizeAttributeBuilder;

struct ClampAttribute;
struct ClampAttributeBuilder;

struct RescaleAttribute;
struct RescaleAttributeBuilder;

struct MulAttribute;
struct MulAttributeBuilder;

struct ArithmeticRightShiftAttribute;
struct ArithmeticRightShiftAttributeBuilder;

struct CondIfAttribute;
struct CondIfAttributeBuilder;

struct WhileLoopAttribute;
struct WhileLoopAttributeBuilder;

struct TransposeAttribute;
struct TransposeAttributeBuilder;

struct TableAttribute;
struct TableAttributeBuilder;

struct MatMulAttribute;
struct MatMulAttributeBuilder;

struct FullyConnectedAttribute;
struct FullyConnectedAttributeBuilder;

struct NegateAttribute;
struct NegateAttributeBuilder;

struct CustomAttribute;
struct CustomAttributeBuilder;

struct FFTAttribute;
struct FFTAttributeBuilder;

struct RFFTAttribute;
struct RFFTAttributeBuilder;

struct Version;
struct VersionBuilder;

struct TosaTensor;
struct TosaTensorBuilder;

struct TosaOperator;
struct TosaOperatorBuilder;

struct TosaBasicBlock;
struct TosaBasicBlockBuilder;

struct TosaRegion;
struct TosaRegionBuilder;

struct TosaGraph;
struct TosaGraphBuilder;

enum DType : uint32_t {
  DType_UNKNOWN = 0,
  DType_BOOL = 1,
  DType_UINT8 = 2,
  DType_INT4 = 3,
  DType_INT8 = 4,
  DType_INT16 = 5,
  DType_INT32 = 6,
  DType_INT48 = 7,
  DType_FP32 = 8,
  DType_UINT16 = 9,
  DType_FP16 = 10,
  DType_BF16 = 11,
  DType_SHAPE = 12,
  DType_FP8E4M3 = 13,
  DType_FP8E5M2 = 14,
  DType_MIN = DType_UNKNOWN,
  DType_MAX = DType_FP8E5M2
};

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

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

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

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

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

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

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

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

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

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

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

enum Attribute : uint8_t {
  Attribute_NONE = 0,
  Attribute_PoolAttribute = 1,
  Attribute_ConvAttribute = 2,
  Attribute_TransposeConvAttribute = 3,
  Attribute_PadAttribute = 4,
  Attribute_AxisAttribute = 5,
  Attribute_ResizeAttribute = 6,
  Attribute_ClampAttribute = 7,
  Attribute_RescaleAttribute = 8,
  Attribute_MulAttribute = 9,
  Attribute_ArithmeticRightShiftAttribute = 10,
  Attribute_CondIfAttribute = 11,
  Attribute_WhileLoopAttribute = 12,
  Attribute_TransposeAttribute = 13,
  Attribute_TableAttribute = 14,
  Attribute_MatMulAttribute = 15,
  Attribute_FullyConnectedAttribute = 16,
  Attribute_NegateAttribute = 17,
  Attribute_CustomAttribute = 18,
  Attribute_FFTAttribute = 19,
  Attribute_RFFTAttribute = 20,
  Attribute_MIN = Attribute_NONE,
  Attribute_MAX = Attribute_RFFTAttribute
};

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

struct ConvAttribute FLATBUFFERS_FINAL_CLASS : private ::flatbuffers::Table {
  typedef ConvAttributeBuilder Builder;
  enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
    VT_PAD = 4,
    VT_STRIDE = 6,
    VT_DILATION = 8,
    VT_INPUT_ZP = 10,
    VT_WEIGHT_ZP = 12,
    VT_LOCAL_BOUND = 14
  };
  const ::flatbuffers::Vector<int32_t> *pad() const {
    return GetPointer<const ::flatbuffers::Vector<int32_t> *>(VT_PAD);
  }
  const ::flatbuffers::Vector<int32_t> *stride() const {
    return GetPointer<const ::flatbuffers::Vector<int32_t> *>(VT_STRIDE);
  }
  const ::flatbuffers::Vector<int32_t> *dilation() const {
    return GetPointer<const ::flatbuffers::Vector<int32_t> *>(VT_DILATION);
  }
  int32_t input_zp() const {
    return GetField<int32_t>(VT_INPUT_ZP, 0);
  }
  int32_t weight_zp() const {
    return GetField<int32_t>(VT_WEIGHT_ZP, 0);
  }
  bool local_bound() const {
    return GetField<uint8_t>(VT_LOCAL_BOUND, 0) != 0;
  }
  bool Verify(::flatbuffers::Verifier &verifier) const {
    return VerifyTableStart(verifier) &&
           VerifyOffset(verifier, VT_PAD) &&
           verifier.VerifyVector(pad()) &&
           VerifyOffset(verifier, VT_STRIDE) &&
           verifier.VerifyVector(stride()) &&
           VerifyOffset(verifier, VT_DILATION) &&
           verifier.VerifyVector(dilation()) &&
           VerifyField<int32_t>(verifier, VT_INPUT_ZP, 4) &&
           VerifyField<int32_t>(verifier, VT_WEIGHT_ZP, 4) &&
           VerifyField<uint8_t>(verifier, VT_LOCAL_BOUND, 1) &&
           verifier.EndTable();
  }
};

struct ConvAttributeBuilder {
  typedef ConvAttribute Table;
  ::flatbuffers::FlatBufferBuilder &fbb_;
  ::flatbuffers::uoffset_t start_;
  void add_pad(::flatbuffers::Offset<::flatbuffers::Vector<int32_t>> pad) {
    fbb_.AddOffset(ConvAttribute::VT_PAD, pad);
  }
  void add_stride(::flatbuffers::Offset<::flatbuffers::Vector<int32_t>> stride) {
    fbb_.AddOffset(ConvAttribute::VT_STRIDE, stride);
  }
  void add_dilation(::flatbuffers::Offset<::flatbuffers::Vector<int32_t>> dilation) {
    fbb_.AddOffset(ConvAttribute::VT_DILATION, dilation);
  }
  void add_input_zp(int32_t input_zp) {
    fbb_.AddElement<int32_t>(ConvAttribute::VT_INPUT_ZP, input_zp, 0);
  }
  void add_weight_zp(int32_t weight_zp) {
    fbb_.AddElement<int32_t>(ConvAttribute::VT_WEIGHT_ZP, weight_zp, 0);
  }
  void add_local_bound(bool local_bound) {
    fbb_.AddElement<uint8_t>(ConvAttribute::VT_LOCAL_BOUND, static_cast<uint8_t>(local_bound), 0);
  }
  explicit ConvAttributeBuilder(::flatbuffers::FlatBufferBuilder &_fbb)
        : fbb_(_fbb) {
    start_ = fbb_.StartTable();
  }
  ::flatbuffers::Offset<ConvAttribute> Finish() {
    const auto end = fbb_.EndTable(start_);
    auto o = ::flatbuffers::Offset<ConvAttribute>(end);
    return o;
  }
};

inline ::flatbuffers::Offset<ConvAttribute> CreateConvAttribute(
    ::flatbuffers::FlatBufferBuilder &_fbb,
    ::flatbuffers::Offset<::flatbuffers::Vector<int32_t>> pad = 0,
    ::flatbuffers::Offset<::flatbuffers::Vector<int32_t>> stride = 0,
    ::flatbuffers::Offset<::flatbuffers::Vector<int32_t>> dilation = 0,
    int32_t input_zp = 0,
    int32_t weight_zp = 0,
    bool local_bound = false) {
  ConvAttributeBuilder builder_(_fbb);
  builder_.add_weight_zp(weight_zp);
  builder_.add_input_zp(input_zp);
  builder_.add_dilation(dilation);
  builder_.add_stride(stride);
  builder_.add_pad(pad);
  builder_.add_local_bound(local_bound);
  return builder_.Finish();
}

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

struct TransposeConvAttribute FLATBUFFERS_FINAL_CLASS : private ::flatbuffers::Table {
  typedef TransposeConvAttributeBuilder Builder;
  enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
    VT_OUT_PAD = 4,
    VT_STRIDE = 6,
    VT_OUTPUT_SHAPE = 8,
    VT_INPUT_ZP = 10,
    VT_WEIGHT_ZP = 12,
    VT_LOCAL_BOUND = 14
  };
  const ::flatbuffers::Vector<int32_t> *out_pad() const {
    return GetPointer<const ::flatbuffers::Vector<int32_t> *>(VT_OUT_PAD);
  }
  const ::flatbuffers::Vector<int32_t> *stride() const {
    return GetPointer<const ::flatbuffers::Vector<int32_t> *>(VT_STRIDE);
  }
  const ::flatbuffers::Vector<int32_t> *output_shape() const {
    return GetPointer<const ::flatbuffers::Vector<int32_t> *>(VT_OUTPUT_SHAPE);
  }
  int32_t input_zp() const {
    return GetField<int32_t>(VT_INPUT_ZP, 0);
  }
  int32_t weight_zp() const {
    return GetField<int32_t>(VT_WEIGHT_ZP, 0);
  }
  bool local_bound() const {
    return GetField<uint8_t>(VT_LOCAL_BOUND, 0) != 0;
  }
  bool Verify(::flatbuffers::Verifier &verifier) const {
    return VerifyTableStart(verifier) &&
           VerifyOffset(verifier, VT_OUT_PAD) &&
           verifier.VerifyVector(out_pad()) &&
           VerifyOffset(verifier, VT_STRIDE) &&
           verifier.VerifyVector(stride()) &&
           VerifyOffset(verifier, VT_OUTPUT_SHAPE) &&
           verifier.VerifyVector(output_shape()) &&
           VerifyField<int32_t>(verifier, VT_INPUT_ZP, 4) &&
           VerifyField<int32_t>(verifier, VT_WEIGHT_ZP, 4) &&
           VerifyField<uint8_t>(verifier, VT_LOCAL_BOUND, 1) &&
           verifier.EndTable();
  }
};

struct TransposeConvAttributeBuilder {
  typedef TransposeConvAttribute Table;
  ::flatbuffers::FlatBufferBuilder &fbb_;
  ::flatbuffers::uoffset_t start_;
  void add_out_pad(::flatbuffers::Offset<::flatbuffers::Vector<int32_t>> out_pad) {
    fbb_.AddOffset(TransposeConvAttribute::VT_OUT_PAD, out_pad);
  }
  void add_stride(::flatbuffers::Offset<::flatbuffers::Vector<int32_t>> stride) {
    fbb_.AddOffset(TransposeConvAttribute::VT_STRIDE, stride);
  }
  void add_output_shape(::flatbuffers::Offset<::flatbuffers::Vector<int32_t>> output_shape) {
    fbb_.AddOffset(TransposeConvAttribute::VT_OUTPUT_SHAPE, output_shape);
  }
  void add_input_zp(int32_t input_zp) {
    fbb_.AddElement<int32_t>(TransposeConvAttribute::VT_INPUT_ZP, input_zp, 0);
  }
  void add_weight_zp(int32_t weight_zp) {
    fbb_.AddElement<int32_t>(TransposeConvAttribute::VT_WEIGHT_ZP, weight_zp, 0);
  }
  void add_local_bound(bool local_bound) {
    fbb_.AddElement<uint8_t>(TransposeConvAttribute::VT_LOCAL_BOUND, static_cast<uint8_t>(local_bound), 0);
  }
  explicit TransposeConvAttributeBuilder(::flatbuffers::FlatBufferBuilder &_fbb)
        : fbb_(_fbb) {
    start_ = fbb_.StartTable();
  }
  ::flatbuffers::Offset<TransposeConvAttribute> Finish() {
    const auto end = fbb_.EndTable(start_);
    auto o = ::flatbuffers::Offset<TransposeConvAttribute>(end);
    return o;
  }
};

inline ::flatbuffers::Offset<TransposeConvAttribute> CreateTransposeConvAttribute(
    ::flatbuffers::FlatBufferBuilder &_fbb,
    ::flatbuffers::Offset<::flatbuffers::Vector<int32_t>> out_pad = 0,
    ::flatbuffers::Offset<::flatbuffers::Vector<int32_t>> stride = 0,
    ::flatbuffers::Offset<::flatbuffers::Vector<int32_t>> output_shape = 0,
    int32_t input_zp = 0,
    int32_t weight_zp = 0,
    bool local_bound = false) {
  TransposeConvAttributeBuilder builder_(_fbb);
  builder_.add_weight_zp(weight_zp);
  builder_.add_input_zp(input_zp);
  builder_.add_output_shape(output_shape);
  builder_.add_stride(stride);
  builder_.add_out_pad(out_pad);
  builder_.add_local_bound(local_bound);
  return builder_.Finish();
}

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

struct PadAttribute FLATBUFFERS_FINAL_CLASS : private ::flatbuffers::Table {
  typedef PadAttributeBuilder Builder;
  enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
    VT_PAD_CONST = 4
  };
  const ::flatbuffers::Vector<uint8_t> *pad_const() const {
    return GetPointer<const ::flatbuffers::Vector<uint8_t> *>(VT_PAD_CONST);
  }
  bool Verify(::flatbuffers::Verifier &verifier) const {
    return VerifyTableStart(verifier) &&
           VerifyOffset(verifier, VT_PAD_CONST) &&
           verifier.VerifyVector(pad_const()) &&
           verifier.EndTable();
  }
};

struct PadAttributeBuilder {
  typedef PadAttribute Table;
  ::flatbuffers::FlatBufferBuilder &fbb_;
  ::flatbuffers::uoffset_t start_;
  void add_pad_const(::flatbuffers::Offset<::flatbuffers::Vector<uint8_t>> pad_const) {
    fbb_.AddOffset(PadAttribute::VT_PAD_CONST, pad_const);
  }
  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<uint8_t>> pad_const = 0) {
  PadAttributeBuilder builder_(_fbb);
  builder_.add_pad_const(pad_const);
  return builder_.Finish();
}

inline ::flatbuffers::Offset<PadAttribute> CreatePadAttributeDirect(
    ::flatbuffers::FlatBufferBuilder &_fbb,
    const std::vector<uint8_t> *pad_const = nullptr) {
  if (pad_const) { _fbb.ForceVectorAlignment(pad_const->size(), sizeof(uint8_t), 8); }
  auto pad_const__ = pad_const ? _fbb.CreateVector<uint8_t>(*pad_const) : 0;
  return tosa::CreatePadAttribute(
      _fbb,
      pad_const__);
}

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

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

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

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

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

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

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

struct ClampAttribute FLATBUFFERS_FINAL_CLASS : private ::flatbuffers::Table {
  typedef ClampAttributeBuilder Builder;
  enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
    VT_MIN_VAL = 4,
    VT_MAX_VAL = 6
  };
  const ::flatbuffers::Vector<uint8_t> *min_val() const {
    return GetPointer<const ::flatbuffers::Vector<uint8_t> *>(VT_MIN_VAL);
  }
  const ::flatbuffers::Vector<uint8_t> *max_val() const {
    return GetPointer<const ::flatbuffers::Vector<uint8_t> *>(VT_MAX_VAL);
  }
  bool Verify(::flatbuffers::Verifier &verifier) const {
    return VerifyTableStart(verifier) &&
           VerifyOffset(verifier, VT_MIN_VAL) &&
           verifier.VerifyVector(min_val()) &&
           VerifyOffset(verifier, VT_MAX_VAL) &&
           verifier.VerifyVector(max_val()) &&
           verifier.EndTable();
  }
};

struct ClampAttributeBuilder {
  typedef ClampAttribute Table;
  ::flatbuffers::FlatBufferBuilder &fbb_;
  ::flatbuffers::uoffset_t start_;
  void add_min_val(::flatbuffers::Offset<::flatbuffers::Vector<uint8_t>> min_val) {
    fbb_.AddOffset(ClampAttribute::VT_MIN_VAL, min_val);
  }
  void add_max_val(::flatbuffers::Offset<::flatbuffers::Vector<uint8_t>> max_val) {
    fbb_.AddOffset(ClampAttribute::VT_MAX_VAL, max_val);
  }
  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,
    ::flatbuffers::Offset<::flatbuffers::Vector<uint8_t>> min_val = 0,
    ::flatbuffers::Offset<::flatbuffers::Vector<uint8_t>> max_val = 0) {
  ClampAttributeBuilder builder_(_fbb);
  builder_.add_max_val(max_val);
  builder_.add_min_val(min_val);
  return builder_.Finish();
}

inline ::flatbuffers::Offset<ClampAttribute> CreateClampAttributeDirect(
    ::flatbuffers::FlatBufferBuilder &_fbb,
    const std::vector<uint8_t> *min_val = nullptr,
    const std::vector<uint8_t> *max_val = nullptr) {
  if (min_val) { _fbb.ForceVectorAlignment(min_val->size(), sizeof(uint8_t), 8); }
  auto min_val__ = min_val ? _fbb.CreateVector<uint8_t>(*min_val) : 0;
  if (max_val) { _fbb.ForceVectorAlignment(max_val->size(), sizeof(uint8_t), 8); }
  auto max_val__ = max_val ? _fbb.CreateVector<uint8_t>(*max_val) : 0;
  return tosa::CreateClampAttribute(
      _fbb,
      min_val__,
      max_val__);
}

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_SCALE32 = 8,
    VT_DOUBLE_ROUND = 10,
    VT_PER_CHANNEL = 12,
    VT_INPUT_UNSIGNED = 14,
    VT_OUTPUT_UNSIGNED = 16
  };
  int32_t input_zp() const {
    return GetField<int32_t>(VT_INPUT_ZP, 0);
  }
  int32_t output_zp() const {
    return GetField<int32_t>(VT_OUTPUT_ZP, 0);
  }
  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) &&
           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_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,
    bool scale32 = false,
    bool double_round = false,
    bool per_channel = false,
    bool input_unsigned = false,
    bool output_unsigned = false) {
  RescaleAttributeBuilder builder_(_fbb);
  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();
}

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

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

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

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

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

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

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

struct CondIfAttributeBuilder {
  typedef CondIfAttribute Table;
  ::flatbuffers::FlatBufferBuilder &fbb_;
  ::flatbuffers::uoffset_t start_;
  void add_then_graph(::flatbuffers::Offset<::flatbuffers::String> then_graph) {
    fbb_.AddOffset(CondIfAttribute::VT_THEN_GRAPH, then_graph);
  }
  void add_else_graph(::flatbuffers::Offset<::flatbuffers::String> else_graph) {
    fbb_.AddOffset(CondIfAttribute::VT_ELSE_GRAPH, else_graph);
  }
  explicit CondIfAttributeBuilder(::flatbuffers::FlatBufferBuilder &_fbb)
        : fbb_(_fbb) {
    start_ = fbb_.StartTable();
  }
  ::flatbuffers::Offset<CondIfAttribute> Finish() {
    const auto end = fbb_.EndTable(start_);
    auto o = ::flatbuffers::Offset<CondIfAttribute>(end);
    return o;
  }
};

inline ::flatbuffers::Offset<CondIfAttribute> CreateCondIfAttribute(
    ::flatbuffers::FlatBufferBuilder &_fbb,
    ::flatbuffers::Offset<::flatbuffers::String> then_graph = 0,
    ::flatbuffers::Offset<::flatbuffers::String> else_graph = 0) {
  CondIfAttributeBuilder builder_(_fbb);
  builder_.add_else_graph(else_graph);
  builder_.add_then_graph(then_graph);
  return builder_.Finish();
}

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

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

struct WhileLoopAttributeBuilder {
  typedef WhileLoopAttribute Table;
  ::flatbuffers::FlatBufferBuilder &fbb_;
  ::flatbuffers::uoffset_t start_;
  void add_cond_graph(::flatbuffers::Offset<::flatbuffers::String> cond_graph) {
    fbb_.AddOffset(WhileLoopAttribute::VT_COND_GRAPH, cond_graph);
  }
  void add_body_graph(::flatbuffers::Offset<::flatbuffers::String> body_graph) {
    fbb_.AddOffset(WhileLoopAttribute::VT_BODY_GRAPH, body_graph);
  }
  explicit WhileLoopAttributeBuilder(::flatbuffers::FlatBufferBuilder &_fbb)
        : fbb_(_fbb) {
    start_ = fbb_.StartTable();
  }
  ::flatbuffers::Offset<WhileLoopAttribute> Finish() {
    const auto end = fbb_.EndTable(start_);
    auto o = ::flatbuffers::Offset<WhileLoopAttribute>(end);
    return o;
  }
};

inline ::flatbuffers::Offset<WhileLoopAttribute> CreateWhileLoopAttribute(
    ::flatbuffers::FlatBufferBuilder &_fbb,
    ::flatbuffers::Offset<::flatbuffers::String> cond_graph = 0,
    ::flatbuffers::Offset<::flatbuffers::String> body_graph = 0) {
  WhileLoopAttributeBuilder builder_(_fbb);
  builder_.add_body_graph(body_graph);
  builder_.add_cond_graph(cond_graph);
  return builder_.Finish();
}

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

struct CustomAttributeBuilder {
  typedef CustomAttribute Table;
  ::flatbuffers::FlatBufferBuilder &fbb_;
  ::flatbuffers::uoffset_t start_;
  void add_operator_name(::flatbuffers::Offset<::flatbuffers::String> operator_name) {
    fbb_.AddOffset(CustomAttribute::VT_OPERATOR_NAME, operator_name);
  }
  void add_domain_name(::flatbuffers::Offset<::flatbuffers::String> domain_name) {
    fbb_.AddOffset(CustomAttribute::VT_DOMAIN_NAME, domain_name);
  }
  void add_implementation_attrs(::flatbuffers::Offset<::flatbuffers::Vector<uint8_t>> implementation_attrs) {
    fbb_.AddOffset(CustomAttribute::VT_IMPLEMENTATION_ATTRS, implementation_attrs);
  }
  explicit CustomAttributeBuilder(::flatbuffers::FlatBufferBuilder &_fbb)
        : fbb_(_fbb) {
    start_ = fbb_.StartTable();
  }
  ::flatbuffers::Offset<CustomAttribute> Finish() {
    const auto end = fbb_.EndTable(start_);
    auto o = ::flatbuffers::Offset<CustomAttribute>(end);
    return o;
  }
};

inline ::flatbuffers::Offset<CustomAttribute> CreateCustomAttribute(
    ::flatbuffers::FlatBufferBuilder &_fbb,
    ::flatbuffers::Offset<::flatbuffers::String> operator_name = 0,
    ::flatbuffers::Offset<::flatbuffers::String> domain_name = 0,
    ::flatbuffers::Offset<::flatbuffers::Vector<uint8_t>> implementation_attrs = 0) {
  CustomAttributeBuilder builder_(_fbb);
  builder_.add_implementation_attrs(implementation_attrs);
  builder_.add_domain_name(domain_name);
  builder_.add_operator_name(operator_name);
  return builder_.Finish();
}

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

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

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

inline ::flatbuffers::Offset<FFTAttribute> CreateFFTAttribute(
    ::flatbuffers::FlatBufferBuilder &_fbb,
    bool inverse = false,
    bool local_bound = false) {
  FFTAttributeBuilder builder_(_fbb);
  builder_.add_local_bound(local_bound);
  builder_.add_inverse(inverse);
  return builder_.Finish();
}

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

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

inline ::flatbuffers::Offset<RFFTAttribute> CreateRFFTAttribute(
    ::flatbuffers::FlatBufferBuilder &_fbb,
    bool local_bound = false) {
  RFFTAttributeBuilder builder_(_fbb);
  builder_.add_local_bound(local_bound);
  return builder_.Finish();
}

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

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

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

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

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

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

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

struct TosaOperator FLATBUFFERS_FINAL_CLASS : private ::flatbuffers::Table {
  typedef TosaOperatorBuilder Builder;
  enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
    VT_OP = 4,
    VT_ATTRIBUTE_TYPE = 6,
    VT_ATTRIBUTE = 8,
    VT_INPUTS = 10,
    VT_OUTPUTS = 12
  };
  tosa::Op op() const {
    return static_cast<tosa::Op>(GetField<uint32_t>(VT_OP, 0));
  }
  tosa::Attribute attribute_type() const {
    return static_cast<tosa::Attribute>(GetField<uint8_t>(VT_ATTRIBUTE_TYPE, 0));
  }
  const void *attribute() const {
    return GetPointer<const void *>(VT_ATTRIBUTE);
  }
  template<typename T> const T *attribute_as() const;
  const tosa::PoolAttribute *attribute_as_PoolAttribute() const {
    return attribute_type() == tosa::Attribute_PoolAttribute ? static_cast<const tosa::PoolAttribute *>(attribute()) : nullptr;
  }
  const tosa::ConvAttribute *attribute_as_ConvAttribute() const {
    return attribute_type() == tosa::Attribute_ConvAttribute ? static_cast<const tosa::ConvAttribute *>(attribute()) : nullptr;
  }
  const tosa::TransposeConvAttribute *attribute_as_TransposeConvAttribute() const {
    return attribute_type() == tosa::Attribute_TransposeConvAttribute ? static_cast<const tosa::TransposeConvAttribute *>(attribute()) : nullptr;
  }
  const tosa::PadAttribute *attribute_as_PadAttribute() const {
    return attribute_type() == tosa::Attribute_PadAttribute ? static_cast<const tosa::PadAttribute *>(attribute()) : nullptr;
  }
  const tosa::AxisAttribute *attribute_as_AxisAttribute() const {
    return attribute_type() == tosa::Attribute_AxisAttribute ? static_cast<const tosa::AxisAttribute *>(attribute()) : nullptr;
  }
  const tosa::ResizeAttribute *attribute_as_ResizeAttribute() const {
    return attribute_type() == tosa::Attribute_ResizeAttribute ? static_cast<const tosa::ResizeAttribute *>(attribute()) : nullptr;
  }
  const tosa::ClampAttribute *attribute_as_ClampAttribute() const {
    return attribute_type() == tosa::Attribute_ClampAttribute ? static_cast<const tosa::ClampAttribute *>(attribute()) : nullptr;
  }
  const tosa::RescaleAttribute *attribute_as_RescaleAttribute() const {
    return attribute_type() == tosa::Attribute_RescaleAttribute ? static_cast<const tosa::RescaleAttribute *>(attribute()) : nullptr;
  }
  const tosa::MulAttribute *attribute_as_MulAttribute() const {
    return attribute_type() == tosa::Attribute_MulAttribute ? static_cast<const tosa::MulAttribute *>(attribute()) : nullptr;
  }
  const tosa::ArithmeticRightShiftAttribute *attribute_as_ArithmeticRightShiftAttribute() const {
    return attribute_type() == tosa::Attribute_ArithmeticRightShiftAttribute ? static_cast<const tosa::ArithmeticRightShiftAttribute *>(attribute()) : nullptr;
  }
  const tosa::CondIfAttribute *attribute_as_CondIfAttribute() const {
    return attribute_type() == tosa::Attribute_CondIfAttribute ? static_cast<const tosa::CondIfAttribute *>(attribute()) : nullptr;
  }
  const tosa::WhileLoopAttribute *attribute_as_WhileLoopAttribute() const {
    return attribute_type() == tosa::Attribute_WhileLoopAttribute ? static_cast<const tosa::WhileLoopAttribute *>(attribute()) : nullptr;
  }
  const tosa::TransposeAttribute *attribute_as_TransposeAttribute() const {
    return attribute_type() == tosa::Attribute_TransposeAttribute ? static_cast<const tosa::TransposeAttribute *>(attribute()) : nullptr;
  }
  const tosa::TableAttribute *attribute_as_TableAttribute() const {
    return attribute_type() == tosa::Attribute_TableAttribute ? static_cast<const tosa::TableAttribute *>(attribute()) : nullptr;
  }
  const tosa::MatMulAttribute *attribute_as_MatMulAttribute() const {
    return attribute_type() == tosa::Attribute_MatMulAttribute ? static_cast<const tosa::MatMulAttribute *>(attribute()) : nullptr;
  }
  const tosa::FullyConnectedAttribute *attribute_as_FullyConnectedAttribute() const {
    return attribute_type() == tosa::Attribute_FullyConnectedAttribute ? static_cast<const tosa::FullyConnectedAttribute *>(attribute()) : nullptr;
  }
  const tosa::NegateAttribute *attribute_as_NegateAttribute() const {
    return attribute_type() == tosa::Attribute_NegateAttribute ? static_cast<const tosa::NegateAttribute *>(attribute()) : nullptr;
  }
  const tosa::CustomAttribute *attribute_as_CustomAttribute() const {
    return attribute_type() == tosa::Attribute_CustomAttribute ? static_cast<const tosa::CustomAttribute *>(attribute()) : nullptr;
  }
  const tosa::FFTAttribute *attribute_as_FFTAttribute() const {
    return attribute_type() == tosa::Attribute_FFTAttribute ? static_cast<const tosa::FFTAttribute *>(attribute()) : nullptr;
  }
  const tosa::RFFTAttribute *attribute_as_RFFTAttribute() const {
    return attribute_type() == tosa::Attribute_RFFTAttribute ? static_cast<const tosa::RFFTAttribute *>(attribute()) : nullptr;
  }
  const ::flatbuffers::Vector<::flatbuffers::Offset<::flatbuffers::String>> *inputs() const {
    return GetPointer<const ::flatbuffers::Vector<::flatbuffers::Offset<::flatbuffers::String>> *>(VT_INPUTS);
  }
  const ::flatbuffers::Vector<::flatbuffers::Offset<::flatbuffers::String>> *outputs() const {
    return GetPointer<const ::flatbuffers::Vector<::flatbuffers::Offset<::flatbuffers::String>> *>(VT_OUTPUTS);
  }
  bool Verify(::flatbuffers::Verifier &verifier) const {
    return VerifyTableStart(verifier) &&
           VerifyField<uint32_t>(verifier, VT_OP, 4) &&
           VerifyField<uint8_t>(verifier, VT_ATTRIBUTE_TYPE, 1) &&
           VerifyOffset(verifier, VT_ATTRIBUTE) &&
           VerifyAttribute(verifier, attribute(), attribute_type()) &&
           VerifyOffset(verifier, VT_INPUTS) &&
           verifier.VerifyVector(inputs()) &&
           verifier.VerifyVectorOfStrings(inputs()) &&
           VerifyOffset(verifier, VT_OUTPUTS) &&
           verifier.VerifyVector(outputs()) &&
           verifier.VerifyVectorOfStrings(outputs()) &&
           verifier.EndTable();
  }
};

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

struct TosaRegion FLATBUFFERS_FINAL_CLASS : private ::flatbuffers::Table {
  typedef TosaRegionBuilder Builder;
  enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
    VT_NAME = 4,
    VT_BLOCKS = 6
  };
  const ::flatbuffers::String *name() const {
    return GetPointer<const ::flatbuffers::String *>(VT_NAME);
  }
  const ::flatbuffers::Vector<::flatbuffers::Offset<tosa::TosaBasicBlock>> *blocks() const {
    return GetPointer<const ::flatbuffers::Vector<::flatbuffers::Offset<tosa::TosaBasicBlock>> *>(VT_BLOCKS);
  }
  bool Verify(::flatbuffers::Verifier &verifier) const {
    return VerifyTableStart(verifier) &&
           VerifyOffset(verifier, VT_NAME) &&
           verifier.VerifyString(name()) &&
           VerifyOffset(verifier, VT_BLOCKS) &&
           verifier.VerifyVector(blocks()) &&
           verifier.VerifyVectorOfTables(blocks()) &&
           verifier.EndTable();
  }
};

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

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

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

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

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

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

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

inline bool VerifyAttribute(::flatbuffers::Verifier &verifier, const void *obj, Attribute type) {
  switch (type) {
    case Attribute_NONE: {
      return true;
    }
    case Attribute_PoolAttribute: {
      auto ptr = reinterpret_cast<const tosa::PoolAttribute *>(obj);
      return verifier.VerifyTable(ptr);
    }
    case Attribute_ConvAttribute: {
      auto ptr = reinterpret_cast<const tosa::ConvAttribute *>(obj);
      return verifier.VerifyTable(ptr);
    }
    case Attribute_TransposeConvAttribute: {
      auto ptr = reinterpret_cast<const tosa::TransposeConvAttribute *>(obj);
      return verifier.VerifyTable(ptr);
    }
    case Attribute_PadAttribute: {
      auto ptr = reinterpret_cast<const tosa::PadAttribute *>(obj);
      return verifier.VerifyTable(ptr);
    }
    case Attribute_AxisAttribute: {
      auto ptr = reinterpret_cast<const tosa::AxisAttribute *>(obj);
      return verifier.VerifyTable(ptr);
    }
    case Attribute_ResizeAttribute: {
      auto ptr = reinterpret_cast<const tosa::ResizeAttribute *>(obj);
      return verifier.VerifyTable(ptr);
    }
    case Attribute_ClampAttribute: {
      auto ptr = reinterpret_cast<const tosa::ClampAttribute *>(obj);
      return verifier.VerifyTable(ptr);
    }
    case Attribute_RescaleAttribute: {
      auto ptr = reinterpret_cast<const tosa::RescaleAttribute *>(obj);
      return verifier.VerifyTable(ptr);
    }
    case Attribute_MulAttribute: {
      auto ptr = reinterpret_cast<const tosa::MulAttribute *>(obj);
      return verifier.VerifyTable(ptr);
    }
    case Attribute_ArithmeticRightShiftAttribute: {
      auto ptr = reinterpret_cast<const tosa::ArithmeticRightShiftAttribute *>(obj);
      return verifier.VerifyTable(ptr);
    }
    case Attribute_CondIfAttribute: {
      auto ptr = reinterpret_cast<const tosa::CondIfAttribute *>(obj);
      return verifier.VerifyTable(ptr);
    }
    case Attribute_WhileLoopAttribute: {
      auto ptr = reinterpret_cast<const tosa::WhileLoopAttribute *>(obj);
      return verifier.VerifyTable(ptr);
    }
    case Attribute_TransposeAttribute: {
      auto ptr = reinterpret_cast<const tosa::TransposeAttribute *>(obj);
      return verifier.VerifyTable(ptr);
    }
    case Attribute_TableAttribute: {
      auto ptr = reinterpret_cast<const tosa::TableAttribute *>(obj);
      return verifier.VerifyTable(ptr);
    }
    case Attribute_MatMulAttribute: {
      auto ptr = reinterpret_cast<const tosa::MatMulAttribute *>(obj);
      return verifier.VerifyTable(ptr);
    }
    case Attribute_FullyConnectedAttribute: {
      auto ptr = reinterpret_cast<const tosa::FullyConnectedAttribute *>(obj);
      return verifier.VerifyTable(ptr);
    }
    case Attribute_NegateAttribute: {
      auto ptr = reinterpret_cast<const tosa::NegateAttribute *>(obj);
      return verifier.VerifyTable(ptr);
    }
    case Attribute_CustomAttribute: {
      auto ptr = reinterpret_cast<const tosa::CustomAttribute *>(obj);
      return verifier.VerifyTable(ptr);
    }
    case Attribute_FFTAttribute: {
      auto ptr = reinterpret_cast<const tosa::FFTAttribute *>(obj);
      return verifier.VerifyTable(ptr);
    }
    case Attribute_RFFTAttribute: {
      auto ptr = reinterpret_cast<const tosa::RFFTAttribute *>(obj);
      return verifier.VerifyTable(ptr);
    }
    default: return true;
  }
}

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

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

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

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

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

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

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

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

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

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

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

}  // namespace tosa

#endif  // FLATBUFFERS_GENERATED_TOSA_TOSA_H_
