
// Copyright (c) 2020-2021, 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 PoolAttribute;
struct PoolAttributeBuilder;

struct ConvAttribute;
struct ConvAttributeBuilder;

struct TransposeConvAttribute;
struct TransposeConvAttributeBuilder;

struct PadAttribute;
struct PadAttributeBuilder;

struct AxisAttribute;
struct AxisAttributeBuilder;

struct ReshapeAttribute;
struct ReshapeAttributeBuilder;

struct SliceAttribute;
struct SliceAttributeBuilder;

struct TileAttribute;
struct TileAttributeBuilder;

struct ResizeAttribute;
struct ResizeAttributeBuilder;

struct ClampAttribute;
struct ClampAttributeBuilder;

struct RescaleAttribute;
struct RescaleAttributeBuilder;

struct MulAttribute;
struct MulAttributeBuilder;

struct ArithmeticRightShiftAttribute;
struct ArithmeticRightShiftAttributeBuilder;

struct CondIfAttribute;
struct CondIfAttributeBuilder;

struct WhileLoopAttribute;
struct WhileLoopAttributeBuilder;

struct TransposeAttribute;
struct TransposeAttributeBuilder;

struct TableAttribute;
struct TableAttributeBuilder;

struct UnaryQuantInfo;
struct UnaryQuantInfoBuilder;

struct ConvQuantInfo;
struct ConvQuantInfoBuilder;

struct MatMulQuantInfo;
struct MatMulQuantInfoBuilder;

struct PadQuantInfo;
struct PadQuantInfoBuilder;

struct Version;
struct VersionBuilder;

struct TosaTensor;
struct TosaTensorBuilder;

struct TosaOperator;
struct TosaOperatorBuilder;

struct TosaBasicBlock;
struct TosaBasicBlockBuilder;

struct TosaGraph;
struct TosaGraphBuilder;

enum DType {
  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_FLOAT = 8,
  DType_MIN = DType_UNKNOWN,
  DType_MAX = DType_FLOAT
};

