
// Copyright (c) 2020, ARM Limited.
//
//    Licensed under the Apache License, Version 2.0 (the "License");
//    you may not use this file except in compliance with the License.
//    You may obtain a copy of the License at
//
//         http://www.apache.org/licenses/LICENSE-2.0
//
//    Unless required by applicable law or agreed to in writing, software
//    distributed under the License is distributed on an "AS IS" BASIS,
//    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//    See the License for the specific language governing permissions and
//    limitations under the License.

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


#ifndef FLATBUFFERS_GENERATED_TOSA_TOSA_H_
#define FLATBUFFERS_GENERATED_TOSA_TOSA_H_

#include "flatbuffers/flatbuffers.h"

namespace tosa {

struct Pool2dAttribute;

struct Conv2dAttribute;

struct TransposeConv2dAttribute;

struct ReluNAttribute;

struct AxisAttribute;

struct ReshapeAttribute;

struct SliceAttribute;

struct TileAttribute;

struct ResizeAttribute;

struct ClampAttribute;

struct RescaleAttribute;

struct CustomAttribute;

struct CondIfAttribute;

struct WhileLoopAttribute;

struct UnaryQuantInfo;

struct ConvQuantInfo;

struct MatMulQuantInfo;

struct PadQuantInfo;

struct Version;

struct TosaTensor;

struct TosaOperator;

struct TosaBasicBlock;

struct TosaGraph;

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

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

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

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

enum Format {
  Format_UNKNOWN = 0,
  Format_NHWC = 1,
  Format_NDHWC = 2,
  Format_OHWI = 3,
  Format_HWIM = 4,
  Format_DOHWI = 5,
  Format_MIN = Format_UNKNOWN,
  Format_MAX = Format_DOHWI
};

inline const Format (&EnumValuesFormat())[6] {
  static const Format values[] = {
    Format_UNKNOWN,
    Format_NHWC,
    Format_NDHWC,
    Format_OHWI,
    Format_HWIM,
    Format_DOHWI
  };
  return values;
}

inline const char * const *EnumNamesFormat() {
  static const char * const names[] = {
    "UNKNOWN",
    "NHWC",
    "NDHWC",
    "OHWI",
    "HWIM",
    "DOHWI",
    nullptr
  };
  return names;
}

inline const char *EnumNameFormat(Format e) {
  if (e < Format_UNKNOWN || e > Format_DOHWI) return "";
  const size_t index = static_cast<size_t>(e);
  return EnumNamesFormat()[index];
}

enum Usage {
  Usage_UNKNOWN = 0,
  Usage_ACTIVATION = 1,
  Usage_WEIGHT = 2,
  Usage_INDEX = 3,
  Usage_MIN = Usage_UNKNOWN,
  Usage_MAX = Usage_INDEX
};

inline const Usage (&EnumValuesUsage())[4] {
  static const Usage values[] = {
    Usage_UNKNOWN,
    Usage_ACTIVATION,
    Usage_WEIGHT,
    Usage_INDEX
  };
  return values;
}

inline const char * const *EnumNamesUsage() {
  static const char * const names[] = {
    "UNKNOWN",
    "ACTIVATION",
    "WEIGHT",
    "INDEX",
    nullptr
  };
  return names;
}

inline const char *EnumNameUsage(Usage e) {
  if (e < Usage_UNKNOWN || e > Usage_INDEX) return "";
  const size_t index = static_cast<size_t>(e);
  return EnumNamesUsage()[index];
}

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

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

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

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

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

inline const Op (&EnumValuesOp())[69] {
  static const Op values[] = {
    Op_UNKNOWN,
    Op_ARGMAX,
    Op_AVG_POOL2D,
    Op_CONV2D,
    Op_CONV3D,
    Op_DEPTHWISE_CONV2D,
    Op_FULLY_CONNECTED,
    Op_MATMUL,
    Op_MAX_POOL2D,
    Op_TRANSPOSE_CONV2D,
    Op_CLAMP,
    Op_RELUN,
    Op_SIGMOID,
    Op_TANH,
    Op_ADD,
    Op_ARITHMETIC_RIGHT_SHIFT,
    Op_BITWISE_AND,
    Op_BITWISE_OR,
    Op_BITWISE_XOR,
    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_RESIZE,
    Op_CAST,
    Op_RESCALE,
    Op_CONST,
    Op_PLACEHOLDER,
    Op_IDENTITY,
    Op_IDENTITYN,
    Op_CUSTOM,
    Op_COND_IF,
    Op_WHILE_LOOP
  };
  return values;
}

inline const char * const *EnumNamesOp() {
  static const char * const names[] = {
    "UNKNOWN",
    "ARGMAX",
    "AVG_POOL2D",
    "CONV2D",
    "CONV3D",
    "DEPTHWISE_CONV2D",
    "FULLY_CONNECTED",
    "MATMUL",
    "MAX_POOL2D",
    "TRANSPOSE_CONV2D",
    "CLAMP",
    "RELUN",
    "SIGMOID",
    "TANH",
    "ADD",
    "ARITHMETIC_RIGHT_SHIFT",
    "BITWISE_AND",
    "BITWISE_OR",
    "BITWISE_XOR",
    "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",
    "RESIZE",
    "CAST",
    "RESCALE",
    "CONST",
    "PLACEHOLDER",
    "IDENTITY",
    "IDENTITYN",
    "CUSTOM",
    "COND_IF",
    "WHILE_LOOP",
    nullptr
  };
  return names;
}

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

enum Attribute {
  Attribute_NONE = 0,
  Attribute_Pool2dAttribute = 1,
  Attribute_Conv2dAttribute = 2,
  Attribute_TransposeConv2dAttribute = 3,
  Attribute_ReluNAttribute = 4,
  Attribute_AxisAttribute = 5,
  Attribute_ReshapeAttribute = 6,
  Attribute_SliceAttribute = 7,
  Attribute_TileAttribute = 8,
  Attribute_ResizeAttribute = 9,
  Attribute_ClampAttribute = 10,
  Attribute_RescaleAttribute = 11,
  Attribute_CustomAttribute = 12,
  Attribute_CondIfAttribute = 13,
  Attribute_WhileLoopAttribute = 14,
  Attribute_MIN = Attribute_NONE,
  Attribute_MAX = Attribute_WhileLoopAttribute
};

inline const Attribute (&EnumValuesAttribute())[15] {
  static const Attribute values[] = {
    Attribute_NONE,
    Attribute_Pool2dAttribute,
    Attribute_Conv2dAttribute,
    Attribute_TransposeConv2dAttribute,
    Attribute_ReluNAttribute,
    Attribute_AxisAttribute,
    Attribute_ReshapeAttribute,
    Attribute_SliceAttribute,
    Attribute_TileAttribute,
    Attribute_ResizeAttribute,
    Attribute_ClampAttribute,
    Attribute_RescaleAttribute,
    Attribute_CustomAttribute,
    Attribute_CondIfAttribute,
    Attribute_WhileLoopAttribute
  };
  return values;
}

inline const char * const *EnumNamesAttribute() {
  static const char * const names[] = {
    "NONE",
    "Pool2dAttribute",
    "Conv2dAttribute",
    "TransposeConv2dAttribute",
    "ReluNAttribute",
    "AxisAttribute",
    "ReshapeAttribute",
    "SliceAttribute",
    "TileAttribute",
    "ResizeAttribute",
    "ClampAttribute",
    "RescaleAttribute",
    "CustomAttribute",
    "CondIfAttribute",
    "WhileLoopAttribute",
    nullptr
  };
  return names;
}

inline const char *EnumNameAttribute(Attribute e) {
  if (e < Attribute_NONE || e > Attribute_WhileLoopAttribute) 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<Pool2dAttribute> {
  static const Attribute enum_value = Attribute_Pool2dAttribute;
};

template<> struct AttributeTraits<Conv2dAttribute> {
  static const Attribute enum_value = Attribute_Conv2dAttribute;
};

template<> struct AttributeTraits<TransposeConv2dAttribute> {
  static const Attribute enum_value = Attribute_TransposeConv2dAttribute;
};

template<> struct AttributeTraits<ReluNAttribute> {
  static const Attribute enum_value = Attribute_ReluNAttribute;
};

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

struct ReluNAttribute FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
  enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
    VT_MAX_INT = 4,
    VT_MAX_FP = 6
  };
  int32_t max_int() const {
    return GetField<int32_t>(VT_MAX_INT, 0);
  }
  float max_fp() const {
    return GetField<float>(VT_MAX_FP, 0.0f);
  }
  bool Verify(flatbuffers::Verifier &verifier) const {
    return VerifyTableStart(verifier) &&
           VerifyField<int32_t>(verifier, VT_MAX_INT) &&
           VerifyField<float>(verifier, VT_MAX_FP) &&
           verifier.EndTable();
  }
};

