diff --git a/include/tosa_generated.h b/include/tosa_generated.h
new file mode 100644
index 0000000..5e883a1
--- /dev/null
+++ b/include/tosa_generated.h
@@ -0,0 +1,2649 @@
+
+// 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 Pool2dAttribute;
+struct Pool2dAttributeBuilder;
+
+struct Conv2dAttribute;
+struct Conv2dAttributeBuilder;
+
+struct TransposeConv2dAttribute;
+struct TransposeConv2dAttributeBuilder;
+
+struct ReluNAttribute;
+struct ReluNAttributeBuilder;
+
+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 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_RELUN = 11,
+  Op_SIGMOID = 12,
+  Op_TANH = 13,
+  Op_ADD = 14,
+  Op_ARITHMETIC_RIGHT_SHIFT = 15,
+  Op_BITWISE_AND = 16,
+  Op_BITWISE_OR = 17,
+  Op_BITWISE_XOR = 18,
+  Op_LOGICAL_AND = 19,
+  Op_LOGICAL_LEFT_SHIFT = 20,
+  Op_LOGICAL_RIGHT_SHIFT = 21,
+  Op_LOGICAL_OR = 22,
+  Op_LOGICAL_XOR = 23,
+  Op_MAXIMUM = 24,
+  Op_MINIMUM = 25,
+  Op_MUL = 26,
+  Op_POW = 27,
+  Op_SUB = 28,
+  Op_TABLE = 29,
+  Op_ABS = 30,
+  Op_BITWISE_NOT = 31,
+  Op_CEIL = 32,
+  Op_CLZ = 33,
+  Op_EXP = 34,
+  Op_FLOOR = 35,
+  Op_LOG = 36,
+  Op_LOGICAL_NOT = 37,
+  Op_NEGATE = 38,
+  Op_RECIPROCAL = 39,
+  Op_RSQRT = 40,
+  Op_SELECT = 41,
+  Op_EQUAL = 42,
+  Op_GREATER = 43,
+  Op_GREATER_EQUAL = 44,
+  Op_REDUCE_ANY = 45,
+  Op_REDUCE_ALL = 46,
+  Op_REDUCE_MAX = 47,
+  Op_REDUCE_MIN = 48,
+  Op_REDUCE_PRODUCT = 49,
+  Op_REDUCE_SUM = 50,
+  Op_CONCAT = 51,
+  Op_PAD = 52,
+  Op_RESHAPE = 53,
+  Op_REVERSE = 54,
+  Op_SLICE = 55,
+  Op_TILE = 56,
+  Op_TRANSPOSE = 57,
+  Op_GATHER = 58,
+  Op_SCATTER = 59,
+  Op_RESIZE = 60,
+  Op_CAST = 61,
+  Op_RESCALE = 62,
+  Op_CONST = 63,
+  Op_PLACEHOLDER = 64,
+  Op_IDENTITY = 65,
+  Op_IDENTITYN = 66,
+  Op_CUSTOM = 67,
+  Op_COND_IF = 68,
+  Op_WHILE_LOOP = 69,
+  Op_MIN = Op_UNKNOWN,
+  Op_MAX = Op_WHILE_LOOP
+};
+
+inline const Op (&EnumValuesOp())[70] {
+  static const Op values[] = {
+    Op_UNKNOWN,
+    Op_ARGMAX,
+    Op_AVG_POOL2D,
+    Op_CONV2D,
+    Op_CONV3D,
+    Op_DEPTHWISE_CONV2D,
+    Op_FULLY_CONNECTED,
+    Op_MATMUL,
+    Op_MAX_POOL2D,
+    Op_TRANSPOSE_CONV2D,
+    Op_CLAMP,
+    Op_RELUN,
+    Op_SIGMOID,
+    Op_TANH,
+    Op_ADD,
+    Op_ARITHMETIC_RIGHT_SHIFT,
+    Op_BITWISE_AND,
+    Op_BITWISE_OR,
+    Op_BITWISE_XOR,
+    Op_LOGICAL_AND,
+    Op_LOGICAL_LEFT_SHIFT,
+    Op_LOGICAL_RIGHT_SHIFT,
+    Op_LOGICAL_OR,
+    Op_LOGICAL_XOR,
+    Op_MAXIMUM,
+    Op_MINIMUM,
+    Op_MUL,
+    Op_POW,
+    Op_SUB,
+    Op_TABLE,
+    Op_ABS,
+    Op_BITWISE_NOT,
+    Op_CEIL,
+    Op_CLZ,
+    Op_EXP,
+    Op_FLOOR,
+    Op_LOG,
+    Op_LOGICAL_NOT,
+    Op_NEGATE,
+    Op_RECIPROCAL,
+    Op_RSQRT,
+    Op_SELECT,
+    Op_EQUAL,
+    Op_GREATER,
+    Op_GREATER_EQUAL,
+    Op_REDUCE_ANY,
+    Op_REDUCE_ALL,
+    Op_REDUCE_MAX,
+    Op_REDUCE_MIN,
+    Op_REDUCE_PRODUCT,
+    Op_REDUCE_SUM,
+    Op_CONCAT,
+    Op_PAD,
+    Op_RESHAPE,
+    Op_REVERSE,
+    Op_SLICE,
+    Op_TILE,
+    Op_TRANSPOSE,
+    Op_GATHER,
+    Op_SCATTER,
+    Op_RESIZE,
+    Op_CAST,
+    Op_RESCALE,
+    Op_CONST,
+    Op_PLACEHOLDER,
+    Op_IDENTITY,
+    Op_IDENTITYN,
+    Op_CUSTOM,
+    Op_COND_IF,
+    Op_WHILE_LOOP
+  };
+  return values;
+}
+
+inline const char * const *EnumNamesOp() {
+  static const char * const names[71] = {
+    "UNKNOWN",
+    "ARGMAX",
+    "AVG_POOL2D",
+    "CONV2D",
+    "CONV3D",
+    "DEPTHWISE_CONV2D",
+    "FULLY_CONNECTED",
+    "MATMUL",
+    "MAX_POOL2D",
+    "TRANSPOSE_CONV2D",
+    "CLAMP",
+    "RELUN",
+    "SIGMOID",
+    "TANH",
+    "ADD",
+    "ARITHMETIC_RIGHT_SHIFT",
+    "BITWISE_AND",
+    "BITWISE_OR",
+    "BITWISE_XOR",
+    "LOGICAL_AND",
+    "LOGICAL_LEFT_SHIFT",
+    "LOGICAL_RIGHT_SHIFT",
+    "LOGICAL_OR",
+    "LOGICAL_XOR",
+    "MAXIMUM",
+    "MINIMUM",
+    "MUL",
+    "POW",
+    "SUB",
+    "TABLE",
+    "ABS",
+    "BITWISE_NOT",
+    "CEIL",
+    "CLZ",
+    "EXP",
+    "FLOOR",
+    "LOG",
+    "LOGICAL_NOT",
+    "NEGATE",
+    "RECIPROCAL",
+    "RSQRT",
+    "SELECT",
+    "EQUAL",
+    "GREATER",
+    "GREATER_EQUAL",
+    "REDUCE_ANY",
+    "REDUCE_ALL",
+    "REDUCE_MAX",
+    "REDUCE_MIN",
+    "REDUCE_PRODUCT",
+    "REDUCE_SUM",
+    "CONCAT",
+    "PAD",
+    "RESHAPE",
+    "REVERSE",
+    "SLICE",
+    "TILE",
+    "TRANSPOSE",
+    "GATHER",
+    "SCATTER",
+    "RESIZE",
+    "CAST",
+    "RESCALE",
+    "CONST",
+    "PLACEHOLDER",
+    "IDENTITY",
+    "IDENTITYN",
+    "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_Pool2dAttribute = 1,
+  Attribute_Conv2dAttribute = 2,
+  Attribute_TransposeConv2dAttribute = 3,
+  Attribute_ReluNAttribute = 4,
+  Attribute_AxisAttribute = 5,
+  Attribute_ReshapeAttribute = 6,
+  Attribute_SliceAttribute = 7,
+  Attribute_TileAttribute = 8,
+  Attribute_ResizeAttribute = 9,
+  Attribute_ClampAttribute = 10,
+  Attribute_RescaleAttribute = 11,
+  Attribute_MulAttribute = 12,
+  Attribute_ArithmeticRightShiftAttribute = 13,
+  Attribute_CondIfAttribute = 14,
+  Attribute_WhileLoopAttribute = 15,
+  Attribute_MIN = Attribute_NONE,
+  Attribute_MAX = Attribute_WhileLoopAttribute
+};
+
+inline const Attribute (&EnumValuesAttribute())[16] {
+  static const Attribute values[] = {
+    Attribute_NONE,
+    Attribute_Pool2dAttribute,
+    Attribute_Conv2dAttribute,
+    Attribute_TransposeConv2dAttribute,
+    Attribute_ReluNAttribute,
+    Attribute_AxisAttribute,
+    Attribute_ReshapeAttribute,
+    Attribute_SliceAttribute,
+    Attribute_TileAttribute,
+    Attribute_ResizeAttribute,
+    Attribute_ClampAttribute,
+    Attribute_RescaleAttribute,
+    Attribute_MulAttribute,
+    Attribute_ArithmeticRightShiftAttribute,
+    Attribute_CondIfAttribute,
+    Attribute_WhileLoopAttribute
+  };
+  return values;
+}
+
+inline const char * const *EnumNamesAttribute() {
+  static const char * const names[17] = {
+    "NONE",
+    "Pool2dAttribute",
+    "Conv2dAttribute",
+    "TransposeConv2dAttribute",
+    "ReluNAttribute",
+    "AxisAttribute",
+    "ReshapeAttribute",
+    "SliceAttribute",
+    "TileAttribute",
+    "ResizeAttribute",
+    "ClampAttribute",
+    "RescaleAttribute",
+    "MulAttribute",
+    "ArithmeticRightShiftAttribute",
+    "CondIfAttribute",
+    "WhileLoopAttribute",
+    nullptr
+  };
+  return names;
+}
+
+inline const char *EnumNameAttribute(Attribute e) {
+  if (flatbuffers::IsOutRange(e, Attribute_NONE, Attribute_WhileLoopAttribute)) return "";
+  const size_t index = static_cast<size_t>(e);
+  return EnumNamesAttribute()[index];
+}
+
+template<typename T> struct AttributeTraits {
+  static const Attribute enum_value = Attribute_NONE;
+};
+
+template<> struct AttributeTraits<tosa::Pool2dAttribute> {
+  static const Attribute enum_value = Attribute_Pool2dAttribute;
+};
+
+template<> struct AttributeTraits<tosa::Conv2dAttribute> {
+  static const Attribute enum_value = Attribute_Conv2dAttribute;
+};
+
+template<> struct AttributeTraits<tosa::TransposeConv2dAttribute> {
+  static const Attribute enum_value = Attribute_TransposeConv2dAttribute;
+};
+
+template<> struct AttributeTraits<tosa::ReluNAttribute> {
+  static const Attribute enum_value = Attribute_ReluNAttribute;
+};
+
+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;
+};
+
+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 Pool2dAttribute FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
+  typedef Pool2dAttributeBuilder 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 Pool2dAttributeBuilder {
+  typedef Pool2dAttribute Table;
+  flatbuffers::FlatBufferBuilder &fbb_;
+  flatbuffers::uoffset_t start_;
+  void add_padding(flatbuffers::Offset<flatbuffers::Vector<int32_t>> padding) {
+    fbb_.AddOffset(Pool2dAttribute::VT_PADDING, padding);
+  }
+  void add_kernel(flatbuffers::Offset<flatbuffers::Vector<int32_t>> kernel) {
+    fbb_.AddOffset(Pool2dAttribute::VT_KERNEL, kernel);
+  }
+  void add_stride(flatbuffers::Offset<flatbuffers::Vector<int32_t>> stride) {
+    fbb_.AddOffset(Pool2dAttribute::VT_STRIDE, stride);
+  }
+  explicit Pool2dAttributeBuilder(flatbuffers::FlatBufferBuilder &_fbb)
+        : fbb_(_fbb) {
+    start_ = fbb_.StartTable();
+  }
+  Pool2dAttributeBuilder &operator=(const Pool2dAttributeBuilder &);
+  flatbuffers::Offset<Pool2dAttribute> Finish() {
+    const auto end = fbb_.EndTable(start_);
+    auto o = flatbuffers::Offset<Pool2dAttribute>(end);
+    return o;
+  }
+};
+
+inline flatbuffers::Offset<Pool2dAttribute> CreatePool2dAttribute(
+    flatbuffers::FlatBufferBuilder &_fbb,
+    flatbuffers::Offset<flatbuffers::Vector<int32_t>> padding = 0,
+    flatbuffers::Offset<flatbuffers::Vector<int32_t>> kernel = 0,
+    flatbuffers::Offset<flatbuffers::Vector<int32_t>> stride = 0) {
+  Pool2dAttributeBuilder builder_(_fbb);
+  builder_.add_stride(stride);
+  builder_.add_kernel(kernel);
+  builder_.add_padding(padding);
+  return builder_.Finish();
+}
+
+inline flatbuffers::Offset<Pool2dAttribute> CreatePool2dAttributeDirect(
+    flatbuffers::FlatBufferBuilder &_fbb,
+    const std::vector<int32_t> *padding = nullptr,
+    const std::vector<int32_t> *kernel = nullptr,
+    const std::vector<int32_t> *stride = nullptr) {
+  auto padding__ = padding ? _fbb.CreateVector<int32_t>(*padding) : 0;
+  auto kernel__ = kernel ? _fbb.CreateVector<int32_t>(*kernel) : 0;
+  auto stride__ = stride ? _fbb.CreateVector<int32_t>(*stride) : 0;
+  return tosa::CreatePool2dAttribute(
+      _fbb,
+      padding__,
+      kernel__,
+      stride__);
+}
+
+struct Conv2dAttribute FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
+  typedef Conv2dAttributeBuilder 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 Conv2dAttributeBuilder {
+  typedef Conv2dAttribute Table;
+  flatbuffers::FlatBufferBuilder &fbb_;
+  flatbuffers::uoffset_t start_;
+  void add_padding(flatbuffers::Offset<flatbuffers::Vector<int32_t>> padding) {
+    fbb_.AddOffset(Conv2dAttribute::VT_PADDING, padding);
+  }
+  void add_stride(flatbuffers::Offset<flatbuffers::Vector<int32_t>> stride) {
+    fbb_.AddOffset(Conv2dAttribute::VT_STRIDE, stride);
+  }
+  void add_dilation(flatbuffers::Offset<flatbuffers::Vector<int32_t>> dilation) {
+    fbb_.AddOffset(Conv2dAttribute::VT_DILATION, dilation);
+  }
+  explicit Conv2dAttributeBuilder(flatbuffers::FlatBufferBuilder &_fbb)
+        : fbb_(_fbb) {
+    start_ = fbb_.StartTable();
+  }
+  Conv2dAttributeBuilder &operator=(const Conv2dAttributeBuilder &);
+  flatbuffers::Offset<Conv2dAttribute> Finish() {
+    const auto end = fbb_.EndTable(start_);
+    auto o = flatbuffers::Offset<Conv2dAttribute>(end);
+    return o;
+  }
+};
+
+inline flatbuffers::Offset<Conv2dAttribute> CreateConv2dAttribute(
+    flatbuffers::FlatBufferBuilder &_fbb,
+    flatbuffers::Offset<flatbuffers::Vector<int32_t>> padding = 0,
+    flatbuffers::Offset<flatbuffers::Vector<int32_t>> stride = 0,
+    flatbuffers::Offset<flatbuffers::Vector<int32_t>> dilation = 0) {
+  Conv2dAttributeBuilder builder_(_fbb);
+  builder_.add_dilation(dilation);
+  builder_.add_stride(stride);
+  builder_.add_padding(padding);
+  return builder_.Finish();
+}
+
+inline flatbuffers::Offset<Conv2dAttribute> CreateConv2dAttributeDirect(
+    flatbuffers::FlatBufferBuilder &_fbb,
+    const std::vector<int32_t> *padding = nullptr,
+    const std::vector<int32_t> *stride = nullptr,
+    const std::vector<int32_t> *dilation = nullptr) {
+  auto padding__ = padding ? _fbb.CreateVector<int32_t>(*padding) : 0;
+  auto stride__ = stride ? _fbb.CreateVector<int32_t>(*stride) : 0;
+  auto dilation__ = dilation ? _fbb.CreateVector<int32_t>(*dilation) : 0;
+  return tosa::CreateConv2dAttribute(
+      _fbb,
+      padding__,
+      stride__,
+      dilation__);
+}
+
+struct TransposeConv2dAttribute FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
+  typedef TransposeConv2dAttributeBuilder 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 TransposeConv2dAttributeBuilder {
+  typedef TransposeConv2dAttribute Table;
+  flatbuffers::FlatBufferBuilder &fbb_;
+  flatbuffers::uoffset_t start_;
+  void add_outpad(flatbuffers::Offset<flatbuffers::Vector<int32_t>> outpad) {
+    fbb_.AddOffset(TransposeConv2dAttribute::VT_OUTPAD, outpad);
+  }
+  void add_stride(flatbuffers::Offset<flatbuffers::Vector<int32_t>> stride) {
+    fbb_.AddOffset(TransposeConv2dAttribute::VT_STRIDE, stride);
+  }
+  void add_dilation(flatbuffers::Offset<flatbuffers::Vector<int32_t>> dilation) {
+    fbb_.AddOffset(TransposeConv2dAttribute::VT_DILATION, dilation);
+  }
+  void add_output_shape(flatbuffers::Offset<flatbuffers::Vector<int32_t>> output_shape) {
+    fbb_.AddOffset(TransposeConv2dAttribute::VT_OUTPUT_SHAPE, output_shape);
+  }
+  explicit TransposeConv2dAttributeBuilder(flatbuffers::FlatBufferBuilder &_fbb)
+        : fbb_(_fbb) {
+    start_ = fbb_.StartTable();
+  }
+  TransposeConv2dAttributeBuilder &operator=(const TransposeConv2dAttributeBuilder &);
+  flatbuffers::Offset<TransposeConv2dAttribute> Finish() {
+    const auto end = fbb_.EndTable(start_);
+    auto o = flatbuffers::Offset<TransposeConv2dAttribute>(end);
+    return o;
+  }
+};
+
+inline flatbuffers::Offset<TransposeConv2dAttribute> CreateTransposeConv2dAttribute(
+    flatbuffers::FlatBufferBuilder &_fbb,
+    flatbuffers::Offset<flatbuffers::Vector<int32_t>> outpad = 0,
+    flatbuffers::Offset<flatbuffers::Vector<int32_t>> stride = 0,
+    flatbuffers::Offset<flatbuffers::Vector<int32_t>> dilation = 0,
+    flatbuffers::Offset<flatbuffers::Vector<int32_t>> output_shape = 0) {
+  TransposeConv2dAttributeBuilder builder_(_fbb);
+  builder_.add_output_shape(output_shape);
+  builder_.add_dilation(dilation);
+  builder_.add_stride(stride);
+  builder_.add_outpad(outpad);
+  return builder_.Finish();
+}
+
+inline flatbuffers::Offset<TransposeConv2dAttribute> CreateTransposeConv2dAttributeDirect(
+    flatbuffers::FlatBufferBuilder &_fbb,
+    const std::vector<int32_t> *outpad = nullptr,
+    const std::vector<int32_t> *stride = nullptr,
+    const std::vector<int32_t> *dilation = nullptr,
+    const std::vector<int32_t> *output_shape = nullptr) {
+  auto outpad__ = outpad ? _fbb.CreateVector<int32_t>(*outpad) : 0;
+  auto stride__ = stride ? _fbb.CreateVector<int32_t>(*stride) : 0;
+  auto dilation__ = dilation ? _fbb.CreateVector<int32_t>(*dilation) : 0;
+  auto output_shape__ = output_shape ? _fbb.CreateVector<int32_t>(*output_shape) : 0;
+  return tosa::CreateTransposeConv2dAttribute(
+      _fbb,
+      outpad__,
+      stride__,
+      dilation__,
+      output_shape__);
+}
+
+struct ReluNAttribute FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
+  typedef ReluNAttributeBuilder Builder;
+  enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
+    VT_MAX_INT = 4,
+    VT_MAX_FP = 6
+  };
+  int32_t max_int() const {
+    return GetField<int32_t>(VT_MAX_INT, 0);
+  }
+  float max_fp() const {
+    return GetField<float>(VT_MAX_FP, 0.0f);
+  }
+  bool Verify(flatbuffers::Verifier &verifier) const {
+    return VerifyTableStart(verifier) &&
+           VerifyField<int32_t>(verifier, VT_MAX_INT) &&
+           VerifyField<float>(verifier, VT_MAX_FP) &&
+           verifier.EndTable();
+  }
+};
+
+struct ReluNAttributeBuilder {
+  typedef ReluNAttribute Table;
+  flatbuffers::FlatBufferBuilder &fbb_;
+  flatbuffers::uoffset_t start_;
+  void add_max_int(int32_t max_int) {
+    fbb_.AddElement<int32_t>(ReluNAttribute::VT_MAX_INT, max_int, 0);
+  }
+  void add_max_fp(float max_fp) {
+    fbb_.AddElement<float>(ReluNAttribute::VT_MAX_FP, max_fp, 0.0f);
+  }
+  explicit ReluNAttributeBuilder(flatbuffers::FlatBufferBuilder &_fbb)
+        : fbb_(_fbb) {
+    start_ = fbb_.StartTable();
+  }
+  ReluNAttributeBuilder &operator=(const ReluNAttributeBuilder &);
+  flatbuffers::Offset<ReluNAttribute> Finish() {
+    const auto end = fbb_.EndTable(start_);
+    auto o = flatbuffers::Offset<ReluNAttribute>(end);
+    return o;
+  }
+};
+
+inline flatbuffers::Offset<ReluNAttribute> CreateReluNAttribute(
+    flatbuffers::FlatBufferBuilder &_fbb,
+    int32_t max_int = 0,
+    float max_fp = 0.0f) {
+  ReluNAttributeBuilder builder_(_fbb);
+  builder_.add_max_fp(max_fp);
+  builder_.add_max_int(max_int);
+  return builder_.Finish();
+}
+
+struct AxisAttribute FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
+  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 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__EXPERIMENTAL = 10
+  };
+  int32_t _major() const {
+    return GetField<int32_t>(VT__MAJOR, 0);
+  }
+  int32_t _minor() const {
+    return GetField<int32_t>(VT__MINOR, 21);
+  }
+  int32_t _patch() const {
+    return GetField<int32_t>(VT__PATCH, 0);
+  }
+  bool _experimental() const {
+    return GetField<uint8_t>(VT__EXPERIMENTAL, 0) != 0;
+  }
+  bool Verify(flatbuffers::Verifier &verifier) const {
+    return VerifyTableStart(verifier) &&
+           VerifyField<int32_t>(verifier, VT__MAJOR) &&
+           VerifyField<int32_t>(verifier, VT__MINOR) &&
+           VerifyField<int32_t>(verifier, VT__PATCH) &&
+           VerifyField<uint8_t>(verifier, VT__EXPERIMENTAL) &&
+           verifier.EndTable();
+  }
+};
+
+struct VersionBuilder {
+  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, 21);
+  }
+  void add__patch(int32_t _patch) {
+    fbb_.AddElement<int32_t>(Version::VT__PATCH, _patch, 0);
+  }
+  void add__experimental(bool _experimental) {
+    fbb_.AddElement<uint8_t>(Version::VT__EXPERIMENTAL, static_cast<uint8_t>(_experimental), 0);
+  }
+  explicit VersionBuilder(flatbuffers::FlatBufferBuilder &_fbb)
+        : fbb_(_fbb) {
+    start_ = fbb_.StartTable();
+  }
+  VersionBuilder &operator=(const VersionBuilder &);
+  flatbuffers::Offset<Version> Finish() {
+    const auto end = fbb_.EndTable(start_);
+    auto o = flatbuffers::Offset<Version>(end);
+    return o;
+  }
+};
+
+inline flatbuffers::Offset<Version> CreateVersion(
+    flatbuffers::FlatBufferBuilder &_fbb,
+    int32_t _major = 0,
+    int32_t _minor = 21,
+    int32_t _patch = 0,
+    bool _experimental = false) {
+  VersionBuilder builder_(_fbb);
+  builder_.add__patch(_patch);
+  builder_.add__minor(_minor);
+  builder_.add__major(_major);
+  builder_.add__experimental(_experimental);
+  return builder_.Finish();
+}
+
+struct TosaTensor FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
+  typedef TosaTensorBuilder Builder;
+  enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
+    VT_NAME = 4,
+    VT_SHAPE = 6,
+    VT_TYPE = 8,
+    VT_NPY_FILENAME = 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::String *npy_filename() const {
+    return GetPointer<const flatbuffers::String *>(VT_NPY_FILENAME);
+  }
+  bool Verify(flatbuffers::Verifier &verifier) const {
+    return VerifyTableStart(verifier) &&
+           VerifyOffset(verifier, VT_NAME) &&
+           verifier.VerifyString(name()) &&
+           VerifyOffset(verifier, VT_SHAPE) &&
+           verifier.VerifyVector(shape()) &&
+           VerifyField<uint32_t>(verifier, VT_TYPE) &&
+           VerifyOffset(verifier, VT_NPY_FILENAME) &&
+           verifier.VerifyString(npy_filename()) &&
+           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_npy_filename(flatbuffers::Offset<flatbuffers::String> npy_filename) {
+    fbb_.AddOffset(TosaTensor::VT_NPY_FILENAME, npy_filename);
+  }
+  explicit TosaTensorBuilder(flatbuffers::FlatBufferBuilder &_fbb)
+        : fbb_(_fbb) {
+    start_ = fbb_.StartTable();
+  }
+  TosaTensorBuilder &operator=(const TosaTensorBuilder &);
+  flatbuffers::Offset<TosaTensor> Finish() {
+    const auto end = fbb_.EndTable(start_);
+    auto o = flatbuffers::Offset<TosaTensor>(end);
+    return o;
+  }
+};
+
+inline flatbuffers::Offset<TosaTensor> CreateTosaTensor(
+    flatbuffers::FlatBufferBuilder &_fbb,
+    flatbuffers::Offset<flatbuffers::String> name = 0,
+    flatbuffers::Offset<flatbuffers::Vector<int32_t>> shape = 0,
+    tosa::DType type = tosa::DType_UNKNOWN,
+    flatbuffers::Offset<flatbuffers::String> npy_filename = 0) {
+  TosaTensorBuilder builder_(_fbb);
+  builder_.add_npy_filename(npy_filename);
+  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 char *npy_filename = nullptr) {
+  auto name__ = name ? _fbb.CreateString(name) : 0;
+  auto shape__ = shape ? _fbb.CreateVector<int32_t>(*shape) : 0;
+  auto npy_filename__ = npy_filename ? _fbb.CreateString(npy_filename) : 0;
+  return tosa::CreateTosaTensor(
+      _fbb,
+      name__,
+      shape__,
+      type,
+      npy_filename__);
+}
+
+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::Pool2dAttribute *attribute_as_Pool2dAttribute() const {
+    return attribute_type() == tosa::Attribute_Pool2dAttribute ? static_cast<const tosa::Pool2dAttribute *>(attribute()) : nullptr;
+  }
+  const tosa::Conv2dAttribute *attribute_as_Conv2dAttribute() const {
+    return attribute_type() == tosa::Attribute_Conv2dAttribute ? static_cast<const tosa::Conv2dAttribute *>(attribute()) : nullptr;
+  }
+  const tosa::TransposeConv2dAttribute *attribute_as_TransposeConv2dAttribute() const {
+    return attribute_type() == tosa::Attribute_TransposeConv2dAttribute ? static_cast<const tosa::TransposeConv2dAttribute *>(attribute()) : nullptr;
+  }
+  const tosa::ReluNAttribute *attribute_as_ReluNAttribute() const {
+    return attribute_type() == tosa::Attribute_ReluNAttribute ? static_cast<const tosa::ReluNAttribute *>(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 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::Pool2dAttribute *TosaOperator::attribute_as<tosa::Pool2dAttribute>() const {
+  return attribute_as_Pool2dAttribute();
+}
+
+template<> inline const tosa::Conv2dAttribute *TosaOperator::attribute_as<tosa::Conv2dAttribute>() const {
+  return attribute_as_Conv2dAttribute();
+}
+
+template<> inline const tosa::TransposeConv2dAttribute *TosaOperator::attribute_as<tosa::TransposeConv2dAttribute>() const {
+  return attribute_as_TransposeConv2dAttribute();
+}
+
+template<> inline const tosa::ReluNAttribute *TosaOperator::attribute_as<tosa::ReluNAttribute>() const {
+  return attribute_as_ReluNAttribute();
+}
+
+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::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_Pool2dAttribute: {
+      auto ptr = reinterpret_cast<const tosa::Pool2dAttribute *>(obj);
+      return verifier.VerifyTable(ptr);
+    }
+    case Attribute_Conv2dAttribute: {
+      auto ptr = reinterpret_cast<const tosa::Conv2dAttribute *>(obj);
+      return verifier.VerifyTable(ptr);
+    }
+    case Attribute_TransposeConv2dAttribute: {
+      auto ptr = reinterpret_cast<const tosa::TransposeConv2dAttribute *>(obj);
+      return verifier.VerifyTable(ptr);
+    }
+    case Attribute_ReluNAttribute: {
+      auto ptr = reinterpret_cast<const tosa::ReluNAttribute *>(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);
+    }
+    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_