inline const DType (&EnumValuesDType())[9] {
  static const DType values[] = {
    DType_UNKNOWN,
    DType_BOOL,
    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[10] = {
    "UNKNOWN",
    "BOOL",
    "UINT8",
    "INT4",
    "INT8",
    "INT16",
    "INT32",
    "INT48",
    "FLOAT",
    nullptr
  };
  return names;
}

inline const char *EnumNameDType(DType e) {
  if (flatbuffers::IsOutRange(e, DType_UNKNOWN, DType_FLOAT)) return "";
  const size_t index = static_cast<size_t>(e);
  return EnumNamesDType()[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[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 {
  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_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_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
  };
  return values;
}

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

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

enum Attribute {
  Attribute_NONE = 0,
  Attribute_PoolAttribute = 1,
  Attribute_ConvAttribute = 2,
  Attribute_TransposeConvAttribute = 3,
  Attribute_PadAttribute = 4,
  Attribute_AxisAttribute = 5,
  Attribute_ReshapeAttribute = 6,
  Attribute_SliceAttribute = 7,
  Attribute_TileAttribute = 8,
  Attribute_ResizeAttribute = 9,
  Attribute_ClampAttribute = 10,
  Attribute_RescaleAttribute = 11,
  Attribute_MulAttribute = 12,
  Attribute_ArithmeticRightShiftAttribute = 13,
  Attribute_CondIfAttribute = 14,
  Attribute_WhileLoopAttribute = 15,
  Attribute_TransposeAttribute = 16,
  Attribute_TableAttribute = 17,
  Attribute_MIN = Attribute_NONE,
  Attribute_MAX = Attribute_TableAttribute
};

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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[6] = {
    "NONE",
    "UnaryQuantInfo",
    "ConvQuantInfo",
    "MatMulQuantInfo",
    "PadQuantInfo",
    nullptr
  };
  return names;
}

inline const char *EnumNameQuantInfo(QuantInfo e) {
  if (flatbuffers::IsOutRange(e, QuantInfo_NONE, 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<tosa::UnaryQuantInfo> {
  static const QuantInfo enum_value = QuantInfo_UnaryQuantInfo;
};

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

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

template<> struct QuantInfoTraits<tosa::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 PoolAttribute FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
  typedef PoolAttributeBuilder Builder;
  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 PoolAttributeBuilder {
  typedef PoolAttribute Table;
  flatbuffers::FlatBufferBuilder &fbb_;
  flatbuffers::uoffset_t start_;
  void add_padding(flatbuffers::Offset<flatbuffers::Vector<int32_t>> padding) {
    fbb_.AddOffset(PoolAttribute::VT_PADDING, padding);
  }
  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);
  }
  explicit PoolAttributeBuilder(flatbuffers::FlatBufferBuilder &_fbb)
        : fbb_(_fbb) {
    start_ = fbb_.StartTable();
  }
  PoolAttributeBuilder &operator=(const PoolAttributeBuilder &);
  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>> padding = 0,
    flatbuffers::Offset<flatbuffers::Vector<int32_t>> kernel = 0,
    flatbuffers::Offset<flatbuffers::Vector<int32_t>> stride = 0) {
  PoolAttributeBuilder builder_(_fbb);
  builder_.add_stride(stride);
  builder_.add_kernel(kernel);
  builder_.add_padding(padding);
  return builder_.Finish();
}

inline flatbuffers::Offset<PoolAttribute> CreatePoolAttributeDirect(
    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::CreatePoolAttribute(
      _fbb,
      padding__,
      kernel__,
      stride__);
}

struct ConvAttribute FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
  typedef ConvAttributeBuilder Builder;
  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 ConvAttributeBuilder {
  typedef ConvAttribute Table;
  flatbuffers::FlatBufferBuilder &fbb_;
  flatbuffers::uoffset_t start_;
  void add_padding(flatbuffers::Offset<flatbuffers::Vector<int32_t>> padding) {
    fbb_.AddOffset(ConvAttribute::VT_PADDING, padding);
  }
  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);
  }
  explicit ConvAttributeBuilder(flatbuffers::FlatBufferBuilder &_fbb)
        : fbb_(_fbb) {
    start_ = fbb_.StartTable();
  }
  ConvAttributeBuilder &operator=(const ConvAttributeBuilder &);
  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>> padding = 0,
    flatbuffers::Offset<flatbuffers::Vector<int32_t>> stride = 0,
    flatbuffers::Offset<flatbuffers::Vector<int32_t>> dilation = 0) {
  ConvAttributeBuilder builder_(_fbb);
  builder_.add_dilation(dilation);
  builder_.add_stride(stride);
  builder_.add_padding(padding);
  return builder_.Finish();
}

inline flatbuffers::Offset<ConvAttribute> CreateConvAttributeDirect(
    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::CreateConvAttribute(
      _fbb,
      padding__,
      stride__,
      dilation__);
}

struct TransposeConvAttribute FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
  typedef TransposeConvAttributeBuilder Builder;
  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 TransposeConvAttributeBuilder {
  typedef TransposeConvAttribute Table;
  flatbuffers::FlatBufferBuilder &fbb_;
  flatbuffers::uoffset_t start_;
  void add_outpad(flatbuffers::Offset<flatbuffers::Vector<int32_t>> outpad) {
    fbb_.AddOffset(TransposeConvAttribute::VT_OUTPAD, outpad);
  }
  void add_stride(flatbuffers::Offset<flatbuffers::Vector<int32_t>> stride) {
    fbb_.AddOffset(TransposeConvAttribute::VT_STRIDE, stride);
  }
  void add_dilation(flatbuffers::Offset<flatbuffers::Vector<int32_t>> dilation) {
    fbb_.AddOffset(TransposeConvAttribute::VT_DILATION, dilation);
  }
  void add_output_shape(flatbuffers::Offset<flatbuffers::Vector<int32_t>> output_shape) {
    fbb_.AddOffset(TransposeConvAttribute::VT_OUTPUT_SHAPE, output_shape);
  }
  explicit TransposeConvAttributeBuilder(flatbuffers::FlatBufferBuilder &_fbb)
        : fbb_(_fbb) {
    start_ = fbb_.StartTable();
  }
  TransposeConvAttributeBuilder &operator=(const TransposeConvAttributeBuilder &);
  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>> 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) {
  TransposeConvAttributeBuilder 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<TransposeConvAttribute> CreateTransposeConvAttributeDirect(
    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::CreateTransposeConvAttribute(
      _fbb,
      outpad__,
      stride__,
      dilation__,
      output_shape__);
}

struct PadAttribute FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
  typedef PadAttributeBuilder Builder;
  enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
    VT_PADDING = 4,
    VT_PAD_CONST_INT = 6,
    VT_PAD_CONST_FP = 8
  };
  const flatbuffers::Vector<int32_t> *padding() const {
    return GetPointer<const flatbuffers::Vector<int32_t> *>(VT_PADDING);
  }
  int32_t pad_const_int() const {
    return GetField<int32_t>(VT_PAD_CONST_INT, 0);
  }
  float pad_const_fp() const {
    return GetField<float>(VT_PAD_CONST_FP, 0.0f);
  }
  bool Verify(flatbuffers::Verifier &verifier) const {
    return VerifyTableStart(verifier) &&
           VerifyOffset(verifier, VT_PADDING) &&
           verifier.VerifyVector(padding()) &&
           VerifyField<int32_t>(verifier, VT_PAD_CONST_INT) &&
           VerifyField<float>(verifier, VT_PAD_CONST_FP) &&
           verifier.EndTable();
  }
};