struct ReluNAttributeBuilder {
  flatbuffers::FlatBufferBuilder &fbb_;
  flatbuffers::uoffset_t start_;
  void add_max_int(int32_t max_int) {
    fbb_.AddElement<int32_t>(ReluNAttribute::VT_MAX_INT, max_int, 0);
  }
  void add_max_fp(float max_fp) {
    fbb_.AddElement<float>(ReluNAttribute::VT_MAX_FP, max_fp, 0.0f);
  }
  explicit ReluNAttributeBuilder(flatbuffers::FlatBufferBuilder &_fbb)
        : fbb_(_fbb) {
    start_ = fbb_.StartTable();
  }
  ReluNAttributeBuilder &operator=(const ReluNAttributeBuilder &);
  flatbuffers::Offset<ReluNAttribute> Finish() {
    const auto end = fbb_.EndTable(start_);
    auto o = flatbuffers::Offset<ReluNAttribute>(end);
    return o;
  }
};

inline flatbuffers::Offset<ReluNAttribute> CreateReluNAttribute(
    flatbuffers::FlatBufferBuilder &_fbb,
    int32_t max_int = 0,
    float max_fp = 0.0f) {
  ReluNAttributeBuilder builder_(_fbb);
  builder_.add_max_fp(max_fp);
  builder_.add_max_int(max_int);
  return builder_.Finish();
}

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

struct CustomAttribute FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
  enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
    VT_IDENTIFIER = 4
  };
  const flatbuffers::String *identifier() const {
    return GetPointer<const flatbuffers::String *>(VT_IDENTIFIER);
  }
  bool Verify(flatbuffers::Verifier &verifier) const {
    return VerifyTableStart(verifier) &&
           VerifyOffset(verifier, VT_IDENTIFIER) &&
           verifier.VerifyString(identifier()) &&
           verifier.EndTable();
  }
};

struct CustomAttributeBuilder {
  flatbuffers::FlatBufferBuilder &fbb_;
  flatbuffers::uoffset_t start_;
  void add_identifier(flatbuffers::Offset<flatbuffers::String> identifier) {
    fbb_.AddOffset(CustomAttribute::VT_IDENTIFIER, identifier);
  }
  explicit CustomAttributeBuilder(flatbuffers::FlatBufferBuilder &_fbb)
        : fbb_(_fbb) {
    start_ = fbb_.StartTable();
  }
  CustomAttributeBuilder &operator=(const CustomAttributeBuilder &);
  flatbuffers::Offset<CustomAttribute> Finish() {
    const auto end = fbb_.EndTable(start_);
    auto o = flatbuffers::Offset<CustomAttribute>(end);
    return o;
  }
};

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

struct TosaTensor FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
  enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
    VT_NAME = 4,
    VT_SHAPE = 6,
    VT_TYPE = 8,
    VT_USAGE = 10,
    VT_FORMAT = 12,
    VT_NPY_FILENAME = 14
  };
  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);
  }
  DType type() const {
    return static_cast<DType>(GetField<uint32_t>(VT_TYPE, 0));
  }
  const flatbuffers::Vector<uint32_t> *usage() const {
    return GetPointer<const flatbuffers::Vector<uint32_t> *>(VT_USAGE);
  }
  const flatbuffers::Vector<uint32_t> *format() const {
    return GetPointer<const flatbuffers::Vector<uint32_t> *>(VT_FORMAT);
  }
  const flatbuffers::String *npy_filename() const {
    return GetPointer<const flatbuffers::String *>(VT_NPY_FILENAME);
  }
  bool Verify(flatbuffers::Verifier &verifier) const {
    return VerifyTableStart(verifier) &&
           VerifyOffset(verifier, VT_NAME) &&
           verifier.VerifyString(name()) &&
           VerifyOffset(verifier, VT_SHAPE) &&
           verifier.VerifyVector(shape()) &&
           VerifyField<uint32_t>(verifier, VT_TYPE) &&
           VerifyOffset(verifier, VT_USAGE) &&
           verifier.VerifyVector(usage()) &&
           VerifyOffset(verifier, VT_FORMAT) &&
           verifier.VerifyVector(format()) &&
           VerifyOffset(verifier, VT_NPY_FILENAME) &&
           verifier.VerifyString(npy_filename()) &&
           verifier.EndTable();
  }
};