struct PadAttributeBuilder {
  typedef PadAttribute Table;
  flatbuffers::FlatBufferBuilder &fbb_;
  flatbuffers::uoffset_t start_;
  void add_padding(flatbuffers::Offset<flatbuffers::Vector<int32_t>> padding) {
    fbb_.AddOffset(PadAttribute::VT_PADDING, padding);
  }
  void add_pad_const_int(int32_t pad_const_int) {
    fbb_.AddElement<int32_t>(PadAttribute::VT_PAD_CONST_INT, pad_const_int, 0);
  }
  void add_pad_const_fp(float pad_const_fp) {
    fbb_.AddElement<float>(PadAttribute::VT_PAD_CONST_FP, pad_const_fp, 0.0f);
  }
  explicit PadAttributeBuilder(flatbuffers::FlatBufferBuilder &_fbb)
        : fbb_(_fbb) {
    start_ = fbb_.StartTable();
  }
  PadAttributeBuilder &operator=(const PadAttributeBuilder &);
  flatbuffers::Offset<PadAttribute> Finish() {
    const auto end = fbb_.EndTable(start_);
    auto o = flatbuffers::Offset<PadAttribute>(end);
    return o;
  }
};

inline flatbuffers::Offset<PadAttribute> CreatePadAttribute(
    flatbuffers::FlatBufferBuilder &_fbb,
    flatbuffers::Offset<flatbuffers::Vector<int32_t>> padding = 0,
    int32_t pad_const_int = 0,
    float pad_const_fp = 0.0f) {
  PadAttributeBuilder builder_(_fbb);
  builder_.add_pad_const_fp(pad_const_fp);
  builder_.add_pad_const_int(pad_const_int);
  builder_.add_padding(padding);
  return builder_.Finish();
}

inline flatbuffers::Offset<PadAttribute> CreatePadAttributeDirect(
    flatbuffers::FlatBufferBuilder &_fbb,
    const std::vector<int32_t> *padding = nullptr,
    int32_t pad_const_int = 0,
    float pad_const_fp = 0.0f) {
  auto padding__ = padding ? _fbb.CreateVector<int32_t>(*padding) : 0;
  return tosa::CreatePadAttribute(
      _fbb,
      padding__,
      pad_const_int,
      pad_const_fp);
}

struct AxisAttribute FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
  typedef AxisAttributeBuilder Builder;
  enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
    VT_AXIS = 4
  };
  int32_t axis() const {
    return GetField<int32_t>(VT_AXIS, 0);
  }
  bool Verify(flatbuffers::Verifier &verifier) const {
    return VerifyTableStart(verifier) &&
           VerifyField<int32_t>(verifier, VT_AXIS) &&
           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();
  }
  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 {
  typedef ReshapeAttributeBuilder Builder;
  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 {
  typedef ReshapeAttribute Table;
  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 {
  typedef SliceAttributeBuilder Builder;
  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 {
  typedef SliceAttribute Table;
  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 {
  typedef TileAttributeBuilder Builder;
  enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
    VT_MULTIPLES = 4
  };
  const flatbuffers::Vector<int32_t> *multiples() const {
    return GetPointer<const flatbuffers::Vector<int32_t> *>(VT_MULTIPLES);
  }
  bool Verify(flatbuffers::Verifier &verifier) const {
    return VerifyTableStart(verifier) &&
           VerifyOffset(verifier, VT_MULTIPLES) &&
           verifier.VerifyVector(multiples()) &&
           verifier.EndTable();
  }
};

struct TileAttributeBuilder {
  typedef TileAttribute Table;
  flatbuffers::FlatBufferBuilder &fbb_;
  flatbuffers::uoffset_t start_;
  void add_multiples(flatbuffers::Offset<flatbuffers::Vector<int32_t>> multiples) {
    fbb_.AddOffset(TileAttribute::VT_MULTIPLES, multiples);
  }
  explicit TileAttributeBuilder(flatbuffers::FlatBufferBuilder &_fbb)
        : fbb_(_fbb) {
    start_ = fbb_.StartTable();
  }
  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 {
  typedef ResizeAttributeBuilder Builder;
  enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
    VT_OUTPUT_SIZE = 4,
    VT_STRIDE = 6,
    VT_OFFSET = 8,
    VT_SHIFT = 10,
    VT_STRIDE_FP = 12,
    VT_OFFSET_FP = 14,
    VT_MODE = 16
  };
  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);
  }
  const flatbuffers::Vector<float> *stride_fp() const {
    return GetPointer<const flatbuffers::Vector<float> *>(VT_STRIDE_FP);
  }
  const flatbuffers::Vector<float> *offset_fp() const {
    return GetPointer<const flatbuffers::Vector<float> *>(VT_OFFSET_FP);
  }
  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_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) &&
           VerifyOffset(verifier, VT_STRIDE_FP) &&
           verifier.VerifyVector(stride_fp()) &&
           VerifyOffset(verifier, VT_OFFSET_FP) &&
           verifier.VerifyVector(offset_fp()) &&
           VerifyField<uint32_t>(verifier, VT_MODE) &&
           verifier.EndTable();
  }
};