struct TosaTensorBuilder {
  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(DType type) {
    fbb_.AddElement<uint32_t>(TosaTensor::VT_TYPE, static_cast<uint32_t>(type), 0);
  }
  void add_usage(flatbuffers::Offset<flatbuffers::Vector<uint32_t>> usage) {
    fbb_.AddOffset(TosaTensor::VT_USAGE, usage);
  }
  void add_format(flatbuffers::Offset<flatbuffers::Vector<uint32_t>> format) {
    fbb_.AddOffset(TosaTensor::VT_FORMAT, format);
  }
  void add_npy_filename(flatbuffers::Offset<flatbuffers::String> npy_filename) {
    fbb_.AddOffset(TosaTensor::VT_NPY_FILENAME, npy_filename);
  }
  explicit TosaTensorBuilder(flatbuffers::FlatBufferBuilder &_fbb)
        : fbb_(_fbb) {
    start_ = fbb_.StartTable();
  }
  TosaTensorBuilder &operator=(const TosaTensorBuilder &);
  flatbuffers::Offset<TosaTensor> Finish() {
    const auto end = fbb_.EndTable(start_);
    auto o = flatbuffers::Offset<TosaTensor>(end);
    return o;
  }
};

inline flatbuffers::Offset<TosaTensor> CreateTosaTensor(
    flatbuffers::FlatBufferBuilder &_fbb,
    flatbuffers::Offset<flatbuffers::String> name = 0,
    flatbuffers::Offset<flatbuffers::Vector<int32_t>> shape = 0,
    DType type = DType_UNKNOWN,
    flatbuffers::Offset<flatbuffers::Vector<uint32_t>> usage = 0,
    flatbuffers::Offset<flatbuffers::Vector<uint32_t>> format = 0,
    flatbuffers::Offset<flatbuffers::String> npy_filename = 0) {
  TosaTensorBuilder builder_(_fbb);
  builder_.add_npy_filename(npy_filename);
  builder_.add_format(format);
  builder_.add_usage(usage);
  builder_.add_type(type);
  builder_.add_shape(shape);
  builder_.add_name(name);
  return builder_.Finish();
}

inline flatbuffers::Offset<TosaTensor> CreateTosaTensorDirect(
    flatbuffers::FlatBufferBuilder &_fbb,
    const char *name = nullptr,
    const std::vector<int32_t> *shape = nullptr,
    DType type = DType_UNKNOWN,
    const std::vector<uint32_t> *usage = nullptr,
    const std::vector<uint32_t> *format = nullptr,
    const char *npy_filename = nullptr) {
  auto name__ = name ? _fbb.CreateString(name) : 0;
  auto shape__ = shape ? _fbb.CreateVector<int32_t>(*shape) : 0;
  auto usage__ = usage ? _fbb.CreateVector<uint32_t>(*usage) : 0;
  auto format__ = format ? _fbb.CreateVector<uint32_t>(*format) : 0;
  auto npy_filename__ = npy_filename ? _fbb.CreateString(npy_filename) : 0;
  return tosa::CreateTosaTensor(
      _fbb,
      name__,
      shape__,
      type,
      usage__,
      format__,
      npy_filename__);
}