struct ResizeAttributeBuilder {
  typedef ResizeAttribute Table;
  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_stride_fp(flatbuffers::Offset<flatbuffers::Vector<float>> stride_fp) {
    fbb_.AddOffset(ResizeAttribute::VT_STRIDE_FP, stride_fp);
  }
  void add_offset_fp(flatbuffers::Offset<flatbuffers::Vector<float>> offset_fp) {
    fbb_.AddOffset(ResizeAttribute::VT_OFFSET_FP, offset_fp);
  }
  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();
  }
  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,
    flatbuffers::Offset<flatbuffers::Vector<float>> stride_fp = 0,
    flatbuffers::Offset<flatbuffers::Vector<float>> offset_fp = 0,
    tosa::ResizeMode mode = tosa::ResizeMode_UNKNOWN) {
  ResizeAttributeBuilder builder_(_fbb);
  builder_.add_mode(mode);
  builder_.add_offset_fp(offset_fp);
  builder_.add_stride_fp(stride_fp);
  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,
    const std::vector<float> *stride_fp = nullptr,
    const std::vector<float> *offset_fp = nullptr,
    tosa::ResizeMode mode = tosa::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;
  auto stride_fp__ = stride_fp ? _fbb.CreateVector<float>(*stride_fp) : 0;
  auto offset_fp__ = offset_fp ? _fbb.CreateVector<float>(*offset_fp) : 0;
  return tosa::CreateResizeAttribute(
      _fbb,
      output_size__,
      stride__,
      offset__,
      shift,
      stride_fp__,
      offset_fp__,
      mode);
}

struct ClampAttribute FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
  typedef ClampAttributeBuilder Builder;
  enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
    VT_MIN_INT = 4,
    VT_MAX_INT = 6,
    VT_MIN_FP = 8,
    VT_MAX_FP = 10
  };
  int32_t min_int() const {
    return GetField<int32_t>(VT_MIN_INT, 0);
  }
  int32_t max_int() const {
    return GetField<int32_t>(VT_MAX_INT, 0);
  }
  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 {
  typedef ClampAttribute Table;
  flatbuffers::FlatBufferBuilder &fbb_;
  flatbuffers::uoffset_t start_;
  void add_min_int(int32_t min_int) {
    fbb_.AddElement<int32_t>(ClampAttribute::VT_MIN_INT, min_int, 0);
  }
  void add_max_int(int32_t max_int) {
    fbb_.AddElement<int32_t>(ClampAttribute::VT_MAX_INT, max_int, 0);
  }
  void add_min_fp(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 {
  typedef RescaleAttributeBuilder Builder;
  enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
    VT_INPUT_ZP = 4,
    VT_OUTPUT_ZP = 6,
    VT_MULTIPLIER = 8,
    VT_SHIFT = 10,
    VT_SCALE32 = 12,
    VT_DOUBLE_ROUND = 14,
    VT_PER_CHANNEL = 16
  };
  int32_t input_zp() const {
    return GetField<int32_t>(VT_INPUT_ZP, 0);
  }
  int32_t output_zp() const {
    return GetField<int32_t>(VT_OUTPUT_ZP, 0);
  }
  const flatbuffers::Vector<int32_t> *multiplier() const {
    return GetPointer<const flatbuffers::Vector<int32_t> *>(VT_MULTIPLIER);
  }
  const flatbuffers::Vector<int32_t> *shift() const {
    return GetPointer<const flatbuffers::Vector<int32_t> *>(VT_SHIFT);
  }
  bool scale32() const {
    return GetField<uint8_t>(VT_SCALE32, 0) != 0;
  }
  bool double_round() const {
    return GetField<uint8_t>(VT_DOUBLE_ROUND, 0) != 0;
  }
  bool per_channel() const {
    return GetField<uint8_t>(VT_PER_CHANNEL, 0) != 0;
  }
  bool Verify(flatbuffers::Verifier &verifier) const {
    return VerifyTableStart(verifier) &&
           VerifyField<int32_t>(verifier, VT_INPUT_ZP) &&
           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 {
  typedef RescaleAttribute Table;
  flatbuffers::FlatBufferBuilder &fbb_;
  flatbuffers::uoffset_t start_;
  void add_input_zp(int32_t input_zp) {
    fbb_.AddElement<int32_t>(RescaleAttribute::VT_INPUT_ZP, input_zp, 0);
  }
  void add_output_zp(int32_t output_zp) {
    fbb_.AddElement<int32_t>(RescaleAttribute::VT_OUTPUT_ZP, output_zp, 0);
  }
  void add_multiplier(flatbuffers::Offset<flatbuffers::Vector<int32_t>> multiplier) {
    fbb_.AddOffset(RescaleAttribute::VT_MULTIPLIER, multiplier);
  }
  void add_shift(flatbuffers::Offset<flatbuffers::Vector<int32_t>> shift) {
    fbb_.AddOffset(RescaleAttribute::VT_SHIFT, shift);
  }
  void add_scale32(bool scale32) {
    fbb_.AddElement<uint8_t>(RescaleAttribute::VT_SCALE32, static_cast<uint8_t>(scale32), 0);
  }
  void add_double_round(bool double_round) {
    fbb_.AddElement<uint8_t>(RescaleAttribute::VT_DOUBLE_ROUND, static_cast<uint8_t>(double_round), 0);
  }
  void add_per_channel(bool per_channel) {
    fbb_.AddElement<uint8_t>(RescaleAttribute::VT_PER_CHANNEL, static_cast<uint8_t>(per_channel), 0);
  }
  explicit RescaleAttributeBuilder(flatbuffers::FlatBufferBuilder &_fbb)
        : fbb_(_fbb) {
    start_ = fbb_.StartTable();
  }
  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 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) &&
           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();
  }
  MulAttributeBuilder &operator=(const MulAttributeBuilder &);
  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) &&
           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();
  }
  ArithmeticRightShiftAttributeBuilder &operator=(const ArithmeticRightShiftAttributeBuilder &);
  flatbuffers::Offset<ArithmeticRightShiftAttribute> Finish() {
    const auto end = fbb_.EndTable(start_);
    auto o = flatbuffers::Offset<ArithmeticRightShiftAttribute>(end);
    return o;
  }
};

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

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