struct TosaOperator FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
  enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
    VT_OP = 4,
    VT_ATTRIBUTE_TYPE = 6,
    VT_ATTRIBUTE = 8,
    VT_INPUTS = 10,
    VT_OUTPUTS = 12,
    VT_QUANT_INFO_TYPE = 14,
    VT_QUANT_INFO = 16
  };
  Op op() const {
    return static_cast<Op>(GetField<uint32_t>(VT_OP, 0));
  }
  Attribute attribute_type() const {
    return static_cast<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 Pool2dAttribute *attribute_as_Pool2dAttribute() const {
    return attribute_type() == Attribute_Pool2dAttribute ? static_cast<const Pool2dAttribute *>(attribute()) : nullptr;
  }
  const Conv2dAttribute *attribute_as_Conv2dAttribute() const {
    return attribute_type() == Attribute_Conv2dAttribute ? static_cast<const Conv2dAttribute *>(attribute()) : nullptr;
  }
  const TransposeConv2dAttribute *attribute_as_TransposeConv2dAttribute() const {
    return attribute_type() == Attribute_TransposeConv2dAttribute ? static_cast<const TransposeConv2dAttribute *>(attribute()) : nullptr;
  }
  const ReluNAttribute *attribute_as_ReluNAttribute() const {
    return attribute_type() == Attribute_ReluNAttribute ? static_cast<const ReluNAttribute *>(attribute()) : nullptr;
  }
  const AxisAttribute *attribute_as_AxisAttribute() const {
    return attribute_type() == Attribute_AxisAttribute ? static_cast<const AxisAttribute *>(attribute()) : nullptr;
  }
  const ReshapeAttribute *attribute_as_ReshapeAttribute() const {
    return attribute_type() == Attribute_ReshapeAttribute ? static_cast<const ReshapeAttribute *>(attribute()) : nullptr;
  }
  const SliceAttribute *attribute_as_SliceAttribute() const {
    return attribute_type() == Attribute_SliceAttribute ? static_cast<const SliceAttribute *>(attribute()) : nullptr;
  }
  const TileAttribute *attribute_as_TileAttribute() const {
    return attribute_type() == Attribute_TileAttribute ? static_cast<const TileAttribute *>(attribute()) : nullptr;
  }
  const ResizeAttribute *attribute_as_ResizeAttribute() const {
    return attribute_type() == Attribute_ResizeAttribute ? static_cast<const ResizeAttribute *>(attribute()) : nullptr;
  }
  const ClampAttribute *attribute_as_ClampAttribute() const {
    return attribute_type() == Attribute_ClampAttribute ? static_cast<const ClampAttribute *>(attribute()) : nullptr;
  }
  const RescaleAttribute *attribute_as_RescaleAttribute() const {
    return attribute_type() == Attribute_RescaleAttribute ? static_cast<const RescaleAttribute *>(attribute()) : nullptr;
  }
  const CustomAttribute *attribute_as_CustomAttribute() const {
    return attribute_type() == Attribute_CustomAttribute ? static_cast<const CustomAttribute *>(attribute()) : nullptr;
  }
  const CondIfAttribute *attribute_as_CondIfAttribute() const {
    return attribute_type() == Attribute_CondIfAttribute ? static_cast<const CondIfAttribute *>(attribute()) : nullptr;
  }
  const WhileLoopAttribute *attribute_as_WhileLoopAttribute() const {
    return attribute_type() == Attribute_WhileLoopAttribute ? static_cast<const WhileLoopAttribute *>(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);
  }
  QuantInfo quant_info_type() const {
    return static_cast<QuantInfo>(GetField<uint8_t>(VT_QUANT_INFO_TYPE, 0));
  }
  const void *quant_info() const {
    return GetPointer<const void *>(VT_QUANT_INFO);
  }
  template<typename T> const T *quant_info_as() const;
  const UnaryQuantInfo *quant_info_as_UnaryQuantInfo() const {
    return quant_info_type() == QuantInfo_UnaryQuantInfo ? static_cast<const UnaryQuantInfo *>(quant_info()) : nullptr;
  }
  const ConvQuantInfo *quant_info_as_ConvQuantInfo() const {
    return quant_info_type() == QuantInfo_ConvQuantInfo ? static_cast<const ConvQuantInfo *>(quant_info()) : nullptr;
  }
  const MatMulQuantInfo *quant_info_as_MatMulQuantInfo() const {
    return quant_info_type() == QuantInfo_MatMulQuantInfo ? static_cast<const MatMulQuantInfo *>(quant_info()) : nullptr;
  }
  const PadQuantInfo *quant_info_as_PadQuantInfo() const {
    return quant_info_type() == QuantInfo_PadQuantInfo ? static_cast<const PadQuantInfo *>(quant_info()) : nullptr;
  }
  bool Verify(flatbuffers::Verifier &verifier) const {
    return VerifyTableStart(verifier) &&
           VerifyField<uint32_t>(verifier, VT_OP) &&
           VerifyField<uint8_t>(verifier, VT_ATTRIBUTE_TYPE) &&
           VerifyOffset(verifier, VT_ATTRIBUTE) &&
           VerifyAttribute(verifier, attribute(), attribute_type()) &&
           VerifyOffset(verifier, VT_INPUTS) &&
           verifier.VerifyVector(inputs()) &&
           verifier.VerifyVectorOfStrings(inputs()) &&
           VerifyOffset(verifier, VT_OUTPUTS) &&
           verifier.VerifyVector(outputs()) &&
           verifier.VerifyVectorOfStrings(outputs()) &&
           VerifyField<uint8_t>(verifier, VT_QUANT_INFO_TYPE) &&
           VerifyOffset(verifier, VT_QUANT_INFO) &&
           VerifyQuantInfo(verifier, quant_info(), quant_info_type()) &&
           verifier.EndTable();
  }
};

template<> inline const Pool2dAttribute *TosaOperator::attribute_as<Pool2dAttribute>() const {
  return attribute_as_Pool2dAttribute();
}

template<> inline const Conv2dAttribute *TosaOperator::attribute_as<Conv2dAttribute>() const {
  return attribute_as_Conv2dAttribute();
}

template<> inline const TransposeConv2dAttribute *TosaOperator::attribute_as<TransposeConv2dAttribute>() const {
  return attribute_as_TransposeConv2dAttribute();
}

template<> inline const ReluNAttribute *TosaOperator::attribute_as<ReluNAttribute>() const {
  return attribute_as_ReluNAttribute();
}

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

inline flatbuffers::Offset<TosaOperator> CreateTosaOperatorDirect(
    flatbuffers::FlatBufferBuilder &_fbb,
    Op op = Op_UNKNOWN,
    Attribute attribute_type = 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,
    QuantInfo quant_info_type = QuantInfo_NONE,
    flatbuffers::Offset<void> quant_info = 0) {
  auto inputs__ = inputs ? _fbb.CreateVector<flatbuffers::Offset<flatbuffers::String>>(*inputs) : 0;
  auto outputs__ = outputs ? _fbb.CreateVector<flatbuffers::Offset<flatbuffers::String>>(*outputs) : 0;
  return tosa::CreateTosaOperator(
      _fbb,
      op,
      attribute_type,
      attribute,
      inputs__,
      outputs__,
      quant_info_type,
      quant_info);
}

struct TosaBasicBlock FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
  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<TosaOperator>> *operators() const {
    return GetPointer<const flatbuffers::Vector<flatbuffers::Offset<TosaOperator>> *>(VT_OPERATORS);
  }
  const flatbuffers::Vector<flatbuffers::Offset<TosaTensor>> *tensors() const {
    return GetPointer<const flatbuffers::Vector<flatbuffers::Offset<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 {
  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<TosaOperator>>> operators) {
    fbb_.AddOffset(TosaBasicBlock::VT_OPERATORS, operators);
  }
  void add_tensors(flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<TosaTensor>>> tensors) {
    fbb_.AddOffset(TosaBasicBlock::VT_TENSORS, tensors);
  }
  void add_inputs(flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>>> inputs) {
    fbb_.AddOffset(TosaBasicBlock::VT_INPUTS, inputs);
  }
  void add_outputs(flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>>> outputs) {
    fbb_.AddOffset(TosaBasicBlock::VT_OUTPUTS, outputs);
  }
  explicit TosaBasicBlockBuilder(flatbuffers::FlatBufferBuilder &_fbb)
        : fbb_(_fbb) {
    start_ = fbb_.StartTable();
  }
  TosaBasicBlockBuilder &operator=(const TosaBasicBlockBuilder &);
  flatbuffers::Offset<TosaBasicBlock> Finish() {
    const auto end = fbb_.EndTable(start_);
    auto o = flatbuffers::Offset<TosaBasicBlock>(end);
    return o;
  }
};