struct CondIfAttributeBuilder {
  typedef CondIfAttribute Table;
  flatbuffers::FlatBufferBuilder &fbb_;
  flatbuffers::uoffset_t start_;
  void add_then_branch(flatbuffers::Offset<flatbuffers::String> then_branch) {
    fbb_.AddOffset(CondIfAttribute::VT_THEN_BRANCH, then_branch);
  }
  void add_else_branch(flatbuffers::Offset<flatbuffers::String> else_branch) {
    fbb_.AddOffset(CondIfAttribute::VT_ELSE_BRANCH, else_branch);
  }
  explicit CondIfAttributeBuilder(flatbuffers::FlatBufferBuilder &_fbb)
        : fbb_(_fbb) {
    start_ = fbb_.StartTable();
  }
  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 {
  typedef WhileLoopAttributeBuilder Builder;
  enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
    VT_COND_BRANCH = 4,
    VT_BODY_BRANCH = 6
  };
  const flatbuffers::String *cond_branch() const {
    return GetPointer<const flatbuffers::String *>(VT_COND_BRANCH);
  }
  const flatbuffers::String *body_branch() const {
    return GetPointer<const flatbuffers::String *>(VT_BODY_BRANCH);
  }
  bool Verify(flatbuffers::Verifier &verifier) const {
    return VerifyTableStart(verifier) &&
           VerifyOffset(verifier, VT_COND_BRANCH) &&
           verifier.VerifyString(cond_branch()) &&
           VerifyOffset(verifier, VT_BODY_BRANCH) &&
           verifier.VerifyString(body_branch()) &&
           verifier.EndTable();
  }
};

struct WhileLoopAttributeBuilder {
  typedef WhileLoopAttribute Table;
  flatbuffers::FlatBufferBuilder &fbb_;
  flatbuffers::uoffset_t start_;
  void add_cond_branch(flatbuffers::Offset<flatbuffers::String> cond_branch) {
    fbb_.AddOffset(WhileLoopAttribute::VT_COND_BRANCH, cond_branch);
  }
  void add_body_branch(flatbuffers::Offset<flatbuffers::String> body_branch) {
    fbb_.AddOffset(WhileLoopAttribute::VT_BODY_BRANCH, body_branch);
  }
  explicit WhileLoopAttributeBuilder(flatbuffers::FlatBufferBuilder &_fbb)
        : fbb_(_fbb) {
    start_ = fbb_.StartTable();
  }
  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 TransposeAttribute FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
  typedef TransposeAttributeBuilder Builder;
  enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
    VT_PERM = 4
  };
  const flatbuffers::Vector<int32_t> *perm() const {
    return GetPointer<const flatbuffers::Vector<int32_t> *>(VT_PERM);
  }
  bool Verify(flatbuffers::Verifier &verifier) const {
    return VerifyTableStart(verifier) &&
           VerifyOffset(verifier, VT_PERM) &&
           verifier.VerifyVector(perm()) &&
           verifier.EndTable();
  }
};

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

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

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

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

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

struct ConvQuantInfoBuilder {
  typedef ConvQuantInfo Table;
  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 {
  typedef MatMulQuantInfoBuilder 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) &&
           VerifyField<int32_t>(verifier, VT_B_ZP) &&
           verifier.EndTable();
  }
};