inline flatbuffers::Offset<TosaBasicBlock> CreateTosaBasicBlock(
    flatbuffers::FlatBufferBuilder &_fbb,
    flatbuffers::Offset<flatbuffers::String> name = 0,
    flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<TosaOperator>>> operators = 0,
    flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<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<TosaOperator>> *operators = nullptr,
    const std::vector<flatbuffers::Offset<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<TosaOperator>>(*operators) : 0;
  auto tensors__ = tensors ? _fbb.CreateVector<flatbuffers::Offset<TosaTensor>>(*tensors) : 0;
  auto inputs__ = inputs ? _fbb.CreateVector<flatbuffers::Offset<flatbuffers::String>>(*inputs) : 0;
  auto outputs__ = outputs ? _fbb.CreateVector<flatbuffers::Offset<flatbuffers::String>>(*outputs) : 0;
  return tosa::CreateTosaBasicBlock(
      _fbb,
      name__,
      operators__,
      tensors__,
      inputs__,
      outputs__);
}

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

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

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

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

inline bool VerifyAttribute(flatbuffers::Verifier &verifier, const void *obj, Attribute type) {
  switch (type) {
    case Attribute_NONE: {
      return true;
    }
    case Attribute_Pool2dAttribute: {
      auto ptr = reinterpret_cast<const Pool2dAttribute *>(obj);
      return verifier.VerifyTable(ptr);
    }
    case Attribute_Conv2dAttribute: {
      auto ptr = reinterpret_cast<const Conv2dAttribute *>(obj);
      return verifier.VerifyTable(ptr);
    }
    case Attribute_TransposeConv2dAttribute: {
      auto ptr = reinterpret_cast<const TransposeConv2dAttribute *>(obj);
      return verifier.VerifyTable(ptr);
    }
    case Attribute_ReluNAttribute: {
      auto ptr = reinterpret_cast<const ReluNAttribute *>(obj);
      return verifier.VerifyTable(ptr);
    }
    case Attribute_AxisAttribute: {
      auto ptr = reinterpret_cast<const AxisAttribute *>(obj);
      return verifier.VerifyTable(ptr);
    }
    case Attribute_ReshapeAttribute: {
      auto ptr = reinterpret_cast<const ReshapeAttribute *>(obj);
      return verifier.VerifyTable(ptr);
    }
    case Attribute_SliceAttribute: {
      auto ptr = reinterpret_cast<const SliceAttribute *>(obj);
      return verifier.VerifyTable(ptr);
    }
    case Attribute_TileAttribute: {
      auto ptr = reinterpret_cast<const TileAttribute *>(obj);
      return verifier.VerifyTable(ptr);
    }
    case Attribute_ResizeAttribute: {
      auto ptr = reinterpret_cast<const ResizeAttribute *>(obj);
      return verifier.VerifyTable(ptr);
    }
    case Attribute_ClampAttribute: {
      auto ptr = reinterpret_cast<const ClampAttribute *>(obj);
      return verifier.VerifyTable(ptr);
    }
    case Attribute_RescaleAttribute: {
      auto ptr = reinterpret_cast<const RescaleAttribute *>(obj);
      return verifier.VerifyTable(ptr);
    }
    case Attribute_CustomAttribute: {
      auto ptr = reinterpret_cast<const CustomAttribute *>(obj);
      return verifier.VerifyTable(ptr);
    }
    case Attribute_CondIfAttribute: {
      auto ptr = reinterpret_cast<const CondIfAttribute *>(obj);
      return verifier.VerifyTable(ptr);
    }
    case Attribute_WhileLoopAttribute: {
      auto ptr = reinterpret_cast<const WhileLoopAttribute *>(obj);
      return verifier.VerifyTable(ptr);
    }
    default: return false;
  }
}

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

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

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

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

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

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

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

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

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

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

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

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

}  // namespace tosa

#endif  // FLATBUFFERS_GENERATED_TOSA_TOSA_H_