struct MatMulQuantInfoBuilder {
  typedef MatMulQuantInfo Table;
  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 {
  typedef PadQuantInfoBuilder Builder;
  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 {
  typedef PadQuantInfo Table;
  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 {
  typedef VersionBuilder Builder;
  enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
    VT__MAJOR = 4,
    VT__MINOR = 6,
    VT__PATCH = 8,
    VT__DRAFT = 10
  };
  int32_t _major() const {
    return GetField<int32_t>(VT__MAJOR, 0);
  }
  int32_t _minor() const {
    return GetField<int32_t>(VT__MINOR, 23);
  }
  int32_t _patch() const {
    return GetField<int32_t>(VT__PATCH, 0);
  }
  bool _draft() const {
    return GetField<uint8_t>(VT__DRAFT, 1) != 0;
  }
  bool Verify(flatbuffers::Verifier &verifier) const {
    return VerifyTableStart(verifier) &&
           VerifyField<int32_t>(verifier, VT__MAJOR) &&
           VerifyField<int32_t>(verifier, VT__MINOR) &&
           VerifyField<int32_t>(verifier, VT__PATCH) &&
           VerifyField<uint8_t>(verifier, VT__DRAFT) &&
           verifier.EndTable();
  }
};

struct VersionBuilder {
  typedef Version Table;
  flatbuffers::FlatBufferBuilder &fbb_;
  flatbuffers::uoffset_t start_;
  void add__major(int32_t _major) {
    fbb_.AddElement<int32_t>(Version::VT__MAJOR, _major, 0);
  }
  void add__minor(int32_t _minor) {
    fbb_.AddElement<int32_t>(Version::VT__MINOR, _minor, 23);
  }
  void add__patch(int32_t _patch) {
    fbb_.AddElement<int32_t>(Version::VT__PATCH, _patch, 0);
  }
  void add__draft(bool _draft) {
    fbb_.AddElement<uint8_t>(Version::VT__DRAFT, static_cast<uint8_t>(_draft), 1);
  }
  explicit VersionBuilder(flatbuffers::FlatBufferBuilder &_fbb)
        : fbb_(_fbb) {
    start_ = fbb_.StartTable();
  }
  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 = 23,
    int32_t _patch = 0,
    bool _draft = true) {
  VersionBuilder builder_(_fbb);
  builder_.add__patch(_patch);
  builder_.add__minor(_minor);
  builder_.add__major(_major);
  builder_.add__draft(_draft);
  return builder_.Finish();
}

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

struct TosaTensorBuilder {
  typedef TosaTensor Table;
  flatbuffers::FlatBufferBuilder &fbb_;
  flatbuffers::uoffset_t start_;
  void add_name(flatbuffers::Offset<flatbuffers::String> name) {
    fbb_.AddOffset(TosaTensor::VT_NAME, name);
  }
  void add_shape(flatbuffers::Offset<flatbuffers::Vector<int32_t>> shape) {
    fbb_.AddOffset(TosaTensor::VT_SHAPE, shape);
  }
  void add_type(tosa::DType type) {
    fbb_.AddElement<uint32_t>(TosaTensor::VT_TYPE, static_cast<uint32_t>(type), 0);
  }
  void add_data(flatbuffers::Offset<flatbuffers::Vector<uint8_t>> data) {
    fbb_.AddOffset(TosaTensor::VT_DATA, data);
  }
  explicit TosaTensorBuilder(flatbuffers::FlatBufferBuilder &_fbb)
        : fbb_(_fbb) {
    start_ = fbb_.StartTable();
  }
  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,
    tosa::DType type = tosa::DType_UNKNOWN,
    flatbuffers::Offset<flatbuffers::Vector<uint8_t>> data = 0) {
  TosaTensorBuilder builder_(_fbb);
  builder_.add_data(data);
  builder_.add_type(type);
  builder_.add_shape(shape);
  builder_.add_name(name);
  return builder_.Finish();
}

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

struct TosaOperator FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
  typedef TosaOperatorBuilder Builder;
  enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
    VT_OP = 4,
    VT_ATTRIBUTE_TYPE = 6,
    VT_ATTRIBUTE = 8,
    VT_INPUTS = 10,
    VT_OUTPUTS = 12,
    VT_QUANT_INFO_TYPE = 14,
    VT_QUANT_INFO = 16
  };
  tosa::Op op() const {
    return static_cast<tosa::Op>(GetField<uint32_t>(VT_OP, 0));
  }
  tosa::Attribute attribute_type() const {
    return static_cast<tosa::Attribute>(GetField<uint8_t>(VT_ATTRIBUTE_TYPE, 0));
  }
  const void *attribute() const {
    return GetPointer<const void *>(VT_ATTRIBUTE);
  }
  template<typename T> const T *attribute_as() const;
  const tosa::PoolAttribute *attribute_as_PoolAttribute() const {
    return attribute_type() == tosa::Attribute_PoolAttribute ? static_cast<const tosa::PoolAttribute *>(attribute()) : nullptr;
  }
  const tosa::ConvAttribute *attribute_as_ConvAttribute() const {
    return attribute_type() == tosa::Attribute_ConvAttribute ? static_cast<const tosa::ConvAttribute *>(attribute()) : nullptr;
  }
  const tosa::TransposeConvAttribute *attribute_as_TransposeConvAttribute() const {
    return attribute_type() == tosa::Attribute_TransposeConvAttribute ? static_cast<const tosa::TransposeConvAttribute *>(attribute()) : nullptr;
  }
  const tosa::PadAttribute *attribute_as_PadAttribute() const {
    return attribute_type() == tosa::Attribute_PadAttribute ? static_cast<const tosa::PadAttribute *>(attribute()) : nullptr;
  }
  const tosa::AxisAttribute *attribute_as_AxisAttribute() const {
    return attribute_type() == tosa::Attribute_AxisAttribute ? static_cast<const tosa::AxisAttribute *>(attribute()) : nullptr;
  }
  const tosa::ReshapeAttribute *attribute_as_ReshapeAttribute() const {
    return attribute_type() == tosa::Attribute_ReshapeAttribute ? static_cast<const tosa::ReshapeAttribute *>(attribute()) : nullptr;
  }
  const tosa::SliceAttribute *attribute_as_SliceAttribute() const {
    return attribute_type() == tosa::Attribute_SliceAttribute ? static_cast<const tosa::SliceAttribute *>(attribute()) : nullptr;
  }
  const tosa::TileAttribute *attribute_as_TileAttribute() const {
    return attribute_type() == tosa::Attribute_TileAttribute ? static_cast<const tosa::TileAttribute *>(attribute()) : nullptr;
  }
  const tosa::ResizeAttribute *attribute_as_ResizeAttribute() const {
    return attribute_type() == tosa::Attribute_ResizeAttribute ? static_cast<const tosa::ResizeAttribute *>(attribute()) : nullptr;
  }
  const tosa::ClampAttribute *attribute_as_ClampAttribute() const {
    return attribute_type() == tosa::Attribute_ClampAttribute ? static_cast<const tosa::ClampAttribute *>(attribute()) : nullptr;
  }
  const tosa::RescaleAttribute *attribute_as_RescaleAttribute() const {
    return attribute_type() == tosa::Attribute_RescaleAttribute ? static_cast<const tosa::RescaleAttribute *>(attribute()) : nullptr;
  }
  const tosa::MulAttribute *attribute_as_MulAttribute() const {
    return attribute_type() == tosa::Attribute_MulAttribute ? static_cast<const tosa::MulAttribute *>(attribute()) : nullptr;
  }
  const tosa::ArithmeticRightShiftAttribute *attribute_as_ArithmeticRightShiftAttribute() const {
    return attribute_type() == tosa::Attribute_ArithmeticRightShiftAttribute ? static_cast<const tosa::ArithmeticRightShiftAttribute *>(attribute()) : nullptr;
  }
  const tosa::CondIfAttribute *attribute_as_CondIfAttribute() const {
    return attribute_type() == tosa::Attribute_CondIfAttribute ? static_cast<const tosa::CondIfAttribute *>(attribute()) : nullptr;
  }
  const tosa::WhileLoopAttribute *attribute_as_WhileLoopAttribute() const {
    return attribute_type() == tosa::Attribute_WhileLoopAttribute ? static_cast<const tosa::WhileLoopAttribute *>(attribute()) : nullptr;
  }
  const tosa::TransposeAttribute *attribute_as_TransposeAttribute() const {
    return attribute_type() == tosa::Attribute_TransposeAttribute ? static_cast<const tosa::TransposeAttribute *>(attribute()) : nullptr;
  }
  const tosa::TableAttribute *attribute_as_TableAttribute() const {
    return attribute_type() == tosa::Attribute_TableAttribute ? static_cast<const tosa::TableAttribute *>(attribute()) : nullptr;
  }
  const 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);
  }
  tosa::QuantInfo quant_info_type() const {
    return static_cast<tosa::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 tosa::UnaryQuantInfo *quant_info_as_UnaryQuantInfo() const {
    return quant_info_type() == tosa::QuantInfo_UnaryQuantInfo ? static_cast<const tosa::UnaryQuantInfo *>(quant_info()) : nullptr;
  }
  const tosa::ConvQuantInfo *quant_info_as_ConvQuantInfo() const {
    return quant_info_type() == tosa::QuantInfo_ConvQuantInfo ? static_cast<const tosa::ConvQuantInfo *>(quant_info()) : nullptr;
  }
  const tosa::MatMulQuantInfo *quant_info_as_MatMulQuantInfo() const {
    return quant_info_type() == tosa::QuantInfo_MatMulQuantInfo ? static_cast<const tosa::MatMulQuantInfo *>(quant_info()) : nullptr;
  }
  const tosa::PadQuantInfo *quant_info_as_PadQuantInfo() const {
    return quant_info_type() == tosa::QuantInfo_PadQuantInfo ? static_cast<const tosa::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 tosa::PoolAttribute *TosaOperator::attribute_as<tosa::PoolAttribute>() const {
  return attribute_as_PoolAttribute();
}

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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);
  }
  void add_quant_info_type(tosa::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,
    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,
    tosa::QuantInfo quant_info_type = tosa::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,
    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,
    tosa::QuantInfo quant_info_type = tosa::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 {
  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();
  }
  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<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 TosaGraph FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
  typedef TosaGraphBuilder Builder;
  enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
    VT_VERSION = 4,
    VT_BLOCKS = 6
  };
  const tosa::Version *version() const {
    return GetPointer<const tosa::Version *>(VT_VERSION);
  }
  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_VERSION) &&
           verifier.VerifyTable(version()) &&
           VerifyOffset(verifier, VT_BLOCKS) &&
           verifier.VerifyVector(blocks()) &&
           verifier.VerifyVectorOfTables(blocks()) &&
           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_blocks(flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<tosa::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<tosa::Version> version = 0,
    flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<tosa::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<tosa::Version> version = 0,
    const std::vector<flatbuffers::Offset<tosa::TosaBasicBlock>> *blocks = nullptr) {
  auto blocks__ = blocks ? _fbb.CreateVector<flatbuffers::Offset<tosa::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_PoolAttribute: {
      auto ptr = reinterpret_cast<const tosa::PoolAttribute *>(obj);
      return verifier.VerifyTable(ptr);
    }
    case Attribute_ConvAttribute: {
      auto ptr = reinterpret_cast<const tosa::ConvAttribute *>(obj);
      return verifier.VerifyTable(ptr);
    }
    case Attribute_TransposeConvAttribute: {
      auto ptr = reinterpret_cast<const tosa::TransposeConvAttribute *>(obj);
      return verifier.VerifyTable(ptr);
    }
    case Attribute_PadAttribute: {
      auto ptr = reinterpret_cast<const tosa::PadAttribute *>(obj);
      return verifier.VerifyTable(ptr);
    }
    case Attribute_AxisAttribute: {
      auto ptr = reinterpret_cast<const tosa::AxisAttribute *>(obj);
      return verifier.VerifyTable(ptr);
    }
    case Attribute_ReshapeAttribute: {
      auto ptr = reinterpret_cast<const tosa::ReshapeAttribute *>(obj);
      return verifier.VerifyTable(ptr);
    }
    case Attribute_SliceAttribute: {
      auto ptr = reinterpret_cast<const tosa::SliceAttribute *>(obj);
      return verifier.VerifyTable(ptr);
    }
    case Attribute_TileAttribute: {
      auto ptr = reinterpret_cast<const tosa::TileAttribute *>(obj);
      return verifier.VerifyTable(ptr);
    }
    case Attribute_ResizeAttribute: {
      auto ptr = reinterpret_cast<const tosa::ResizeAttribute *>(obj);
      return verifier.VerifyTable(ptr);
    }
    case Attribute_ClampAttribute: {
      auto ptr = reinterpret_cast<const tosa::ClampAttribute *>(obj);
      return verifier.VerifyTable(ptr);
    }
    case Attribute_RescaleAttribute: {
      auto ptr = reinterpret_cast<const tosa::RescaleAttribute *>(obj);
      return verifier.VerifyTable(ptr);
    }
    case Attribute_MulAttribute: {
      auto ptr = reinterpret_cast<const tosa::MulAttribute *>(obj);
      return verifier.VerifyTable(ptr);
    }
    case Attribute_ArithmeticRightShiftAttribute: {
      auto ptr = reinterpret_cast<const tosa::ArithmeticRightShiftAttribute *>(obj);
      return verifier.VerifyTable(ptr);
    }
    case Attribute_CondIfAttribute: {
      auto ptr = reinterpret_cast<const tosa::CondIfAttribute *>(obj);
      return verifier.VerifyTable(ptr);
    }
    case Attribute_WhileLoopAttribute: {
      auto ptr = reinterpret_cast<const tosa::WhileLoopAttribute *>(obj);
      return verifier.VerifyTable(ptr);
    }
    case Attribute_TransposeAttribute: {
      auto ptr = reinterpret_cast<const tosa::TransposeAttribute *>(obj);
      return verifier.VerifyTable(ptr);
    }
    case Attribute_TableAttribute: {
      auto ptr = reinterpret_cast<const tosa::TableAttribute *>(obj);
      return verifier.VerifyTable(ptr);
    }
    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 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 tosa::UnaryQuantInfo *>(obj);
      return verifier.VerifyTable(ptr);
    }
    case QuantInfo_ConvQuantInfo: {
      auto ptr = reinterpret_cast<const tosa::ConvQuantInfo *>(obj);
      return verifier.VerifyTable(ptr);
    }
    case QuantInfo_MatMulQuantInfo: {
      auto ptr = reinterpret_cast<const tosa::MatMulQuantInfo *>(obj);
      return verifier.VerifyTable(ptr);
    }
    case QuantInfo_PadQuantInfo: {
      auto ptr = reinterpret_cast<const tosa::PadQuantInfo *>(obj);
      return verifier.VerifyTable(ptr);
    }
    default: return true;
  }
}

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_
