//
// Copyright © 2021 Arm Ltd and Contributors. All rights reserved.
// SPDX-License-Identifier: MIT
//
// automatically generated by the FlatBuffers compiler, do not modify


#ifndef FLATBUFFERS_GENERATED_ARMNNSCHEMA_ARMNNSERIALIZER_H_
#define FLATBUFFERS_GENERATED_ARMNNSCHEMA_ARMNNSERIALIZER_H_

#include "flatbuffers/flatbuffers.h"

namespace armnnSerializer {

struct TensorInfo;
struct TensorInfoBuilder;

struct Connection;

struct ByteData;
struct ByteDataBuilder;

struct ShortData;
struct ShortDataBuilder;

struct IntData;
struct IntDataBuilder;

struct LongData;
struct LongDataBuilder;

struct ConstTensor;
struct ConstTensorBuilder;

struct InputSlot;
struct InputSlotBuilder;

struct OutputSlot;
struct OutputSlotBuilder;

struct LayerBase;
struct LayerBaseBuilder;

struct BindableLayerBase;
struct BindableLayerBaseBuilder;

struct AbsLayer;
struct AbsLayerBuilder;

struct ActivationLayer;
struct ActivationLayerBuilder;

struct ActivationDescriptor;
struct ActivationDescriptorBuilder;

struct AdditionLayer;
struct AdditionLayerBuilder;

struct ArgMinMaxLayer;
struct ArgMinMaxLayerBuilder;

struct ArgMinMaxDescriptor;
struct ArgMinMaxDescriptorBuilder;

struct CastLayer;
struct CastLayerBuilder;

struct ComparisonDescriptor;
struct ComparisonDescriptorBuilder;

struct ComparisonLayer;
struct ComparisonLayerBuilder;

struct ConstantLayer;
struct ConstantLayerBuilder;

struct Convolution2dLayer;
struct Convolution2dLayerBuilder;

struct Convolution2dDescriptor;
struct Convolution2dDescriptorBuilder;

struct DepthToSpaceLayer;
struct DepthToSpaceLayerBuilder;

struct DepthToSpaceDescriptor;
struct DepthToSpaceDescriptorBuilder;

struct DivisionLayer;
struct DivisionLayerBuilder;

struct ElementwiseUnaryDescriptor;
struct ElementwiseUnaryDescriptorBuilder;

struct ElementwiseUnaryLayer;
struct ElementwiseUnaryLayerBuilder;

struct EqualLayer;
struct EqualLayerBuilder;

struct FillLayer;
struct FillLayerBuilder;

struct FillDescriptor;
struct FillDescriptorBuilder;

struct FloorLayer;
struct FloorLayerBuilder;

struct FullyConnectedLayer;
struct FullyConnectedLayerBuilder;

struct FullyConnectedDescriptor;
struct FullyConnectedDescriptorBuilder;

struct GatherLayer;
struct GatherLayerBuilder;

struct GatherDescriptor;
struct GatherDescriptorBuilder;

struct GreaterLayer;
struct GreaterLayerBuilder;

struct InputLayer;
struct InputLayerBuilder;

struct InstanceNormalizationLayer;
struct InstanceNormalizationLayerBuilder;

struct InstanceNormalizationDescriptor;
struct InstanceNormalizationDescriptorBuilder;

struct LogSoftmaxLayer;
struct LogSoftmaxLayerBuilder;

struct LogSoftmaxDescriptor;
struct LogSoftmaxDescriptorBuilder;

struct L2NormalizationLayer;
struct L2NormalizationLayerBuilder;

struct L2NormalizationDescriptor;
struct L2NormalizationDescriptorBuilder;

struct LogicalBinaryDescriptor;
struct LogicalBinaryDescriptorBuilder;

struct LogicalBinaryLayer;
struct LogicalBinaryLayerBuilder;

struct MinimumLayer;
struct MinimumLayerBuilder;

struct MaximumLayer;
struct MaximumLayerBuilder;

struct MultiplicationLayer;
struct MultiplicationLayerBuilder;

struct Pooling2dLayer;
struct Pooling2dLayerBuilder;

struct Pooling2dDescriptor;
struct Pooling2dDescriptorBuilder;

struct QuantizeLayer;
struct QuantizeLayerBuilder;

struct SoftmaxLayer;
struct SoftmaxLayerBuilder;

struct SoftmaxDescriptor;
struct SoftmaxDescriptorBuilder;

struct DepthwiseConvolution2dLayer;
struct DepthwiseConvolution2dLayerBuilder;

struct DepthwiseConvolution2dDescriptor;
struct DepthwiseConvolution2dDescriptorBuilder;

struct OutputLayer;
struct OutputLayerBuilder;

struct ReshapeLayer;
struct ReshapeLayerBuilder;

struct ReshapeDescriptor;
struct ReshapeDescriptorBuilder;

struct PermuteLayer;
struct PermuteLayerBuilder;

struct PermuteDescriptor;
struct PermuteDescriptorBuilder;

struct ShapeLayer;
struct ShapeLayerBuilder;

struct SpaceToBatchNdLayer;
struct SpaceToBatchNdLayerBuilder;

struct SpaceToBatchNdDescriptor;
struct SpaceToBatchNdDescriptorBuilder;

struct SpaceToDepthLayer;
struct SpaceToDepthLayerBuilder;

struct SpaceToDepthDescriptor;
struct SpaceToDepthDescriptorBuilder;

struct SubtractionLayer;
struct SubtractionLayerBuilder;

struct BatchToSpaceNdLayer;
struct BatchToSpaceNdLayerBuilder;

struct BatchToSpaceNdDescriptor;
struct BatchToSpaceNdDescriptorBuilder;

struct NormalizationLayer;
struct NormalizationLayerBuilder;

struct NormalizationDescriptor;
struct NormalizationDescriptorBuilder;

struct MeanLayer;
struct MeanLayerBuilder;

struct MeanDescriptor;
struct MeanDescriptorBuilder;

struct PadLayer;
struct PadLayerBuilder;

struct PadDescriptor;
struct PadDescriptorBuilder;

struct RsqrtLayer;
struct RsqrtLayerBuilder;

struct BatchNormalizationLayer;
struct BatchNormalizationLayerBuilder;

struct BatchNormalizationDescriptor;
struct BatchNormalizationDescriptorBuilder;

struct ResizeBilinearLayer;
struct ResizeBilinearLayerBuilder;

struct ResizeBilinearDescriptor;
struct ResizeBilinearDescriptorBuilder;

struct SliceLayer;
struct SliceLayerBuilder;

struct SliceDescriptor;
struct SliceDescriptorBuilder;

struct StridedSliceLayer;
struct StridedSliceLayerBuilder;

struct StridedSliceDescriptor;
struct StridedSliceDescriptorBuilder;

struct ConcatLayer;
struct ConcatLayerBuilder;

struct MergerLayer;
struct MergerLayerBuilder;

struct UintVector;
struct UintVectorBuilder;

struct OriginsDescriptor;
struct OriginsDescriptorBuilder;

struct ViewsDescriptor;
struct ViewsDescriptorBuilder;

struct SplitterLayer;
struct SplitterLayerBuilder;

struct DetectionPostProcessLayer;
struct DetectionPostProcessLayerBuilder;

struct DetectionPostProcessDescriptor;
struct DetectionPostProcessDescriptorBuilder;

struct LstmInputParams;
struct LstmInputParamsBuilder;

struct LstmDescriptor;
struct LstmDescriptorBuilder;

struct LstmLayer;
struct LstmLayerBuilder;

struct QLstmInputParams;
struct QLstmInputParamsBuilder;

struct QLstmDescriptor;
struct QLstmDescriptorBuilder;

struct QLstmLayer;
struct QLstmLayerBuilder;

struct QuantizedLstmInputParams;
struct QuantizedLstmInputParamsBuilder;

struct QuantizedLstmLayer;
struct QuantizedLstmLayerBuilder;

struct DequantizeLayer;
struct DequantizeLayerBuilder;

struct MergeLayer;
struct MergeLayerBuilder;

struct SwitchLayer;
struct SwitchLayerBuilder;

struct PreluLayer;
struct PreluLayerBuilder;

struct TransposeConvolution2dLayer;
struct TransposeConvolution2dLayerBuilder;

struct TransposeConvolution2dDescriptor;
struct TransposeConvolution2dDescriptorBuilder;

struct TransposeLayer;
struct TransposeLayerBuilder;

struct TransposeDescriptor;
struct TransposeDescriptorBuilder;

struct ResizeLayer;
struct ResizeLayerBuilder;

struct ResizeDescriptor;
struct ResizeDescriptorBuilder;

struct StackLayer;
struct StackLayerBuilder;

struct StackDescriptor;
struct StackDescriptorBuilder;

struct StandInDescriptor;
struct StandInDescriptorBuilder;

struct StandInLayer;
struct StandInLayerBuilder;

struct RankLayer;
struct RankLayerBuilder;

struct ReduceLayer;
struct ReduceLayerBuilder;

struct ReduceDescriptor;
struct ReduceDescriptorBuilder;

struct AnyLayer;
struct AnyLayerBuilder;

struct FeatureCompatibilityVersions;
struct FeatureCompatibilityVersionsBuilder;

struct SerializedGraph;
struct SerializedGraphBuilder;

enum ActivationFunction {
  ActivationFunction_Sigmoid = 0,
  ActivationFunction_TanH = 1,
  ActivationFunction_Linear = 2,
  ActivationFunction_ReLu = 3,
  ActivationFunction_BoundedReLu = 4,
  ActivationFunction_SoftReLu = 5,
  ActivationFunction_LeakyReLu = 6,
  ActivationFunction_Abs = 7,
  ActivationFunction_Sqrt = 8,
  ActivationFunction_Square = 9,
  ActivationFunction_Elu = 10,
  ActivationFunction_HardSwish = 11,
  ActivationFunction_MIN = ActivationFunction_Sigmoid,
  ActivationFunction_MAX = ActivationFunction_HardSwish
};

inline const ActivationFunction (&EnumValuesActivationFunction())[12] {
  static const ActivationFunction values[] = {
    ActivationFunction_Sigmoid,
    ActivationFunction_TanH,
    ActivationFunction_Linear,
    ActivationFunction_ReLu,
    ActivationFunction_BoundedReLu,
    ActivationFunction_SoftReLu,
    ActivationFunction_LeakyReLu,
    ActivationFunction_Abs,
    ActivationFunction_Sqrt,
    ActivationFunction_Square,
    ActivationFunction_Elu,
    ActivationFunction_HardSwish
  };
  return values;
}

inline const char * const *EnumNamesActivationFunction() {
  static const char * const names[13] = {
    "Sigmoid",
    "TanH",
    "Linear",
    "ReLu",
    "BoundedReLu",
    "SoftReLu",
    "LeakyReLu",
    "Abs",
    "Sqrt",
    "Square",
    "Elu",
    "HardSwish",
    nullptr
  };
  return names;
}

inline const char *EnumNameActivationFunction(ActivationFunction e) {
  if (flatbuffers::IsOutRange(e, ActivationFunction_Sigmoid, ActivationFunction_HardSwish)) return "";
  const size_t index = static_cast<size_t>(e);
  return EnumNamesActivationFunction()[index];
}

enum ArgMinMaxFunction {
  ArgMinMaxFunction_Min = 0,
  ArgMinMaxFunction_Max = 1,
  ArgMinMaxFunction_MIN = ArgMinMaxFunction_Min,
  ArgMinMaxFunction_MAX = ArgMinMaxFunction_Max
};

inline const ArgMinMaxFunction (&EnumValuesArgMinMaxFunction())[2] {
  static const ArgMinMaxFunction values[] = {
    ArgMinMaxFunction_Min,
    ArgMinMaxFunction_Max
  };
  return values;
}

inline const char * const *EnumNamesArgMinMaxFunction() {
  static const char * const names[3] = {
    "Min",
    "Max",
    nullptr
  };
  return names;
}

inline const char *EnumNameArgMinMaxFunction(ArgMinMaxFunction e) {
  if (flatbuffers::IsOutRange(e, ArgMinMaxFunction_Min, ArgMinMaxFunction_Max)) return "";
  const size_t index = static_cast<size_t>(e);
  return EnumNamesArgMinMaxFunction()[index];
}

enum DataType {
  DataType_Float16 = 0,
  DataType_Float32 = 1,
  DataType_QuantisedAsymm8 = 2,
  DataType_Signed32 = 3,
  DataType_Boolean = 4,
  DataType_QuantisedSymm16 = 5,
  DataType_QAsymmU8 = 6,
  DataType_QSymmS16 = 7,
  DataType_QAsymmS8 = 8,
  DataType_QSymmS8 = 9,
  DataType_Signed64 = 10,
  DataType_MIN = DataType_Float16,
  DataType_MAX = DataType_Signed64
};

inline const DataType (&EnumValuesDataType())[11] {
  static const DataType values[] = {
    DataType_Float16,
    DataType_Float32,
    DataType_QuantisedAsymm8,
    DataType_Signed32,
    DataType_Boolean,
    DataType_QuantisedSymm16,
    DataType_QAsymmU8,
    DataType_QSymmS16,
    DataType_QAsymmS8,
    DataType_QSymmS8,
    DataType_Signed64
  };
  return values;
}

inline const char * const *EnumNamesDataType() {
  static const char * const names[12] = {
    "Float16",
    "Float32",
    "QuantisedAsymm8",
    "Signed32",
    "Boolean",
    "QuantisedSymm16",
    "QAsymmU8",
    "QSymmS16",
    "QAsymmS8",
    "QSymmS8",
    "Signed64",
    nullptr
  };
  return names;
}

inline const char *EnumNameDataType(DataType e) {
  if (flatbuffers::IsOutRange(e, DataType_Float16, DataType_Signed64)) return "";
  const size_t index = static_cast<size_t>(e);
  return EnumNamesDataType()[index];
}

enum DataLayout {
  DataLayout_NHWC = 0,
  DataLayout_NCHW = 1,
  DataLayout_MIN = DataLayout_NHWC,
  DataLayout_MAX = DataLayout_NCHW
};

inline const DataLayout (&EnumValuesDataLayout())[2] {
  static const DataLayout values[] = {
    DataLayout_NHWC,
    DataLayout_NCHW
  };
  return values;
}

inline const char * const *EnumNamesDataLayout() {
  static const char * const names[3] = {
    "NHWC",
    "NCHW",
    nullptr
  };
  return names;
}

inline const char *EnumNameDataLayout(DataLayout e) {
  if (flatbuffers::IsOutRange(e, DataLayout_NHWC, DataLayout_NCHW)) return "";
  const size_t index = static_cast<size_t>(e);
  return EnumNamesDataLayout()[index];
}

enum ReduceOperation {
  ReduceOperation_Sum = 0,
  ReduceOperation_Max = 1,
  ReduceOperation_Mean = 2,
  ReduceOperation_Min = 3,
  ReduceOperation_MIN = ReduceOperation_Sum,
  ReduceOperation_MAX = ReduceOperation_Min
};

inline const ReduceOperation (&EnumValuesReduceOperation())[4] {
  static const ReduceOperation values[] = {
    ReduceOperation_Sum,
    ReduceOperation_Max,
    ReduceOperation_Mean,
    ReduceOperation_Min
  };
  return values;
}

inline const char * const *EnumNamesReduceOperation() {
  static const char * const names[5] = {
    "Sum",
    "Max",
    "Mean",
    "Min",
    nullptr
  };
  return names;
}

inline const char *EnumNameReduceOperation(ReduceOperation e) {
  if (flatbuffers::IsOutRange(e, ReduceOperation_Sum, ReduceOperation_Min)) return "";
  const size_t index = static_cast<size_t>(e);
  return EnumNamesReduceOperation()[index];
}

enum ResizeMethod {
  ResizeMethod_NearestNeighbor = 0,
  ResizeMethod_Bilinear = 1,
  ResizeMethod_MIN = ResizeMethod_NearestNeighbor,
  ResizeMethod_MAX = ResizeMethod_Bilinear
};

inline const ResizeMethod (&EnumValuesResizeMethod())[2] {
  static const ResizeMethod values[] = {
    ResizeMethod_NearestNeighbor,
    ResizeMethod_Bilinear
  };
  return values;
}

inline const char * const *EnumNamesResizeMethod() {
  static const char * const names[3] = {
    "NearestNeighbor",
    "Bilinear",
    nullptr
  };
  return names;
}

inline const char *EnumNameResizeMethod(ResizeMethod e) {
  if (flatbuffers::IsOutRange(e, ResizeMethod_NearestNeighbor, ResizeMethod_Bilinear)) return "";
  const size_t index = static_cast<size_t>(e);
  return EnumNamesResizeMethod()[index];
}

enum ConstTensorData {
  ConstTensorData_NONE = 0,
  ConstTensorData_ByteData = 1,
  ConstTensorData_ShortData = 2,
  ConstTensorData_IntData = 3,
  ConstTensorData_LongData = 4,
  ConstTensorData_MIN = ConstTensorData_NONE,
  ConstTensorData_MAX = ConstTensorData_LongData
};

inline const ConstTensorData (&EnumValuesConstTensorData())[5] {
  static const ConstTensorData values[] = {
    ConstTensorData_NONE,
    ConstTensorData_ByteData,
    ConstTensorData_ShortData,
    ConstTensorData_IntData,
    ConstTensorData_LongData
  };
  return values;
}

inline const char * const *EnumNamesConstTensorData() {
  static const char * const names[6] = {
    "NONE",
    "ByteData",
    "ShortData",
    "IntData",
    "LongData",
    nullptr
  };
  return names;
}

inline const char *EnumNameConstTensorData(ConstTensorData e) {
  if (flatbuffers::IsOutRange(e, ConstTensorData_NONE, ConstTensorData_LongData)) return "";
  const size_t index = static_cast<size_t>(e);
  return EnumNamesConstTensorData()[index];
}

template<typename T> struct ConstTensorDataTraits {
  static const ConstTensorData enum_value = ConstTensorData_NONE;
};

template<> struct ConstTensorDataTraits<armnnSerializer::ByteData> {
  static const ConstTensorData enum_value = ConstTensorData_ByteData;
};

template<> struct ConstTensorDataTraits<armnnSerializer::ShortData> {
  static const ConstTensorData enum_value = ConstTensorData_ShortData;
};

template<> struct ConstTensorDataTraits<armnnSerializer::IntData> {
  static const ConstTensorData enum_value = ConstTensorData_IntData;
};

template<> struct ConstTensorDataTraits<armnnSerializer::LongData> {
  static const ConstTensorData enum_value = ConstTensorData_LongData;
};

bool VerifyConstTensorData(flatbuffers::Verifier &verifier, const void *obj, ConstTensorData type);
bool VerifyConstTensorDataVector(flatbuffers::Verifier &verifier, const flatbuffers::Vector<flatbuffers::Offset<void>> *values, const flatbuffers::Vector<uint8_t> *types);

enum LayerType {
  LayerType_Addition = 0,
  LayerType_Input = 1,
  LayerType_Multiplication = 2,
  LayerType_Output = 3,
  LayerType_Pooling2d = 4,
  LayerType_Reshape = 5,
  LayerType_Softmax = 6,
  LayerType_Convolution2d = 7,
  LayerType_DepthwiseConvolution2d = 8,
  LayerType_Activation = 9,
  LayerType_Permute = 10,
  LayerType_FullyConnected = 11,
  LayerType_Constant = 12,
  LayerType_SpaceToBatchNd = 13,
  LayerType_BatchToSpaceNd = 14,
  LayerType_Division = 15,
  LayerType_Minimum = 16,
  LayerType_Equal = 17,
  LayerType_Maximum = 18,
  LayerType_Normalization = 19,
  LayerType_Pad = 20,
  LayerType_Rsqrt = 21,
  LayerType_Floor = 22,
  LayerType_BatchNormalization = 23,
  LayerType_Greater = 24,
  LayerType_ResizeBilinear = 25,
  LayerType_Subtraction = 26,
  LayerType_StridedSlice = 27,
  LayerType_Gather = 28,
  LayerType_Mean = 29,
  LayerType_Merger = 30,
  LayerType_L2Normalization = 31,
  LayerType_Splitter = 32,
  LayerType_DetectionPostProcess = 33,
  LayerType_Lstm = 34,
  LayerType_Quantize = 35,
  LayerType_Dequantize = 36,
  LayerType_Merge = 37,
  LayerType_Switch = 38,
  LayerType_Concat = 39,
  LayerType_SpaceToDepth = 40,
  LayerType_Prelu = 41,
  LayerType_TransposeConvolution2d = 42,
  LayerType_Resize = 43,
  LayerType_Stack = 44,
  LayerType_QuantizedLstm = 45,
  LayerType_Abs = 46,
  LayerType_ArgMinMax = 47,
  LayerType_Slice = 48,
  LayerType_DepthToSpace = 49,
  LayerType_InstanceNormalization = 50,
  LayerType_LogSoftmax = 51,
  LayerType_Comparison = 52,
  LayerType_StandIn = 53,
  LayerType_ElementwiseUnary = 54,
  LayerType_Transpose = 55,
  LayerType_QLstm = 56,
  LayerType_Fill = 57,
  LayerType_Rank = 58,
  LayerType_LogicalBinary = 59,
  LayerType_Reduce = 60,
  LayerType_Cast = 61,
  LayerType_Shape = 62,
  LayerType_MIN = LayerType_Addition,
  LayerType_MAX = LayerType_Shape
};

inline const LayerType (&EnumValuesLayerType())[63] {
  static const LayerType values[] = {
    LayerType_Addition,
    LayerType_Input,
    LayerType_Multiplication,
    LayerType_Output,
    LayerType_Pooling2d,
    LayerType_Reshape,
    LayerType_Softmax,
    LayerType_Convolution2d,
    LayerType_DepthwiseConvolution2d,
    LayerType_Activation,
    LayerType_Permute,
    LayerType_FullyConnected,
    LayerType_Constant,
    LayerType_SpaceToBatchNd,
    LayerType_BatchToSpaceNd,
    LayerType_Division,
    LayerType_Minimum,
    LayerType_Equal,
    LayerType_Maximum,
    LayerType_Normalization,
    LayerType_Pad,
    LayerType_Rsqrt,
    LayerType_Floor,
    LayerType_BatchNormalization,
    LayerType_Greater,
    LayerType_ResizeBilinear,
    LayerType_Subtraction,
    LayerType_StridedSlice,
    LayerType_Gather,
    LayerType_Mean,
    LayerType_Merger,
    LayerType_L2Normalization,
    LayerType_Splitter,
    LayerType_DetectionPostProcess,
    LayerType_Lstm,
    LayerType_Quantize,
    LayerType_Dequantize,
    LayerType_Merge,
    LayerType_Switch,
    LayerType_Concat,
    LayerType_SpaceToDepth,
    LayerType_Prelu,
    LayerType_TransposeConvolution2d,
    LayerType_Resize,
    LayerType_Stack,
    LayerType_QuantizedLstm,
    LayerType_Abs,
    LayerType_ArgMinMax,
    LayerType_Slice,
    LayerType_DepthToSpace,
    LayerType_InstanceNormalization,
    LayerType_LogSoftmax,
    LayerType_Comparison,
    LayerType_StandIn,
    LayerType_ElementwiseUnary,
    LayerType_Transpose,
    LayerType_QLstm,
    LayerType_Fill,
    LayerType_Rank,
    LayerType_LogicalBinary,
    LayerType_Reduce,
    LayerType_Cast,
    LayerType_Shape
  };
  return values;
}

inline const char * const *EnumNamesLayerType() {
  static const char * const names[64] = {
    "Addition",
    "Input",
    "Multiplication",
    "Output",
    "Pooling2d",
    "Reshape",
    "Softmax",
    "Convolution2d",
    "DepthwiseConvolution2d",
    "Activation",
    "Permute",
    "FullyConnected",
    "Constant",
    "SpaceToBatchNd",
    "BatchToSpaceNd",
    "Division",
    "Minimum",
    "Equal",
    "Maximum",
    "Normalization",
    "Pad",
    "Rsqrt",
    "Floor",
    "BatchNormalization",
    "Greater",
    "ResizeBilinear",
    "Subtraction",
    "StridedSlice",
    "Gather",
    "Mean",
    "Merger",
    "L2Normalization",
    "Splitter",
    "DetectionPostProcess",
    "Lstm",
    "Quantize",
    "Dequantize",
    "Merge",
    "Switch",
    "Concat",
    "SpaceToDepth",
    "Prelu",
    "TransposeConvolution2d",
    "Resize",
    "Stack",
    "QuantizedLstm",
    "Abs",
    "ArgMinMax",
    "Slice",
    "DepthToSpace",
    "InstanceNormalization",
    "LogSoftmax",
    "Comparison",
    "StandIn",
    "ElementwiseUnary",
    "Transpose",
    "QLstm",
    "Fill",
    "Rank",
    "LogicalBinary",
    "Reduce",
    "Cast",
    "Shape",
    nullptr
  };
  return names;
}

inline const char *EnumNameLayerType(LayerType e) {
  if (flatbuffers::IsOutRange(e, LayerType_Addition, LayerType_Shape)) return "";
  const size_t index = static_cast<size_t>(e);
  return EnumNamesLayerType()[index];
}

enum ComparisonOperation {
  ComparisonOperation_Equal = 0,
  ComparisonOperation_Greater = 1,
  ComparisonOperation_GreaterOrEqual = 2,
  ComparisonOperation_Less = 3,
  ComparisonOperation_LessOrEqual = 4,
  ComparisonOperation_NotEqual = 5,
  ComparisonOperation_MIN = ComparisonOperation_Equal,
  ComparisonOperation_MAX = ComparisonOperation_NotEqual
};

inline const ComparisonOperation (&EnumValuesComparisonOperation())[6] {
  static const ComparisonOperation values[] = {
    ComparisonOperation_Equal,
    ComparisonOperation_Greater,
    ComparisonOperation_GreaterOrEqual,
    ComparisonOperation_Less,
    ComparisonOperation_LessOrEqual,
    ComparisonOperation_NotEqual
  };
  return values;
}

inline const char * const *EnumNamesComparisonOperation() {
  static const char * const names[7] = {
    "Equal",
    "Greater",
    "GreaterOrEqual",
    "Less",
    "LessOrEqual",
    "NotEqual",
    nullptr
  };
  return names;
}

inline const char *EnumNameComparisonOperation(ComparisonOperation e) {
  if (flatbuffers::IsOutRange(e, ComparisonOperation_Equal, ComparisonOperation_NotEqual)) return "";
  const size_t index = static_cast<size_t>(e);
  return EnumNamesComparisonOperation()[index];
}

enum UnaryOperation {
  UnaryOperation_Abs = 0,
  UnaryOperation_Rsqrt = 1,
  UnaryOperation_Sqrt = 2,
  UnaryOperation_Exp = 3,
  UnaryOperation_Neg = 4,
  UnaryOperation_LogicalNot = 5,
  UnaryOperation_Log = 6,
  UnaryOperation_Sin = 7,
  UnaryOperation_MIN = UnaryOperation_Abs,
  UnaryOperation_MAX = UnaryOperation_Sin
};

inline const UnaryOperation (&EnumValuesUnaryOperation())[8] {
  static const UnaryOperation values[] = {
    UnaryOperation_Abs,
    UnaryOperation_Rsqrt,
    UnaryOperation_Sqrt,
    UnaryOperation_Exp,
    UnaryOperation_Neg,
    UnaryOperation_LogicalNot,
    UnaryOperation_Log,
    UnaryOperation_Sin
  };
  return values;
}

inline const char * const *EnumNamesUnaryOperation() {
  static const char * const names[9] = {
    "Abs",
    "Rsqrt",
    "Sqrt",
    "Exp",
    "Neg",
    "LogicalNot",
    "Log",
    "Sin",
    nullptr
  };
  return names;
}

inline const char *EnumNameUnaryOperation(UnaryOperation e) {
  if (flatbuffers::IsOutRange(e, UnaryOperation_Abs, UnaryOperation_Sin)) return "";
  const size_t index = static_cast<size_t>(e);
  return EnumNamesUnaryOperation()[index];
}

enum LogicalBinaryOperation {
  LogicalBinaryOperation_LogicalAnd = 0,
  LogicalBinaryOperation_LogicalOr = 1,
  LogicalBinaryOperation_MIN = LogicalBinaryOperation_LogicalAnd,
  LogicalBinaryOperation_MAX = LogicalBinaryOperation_LogicalOr
};

inline const LogicalBinaryOperation (&EnumValuesLogicalBinaryOperation())[2] {
  static const LogicalBinaryOperation values[] = {
    LogicalBinaryOperation_LogicalAnd,
    LogicalBinaryOperation_LogicalOr
  };
  return values;
}

inline const char * const *EnumNamesLogicalBinaryOperation() {
  static const char * const names[3] = {
    "LogicalAnd",
    "LogicalOr",
    nullptr
  };
  return names;
}

inline const char *EnumNameLogicalBinaryOperation(LogicalBinaryOperation e) {
  if (flatbuffers::IsOutRange(e, LogicalBinaryOperation_LogicalAnd, LogicalBinaryOperation_LogicalOr)) return "";
  const size_t index = static_cast<size_t>(e);
  return EnumNamesLogicalBinaryOperation()[index];
}

enum PoolingAlgorithm {
  PoolingAlgorithm_Max = 0,
  PoolingAlgorithm_Average = 1,
  PoolingAlgorithm_L2 = 2,
  PoolingAlgorithm_MIN = PoolingAlgorithm_Max,
  PoolingAlgorithm_MAX = PoolingAlgorithm_L2
};

inline const PoolingAlgorithm (&EnumValuesPoolingAlgorithm())[3] {
  static const PoolingAlgorithm values[] = {
    PoolingAlgorithm_Max,
    PoolingAlgorithm_Average,
    PoolingAlgorithm_L2
  };
  return values;
}

inline const char * const *EnumNamesPoolingAlgorithm() {
  static const char * const names[4] = {
    "Max",
    "Average",
    "L2",
    nullptr
  };
  return names;
}

inline const char *EnumNamePoolingAlgorithm(PoolingAlgorithm e) {
  if (flatbuffers::IsOutRange(e, PoolingAlgorithm_Max, PoolingAlgorithm_L2)) return "";
  const size_t index = static_cast<size_t>(e);
  return EnumNamesPoolingAlgorithm()[index];
}

enum OutputShapeRounding {
  OutputShapeRounding_Floor = 0,
  OutputShapeRounding_Ceiling = 1,
  OutputShapeRounding_MIN = OutputShapeRounding_Floor,
  OutputShapeRounding_MAX = OutputShapeRounding_Ceiling
};

inline const OutputShapeRounding (&EnumValuesOutputShapeRounding())[2] {
  static const OutputShapeRounding values[] = {
    OutputShapeRounding_Floor,
    OutputShapeRounding_Ceiling
  };
  return values;
}

inline const char * const *EnumNamesOutputShapeRounding() {
  static const char * const names[3] = {
    "Floor",
    "Ceiling",
    nullptr
  };
  return names;
}

inline const char *EnumNameOutputShapeRounding(OutputShapeRounding e) {
  if (flatbuffers::IsOutRange(e, OutputShapeRounding_Floor, OutputShapeRounding_Ceiling)) return "";
  const size_t index = static_cast<size_t>(e);
  return EnumNamesOutputShapeRounding()[index];
}

enum PaddingMethod {
  PaddingMethod_IgnoreValue = 0,
  PaddingMethod_Exclude = 1,
  PaddingMethod_MIN = PaddingMethod_IgnoreValue,
  PaddingMethod_MAX = PaddingMethod_Exclude
};

inline const PaddingMethod (&EnumValuesPaddingMethod())[2] {
  static const PaddingMethod values[] = {
    PaddingMethod_IgnoreValue,
    PaddingMethod_Exclude
  };
  return values;
}

inline const char * const *EnumNamesPaddingMethod() {
  static const char * const names[3] = {
    "IgnoreValue",
    "Exclude",
    nullptr
  };
  return names;
}

inline const char *EnumNamePaddingMethod(PaddingMethod e) {
  if (flatbuffers::IsOutRange(e, PaddingMethod_IgnoreValue, PaddingMethod_Exclude)) return "";
  const size_t index = static_cast<size_t>(e);
  return EnumNamesPaddingMethod()[index];
}

enum NormalizationAlgorithmChannel {
  NormalizationAlgorithmChannel_Across = 0,
  NormalizationAlgorithmChannel_Within = 1,
  NormalizationAlgorithmChannel_MIN = NormalizationAlgorithmChannel_Across,
  NormalizationAlgorithmChannel_MAX = NormalizationAlgorithmChannel_Within
};

inline const NormalizationAlgorithmChannel (&EnumValuesNormalizationAlgorithmChannel())[2] {
  static const NormalizationAlgorithmChannel values[] = {
    NormalizationAlgorithmChannel_Across,
    NormalizationAlgorithmChannel_Within
  };
  return values;
}

inline const char * const *EnumNamesNormalizationAlgorithmChannel() {
  static const char * const names[3] = {
    "Across",
    "Within",
    nullptr
  };
  return names;
}

inline const char *EnumNameNormalizationAlgorithmChannel(NormalizationAlgorithmChannel e) {
  if (flatbuffers::IsOutRange(e, NormalizationAlgorithmChannel_Across, NormalizationAlgorithmChannel_Within)) return "";
  const size_t index = static_cast<size_t>(e);
  return EnumNamesNormalizationAlgorithmChannel()[index];
}

enum NormalizationAlgorithmMethod {
  NormalizationAlgorithmMethod_LocalBrightness = 0,
  NormalizationAlgorithmMethod_LocalContrast = 1,
  NormalizationAlgorithmMethod_MIN = NormalizationAlgorithmMethod_LocalBrightness,
  NormalizationAlgorithmMethod_MAX = NormalizationAlgorithmMethod_LocalContrast
};

inline const NormalizationAlgorithmMethod (&EnumValuesNormalizationAlgorithmMethod())[2] {
  static const NormalizationAlgorithmMethod values[] = {
    NormalizationAlgorithmMethod_LocalBrightness,
    NormalizationAlgorithmMethod_LocalContrast
  };
  return values;
}

inline const char * const *EnumNamesNormalizationAlgorithmMethod() {
  static const char * const names[3] = {
    "LocalBrightness",
    "LocalContrast",
    nullptr
  };
  return names;
}

inline const char *EnumNameNormalizationAlgorithmMethod(NormalizationAlgorithmMethod e) {
  if (flatbuffers::IsOutRange(e, NormalizationAlgorithmMethod_LocalBrightness, NormalizationAlgorithmMethod_LocalContrast)) return "";
  const size_t index = static_cast<size_t>(e);
  return EnumNamesNormalizationAlgorithmMethod()[index];
}

enum Layer {
  Layer_NONE = 0,
  Layer_ActivationLayer = 1,
  Layer_AdditionLayer = 2,
  Layer_BatchToSpaceNdLayer = 3,
  Layer_BatchNormalizationLayer = 4,
  Layer_ConstantLayer = 5,
  Layer_Convolution2dLayer = 6,
  Layer_DepthwiseConvolution2dLayer = 7,
  Layer_FullyConnectedLayer = 8,
  Layer_InputLayer = 9,
  Layer_MultiplicationLayer = 10,
  Layer_OutputLayer = 11,
  Layer_PermuteLayer = 12,
  Layer_Pooling2dLayer = 13,
  Layer_ReshapeLayer = 14,
  Layer_SoftmaxLayer = 15,
  Layer_SpaceToBatchNdLayer = 16,
  Layer_DivisionLayer = 17,
  Layer_MinimumLayer = 18,
  Layer_EqualLayer = 19,
  Layer_MaximumLayer = 20,
  Layer_NormalizationLayer = 21,
  Layer_PadLayer = 22,
  Layer_RsqrtLayer = 23,
  Layer_FloorLayer = 24,
  Layer_GreaterLayer = 25,
  Layer_ResizeBilinearLayer = 26,
  Layer_SubtractionLayer = 27,
  Layer_StridedSliceLayer = 28,
  Layer_GatherLayer = 29,
  Layer_MeanLayer = 30,
  Layer_MergerLayer = 31,
  Layer_L2NormalizationLayer = 32,
  Layer_SplitterLayer = 33,
  Layer_DetectionPostProcessLayer = 34,
  Layer_LstmLayer = 35,
  Layer_QuantizedLstmLayer = 36,
  Layer_QuantizeLayer = 37,
  Layer_DequantizeLayer = 38,
  Layer_MergeLayer = 39,
  Layer_SwitchLayer = 40,
  Layer_ConcatLayer = 41,
  Layer_SpaceToDepthLayer = 42,
  Layer_PreluLayer = 43,
  Layer_TransposeConvolution2dLayer = 44,
  Layer_ResizeLayer = 45,
  Layer_StackLayer = 46,
  Layer_AbsLayer = 47,
  Layer_ArgMinMaxLayer = 48,
  Layer_SliceLayer = 49,
  Layer_DepthToSpaceLayer = 50,
  Layer_InstanceNormalizationLayer = 51,
  Layer_LogSoftmaxLayer = 52,
  Layer_ComparisonLayer = 53,
  Layer_StandInLayer = 54,
  Layer_ElementwiseUnaryLayer = 55,
  Layer_TransposeLayer = 56,
  Layer_QLstmLayer = 57,
  Layer_FillLayer = 58,
  Layer_RankLayer = 59,
  Layer_LogicalBinaryLayer = 60,
  Layer_ReduceLayer = 61,
  Layer_CastLayer = 62,
  Layer_ShapeLayer = 63,
  Layer_MIN = Layer_NONE,
  Layer_MAX = Layer_ShapeLayer
};

inline const Layer (&EnumValuesLayer())[64] {
  static const Layer values[] = {
    Layer_NONE,
    Layer_ActivationLayer,
    Layer_AdditionLayer,
    Layer_BatchToSpaceNdLayer,
    Layer_BatchNormalizationLayer,
    Layer_ConstantLayer,
    Layer_Convolution2dLayer,
    Layer_DepthwiseConvolution2dLayer,
    Layer_FullyConnectedLayer,
    Layer_InputLayer,
    Layer_MultiplicationLayer,
    Layer_OutputLayer,
    Layer_PermuteLayer,
    Layer_Pooling2dLayer,
    Layer_ReshapeLayer,
    Layer_SoftmaxLayer,
    Layer_SpaceToBatchNdLayer,
    Layer_DivisionLayer,
    Layer_MinimumLayer,
    Layer_EqualLayer,
    Layer_MaximumLayer,
    Layer_NormalizationLayer,
    Layer_PadLayer,
    Layer_RsqrtLayer,
    Layer_FloorLayer,
    Layer_GreaterLayer,
    Layer_ResizeBilinearLayer,
    Layer_SubtractionLayer,
    Layer_StridedSliceLayer,
    Layer_GatherLayer,
    Layer_MeanLayer,
    Layer_MergerLayer,
    Layer_L2NormalizationLayer,
    Layer_SplitterLayer,
    Layer_DetectionPostProcessLayer,
    Layer_LstmLayer,
    Layer_QuantizedLstmLayer,
    Layer_QuantizeLayer,
    Layer_DequantizeLayer,
    Layer_MergeLayer,
    Layer_SwitchLayer,
    Layer_ConcatLayer,
    Layer_SpaceToDepthLayer,
    Layer_PreluLayer,
    Layer_TransposeConvolution2dLayer,
    Layer_ResizeLayer,
    Layer_StackLayer,
    Layer_AbsLayer,
    Layer_ArgMinMaxLayer,
    Layer_SliceLayer,
    Layer_DepthToSpaceLayer,
    Layer_InstanceNormalizationLayer,
    Layer_LogSoftmaxLayer,
    Layer_ComparisonLayer,
    Layer_StandInLayer,
    Layer_ElementwiseUnaryLayer,
    Layer_TransposeLayer,
    Layer_QLstmLayer,
    Layer_FillLayer,
    Layer_RankLayer,
    Layer_LogicalBinaryLayer,
    Layer_ReduceLayer,
    Layer_CastLayer,
    Layer_ShapeLayer
  };
  return values;
}

inline const char * const *EnumNamesLayer() {
  static const char * const names[65] = {
    "NONE",
    "ActivationLayer",
    "AdditionLayer",
    "BatchToSpaceNdLayer",
    "BatchNormalizationLayer",
    "ConstantLayer",
    "Convolution2dLayer",
    "DepthwiseConvolution2dLayer",
    "FullyConnectedLayer",
    "InputLayer",
    "MultiplicationLayer",
    "OutputLayer",
    "PermuteLayer",
    "Pooling2dLayer",
    "ReshapeLayer",
    "SoftmaxLayer",
    "SpaceToBatchNdLayer",
    "DivisionLayer",
    "MinimumLayer",
    "EqualLayer",
    "MaximumLayer",
    "NormalizationLayer",
    "PadLayer",
    "RsqrtLayer",
    "FloorLayer",
    "GreaterLayer",
    "ResizeBilinearLayer",
    "SubtractionLayer",
    "StridedSliceLayer",
    "GatherLayer",
    "MeanLayer",
    "MergerLayer",
    "L2NormalizationLayer",
    "SplitterLayer",
    "DetectionPostProcessLayer",
    "LstmLayer",
    "QuantizedLstmLayer",
    "QuantizeLayer",
    "DequantizeLayer",
    "MergeLayer",
    "SwitchLayer",
    "ConcatLayer",
    "SpaceToDepthLayer",
    "PreluLayer",
    "TransposeConvolution2dLayer",
    "ResizeLayer",
    "StackLayer",
    "AbsLayer",
    "ArgMinMaxLayer",
    "SliceLayer",
    "DepthToSpaceLayer",
    "InstanceNormalizationLayer",
    "LogSoftmaxLayer",
    "ComparisonLayer",
    "StandInLayer",
    "ElementwiseUnaryLayer",
    "TransposeLayer",
    "QLstmLayer",
    "FillLayer",
    "RankLayer",
    "LogicalBinaryLayer",
    "ReduceLayer",
    "CastLayer",
    "ShapeLayer",
    nullptr
  };
  return names;
}

inline const char *EnumNameLayer(Layer e) {
  if (flatbuffers::IsOutRange(e, Layer_NONE, Layer_ShapeLayer)) return "";
  const size_t index = static_cast<size_t>(e);
  return EnumNamesLayer()[index];
}

template<typename T> struct LayerTraits {
  static const Layer enum_value = Layer_NONE;
};

template<> struct LayerTraits<armnnSerializer::ActivationLayer> {
  static const Layer enum_value = Layer_ActivationLayer;
};

template<> struct LayerTraits<armnnSerializer::AdditionLayer> {
  static const Layer enum_value = Layer_AdditionLayer;
};

template<> struct LayerTraits<armnnSerializer::BatchToSpaceNdLayer> {
  static const Layer enum_value = Layer_BatchToSpaceNdLayer;
};

template<> struct LayerTraits<armnnSerializer::BatchNormalizationLayer> {
  static const Layer enum_value = Layer_BatchNormalizationLayer;
};

template<> struct LayerTraits<armnnSerializer::ConstantLayer> {
  static const Layer enum_value = Layer_ConstantLayer;
};

template<> struct LayerTraits<armnnSerializer::Convolution2dLayer> {
  static const Layer enum_value = Layer_Convolution2dLayer;
};

template<> struct LayerTraits<armnnSerializer::DepthwiseConvolution2dLayer> {
  static const Layer enum_value = Layer_DepthwiseConvolution2dLayer;
};

template<> struct LayerTraits<armnnSerializer::FullyConnectedLayer> {
  static const Layer enum_value = Layer_FullyConnectedLayer;
};

template<> struct LayerTraits<armnnSerializer::InputLayer> {
  static const Layer enum_value = Layer_InputLayer;
};

template<> struct LayerTraits<armnnSerializer::MultiplicationLayer> {
  static const Layer enum_value = Layer_MultiplicationLayer;
};

template<> struct LayerTraits<armnnSerializer::OutputLayer> {
  static const Layer enum_value = Layer_OutputLayer;
};

template<> struct LayerTraits<armnnSerializer::PermuteLayer> {
  static const Layer enum_value = Layer_PermuteLayer;
};

template<> struct LayerTraits<armnnSerializer::Pooling2dLayer> {
  static const Layer enum_value = Layer_Pooling2dLayer;
};

template<> struct LayerTraits<armnnSerializer::ReshapeLayer> {
  static const Layer enum_value = Layer_ReshapeLayer;
};

template<> struct LayerTraits<armnnSerializer::SoftmaxLayer> {
  static const Layer enum_value = Layer_SoftmaxLayer;
};

template<> struct LayerTraits<armnnSerializer::SpaceToBatchNdLayer> {
  static const Layer enum_value = Layer_SpaceToBatchNdLayer;
};

template<> struct LayerTraits<armnnSerializer::DivisionLayer> {
  static const Layer enum_value = Layer_DivisionLayer;
};

template<> struct LayerTraits<armnnSerializer::MinimumLayer> {
  static const Layer enum_value = Layer_MinimumLayer;
};

template<> struct LayerTraits<armnnSerializer::EqualLayer> {
  static const Layer enum_value = Layer_EqualLayer;
};

template<> struct LayerTraits<armnnSerializer::MaximumLayer> {
  static const Layer enum_value = Layer_MaximumLayer;
};

template<> struct LayerTraits<armnnSerializer::NormalizationLayer> {
  static const Layer enum_value = Layer_NormalizationLayer;
};

template<> struct LayerTraits<armnnSerializer::PadLayer> {
  static const Layer enum_value = Layer_PadLayer;
};

template<> struct LayerTraits<armnnSerializer::RsqrtLayer> {
  static const Layer enum_value = Layer_RsqrtLayer;
};

template<> struct LayerTraits<armnnSerializer::FloorLayer> {
  static const Layer enum_value = Layer_FloorLayer;
};

template<> struct LayerTraits<armnnSerializer::GreaterLayer> {
  static const Layer enum_value = Layer_GreaterLayer;
};

template<> struct LayerTraits<armnnSerializer::ResizeBilinearLayer> {
  static const Layer enum_value = Layer_ResizeBilinearLayer;
};

template<> struct LayerTraits<armnnSerializer::SubtractionLayer> {
  static const Layer enum_value = Layer_SubtractionLayer;
};

template<> struct LayerTraits<armnnSerializer::StridedSliceLayer> {
  static const Layer enum_value = Layer_StridedSliceLayer;
};

template<> struct LayerTraits<armnnSerializer::GatherLayer> {
  static const Layer enum_value = Layer_GatherLayer;
};

template<> struct LayerTraits<armnnSerializer::MeanLayer> {
  static const Layer enum_value = Layer_MeanLayer;
};

template<> struct LayerTraits<armnnSerializer::MergerLayer> {
  static const Layer enum_value = Layer_MergerLayer;
};

template<> struct LayerTraits<armnnSerializer::L2NormalizationLayer> {
  static const Layer enum_value = Layer_L2NormalizationLayer;
};

template<> struct LayerTraits<armnnSerializer::SplitterLayer> {
  static const Layer enum_value = Layer_SplitterLayer;
};

template<> struct LayerTraits<armnnSerializer::DetectionPostProcessLayer> {
  static const Layer enum_value = Layer_DetectionPostProcessLayer;
};

template<> struct LayerTraits<armnnSerializer::LstmLayer> {
  static const Layer enum_value = Layer_LstmLayer;
};

template<> struct LayerTraits<armnnSerializer::QuantizedLstmLayer> {
  static const Layer enum_value = Layer_QuantizedLstmLayer;
};

template<> struct LayerTraits<armnnSerializer::QuantizeLayer> {
  static const Layer enum_value = Layer_QuantizeLayer;
};

template<> struct LayerTraits<armnnSerializer::DequantizeLayer> {
  static const Layer enum_value = Layer_DequantizeLayer;
};

template<> struct LayerTraits<armnnSerializer::MergeLayer> {
  static const Layer enum_value = Layer_MergeLayer;
};

template<> struct LayerTraits<armnnSerializer::SwitchLayer> {
  static const Layer enum_value = Layer_SwitchLayer;
};

template<> struct LayerTraits<armnnSerializer::ConcatLayer> {
  static const Layer enum_value = Layer_ConcatLayer;
};

template<> struct LayerTraits<armnnSerializer::SpaceToDepthLayer> {
  static const Layer enum_value = Layer_SpaceToDepthLayer;
};

template<> struct LayerTraits<armnnSerializer::PreluLayer> {
  static const Layer enum_value = Layer_PreluLayer;
};

template<> struct LayerTraits<armnnSerializer::TransposeConvolution2dLayer> {
  static const Layer enum_value = Layer_TransposeConvolution2dLayer;
};

template<> struct LayerTraits<armnnSerializer::ResizeLayer> {
  static const Layer enum_value = Layer_ResizeLayer;
};

template<> struct LayerTraits<armnnSerializer::StackLayer> {
  static const Layer enum_value = Layer_StackLayer;
};

template<> struct LayerTraits<armnnSerializer::AbsLayer> {
  static const Layer enum_value = Layer_AbsLayer;
};

template<> struct LayerTraits<armnnSerializer::ArgMinMaxLayer> {
  static const Layer enum_value = Layer_ArgMinMaxLayer;
};

template<> struct LayerTraits<armnnSerializer::SliceLayer> {
  static const Layer enum_value = Layer_SliceLayer;
};

template<> struct LayerTraits<armnnSerializer::DepthToSpaceLayer> {
  static const Layer enum_value = Layer_DepthToSpaceLayer;
};

template<> struct LayerTraits<armnnSerializer::InstanceNormalizationLayer> {
  static const Layer enum_value = Layer_InstanceNormalizationLayer;
};

template<> struct LayerTraits<armnnSerializer::LogSoftmaxLayer> {
  static const Layer enum_value = Layer_LogSoftmaxLayer;
};

template<> struct LayerTraits<armnnSerializer::ComparisonLayer> {
  static const Layer enum_value = Layer_ComparisonLayer;
};

template<> struct LayerTraits<armnnSerializer::StandInLayer> {
  static const Layer enum_value = Layer_StandInLayer;
};

template<> struct LayerTraits<armnnSerializer::ElementwiseUnaryLayer> {
  static const Layer enum_value = Layer_ElementwiseUnaryLayer;
};

template<> struct LayerTraits<armnnSerializer::TransposeLayer> {
  static const Layer enum_value = Layer_TransposeLayer;
};

template<> struct LayerTraits<armnnSerializer::QLstmLayer> {
  static const Layer enum_value = Layer_QLstmLayer;
};

template<> struct LayerTraits<armnnSerializer::FillLayer> {
  static const Layer enum_value = Layer_FillLayer;
};

template<> struct LayerTraits<armnnSerializer::RankLayer> {
  static const Layer enum_value = Layer_RankLayer;
};

template<> struct LayerTraits<armnnSerializer::LogicalBinaryLayer> {
  static const Layer enum_value = Layer_LogicalBinaryLayer;
};

template<> struct LayerTraits<armnnSerializer::ReduceLayer> {
  static const Layer enum_value = Layer_ReduceLayer;
};

template<> struct LayerTraits<armnnSerializer::CastLayer> {
  static const Layer enum_value = Layer_CastLayer;
};

template<> struct LayerTraits<armnnSerializer::ShapeLayer> {
  static const Layer enum_value = Layer_ShapeLayer;
};

bool VerifyLayer(flatbuffers::Verifier &verifier, const void *obj, Layer type);
bool VerifyLayerVector(flatbuffers::Verifier &verifier, const flatbuffers::Vector<flatbuffers::Offset<void>> *values, const flatbuffers::Vector<uint8_t> *types);

FLATBUFFERS_MANUALLY_ALIGNED_STRUCT(4) Connection FLATBUFFERS_FINAL_CLASS {
 private:
  uint32_t sourceLayerIndex_;
  uint32_t outputSlotIndex_;

 public:
  Connection() {
    memset(static_cast<void *>(this), 0, sizeof(Connection));
  }
  Connection(uint32_t _sourceLayerIndex, uint32_t _outputSlotIndex)
      : sourceLayerIndex_(flatbuffers::EndianScalar(_sourceLayerIndex)),
        outputSlotIndex_(flatbuffers::EndianScalar(_outputSlotIndex)) {
  }
  uint32_t sourceLayerIndex() const {
    return flatbuffers::EndianScalar(sourceLayerIndex_);
  }
  uint32_t outputSlotIndex() const {
    return flatbuffers::EndianScalar(outputSlotIndex_);
  }
};
FLATBUFFERS_STRUCT_END(Connection, 8);

struct TensorInfo FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
  typedef TensorInfoBuilder Builder;
  enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
    VT_DIMENSIONS = 4,
    VT_DATATYPE = 6,
    VT_QUANTIZATIONSCALE = 8,
    VT_QUANTIZATIONOFFSET = 10,
    VT_QUANTIZATIONSCALES = 12,
    VT_QUANTIZATIONDIM = 14,
    VT_DIMENSIONALITY = 16,
    VT_DIMENSIONSPECIFICITY = 18
  };
  const flatbuffers::Vector<uint32_t> *dimensions() const {
    return GetPointer<const flatbuffers::Vector<uint32_t> *>(VT_DIMENSIONS);
  }
  armnnSerializer::DataType dataType() const {
    return static_cast<armnnSerializer::DataType>(GetField<int8_t>(VT_DATATYPE, 0));
  }
  float quantizationScale() const {
    return GetField<float>(VT_QUANTIZATIONSCALE, 1.0f);
  }
  int32_t quantizationOffset() const {
    return GetField<int32_t>(VT_QUANTIZATIONOFFSET, 0);
  }
  const flatbuffers::Vector<float> *quantizationScales() const {
    return GetPointer<const flatbuffers::Vector<float> *>(VT_QUANTIZATIONSCALES);
  }
  uint32_t quantizationDim() const {
    return GetField<uint32_t>(VT_QUANTIZATIONDIM, 0);
  }
  uint32_t dimensionality() const {
    return GetField<uint32_t>(VT_DIMENSIONALITY, 1);
  }
  const flatbuffers::Vector<uint8_t> *dimensionSpecificity() const {
    return GetPointer<const flatbuffers::Vector<uint8_t> *>(VT_DIMENSIONSPECIFICITY);
  }
  bool Verify(flatbuffers::Verifier &verifier) const {
    return VerifyTableStart(verifier) &&
           VerifyOffset(verifier, VT_DIMENSIONS) &&
           verifier.VerifyVector(dimensions()) &&
           VerifyField<int8_t>(verifier, VT_DATATYPE) &&
           VerifyField<float>(verifier, VT_QUANTIZATIONSCALE) &&
           VerifyField<int32_t>(verifier, VT_QUANTIZATIONOFFSET) &&
           VerifyOffset(verifier, VT_QUANTIZATIONSCALES) &&
           verifier.VerifyVector(quantizationScales()) &&
           VerifyField<uint32_t>(verifier, VT_QUANTIZATIONDIM) &&
           VerifyField<uint32_t>(verifier, VT_DIMENSIONALITY) &&
           VerifyOffset(verifier, VT_DIMENSIONSPECIFICITY) &&
           verifier.VerifyVector(dimensionSpecificity()) &&
           verifier.EndTable();
  }
};

struct TensorInfoBuilder {
  typedef TensorInfo Table;
  flatbuffers::FlatBufferBuilder &fbb_;
  flatbuffers::uoffset_t start_;
  void add_dimensions(flatbuffers::Offset<flatbuffers::Vector<uint32_t>> dimensions) {
    fbb_.AddOffset(TensorInfo::VT_DIMENSIONS, dimensions);
  }
  void add_dataType(armnnSerializer::DataType dataType) {
    fbb_.AddElement<int8_t>(TensorInfo::VT_DATATYPE, static_cast<int8_t>(dataType), 0);
  }
  void add_quantizationScale(float quantizationScale) {
    fbb_.AddElement<float>(TensorInfo::VT_QUANTIZATIONSCALE, quantizationScale, 1.0f);
  }
  void add_quantizationOffset(int32_t quantizationOffset) {
    fbb_.AddElement<int32_t>(TensorInfo::VT_QUANTIZATIONOFFSET, quantizationOffset, 0);
  }
  void add_quantizationScales(flatbuffers::Offset<flatbuffers::Vector<float>> quantizationScales) {
    fbb_.AddOffset(TensorInfo::VT_QUANTIZATIONSCALES, quantizationScales);
  }
  void add_quantizationDim(uint32_t quantizationDim) {
    fbb_.AddElement<uint32_t>(TensorInfo::VT_QUANTIZATIONDIM, quantizationDim, 0);
  }
  void add_dimensionality(uint32_t dimensionality) {
    fbb_.AddElement<uint32_t>(TensorInfo::VT_DIMENSIONALITY, dimensionality, 1);
  }
  void add_dimensionSpecificity(flatbuffers::Offset<flatbuffers::Vector<uint8_t>> dimensionSpecificity) {
    fbb_.AddOffset(TensorInfo::VT_DIMENSIONSPECIFICITY, dimensionSpecificity);
  }
  explicit TensorInfoBuilder(flatbuffers::FlatBufferBuilder &_fbb)
        : fbb_(_fbb) {
    start_ = fbb_.StartTable();
  }
  TensorInfoBuilder &operator=(const TensorInfoBuilder &);
  flatbuffers::Offset<TensorInfo> Finish() {
    const auto end = fbb_.EndTable(start_);
    auto o = flatbuffers::Offset<TensorInfo>(end);
    return o;
  }
};

inline flatbuffers::Offset<TensorInfo> CreateTensorInfo(
    flatbuffers::FlatBufferBuilder &_fbb,
    flatbuffers::Offset<flatbuffers::Vector<uint32_t>> dimensions = 0,
    armnnSerializer::DataType dataType = armnnSerializer::DataType_Float16,
    float quantizationScale = 1.0f,
    int32_t quantizationOffset = 0,
    flatbuffers::Offset<flatbuffers::Vector<float>> quantizationScales = 0,
    uint32_t quantizationDim = 0,
    uint32_t dimensionality = 1,
    flatbuffers::Offset<flatbuffers::Vector<uint8_t>> dimensionSpecificity = 0) {
  TensorInfoBuilder builder_(_fbb);
  builder_.add_dimensionSpecificity(dimensionSpecificity);
  builder_.add_dimensionality(dimensionality);
  builder_.add_quantizationDim(quantizationDim);
  builder_.add_quantizationScales(quantizationScales);
  builder_.add_quantizationOffset(quantizationOffset);
  builder_.add_quantizationScale(quantizationScale);
  builder_.add_dimensions(dimensions);
  builder_.add_dataType(dataType);
  return builder_.Finish();
}

inline flatbuffers::Offset<TensorInfo> CreateTensorInfoDirect(
    flatbuffers::FlatBufferBuilder &_fbb,
    const std::vector<uint32_t> *dimensions = nullptr,
    armnnSerializer::DataType dataType = armnnSerializer::DataType_Float16,
    float quantizationScale = 1.0f,
    int32_t quantizationOffset = 0,
    const std::vector<float> *quantizationScales = nullptr,
    uint32_t quantizationDim = 0,
    uint32_t dimensionality = 1,
    const std::vector<uint8_t> *dimensionSpecificity = nullptr) {
  auto dimensions__ = dimensions ? _fbb.CreateVector<uint32_t>(*dimensions) : 0;
  auto quantizationScales__ = quantizationScales ? _fbb.CreateVector<float>(*quantizationScales) : 0;
  auto dimensionSpecificity__ = dimensionSpecificity ? _fbb.CreateVector<uint8_t>(*dimensionSpecificity) : 0;
  return armnnSerializer::CreateTensorInfo(
      _fbb,
      dimensions__,
      dataType,
      quantizationScale,
      quantizationOffset,
      quantizationScales__,
      quantizationDim,
      dimensionality,
      dimensionSpecificity__);
}

struct ByteData FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
  typedef ByteDataBuilder Builder;
  enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
    VT_DATA = 4
  };
  const flatbuffers::Vector<int8_t> *data() const {
    return GetPointer<const flatbuffers::Vector<int8_t> *>(VT_DATA);
  }
  bool Verify(flatbuffers::Verifier &verifier) const {
    return VerifyTableStart(verifier) &&
           VerifyOffset(verifier, VT_DATA) &&
           verifier.VerifyVector(data()) &&
           verifier.EndTable();
  }
};

struct ByteDataBuilder {
  typedef ByteData Table;
  flatbuffers::FlatBufferBuilder &fbb_;
  flatbuffers::uoffset_t start_;
  void add_data(flatbuffers::Offset<flatbuffers::Vector<int8_t>> data) {
    fbb_.AddOffset(ByteData::VT_DATA, data);
  }
  explicit ByteDataBuilder(flatbuffers::FlatBufferBuilder &_fbb)
        : fbb_(_fbb) {
    start_ = fbb_.StartTable();
  }
  ByteDataBuilder &operator=(const ByteDataBuilder &);
  flatbuffers::Offset<ByteData> Finish() {
    const auto end = fbb_.EndTable(start_);
    auto o = flatbuffers::Offset<ByteData>(end);
    return o;
  }
};

inline flatbuffers::Offset<ByteData> CreateByteData(
    flatbuffers::FlatBufferBuilder &_fbb,
    flatbuffers::Offset<flatbuffers::Vector<int8_t>> data = 0) {
  ByteDataBuilder builder_(_fbb);
  builder_.add_data(data);
  return builder_.Finish();
}

inline flatbuffers::Offset<ByteData> CreateByteDataDirect(
    flatbuffers::FlatBufferBuilder &_fbb,
    const std::vector<int8_t> *data = nullptr) {
  auto data__ = data ? _fbb.CreateVector<int8_t>(*data) : 0;
  return armnnSerializer::CreateByteData(
      _fbb,
      data__);
}

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

struct ShortDataBuilder {
  typedef ShortData Table;
  flatbuffers::FlatBufferBuilder &fbb_;
  flatbuffers::uoffset_t start_;
  void add_data(flatbuffers::Offset<flatbuffers::Vector<int16_t>> data) {
    fbb_.AddOffset(ShortData::VT_DATA, data);
  }
  explicit ShortDataBuilder(flatbuffers::FlatBufferBuilder &_fbb)
        : fbb_(_fbb) {
    start_ = fbb_.StartTable();
  }
  ShortDataBuilder &operator=(const ShortDataBuilder &);
  flatbuffers::Offset<ShortData> Finish() {
    const auto end = fbb_.EndTable(start_);
    auto o = flatbuffers::Offset<ShortData>(end);
    return o;
  }
};

inline flatbuffers::Offset<ShortData> CreateShortData(
    flatbuffers::FlatBufferBuilder &_fbb,
    flatbuffers::Offset<flatbuffers::Vector<int16_t>> data = 0) {
  ShortDataBuilder builder_(_fbb);
  builder_.add_data(data);
  return builder_.Finish();
}

inline flatbuffers::Offset<ShortData> CreateShortDataDirect(
    flatbuffers::FlatBufferBuilder &_fbb,
    const std::vector<int16_t> *data = nullptr) {
  auto data__ = data ? _fbb.CreateVector<int16_t>(*data) : 0;
  return armnnSerializer::CreateShortData(
      _fbb,
      data__);
}

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

struct IntDataBuilder {
  typedef IntData Table;
  flatbuffers::FlatBufferBuilder &fbb_;
  flatbuffers::uoffset_t start_;
  void add_data(flatbuffers::Offset<flatbuffers::Vector<int32_t>> data) {
    fbb_.AddOffset(IntData::VT_DATA, data);
  }
  explicit IntDataBuilder(flatbuffers::FlatBufferBuilder &_fbb)
        : fbb_(_fbb) {
    start_ = fbb_.StartTable();
  }
  IntDataBuilder &operator=(const IntDataBuilder &);
  flatbuffers::Offset<IntData> Finish() {
    const auto end = fbb_.EndTable(start_);
    auto o = flatbuffers::Offset<IntData>(end);
    return o;
  }
};

inline flatbuffers::Offset<IntData> CreateIntData(
    flatbuffers::FlatBufferBuilder &_fbb,
    flatbuffers::Offset<flatbuffers::Vector<int32_t>> data = 0) {
  IntDataBuilder builder_(_fbb);
  builder_.add_data(data);
  return builder_.Finish();
}

inline flatbuffers::Offset<IntData> CreateIntDataDirect(
    flatbuffers::FlatBufferBuilder &_fbb,
    const std::vector<int32_t> *data = nullptr) {
  auto data__ = data ? _fbb.CreateVector<int32_t>(*data) : 0;
  return armnnSerializer::CreateIntData(
      _fbb,
      data__);
}

struct LongData FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
  typedef LongDataBuilder Builder;
  enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
    VT_DATA = 4
  };
  const flatbuffers::Vector<int64_t> *data() const {
    return GetPointer<const flatbuffers::Vector<int64_t> *>(VT_DATA);
  }
  bool Verify(flatbuffers::Verifier &verifier) const {
    return VerifyTableStart(verifier) &&
           VerifyOffset(verifier, VT_DATA) &&
           verifier.VerifyVector(data()) &&
           verifier.EndTable();
  }
};

struct LongDataBuilder {
  typedef LongData Table;
  flatbuffers::FlatBufferBuilder &fbb_;
  flatbuffers::uoffset_t start_;
  void add_data(flatbuffers::Offset<flatbuffers::Vector<int64_t>> data) {
    fbb_.AddOffset(LongData::VT_DATA, data);
  }
  explicit LongDataBuilder(flatbuffers::FlatBufferBuilder &_fbb)
        : fbb_(_fbb) {
    start_ = fbb_.StartTable();
  }
  LongDataBuilder &operator=(const LongDataBuilder &);
  flatbuffers::Offset<LongData> Finish() {
    const auto end = fbb_.EndTable(start_);
    auto o = flatbuffers::Offset<LongData>(end);
    return o;
  }
};

inline flatbuffers::Offset<LongData> CreateLongData(
    flatbuffers::FlatBufferBuilder &_fbb,
    flatbuffers::Offset<flatbuffers::Vector<int64_t>> data = 0) {
  LongDataBuilder builder_(_fbb);
  builder_.add_data(data);
  return builder_.Finish();
}

inline flatbuffers::Offset<LongData> CreateLongDataDirect(
    flatbuffers::FlatBufferBuilder &_fbb,
    const std::vector<int64_t> *data = nullptr) {
  auto data__ = data ? _fbb.CreateVector<int64_t>(*data) : 0;
  return armnnSerializer::CreateLongData(
      _fbb,
      data__);
}

struct ConstTensor FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
  typedef ConstTensorBuilder Builder;
  enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
    VT_INFO = 4,
    VT_DATA_TYPE = 6,
    VT_DATA = 8
  };
  const armnnSerializer::TensorInfo *info() const {
    return GetPointer<const armnnSerializer::TensorInfo *>(VT_INFO);
  }
  armnnSerializer::ConstTensorData data_type() const {
    return static_cast<armnnSerializer::ConstTensorData>(GetField<uint8_t>(VT_DATA_TYPE, 0));
  }
  const void *data() const {
    return GetPointer<const void *>(VT_DATA);
  }
  template<typename T> const T *data_as() const;
  const armnnSerializer::ByteData *data_as_ByteData() const {
    return data_type() == armnnSerializer::ConstTensorData_ByteData ? static_cast<const armnnSerializer::ByteData *>(data()) : nullptr;
  }
  const armnnSerializer::ShortData *data_as_ShortData() const {
    return data_type() == armnnSerializer::ConstTensorData_ShortData ? static_cast<const armnnSerializer::ShortData *>(data()) : nullptr;
  }
  const armnnSerializer::IntData *data_as_IntData() const {
    return data_type() == armnnSerializer::ConstTensorData_IntData ? static_cast<const armnnSerializer::IntData *>(data()) : nullptr;
  }
  const armnnSerializer::LongData *data_as_LongData() const {
    return data_type() == armnnSerializer::ConstTensorData_LongData ? static_cast<const armnnSerializer::LongData *>(data()) : nullptr;
  }
  bool Verify(flatbuffers::Verifier &verifier) const {
    return VerifyTableStart(verifier) &&
           VerifyOffset(verifier, VT_INFO) &&
           verifier.VerifyTable(info()) &&
           VerifyField<uint8_t>(verifier, VT_DATA_TYPE) &&
           VerifyOffset(verifier, VT_DATA) &&
           VerifyConstTensorData(verifier, data(), data_type()) &&
           verifier.EndTable();
  }
};

template<> inline const armnnSerializer::ByteData *ConstTensor::data_as<armnnSerializer::ByteData>() const {
  return data_as_ByteData();
}

template<> inline const armnnSerializer::ShortData *ConstTensor::data_as<armnnSerializer::ShortData>() const {
  return data_as_ShortData();
}

template<> inline const armnnSerializer::IntData *ConstTensor::data_as<armnnSerializer::IntData>() const {
  return data_as_IntData();
}

template<> inline const armnnSerializer::LongData *ConstTensor::data_as<armnnSerializer::LongData>() const {
  return data_as_LongData();
}

struct ConstTensorBuilder {
  typedef ConstTensor Table;
  flatbuffers::FlatBufferBuilder &fbb_;
  flatbuffers::uoffset_t start_;
  void add_info(flatbuffers::Offset<armnnSerializer::TensorInfo> info) {
    fbb_.AddOffset(ConstTensor::VT_INFO, info);
  }
  void add_data_type(armnnSerializer::ConstTensorData data_type) {
    fbb_.AddElement<uint8_t>(ConstTensor::VT_DATA_TYPE, static_cast<uint8_t>(data_type), 0);
  }
  void add_data(flatbuffers::Offset<void> data) {
    fbb_.AddOffset(ConstTensor::VT_DATA, data);
  }
  explicit ConstTensorBuilder(flatbuffers::FlatBufferBuilder &_fbb)
        : fbb_(_fbb) {
    start_ = fbb_.StartTable();
  }
  ConstTensorBuilder &operator=(const ConstTensorBuilder &);
  flatbuffers::Offset<ConstTensor> Finish() {
    const auto end = fbb_.EndTable(start_);
    auto o = flatbuffers::Offset<ConstTensor>(end);
    return o;
  }
};

inline flatbuffers::Offset<ConstTensor> CreateConstTensor(
    flatbuffers::FlatBufferBuilder &_fbb,
    flatbuffers::Offset<armnnSerializer::TensorInfo> info = 0,
    armnnSerializer::ConstTensorData data_type = armnnSerializer::ConstTensorData_NONE,
    flatbuffers::Offset<void> data = 0) {
  ConstTensorBuilder builder_(_fbb);
  builder_.add_data(data);
  builder_.add_info(info);
  builder_.add_data_type(data_type);
  return builder_.Finish();
}

struct InputSlot FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
  typedef InputSlotBuilder Builder;
  enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
    VT_INDEX = 4,
    VT_CONNECTION = 6
  };
  uint32_t index() const {
    return GetField<uint32_t>(VT_INDEX, 0);
  }
  const armnnSerializer::Connection *connection() const {
    return GetStruct<const armnnSerializer::Connection *>(VT_CONNECTION);
  }
  bool Verify(flatbuffers::Verifier &verifier) const {
    return VerifyTableStart(verifier) &&
           VerifyField<uint32_t>(verifier, VT_INDEX) &&
           VerifyField<armnnSerializer::Connection>(verifier, VT_CONNECTION) &&
           verifier.EndTable();
  }
};

struct InputSlotBuilder {
  typedef InputSlot Table;
  flatbuffers::FlatBufferBuilder &fbb_;
  flatbuffers::uoffset_t start_;
  void add_index(uint32_t index) {
    fbb_.AddElement<uint32_t>(InputSlot::VT_INDEX, index, 0);
  }
  void add_connection(const armnnSerializer::Connection *connection) {
    fbb_.AddStruct(InputSlot::VT_CONNECTION, connection);
  }
  explicit InputSlotBuilder(flatbuffers::FlatBufferBuilder &_fbb)
        : fbb_(_fbb) {
    start_ = fbb_.StartTable();
  }
  InputSlotBuilder &operator=(const InputSlotBuilder &);
  flatbuffers::Offset<InputSlot> Finish() {
    const auto end = fbb_.EndTable(start_);
    auto o = flatbuffers::Offset<InputSlot>(end);
    return o;
  }
};

inline flatbuffers::Offset<InputSlot> CreateInputSlot(
    flatbuffers::FlatBufferBuilder &_fbb,
    uint32_t index = 0,
    const armnnSerializer::Connection *connection = 0) {
  InputSlotBuilder builder_(_fbb);
  builder_.add_connection(connection);
  builder_.add_index(index);
  return builder_.Finish();
}

struct OutputSlot FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
  typedef OutputSlotBuilder Builder;
  enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
    VT_INDEX = 4,
    VT_TENSORINFO = 6
  };
  uint32_t index() const {
    return GetField<uint32_t>(VT_INDEX, 0);
  }
  const armnnSerializer::TensorInfo *tensorInfo() const {
    return GetPointer<const armnnSerializer::TensorInfo *>(VT_TENSORINFO);
  }
  bool Verify(flatbuffers::Verifier &verifier) const {
    return VerifyTableStart(verifier) &&
           VerifyField<uint32_t>(verifier, VT_INDEX) &&
           VerifyOffset(verifier, VT_TENSORINFO) &&
           verifier.VerifyTable(tensorInfo()) &&
           verifier.EndTable();
  }
};

struct OutputSlotBuilder {
  typedef OutputSlot Table;
  flatbuffers::FlatBufferBuilder &fbb_;
  flatbuffers::uoffset_t start_;
  void add_index(uint32_t index) {
    fbb_.AddElement<uint32_t>(OutputSlot::VT_INDEX, index, 0);
  }
  void add_tensorInfo(flatbuffers::Offset<armnnSerializer::TensorInfo> tensorInfo) {
    fbb_.AddOffset(OutputSlot::VT_TENSORINFO, tensorInfo);
  }
  explicit OutputSlotBuilder(flatbuffers::FlatBufferBuilder &_fbb)
        : fbb_(_fbb) {
    start_ = fbb_.StartTable();
  }
  OutputSlotBuilder &operator=(const OutputSlotBuilder &);
  flatbuffers::Offset<OutputSlot> Finish() {
    const auto end = fbb_.EndTable(start_);
    auto o = flatbuffers::Offset<OutputSlot>(end);
    return o;
  }
};

inline flatbuffers::Offset<OutputSlot> CreateOutputSlot(
    flatbuffers::FlatBufferBuilder &_fbb,
    uint32_t index = 0,
    flatbuffers::Offset<armnnSerializer::TensorInfo> tensorInfo = 0) {
  OutputSlotBuilder builder_(_fbb);
  builder_.add_tensorInfo(tensorInfo);
  builder_.add_index(index);
  return builder_.Finish();
}

struct LayerBase FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
  typedef LayerBaseBuilder Builder;
  enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
    VT_INDEX = 4,
    VT_LAYERNAME = 6,
    VT_LAYERTYPE = 8,
    VT_INPUTSLOTS = 10,
    VT_OUTPUTSLOTS = 12
  };
  uint32_t index() const {
    return GetField<uint32_t>(VT_INDEX, 0);
  }
  const flatbuffers::String *layerName() const {
    return GetPointer<const flatbuffers::String *>(VT_LAYERNAME);
  }
  armnnSerializer::LayerType layerType() const {
    return static_cast<armnnSerializer::LayerType>(GetField<uint32_t>(VT_LAYERTYPE, 0));
  }
  const flatbuffers::Vector<flatbuffers::Offset<armnnSerializer::InputSlot>> *inputSlots() const {
    return GetPointer<const flatbuffers::Vector<flatbuffers::Offset<armnnSerializer::InputSlot>> *>(VT_INPUTSLOTS);
  }
  const flatbuffers::Vector<flatbuffers::Offset<armnnSerializer::OutputSlot>> *outputSlots() const {
    return GetPointer<const flatbuffers::Vector<flatbuffers::Offset<armnnSerializer::OutputSlot>> *>(VT_OUTPUTSLOTS);
  }
  bool Verify(flatbuffers::Verifier &verifier) const {
    return VerifyTableStart(verifier) &&
           VerifyField<uint32_t>(verifier, VT_INDEX) &&
           VerifyOffset(verifier, VT_LAYERNAME) &&
           verifier.VerifyString(layerName()) &&
           VerifyField<uint32_t>(verifier, VT_LAYERTYPE) &&
           VerifyOffset(verifier, VT_INPUTSLOTS) &&
           verifier.VerifyVector(inputSlots()) &&
           verifier.VerifyVectorOfTables(inputSlots()) &&
           VerifyOffset(verifier, VT_OUTPUTSLOTS) &&
           verifier.VerifyVector(outputSlots()) &&
           verifier.VerifyVectorOfTables(outputSlots()) &&
           verifier.EndTable();
  }
};

struct LayerBaseBuilder {
  typedef LayerBase Table;
  flatbuffers::FlatBufferBuilder &fbb_;
  flatbuffers::uoffset_t start_;
  void add_index(uint32_t index) {
    fbb_.AddElement<uint32_t>(LayerBase::VT_INDEX, index, 0);
  }
  void add_layerName(flatbuffers::Offset<flatbuffers::String> layerName) {
    fbb_.AddOffset(LayerBase::VT_LAYERNAME, layerName);
  }
  void add_layerType(armnnSerializer::LayerType layerType) {
    fbb_.AddElement<uint32_t>(LayerBase::VT_LAYERTYPE, static_cast<uint32_t>(layerType), 0);
  }
  void add_inputSlots(flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<armnnSerializer::InputSlot>>> inputSlots) {
    fbb_.AddOffset(LayerBase::VT_INPUTSLOTS, inputSlots);
  }
  void add_outputSlots(flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<armnnSerializer::OutputSlot>>> outputSlots) {
    fbb_.AddOffset(LayerBase::VT_OUTPUTSLOTS, outputSlots);
  }
  explicit LayerBaseBuilder(flatbuffers::FlatBufferBuilder &_fbb)
        : fbb_(_fbb) {
    start_ = fbb_.StartTable();
  }
  LayerBaseBuilder &operator=(const LayerBaseBuilder &);
  flatbuffers::Offset<LayerBase> Finish() {
    const auto end = fbb_.EndTable(start_);
    auto o = flatbuffers::Offset<LayerBase>(end);
    return o;
  }
};

inline flatbuffers::Offset<LayerBase> CreateLayerBase(
    flatbuffers::FlatBufferBuilder &_fbb,
    uint32_t index = 0,
    flatbuffers::Offset<flatbuffers::String> layerName = 0,
    armnnSerializer::LayerType layerType = armnnSerializer::LayerType_Addition,
    flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<armnnSerializer::InputSlot>>> inputSlots = 0,
    flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<armnnSerializer::OutputSlot>>> outputSlots = 0) {
  LayerBaseBuilder builder_(_fbb);
  builder_.add_outputSlots(outputSlots);
  builder_.add_inputSlots(inputSlots);
  builder_.add_layerType(layerType);
  builder_.add_layerName(layerName);
  builder_.add_index(index);
  return builder_.Finish();
}

inline flatbuffers::Offset<LayerBase> CreateLayerBaseDirect(
    flatbuffers::FlatBufferBuilder &_fbb,
    uint32_t index = 0,
    const char *layerName = nullptr,
    armnnSerializer::LayerType layerType = armnnSerializer::LayerType_Addition,
    const std::vector<flatbuffers::Offset<armnnSerializer::InputSlot>> *inputSlots = nullptr,
    const std::vector<flatbuffers::Offset<armnnSerializer::OutputSlot>> *outputSlots = nullptr) {
  auto layerName__ = layerName ? _fbb.CreateString(layerName) : 0;
  auto inputSlots__ = inputSlots ? _fbb.CreateVector<flatbuffers::Offset<armnnSerializer::InputSlot>>(*inputSlots) : 0;
  auto outputSlots__ = outputSlots ? _fbb.CreateVector<flatbuffers::Offset<armnnSerializer::OutputSlot>>(*outputSlots) : 0;
  return armnnSerializer::CreateLayerBase(
      _fbb,
      index,
      layerName__,
      layerType,
      inputSlots__,
      outputSlots__);
}

struct BindableLayerBase FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
  typedef BindableLayerBaseBuilder Builder;
  enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
    VT_BASE = 4,
    VT_LAYERBINDINGID = 6
  };
  const armnnSerializer::LayerBase *base() const {
    return GetPointer<const armnnSerializer::LayerBase *>(VT_BASE);
  }
  int32_t layerBindingId() const {
    return GetField<int32_t>(VT_LAYERBINDINGID, 0);
  }
  bool Verify(flatbuffers::Verifier &verifier) const {
    return VerifyTableStart(verifier) &&
           VerifyOffset(verifier, VT_BASE) &&
           verifier.VerifyTable(base()) &&
           VerifyField<int32_t>(verifier, VT_LAYERBINDINGID) &&
           verifier.EndTable();
  }
};

struct BindableLayerBaseBuilder {
  typedef BindableLayerBase Table;
  flatbuffers::FlatBufferBuilder &fbb_;
  flatbuffers::uoffset_t start_;
  void add_base(flatbuffers::Offset<armnnSerializer::LayerBase> base) {
    fbb_.AddOffset(BindableLayerBase::VT_BASE, base);
  }
  void add_layerBindingId(int32_t layerBindingId) {
    fbb_.AddElement<int32_t>(BindableLayerBase::VT_LAYERBINDINGID, layerBindingId, 0);
  }
  explicit BindableLayerBaseBuilder(flatbuffers::FlatBufferBuilder &_fbb)
        : fbb_(_fbb) {
    start_ = fbb_.StartTable();
  }
  BindableLayerBaseBuilder &operator=(const BindableLayerBaseBuilder &);
  flatbuffers::Offset<BindableLayerBase> Finish() {
    const auto end = fbb_.EndTable(start_);
    auto o = flatbuffers::Offset<BindableLayerBase>(end);
    return o;
  }
};

inline flatbuffers::Offset<BindableLayerBase> CreateBindableLayerBase(
    flatbuffers::FlatBufferBuilder &_fbb,
    flatbuffers::Offset<armnnSerializer::LayerBase> base = 0,
    int32_t layerBindingId = 0) {
  BindableLayerBaseBuilder builder_(_fbb);
  builder_.add_layerBindingId(layerBindingId);
  builder_.add_base(base);
  return builder_.Finish();
}

/// @deprecated Use ElementwiseUnaryLayer instead
struct AbsLayer FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
  typedef AbsLayerBuilder Builder;
  enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
    VT_BASE = 4
  };
  const armnnSerializer::LayerBase *base() const {
    return GetPointer<const armnnSerializer::LayerBase *>(VT_BASE);
  }
  bool Verify(flatbuffers::Verifier &verifier) const {
    return VerifyTableStart(verifier) &&
           VerifyOffset(verifier, VT_BASE) &&
           verifier.VerifyTable(base()) &&
           verifier.EndTable();
  }
};

struct AbsLayerBuilder {
  typedef AbsLayer Table;
  flatbuffers::FlatBufferBuilder &fbb_;
  flatbuffers::uoffset_t start_;
  void add_base(flatbuffers::Offset<armnnSerializer::LayerBase> base) {
    fbb_.AddOffset(AbsLayer::VT_BASE, base);
  }
  explicit AbsLayerBuilder(flatbuffers::FlatBufferBuilder &_fbb)
        : fbb_(_fbb) {
    start_ = fbb_.StartTable();
  }
  AbsLayerBuilder &operator=(const AbsLayerBuilder &);
  flatbuffers::Offset<AbsLayer> Finish() {
    const auto end = fbb_.EndTable(start_);
    auto o = flatbuffers::Offset<AbsLayer>(end);
    return o;
  }
};

inline flatbuffers::Offset<AbsLayer> CreateAbsLayer(
    flatbuffers::FlatBufferBuilder &_fbb,
    flatbuffers::Offset<armnnSerializer::LayerBase> base = 0) {
  AbsLayerBuilder builder_(_fbb);
  builder_.add_base(base);
  return builder_.Finish();
}

struct ActivationLayer FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
  typedef ActivationLayerBuilder Builder;
  enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
    VT_BASE = 4,
    VT_DESCRIPTOR = 6
  };
  const armnnSerializer::LayerBase *base() const {
    return GetPointer<const armnnSerializer::LayerBase *>(VT_BASE);
  }
  const armnnSerializer::ActivationDescriptor *descriptor() const {
    return GetPointer<const armnnSerializer::ActivationDescriptor *>(VT_DESCRIPTOR);
  }
  bool Verify(flatbuffers::Verifier &verifier) const {
    return VerifyTableStart(verifier) &&
           VerifyOffset(verifier, VT_BASE) &&
           verifier.VerifyTable(base()) &&
           VerifyOffset(verifier, VT_DESCRIPTOR) &&
           verifier.VerifyTable(descriptor()) &&
           verifier.EndTable();
  }
};

struct ActivationLayerBuilder {
  typedef ActivationLayer Table;
  flatbuffers::FlatBufferBuilder &fbb_;
  flatbuffers::uoffset_t start_;
  void add_base(flatbuffers::Offset<armnnSerializer::LayerBase> base) {
    fbb_.AddOffset(ActivationLayer::VT_BASE, base);
  }
  void add_descriptor(flatbuffers::Offset<armnnSerializer::ActivationDescriptor> descriptor) {
    fbb_.AddOffset(ActivationLayer::VT_DESCRIPTOR, descriptor);
  }
  explicit ActivationLayerBuilder(flatbuffers::FlatBufferBuilder &_fbb)
        : fbb_(_fbb) {
    start_ = fbb_.StartTable();
  }
  ActivationLayerBuilder &operator=(const ActivationLayerBuilder &);
  flatbuffers::Offset<ActivationLayer> Finish() {
    const auto end = fbb_.EndTable(start_);
    auto o = flatbuffers::Offset<ActivationLayer>(end);
    return o;
  }
};

inline flatbuffers::Offset<ActivationLayer> CreateActivationLayer(
    flatbuffers::FlatBufferBuilder &_fbb,
    flatbuffers::Offset<armnnSerializer::LayerBase> base = 0,
    flatbuffers::Offset<armnnSerializer::ActivationDescriptor> descriptor = 0) {
  ActivationLayerBuilder builder_(_fbb);
  builder_.add_descriptor(descriptor);
  builder_.add_base(base);
  return builder_.Finish();
}

struct ActivationDescriptor FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
  typedef ActivationDescriptorBuilder Builder;
  enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
    VT_ACTIVATIONFUNCTION = 4,
    VT_A = 6,
    VT_B = 8
  };
  armnnSerializer::ActivationFunction activationFunction() const {
    return static_cast<armnnSerializer::ActivationFunction>(GetField<int8_t>(VT_ACTIVATIONFUNCTION, 0));
  }
  float a() const {
    return GetField<float>(VT_A, 0.0f);
  }
  float b() const {
    return GetField<float>(VT_B, 0.0f);
  }
  bool Verify(flatbuffers::Verifier &verifier) const {
    return VerifyTableStart(verifier) &&
           VerifyField<int8_t>(verifier, VT_ACTIVATIONFUNCTION) &&
           VerifyField<float>(verifier, VT_A) &&
           VerifyField<float>(verifier, VT_B) &&
           verifier.EndTable();
  }
};

struct ActivationDescriptorBuilder {
  typedef ActivationDescriptor Table;
  flatbuffers::FlatBufferBuilder &fbb_;
  flatbuffers::uoffset_t start_;
  void add_activationFunction(armnnSerializer::ActivationFunction activationFunction) {
    fbb_.AddElement<int8_t>(ActivationDescriptor::VT_ACTIVATIONFUNCTION, static_cast<int8_t>(activationFunction), 0);
  }
  void add_a(float a) {
    fbb_.AddElement<float>(ActivationDescriptor::VT_A, a, 0.0f);
  }
  void add_b(float b) {
    fbb_.AddElement<float>(ActivationDescriptor::VT_B, b, 0.0f);
  }
  explicit ActivationDescriptorBuilder(flatbuffers::FlatBufferBuilder &_fbb)
        : fbb_(_fbb) {
    start_ = fbb_.StartTable();
  }
  ActivationDescriptorBuilder &operator=(const ActivationDescriptorBuilder &);
  flatbuffers::Offset<ActivationDescriptor> Finish() {
    const auto end = fbb_.EndTable(start_);
    auto o = flatbuffers::Offset<ActivationDescriptor>(end);
    return o;
  }
};

inline flatbuffers::Offset<ActivationDescriptor> CreateActivationDescriptor(
    flatbuffers::FlatBufferBuilder &_fbb,
    armnnSerializer::ActivationFunction activationFunction = armnnSerializer::ActivationFunction_Sigmoid,
    float a = 0.0f,
    float b = 0.0f) {
  ActivationDescriptorBuilder builder_(_fbb);
  builder_.add_b(b);
  builder_.add_a(a);
  builder_.add_activationFunction(activationFunction);
  return builder_.Finish();
}

struct AdditionLayer FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
  typedef AdditionLayerBuilder Builder;
  enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
    VT_BASE = 4
  };
  const armnnSerializer::LayerBase *base() const {
    return GetPointer<const armnnSerializer::LayerBase *>(VT_BASE);
  }
  bool Verify(flatbuffers::Verifier &verifier) const {
    return VerifyTableStart(verifier) &&
           VerifyOffset(verifier, VT_BASE) &&
           verifier.VerifyTable(base()) &&
           verifier.EndTable();
  }
};

struct AdditionLayerBuilder {
  typedef AdditionLayer Table;
  flatbuffers::FlatBufferBuilder &fbb_;
  flatbuffers::uoffset_t start_;
  void add_base(flatbuffers::Offset<armnnSerializer::LayerBase> base) {
    fbb_.AddOffset(AdditionLayer::VT_BASE, base);
  }
  explicit AdditionLayerBuilder(flatbuffers::FlatBufferBuilder &_fbb)
        : fbb_(_fbb) {
    start_ = fbb_.StartTable();
  }
  AdditionLayerBuilder &operator=(const AdditionLayerBuilder &);
  flatbuffers::Offset<AdditionLayer> Finish() {
    const auto end = fbb_.EndTable(start_);
    auto o = flatbuffers::Offset<AdditionLayer>(end);
    return o;
  }
};

inline flatbuffers::Offset<AdditionLayer> CreateAdditionLayer(
    flatbuffers::FlatBufferBuilder &_fbb,
    flatbuffers::Offset<armnnSerializer::LayerBase> base = 0) {
  AdditionLayerBuilder builder_(_fbb);
  builder_.add_base(base);
  return builder_.Finish();
}

struct ArgMinMaxLayer FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
  typedef ArgMinMaxLayerBuilder Builder;
  enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
    VT_BASE = 4,
    VT_DESCRIPTOR = 6
  };
  const armnnSerializer::LayerBase *base() const {
    return GetPointer<const armnnSerializer::LayerBase *>(VT_BASE);
  }
  const armnnSerializer::ArgMinMaxDescriptor *descriptor() const {
    return GetPointer<const armnnSerializer::ArgMinMaxDescriptor *>(VT_DESCRIPTOR);
  }
  bool Verify(flatbuffers::Verifier &verifier) const {
    return VerifyTableStart(verifier) &&
           VerifyOffset(verifier, VT_BASE) &&
           verifier.VerifyTable(base()) &&
           VerifyOffset(verifier, VT_DESCRIPTOR) &&
           verifier.VerifyTable(descriptor()) &&
           verifier.EndTable();
  }
};

struct ArgMinMaxLayerBuilder {
  typedef ArgMinMaxLayer Table;
  flatbuffers::FlatBufferBuilder &fbb_;
  flatbuffers::uoffset_t start_;
  void add_base(flatbuffers::Offset<armnnSerializer::LayerBase> base) {
    fbb_.AddOffset(ArgMinMaxLayer::VT_BASE, base);
  }
  void add_descriptor(flatbuffers::Offset<armnnSerializer::ArgMinMaxDescriptor> descriptor) {
    fbb_.AddOffset(ArgMinMaxLayer::VT_DESCRIPTOR, descriptor);
  }
  explicit ArgMinMaxLayerBuilder(flatbuffers::FlatBufferBuilder &_fbb)
        : fbb_(_fbb) {
    start_ = fbb_.StartTable();
  }
  ArgMinMaxLayerBuilder &operator=(const ArgMinMaxLayerBuilder &);
  flatbuffers::Offset<ArgMinMaxLayer> Finish() {
    const auto end = fbb_.EndTable(start_);
    auto o = flatbuffers::Offset<ArgMinMaxLayer>(end);
    return o;
  }
};

inline flatbuffers::Offset<ArgMinMaxLayer> CreateArgMinMaxLayer(
    flatbuffers::FlatBufferBuilder &_fbb,
    flatbuffers::Offset<armnnSerializer::LayerBase> base = 0,
    flatbuffers::Offset<armnnSerializer::ArgMinMaxDescriptor> descriptor = 0) {
  ArgMinMaxLayerBuilder builder_(_fbb);
  builder_.add_descriptor(descriptor);
  builder_.add_base(base);
  return builder_.Finish();
}

struct ArgMinMaxDescriptor FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
  typedef ArgMinMaxDescriptorBuilder Builder;
  enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
    VT_ARGMINMAXFUNCTION = 4,
    VT_AXIS = 6
  };
  armnnSerializer::ArgMinMaxFunction argMinMaxFunction() const {
    return static_cast<armnnSerializer::ArgMinMaxFunction>(GetField<int8_t>(VT_ARGMINMAXFUNCTION, 0));
  }
  int32_t axis() const {
    return GetField<int32_t>(VT_AXIS, 0);
  }
  bool Verify(flatbuffers::Verifier &verifier) const {
    return VerifyTableStart(verifier) &&
           VerifyField<int8_t>(verifier, VT_ARGMINMAXFUNCTION) &&
           VerifyField<int32_t>(verifier, VT_AXIS) &&
           verifier.EndTable();
  }
};

struct ArgMinMaxDescriptorBuilder {
  typedef ArgMinMaxDescriptor Table;
  flatbuffers::FlatBufferBuilder &fbb_;
  flatbuffers::uoffset_t start_;
  void add_argMinMaxFunction(armnnSerializer::ArgMinMaxFunction argMinMaxFunction) {
    fbb_.AddElement<int8_t>(ArgMinMaxDescriptor::VT_ARGMINMAXFUNCTION, static_cast<int8_t>(argMinMaxFunction), 0);
  }
  void add_axis(int32_t axis) {
    fbb_.AddElement<int32_t>(ArgMinMaxDescriptor::VT_AXIS, axis, 0);
  }
  explicit ArgMinMaxDescriptorBuilder(flatbuffers::FlatBufferBuilder &_fbb)
        : fbb_(_fbb) {
    start_ = fbb_.StartTable();
  }
  ArgMinMaxDescriptorBuilder &operator=(const ArgMinMaxDescriptorBuilder &);
  flatbuffers::Offset<ArgMinMaxDescriptor> Finish() {
    const auto end = fbb_.EndTable(start_);
    auto o = flatbuffers::Offset<ArgMinMaxDescriptor>(end);
    return o;
  }
};

inline flatbuffers::Offset<ArgMinMaxDescriptor> CreateArgMinMaxDescriptor(
    flatbuffers::FlatBufferBuilder &_fbb,
    armnnSerializer::ArgMinMaxFunction argMinMaxFunction = armnnSerializer::ArgMinMaxFunction_Min,
    int32_t axis = 0) {
  ArgMinMaxDescriptorBuilder builder_(_fbb);
  builder_.add_axis(axis);
  builder_.add_argMinMaxFunction(argMinMaxFunction);
  return builder_.Finish();
}

struct CastLayer FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
  typedef CastLayerBuilder Builder;
  enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
    VT_BASE = 4
  };
  const armnnSerializer::LayerBase *base() const {
    return GetPointer<const armnnSerializer::LayerBase *>(VT_BASE);
  }
  bool Verify(flatbuffers::Verifier &verifier) const {
    return VerifyTableStart(verifier) &&
           VerifyOffset(verifier, VT_BASE) &&
           verifier.VerifyTable(base()) &&
           verifier.EndTable();
  }
};

struct CastLayerBuilder {
  typedef CastLayer Table;
  flatbuffers::FlatBufferBuilder &fbb_;
  flatbuffers::uoffset_t start_;
  void add_base(flatbuffers::Offset<armnnSerializer::LayerBase> base) {
    fbb_.AddOffset(CastLayer::VT_BASE, base);
  }
  explicit CastLayerBuilder(flatbuffers::FlatBufferBuilder &_fbb)
        : fbb_(_fbb) {
    start_ = fbb_.StartTable();
  }
  CastLayerBuilder &operator=(const CastLayerBuilder &);
  flatbuffers::Offset<CastLayer> Finish() {
    const auto end = fbb_.EndTable(start_);
    auto o = flatbuffers::Offset<CastLayer>(end);
    return o;
  }
};

inline flatbuffers::Offset<CastLayer> CreateCastLayer(
    flatbuffers::FlatBufferBuilder &_fbb,
    flatbuffers::Offset<armnnSerializer::LayerBase> base = 0) {
  CastLayerBuilder builder_(_fbb);
  builder_.add_base(base);
  return builder_.Finish();
}

struct ComparisonDescriptor FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
  typedef ComparisonDescriptorBuilder Builder;
  enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
    VT_OPERATION = 4
  };
  armnnSerializer::ComparisonOperation operation() const {
    return static_cast<armnnSerializer::ComparisonOperation>(GetField<int8_t>(VT_OPERATION, 0));
  }
  bool Verify(flatbuffers::Verifier &verifier) const {
    return VerifyTableStart(verifier) &&
           VerifyField<int8_t>(verifier, VT_OPERATION) &&
           verifier.EndTable();
  }
};

struct ComparisonDescriptorBuilder {
  typedef ComparisonDescriptor Table;
  flatbuffers::FlatBufferBuilder &fbb_;
  flatbuffers::uoffset_t start_;
  void add_operation(armnnSerializer::ComparisonOperation operation) {
    fbb_.AddElement<int8_t>(ComparisonDescriptor::VT_OPERATION, static_cast<int8_t>(operation), 0);
  }
  explicit ComparisonDescriptorBuilder(flatbuffers::FlatBufferBuilder &_fbb)
        : fbb_(_fbb) {
    start_ = fbb_.StartTable();
  }
  ComparisonDescriptorBuilder &operator=(const ComparisonDescriptorBuilder &);
  flatbuffers::Offset<ComparisonDescriptor> Finish() {
    const auto end = fbb_.EndTable(start_);
    auto o = flatbuffers::Offset<ComparisonDescriptor>(end);
    return o;
  }
};

inline flatbuffers::Offset<ComparisonDescriptor> CreateComparisonDescriptor(
    flatbuffers::FlatBufferBuilder &_fbb,
    armnnSerializer::ComparisonOperation operation = armnnSerializer::ComparisonOperation_Equal) {
  ComparisonDescriptorBuilder builder_(_fbb);
  builder_.add_operation(operation);
  return builder_.Finish();
}

struct ComparisonLayer FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
  typedef ComparisonLayerBuilder Builder;
  enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
    VT_BASE = 4,
    VT_DESCRIPTOR = 6
  };
  const armnnSerializer::LayerBase *base() const {
    return GetPointer<const armnnSerializer::LayerBase *>(VT_BASE);
  }
  const armnnSerializer::ComparisonDescriptor *descriptor() const {
    return GetPointer<const armnnSerializer::ComparisonDescriptor *>(VT_DESCRIPTOR);
  }
  bool Verify(flatbuffers::Verifier &verifier) const {
    return VerifyTableStart(verifier) &&
           VerifyOffset(verifier, VT_BASE) &&
           verifier.VerifyTable(base()) &&
           VerifyOffset(verifier, VT_DESCRIPTOR) &&
           verifier.VerifyTable(descriptor()) &&
           verifier.EndTable();
  }
};

struct ComparisonLayerBuilder {
  typedef ComparisonLayer Table;
  flatbuffers::FlatBufferBuilder &fbb_;
  flatbuffers::uoffset_t start_;
  void add_base(flatbuffers::Offset<armnnSerializer::LayerBase> base) {
    fbb_.AddOffset(ComparisonLayer::VT_BASE, base);
  }
  void add_descriptor(flatbuffers::Offset<armnnSerializer::ComparisonDescriptor> descriptor) {
    fbb_.AddOffset(ComparisonLayer::VT_DESCRIPTOR, descriptor);
  }
  explicit ComparisonLayerBuilder(flatbuffers::FlatBufferBuilder &_fbb)
        : fbb_(_fbb) {
    start_ = fbb_.StartTable();
  }
  ComparisonLayerBuilder &operator=(const ComparisonLayerBuilder &);
  flatbuffers::Offset<ComparisonLayer> Finish() {
    const auto end = fbb_.EndTable(start_);
    auto o = flatbuffers::Offset<ComparisonLayer>(end);
    return o;
  }
};

inline flatbuffers::Offset<ComparisonLayer> CreateComparisonLayer(
    flatbuffers::FlatBufferBuilder &_fbb,
    flatbuffers::Offset<armnnSerializer::LayerBase> base = 0,
    flatbuffers::Offset<armnnSerializer::ComparisonDescriptor> descriptor = 0) {
  ComparisonLayerBuilder builder_(_fbb);
  builder_.add_descriptor(descriptor);
  builder_.add_base(base);
  return builder_.Finish();
}

struct ConstantLayer FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
  typedef ConstantLayerBuilder Builder;
  enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
    VT_BASE = 4,
    VT_INPUT = 6
  };
  const armnnSerializer::LayerBase *base() const {
    return GetPointer<const armnnSerializer::LayerBase *>(VT_BASE);
  }
  const armnnSerializer::ConstTensor *input() const {
    return GetPointer<const armnnSerializer::ConstTensor *>(VT_INPUT);
  }
  bool Verify(flatbuffers::Verifier &verifier) const {
    return VerifyTableStart(verifier) &&
           VerifyOffset(verifier, VT_BASE) &&
           verifier.VerifyTable(base()) &&
           VerifyOffset(verifier, VT_INPUT) &&
           verifier.VerifyTable(input()) &&
           verifier.EndTable();
  }
};

struct ConstantLayerBuilder {
  typedef ConstantLayer Table;
  flatbuffers::FlatBufferBuilder &fbb_;
  flatbuffers::uoffset_t start_;
  void add_base(flatbuffers::Offset<armnnSerializer::LayerBase> base) {
    fbb_.AddOffset(ConstantLayer::VT_BASE, base);
  }
  void add_input(flatbuffers::Offset<armnnSerializer::ConstTensor> input) {
    fbb_.AddOffset(ConstantLayer::VT_INPUT, input);
  }
  explicit ConstantLayerBuilder(flatbuffers::FlatBufferBuilder &_fbb)
        : fbb_(_fbb) {
    start_ = fbb_.StartTable();
  }
  ConstantLayerBuilder &operator=(const ConstantLayerBuilder &);
  flatbuffers::Offset<ConstantLayer> Finish() {
    const auto end = fbb_.EndTable(start_);
    auto o = flatbuffers::Offset<ConstantLayer>(end);
    return o;
  }
};

inline flatbuffers::Offset<ConstantLayer> CreateConstantLayer(
    flatbuffers::FlatBufferBuilder &_fbb,
    flatbuffers::Offset<armnnSerializer::LayerBase> base = 0,
    flatbuffers::Offset<armnnSerializer::ConstTensor> input = 0) {
  ConstantLayerBuilder builder_(_fbb);
  builder_.add_input(input);
  builder_.add_base(base);
  return builder_.Finish();
}

struct Convolution2dLayer FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
  typedef Convolution2dLayerBuilder Builder;
  enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
    VT_BASE = 4,
    VT_DESCRIPTOR = 6,
    VT_WEIGHTS = 8,
    VT_BIASES = 10
  };
  const armnnSerializer::LayerBase *base() const {
    return GetPointer<const armnnSerializer::LayerBase *>(VT_BASE);
  }
  const armnnSerializer::Convolution2dDescriptor *descriptor() const {
    return GetPointer<const armnnSerializer::Convolution2dDescriptor *>(VT_DESCRIPTOR);
  }
  const armnnSerializer::ConstTensor *weights() const {
    return GetPointer<const armnnSerializer::ConstTensor *>(VT_WEIGHTS);
  }
  const armnnSerializer::ConstTensor *biases() const {
    return GetPointer<const armnnSerializer::ConstTensor *>(VT_BIASES);
  }
  bool Verify(flatbuffers::Verifier &verifier) const {
    return VerifyTableStart(verifier) &&
           VerifyOffset(verifier, VT_BASE) &&
           verifier.VerifyTable(base()) &&
           VerifyOffset(verifier, VT_DESCRIPTOR) &&
           verifier.VerifyTable(descriptor()) &&
           VerifyOffset(verifier, VT_WEIGHTS) &&
           verifier.VerifyTable(weights()) &&
           VerifyOffset(verifier, VT_BIASES) &&
           verifier.VerifyTable(biases()) &&
           verifier.EndTable();
  }
};

struct Convolution2dLayerBuilder {
  typedef Convolution2dLayer Table;
  flatbuffers::FlatBufferBuilder &fbb_;
  flatbuffers::uoffset_t start_;
  void add_base(flatbuffers::Offset<armnnSerializer::LayerBase> base) {
    fbb_.AddOffset(Convolution2dLayer::VT_BASE, base);
  }
  void add_descriptor(flatbuffers::Offset<armnnSerializer::Convolution2dDescriptor> descriptor) {
    fbb_.AddOffset(Convolution2dLayer::VT_DESCRIPTOR, descriptor);
  }
  void add_weights(flatbuffers::Offset<armnnSerializer::ConstTensor> weights) {
    fbb_.AddOffset(Convolution2dLayer::VT_WEIGHTS, weights);
  }
  void add_biases(flatbuffers::Offset<armnnSerializer::ConstTensor> biases) {
    fbb_.AddOffset(Convolution2dLayer::VT_BIASES, biases);
  }
  explicit Convolution2dLayerBuilder(flatbuffers::FlatBufferBuilder &_fbb)
        : fbb_(_fbb) {
    start_ = fbb_.StartTable();
  }
  Convolution2dLayerBuilder &operator=(const Convolution2dLayerBuilder &);
  flatbuffers::Offset<Convolution2dLayer> Finish() {
    const auto end = fbb_.EndTable(start_);
    auto o = flatbuffers::Offset<Convolution2dLayer>(end);
    return o;
  }
};

inline flatbuffers::Offset<Convolution2dLayer> CreateConvolution2dLayer(
    flatbuffers::FlatBufferBuilder &_fbb,
    flatbuffers::Offset<armnnSerializer::LayerBase> base = 0,
    flatbuffers::Offset<armnnSerializer::Convolution2dDescriptor> descriptor = 0,
    flatbuffers::Offset<armnnSerializer::ConstTensor> weights = 0,
    flatbuffers::Offset<armnnSerializer::ConstTensor> biases = 0) {
  Convolution2dLayerBuilder builder_(_fbb);
  builder_.add_biases(biases);
  builder_.add_weights(weights);
  builder_.add_descriptor(descriptor);
  builder_.add_base(base);
  return builder_.Finish();
}

struct Convolution2dDescriptor FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
  typedef Convolution2dDescriptorBuilder Builder;
  enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
    VT_PADLEFT = 4,
    VT_PADRIGHT = 6,
    VT_PADTOP = 8,
    VT_PADBOTTOM = 10,
    VT_STRIDEX = 12,
    VT_STRIDEY = 14,
    VT_DILATIONX = 16,
    VT_DILATIONY = 18,
    VT_BIASENABLED = 20,
    VT_DATALAYOUT = 22
  };
  uint32_t padLeft() const {
    return GetField<uint32_t>(VT_PADLEFT, 0);
  }
  uint32_t padRight() const {
    return GetField<uint32_t>(VT_PADRIGHT, 0);
  }
  uint32_t padTop() const {
    return GetField<uint32_t>(VT_PADTOP, 0);
  }
  uint32_t padBottom() const {
    return GetField<uint32_t>(VT_PADBOTTOM, 0);
  }
  uint32_t strideX() const {
    return GetField<uint32_t>(VT_STRIDEX, 0);
  }
  uint32_t strideY() const {
    return GetField<uint32_t>(VT_STRIDEY, 0);
  }
  uint32_t dilationX() const {
    return GetField<uint32_t>(VT_DILATIONX, 1);
  }
  uint32_t dilationY() const {
    return GetField<uint32_t>(VT_DILATIONY, 1);
  }
  bool biasEnabled() const {
    return GetField<uint8_t>(VT_BIASENABLED, 0) != 0;
  }
  armnnSerializer::DataLayout dataLayout() const {
    return static_cast<armnnSerializer::DataLayout>(GetField<int8_t>(VT_DATALAYOUT, 1));
  }
  bool Verify(flatbuffers::Verifier &verifier) const {
    return VerifyTableStart(verifier) &&
           VerifyField<uint32_t>(verifier, VT_PADLEFT) &&
           VerifyField<uint32_t>(verifier, VT_PADRIGHT) &&
           VerifyField<uint32_t>(verifier, VT_PADTOP) &&
           VerifyField<uint32_t>(verifier, VT_PADBOTTOM) &&
           VerifyField<uint32_t>(verifier, VT_STRIDEX) &&
           VerifyField<uint32_t>(verifier, VT_STRIDEY) &&
           VerifyField<uint32_t>(verifier, VT_DILATIONX) &&
           VerifyField<uint32_t>(verifier, VT_DILATIONY) &&
           VerifyField<uint8_t>(verifier, VT_BIASENABLED) &&
           VerifyField<int8_t>(verifier, VT_DATALAYOUT) &&
           verifier.EndTable();
  }
};

struct Convolution2dDescriptorBuilder {
  typedef Convolution2dDescriptor Table;
  flatbuffers::FlatBufferBuilder &fbb_;
  flatbuffers::uoffset_t start_;
  void add_padLeft(uint32_t padLeft) {
    fbb_.AddElement<uint32_t>(Convolution2dDescriptor::VT_PADLEFT, padLeft, 0);
  }
  void add_padRight(uint32_t padRight) {
    fbb_.AddElement<uint32_t>(Convolution2dDescriptor::VT_PADRIGHT, padRight, 0);
  }
  void add_padTop(uint32_t padTop) {
    fbb_.AddElement<uint32_t>(Convolution2dDescriptor::VT_PADTOP, padTop, 0);
  }
  void add_padBottom(uint32_t padBottom) {
    fbb_.AddElement<uint32_t>(Convolution2dDescriptor::VT_PADBOTTOM, padBottom, 0);
  }
  void add_strideX(uint32_t strideX) {
    fbb_.AddElement<uint32_t>(Convolution2dDescriptor::VT_STRIDEX, strideX, 0);
  }
  void add_strideY(uint32_t strideY) {
    fbb_.AddElement<uint32_t>(Convolution2dDescriptor::VT_STRIDEY, strideY, 0);
  }
  void add_dilationX(uint32_t dilationX) {
    fbb_.AddElement<uint32_t>(Convolution2dDescriptor::VT_DILATIONX, dilationX, 1);
  }
  void add_dilationY(uint32_t dilationY) {
    fbb_.AddElement<uint32_t>(Convolution2dDescriptor::VT_DILATIONY, dilationY, 1);
  }
  void add_biasEnabled(bool biasEnabled) {
    fbb_.AddElement<uint8_t>(Convolution2dDescriptor::VT_BIASENABLED, static_cast<uint8_t>(biasEnabled), 0);
  }
  void add_dataLayout(armnnSerializer::DataLayout dataLayout) {
    fbb_.AddElement<int8_t>(Convolution2dDescriptor::VT_DATALAYOUT, static_cast<int8_t>(dataLayout), 1);
  }
  explicit Convolution2dDescriptorBuilder(flatbuffers::FlatBufferBuilder &_fbb)
        : fbb_(_fbb) {
    start_ = fbb_.StartTable();
  }
  Convolution2dDescriptorBuilder &operator=(const Convolution2dDescriptorBuilder &);
  flatbuffers::Offset<Convolution2dDescriptor> Finish() {
    const auto end = fbb_.EndTable(start_);
    auto o = flatbuffers::Offset<Convolution2dDescriptor>(end);
    return o;
  }
};

inline flatbuffers::Offset<Convolution2dDescriptor> CreateConvolution2dDescriptor(
    flatbuffers::FlatBufferBuilder &_fbb,
    uint32_t padLeft = 0,
    uint32_t padRight = 0,
    uint32_t padTop = 0,
    uint32_t padBottom = 0,
    uint32_t strideX = 0,
    uint32_t strideY = 0,
    uint32_t dilationX = 1,
    uint32_t dilationY = 1,
    bool biasEnabled = false,
    armnnSerializer::DataLayout dataLayout = armnnSerializer::DataLayout_NCHW) {
  Convolution2dDescriptorBuilder builder_(_fbb);
  builder_.add_dilationY(dilationY);
  builder_.add_dilationX(dilationX);
  builder_.add_strideY(strideY);
  builder_.add_strideX(strideX);
  builder_.add_padBottom(padBottom);
  builder_.add_padTop(padTop);
  builder_.add_padRight(padRight);
  builder_.add_padLeft(padLeft);
  builder_.add_dataLayout(dataLayout);
  builder_.add_biasEnabled(biasEnabled);
  return builder_.Finish();
}

struct DepthToSpaceLayer FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
  typedef DepthToSpaceLayerBuilder Builder;
  enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
    VT_BASE = 4,
    VT_DESCRIPTOR = 6
  };
  const armnnSerializer::LayerBase *base() const {
    return GetPointer<const armnnSerializer::LayerBase *>(VT_BASE);
  }
  const armnnSerializer::DepthToSpaceDescriptor *descriptor() const {
    return GetPointer<const armnnSerializer::DepthToSpaceDescriptor *>(VT_DESCRIPTOR);
  }
  bool Verify(flatbuffers::Verifier &verifier) const {
    return VerifyTableStart(verifier) &&
           VerifyOffset(verifier, VT_BASE) &&
           verifier.VerifyTable(base()) &&
           VerifyOffset(verifier, VT_DESCRIPTOR) &&
           verifier.VerifyTable(descriptor()) &&
           verifier.EndTable();
  }
};

struct DepthToSpaceLayerBuilder {
  typedef DepthToSpaceLayer Table;
  flatbuffers::FlatBufferBuilder &fbb_;
  flatbuffers::uoffset_t start_;
  void add_base(flatbuffers::Offset<armnnSerializer::LayerBase> base) {
    fbb_.AddOffset(DepthToSpaceLayer::VT_BASE, base);
  }
  void add_descriptor(flatbuffers::Offset<armnnSerializer::DepthToSpaceDescriptor> descriptor) {
    fbb_.AddOffset(DepthToSpaceLayer::VT_DESCRIPTOR, descriptor);
  }
  explicit DepthToSpaceLayerBuilder(flatbuffers::FlatBufferBuilder &_fbb)
        : fbb_(_fbb) {
    start_ = fbb_.StartTable();
  }
  DepthToSpaceLayerBuilder &operator=(const DepthToSpaceLayerBuilder &);
  flatbuffers::Offset<DepthToSpaceLayer> Finish() {
    const auto end = fbb_.EndTable(start_);
    auto o = flatbuffers::Offset<DepthToSpaceLayer>(end);
    return o;
  }
};

inline flatbuffers::Offset<DepthToSpaceLayer> CreateDepthToSpaceLayer(
    flatbuffers::FlatBufferBuilder &_fbb,
    flatbuffers::Offset<armnnSerializer::LayerBase> base = 0,
    flatbuffers::Offset<armnnSerializer::DepthToSpaceDescriptor> descriptor = 0) {
  DepthToSpaceLayerBuilder builder_(_fbb);
  builder_.add_descriptor(descriptor);
  builder_.add_base(base);
  return builder_.Finish();
}

struct DepthToSpaceDescriptor FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
  typedef DepthToSpaceDescriptorBuilder Builder;
  enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
    VT_BLOCKSIZE = 4,
    VT_DATALAYOUT = 6
  };
  uint32_t blockSize() const {
    return GetField<uint32_t>(VT_BLOCKSIZE, 0);
  }
  armnnSerializer::DataLayout dataLayout() const {
    return static_cast<armnnSerializer::DataLayout>(GetField<int8_t>(VT_DATALAYOUT, 0));
  }
  bool Verify(flatbuffers::Verifier &verifier) const {
    return VerifyTableStart(verifier) &&
           VerifyField<uint32_t>(verifier, VT_BLOCKSIZE) &&
           VerifyField<int8_t>(verifier, VT_DATALAYOUT) &&
           verifier.EndTable();
  }
};

struct DepthToSpaceDescriptorBuilder {
  typedef DepthToSpaceDescriptor Table;
  flatbuffers::FlatBufferBuilder &fbb_;
  flatbuffers::uoffset_t start_;
  void add_blockSize(uint32_t blockSize) {
    fbb_.AddElement<uint32_t>(DepthToSpaceDescriptor::VT_BLOCKSIZE, blockSize, 0);
  }
  void add_dataLayout(armnnSerializer::DataLayout dataLayout) {
    fbb_.AddElement<int8_t>(DepthToSpaceDescriptor::VT_DATALAYOUT, static_cast<int8_t>(dataLayout), 0);
  }
  explicit DepthToSpaceDescriptorBuilder(flatbuffers::FlatBufferBuilder &_fbb)
        : fbb_(_fbb) {
    start_ = fbb_.StartTable();
  }
  DepthToSpaceDescriptorBuilder &operator=(const DepthToSpaceDescriptorBuilder &);
  flatbuffers::Offset<DepthToSpaceDescriptor> Finish() {
    const auto end = fbb_.EndTable(start_);
    auto o = flatbuffers::Offset<DepthToSpaceDescriptor>(end);
    return o;
  }
};

inline flatbuffers::Offset<DepthToSpaceDescriptor> CreateDepthToSpaceDescriptor(
    flatbuffers::FlatBufferBuilder &_fbb,
    uint32_t blockSize = 0,
    armnnSerializer::DataLayout dataLayout = armnnSerializer::DataLayout_NHWC) {
  DepthToSpaceDescriptorBuilder builder_(_fbb);
  builder_.add_blockSize(blockSize);
  builder_.add_dataLayout(dataLayout);
  return builder_.Finish();
}

struct DivisionLayer FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
  typedef DivisionLayerBuilder Builder;
  enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
    VT_BASE = 4
  };
  const armnnSerializer::LayerBase *base() const {
    return GetPointer<const armnnSerializer::LayerBase *>(VT_BASE);
  }
  bool Verify(flatbuffers::Verifier &verifier) const {
    return VerifyTableStart(verifier) &&
           VerifyOffset(verifier, VT_BASE) &&
           verifier.VerifyTable(base()) &&
           verifier.EndTable();
  }
};

struct DivisionLayerBuilder {
  typedef DivisionLayer Table;
  flatbuffers::FlatBufferBuilder &fbb_;
  flatbuffers::uoffset_t start_;
  void add_base(flatbuffers::Offset<armnnSerializer::LayerBase> base) {
    fbb_.AddOffset(DivisionLayer::VT_BASE, base);
  }
  explicit DivisionLayerBuilder(flatbuffers::FlatBufferBuilder &_fbb)
        : fbb_(_fbb) {
    start_ = fbb_.StartTable();
  }
  DivisionLayerBuilder &operator=(const DivisionLayerBuilder &);
  flatbuffers::Offset<DivisionLayer> Finish() {
    const auto end = fbb_.EndTable(start_);
    auto o = flatbuffers::Offset<DivisionLayer>(end);
    return o;
  }
};

inline flatbuffers::Offset<DivisionLayer> CreateDivisionLayer(
    flatbuffers::FlatBufferBuilder &_fbb,
    flatbuffers::Offset<armnnSerializer::LayerBase> base = 0) {
  DivisionLayerBuilder builder_(_fbb);
  builder_.add_base(base);
  return builder_.Finish();
}

struct ElementwiseUnaryDescriptor FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
  typedef ElementwiseUnaryDescriptorBuilder Builder;
  enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
    VT_OPERATION = 4
  };
  armnnSerializer::UnaryOperation operation() const {
    return static_cast<armnnSerializer::UnaryOperation>(GetField<int8_t>(VT_OPERATION, 0));
  }
  bool Verify(flatbuffers::Verifier &verifier) const {
    return VerifyTableStart(verifier) &&
           VerifyField<int8_t>(verifier, VT_OPERATION) &&
           verifier.EndTable();
  }
};

struct ElementwiseUnaryDescriptorBuilder {
  typedef ElementwiseUnaryDescriptor Table;
  flatbuffers::FlatBufferBuilder &fbb_;
  flatbuffers::uoffset_t start_;
  void add_operation(armnnSerializer::UnaryOperation operation) {
    fbb_.AddElement<int8_t>(ElementwiseUnaryDescriptor::VT_OPERATION, static_cast<int8_t>(operation), 0);
  }
  explicit ElementwiseUnaryDescriptorBuilder(flatbuffers::FlatBufferBuilder &_fbb)
        : fbb_(_fbb) {
    start_ = fbb_.StartTable();
  }
  ElementwiseUnaryDescriptorBuilder &operator=(const ElementwiseUnaryDescriptorBuilder &);
  flatbuffers::Offset<ElementwiseUnaryDescriptor> Finish() {
    const auto end = fbb_.EndTable(start_);
    auto o = flatbuffers::Offset<ElementwiseUnaryDescriptor>(end);
    return o;
  }
};

inline flatbuffers::Offset<ElementwiseUnaryDescriptor> CreateElementwiseUnaryDescriptor(
    flatbuffers::FlatBufferBuilder &_fbb,
    armnnSerializer::UnaryOperation operation = armnnSerializer::UnaryOperation_Abs) {
  ElementwiseUnaryDescriptorBuilder builder_(_fbb);
  builder_.add_operation(operation);
  return builder_.Finish();
}

struct ElementwiseUnaryLayer FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
  typedef ElementwiseUnaryLayerBuilder Builder;
  enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
    VT_BASE = 4,
    VT_DESCRIPTOR = 6
  };
  const armnnSerializer::LayerBase *base() const {
    return GetPointer<const armnnSerializer::LayerBase *>(VT_BASE);
  }
  const armnnSerializer::ElementwiseUnaryDescriptor *descriptor() const {
    return GetPointer<const armnnSerializer::ElementwiseUnaryDescriptor *>(VT_DESCRIPTOR);
  }
  bool Verify(flatbuffers::Verifier &verifier) const {
    return VerifyTableStart(verifier) &&
           VerifyOffset(verifier, VT_BASE) &&
           verifier.VerifyTable(base()) &&
           VerifyOffset(verifier, VT_DESCRIPTOR) &&
           verifier.VerifyTable(descriptor()) &&
           verifier.EndTable();
  }
};

struct ElementwiseUnaryLayerBuilder {
  typedef ElementwiseUnaryLayer Table;
  flatbuffers::FlatBufferBuilder &fbb_;
  flatbuffers::uoffset_t start_;
  void add_base(flatbuffers::Offset<armnnSerializer::LayerBase> base) {
    fbb_.AddOffset(ElementwiseUnaryLayer::VT_BASE, base);
  }
  void add_descriptor(flatbuffers::Offset<armnnSerializer::ElementwiseUnaryDescriptor> descriptor) {
    fbb_.AddOffset(ElementwiseUnaryLayer::VT_DESCRIPTOR, descriptor);
  }
  explicit ElementwiseUnaryLayerBuilder(flatbuffers::FlatBufferBuilder &_fbb)
        : fbb_(_fbb) {
    start_ = fbb_.StartTable();
  }
  ElementwiseUnaryLayerBuilder &operator=(const ElementwiseUnaryLayerBuilder &);
  flatbuffers::Offset<ElementwiseUnaryLayer> Finish() {
    const auto end = fbb_.EndTable(start_);
    auto o = flatbuffers::Offset<ElementwiseUnaryLayer>(end);
    return o;
  }
};

inline flatbuffers::Offset<ElementwiseUnaryLayer> CreateElementwiseUnaryLayer(
    flatbuffers::FlatBufferBuilder &_fbb,
    flatbuffers::Offset<armnnSerializer::LayerBase> base = 0,
    flatbuffers::Offset<armnnSerializer::ElementwiseUnaryDescriptor> descriptor = 0) {
  ElementwiseUnaryLayerBuilder builder_(_fbb);
  builder_.add_descriptor(descriptor);
  builder_.add_base(base);
  return builder_.Finish();
}

/// @deprecated Use ComparisonLayer instead
struct EqualLayer FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
  typedef EqualLayerBuilder Builder;
  enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
    VT_BASE = 4
  };
  const armnnSerializer::LayerBase *base() const {
    return GetPointer<const armnnSerializer::LayerBase *>(VT_BASE);
  }
  bool Verify(flatbuffers::Verifier &verifier) const {
    return VerifyTableStart(verifier) &&
           VerifyOffset(verifier, VT_BASE) &&
           verifier.VerifyTable(base()) &&
           verifier.EndTable();
  }
};

struct EqualLayerBuilder {
  typedef EqualLayer Table;
  flatbuffers::FlatBufferBuilder &fbb_;
  flatbuffers::uoffset_t start_;
  void add_base(flatbuffers::Offset<armnnSerializer::LayerBase> base) {
    fbb_.AddOffset(EqualLayer::VT_BASE, base);
  }
  explicit EqualLayerBuilder(flatbuffers::FlatBufferBuilder &_fbb)
        : fbb_(_fbb) {
    start_ = fbb_.StartTable();
  }
  EqualLayerBuilder &operator=(const EqualLayerBuilder &);
  flatbuffers::Offset<EqualLayer> Finish() {
    const auto end = fbb_.EndTable(start_);
    auto o = flatbuffers::Offset<EqualLayer>(end);
    return o;
  }
};

inline flatbuffers::Offset<EqualLayer> CreateEqualLayer(
    flatbuffers::FlatBufferBuilder &_fbb,
    flatbuffers::Offset<armnnSerializer::LayerBase> base = 0) {
  EqualLayerBuilder builder_(_fbb);
  builder_.add_base(base);
  return builder_.Finish();
}

struct FillLayer FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
  typedef FillLayerBuilder Builder;
  enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
    VT_BASE = 4,
    VT_DESCRIPTOR = 6
  };
  const armnnSerializer::LayerBase *base() const {
    return GetPointer<const armnnSerializer::LayerBase *>(VT_BASE);
  }
  const armnnSerializer::FillDescriptor *descriptor() const {
    return GetPointer<const armnnSerializer::FillDescriptor *>(VT_DESCRIPTOR);
  }
  bool Verify(flatbuffers::Verifier &verifier) const {
    return VerifyTableStart(verifier) &&
           VerifyOffset(verifier, VT_BASE) &&
           verifier.VerifyTable(base()) &&
           VerifyOffset(verifier, VT_DESCRIPTOR) &&
           verifier.VerifyTable(descriptor()) &&
           verifier.EndTable();
  }
};

struct FillLayerBuilder {
  typedef FillLayer Table;
  flatbuffers::FlatBufferBuilder &fbb_;
  flatbuffers::uoffset_t start_;
  void add_base(flatbuffers::Offset<armnnSerializer::LayerBase> base) {
    fbb_.AddOffset(FillLayer::VT_BASE, base);
  }
  void add_descriptor(flatbuffers::Offset<armnnSerializer::FillDescriptor> descriptor) {
    fbb_.AddOffset(FillLayer::VT_DESCRIPTOR, descriptor);
  }
  explicit FillLayerBuilder(flatbuffers::FlatBufferBuilder &_fbb)
        : fbb_(_fbb) {
    start_ = fbb_.StartTable();
  }
  FillLayerBuilder &operator=(const FillLayerBuilder &);
  flatbuffers::Offset<FillLayer> Finish() {
    const auto end = fbb_.EndTable(start_);
    auto o = flatbuffers::Offset<FillLayer>(end);
    return o;
  }
};

inline flatbuffers::Offset<FillLayer> CreateFillLayer(
    flatbuffers::FlatBufferBuilder &_fbb,
    flatbuffers::Offset<armnnSerializer::LayerBase> base = 0,
    flatbuffers::Offset<armnnSerializer::FillDescriptor> descriptor = 0) {
  FillLayerBuilder builder_(_fbb);
  builder_.add_descriptor(descriptor);
  builder_.add_base(base);
  return builder_.Finish();
}

struct FillDescriptor FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
  typedef FillDescriptorBuilder Builder;
  enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
    VT_VALUE = 4
  };
  float value() const {
    return GetField<float>(VT_VALUE, 0.0f);
  }
  bool Verify(flatbuffers::Verifier &verifier) const {
    return VerifyTableStart(verifier) &&
           VerifyField<float>(verifier, VT_VALUE) &&
           verifier.EndTable();
  }
};

struct FillDescriptorBuilder {
  typedef FillDescriptor Table;
  flatbuffers::FlatBufferBuilder &fbb_;
  flatbuffers::uoffset_t start_;
  void add_value(float value) {
    fbb_.AddElement<float>(FillDescriptor::VT_VALUE, value, 0.0f);
  }
  explicit FillDescriptorBuilder(flatbuffers::FlatBufferBuilder &_fbb)
        : fbb_(_fbb) {
    start_ = fbb_.StartTable();
  }
  FillDescriptorBuilder &operator=(const FillDescriptorBuilder &);
  flatbuffers::Offset<FillDescriptor> Finish() {
    const auto end = fbb_.EndTable(start_);
    auto o = flatbuffers::Offset<FillDescriptor>(end);
    return o;
  }
};

inline flatbuffers::Offset<FillDescriptor> CreateFillDescriptor(
    flatbuffers::FlatBufferBuilder &_fbb,
    float value = 0.0f) {
  FillDescriptorBuilder builder_(_fbb);
  builder_.add_value(value);
  return builder_.Finish();
}

struct FloorLayer FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
  typedef FloorLayerBuilder Builder;
  enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
    VT_BASE = 4
  };
  const armnnSerializer::LayerBase *base() const {
    return GetPointer<const armnnSerializer::LayerBase *>(VT_BASE);
  }
  bool Verify(flatbuffers::Verifier &verifier) const {
    return VerifyTableStart(verifier) &&
           VerifyOffset(verifier, VT_BASE) &&
           verifier.VerifyTable(base()) &&
           verifier.EndTable();
  }
};

struct FloorLayerBuilder {
  typedef FloorLayer Table;
  flatbuffers::FlatBufferBuilder &fbb_;
  flatbuffers::uoffset_t start_;
  void add_base(flatbuffers::Offset<armnnSerializer::LayerBase> base) {
    fbb_.AddOffset(FloorLayer::VT_BASE, base);
  }
  explicit FloorLayerBuilder(flatbuffers::FlatBufferBuilder &_fbb)
        : fbb_(_fbb) {
    start_ = fbb_.StartTable();
  }
  FloorLayerBuilder &operator=(const FloorLayerBuilder &);
  flatbuffers::Offset<FloorLayer> Finish() {
    const auto end = fbb_.EndTable(start_);
    auto o = flatbuffers::Offset<FloorLayer>(end);
    return o;
  }
};

inline flatbuffers::Offset<FloorLayer> CreateFloorLayer(
    flatbuffers::FlatBufferBuilder &_fbb,
    flatbuffers::Offset<armnnSerializer::LayerBase> base = 0) {
  FloorLayerBuilder builder_(_fbb);
  builder_.add_base(base);
  return builder_.Finish();
}

struct FullyConnectedLayer FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
  typedef FullyConnectedLayerBuilder Builder;
  enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
    VT_BASE = 4,
    VT_DESCRIPTOR = 6,
    VT_WEIGHTS = 8,
    VT_BIASES = 10
  };
  const armnnSerializer::LayerBase *base() const {
    return GetPointer<const armnnSerializer::LayerBase *>(VT_BASE);
  }
  const armnnSerializer::FullyConnectedDescriptor *descriptor() const {
    return GetPointer<const armnnSerializer::FullyConnectedDescriptor *>(VT_DESCRIPTOR);
  }
  const armnnSerializer::ConstTensor *weights() const {
    return GetPointer<const armnnSerializer::ConstTensor *>(VT_WEIGHTS);
  }
  const armnnSerializer::ConstTensor *biases() const {
    return GetPointer<const armnnSerializer::ConstTensor *>(VT_BIASES);
  }
  bool Verify(flatbuffers::Verifier &verifier) const {
    return VerifyTableStart(verifier) &&
           VerifyOffset(verifier, VT_BASE) &&
           verifier.VerifyTable(base()) &&
           VerifyOffset(verifier, VT_DESCRIPTOR) &&
           verifier.VerifyTable(descriptor()) &&
           VerifyOffset(verifier, VT_WEIGHTS) &&
           verifier.VerifyTable(weights()) &&
           VerifyOffset(verifier, VT_BIASES) &&
           verifier.VerifyTable(biases()) &&
           verifier.EndTable();
  }
};

struct FullyConnectedLayerBuilder {
  typedef FullyConnectedLayer Table;
  flatbuffers::FlatBufferBuilder &fbb_;
  flatbuffers::uoffset_t start_;
  void add_base(flatbuffers::Offset<armnnSerializer::LayerBase> base) {
    fbb_.AddOffset(FullyConnectedLayer::VT_BASE, base);
  }
  void add_descriptor(flatbuffers::Offset<armnnSerializer::FullyConnectedDescriptor> descriptor) {
    fbb_.AddOffset(FullyConnectedLayer::VT_DESCRIPTOR, descriptor);
  }
  void add_weights(flatbuffers::Offset<armnnSerializer::ConstTensor> weights) {
    fbb_.AddOffset(FullyConnectedLayer::VT_WEIGHTS, weights);
  }
  void add_biases(flatbuffers::Offset<armnnSerializer::ConstTensor> biases) {
    fbb_.AddOffset(FullyConnectedLayer::VT_BIASES, biases);
  }
  explicit FullyConnectedLayerBuilder(flatbuffers::FlatBufferBuilder &_fbb)
        : fbb_(_fbb) {
    start_ = fbb_.StartTable();
  }
  FullyConnectedLayerBuilder &operator=(const FullyConnectedLayerBuilder &);
  flatbuffers::Offset<FullyConnectedLayer> Finish() {
    const auto end = fbb_.EndTable(start_);
    auto o = flatbuffers::Offset<FullyConnectedLayer>(end);
    return o;
  }
};

inline flatbuffers::Offset<FullyConnectedLayer> CreateFullyConnectedLayer(
    flatbuffers::FlatBufferBuilder &_fbb,
    flatbuffers::Offset<armnnSerializer::LayerBase> base = 0,
    flatbuffers::Offset<armnnSerializer::FullyConnectedDescriptor> descriptor = 0,
    flatbuffers::Offset<armnnSerializer::ConstTensor> weights = 0,
    flatbuffers::Offset<armnnSerializer::ConstTensor> biases = 0) {
  FullyConnectedLayerBuilder builder_(_fbb);
  builder_.add_biases(biases);
  builder_.add_weights(weights);
  builder_.add_descriptor(descriptor);
  builder_.add_base(base);
  return builder_.Finish();
}

struct FullyConnectedDescriptor FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
  typedef FullyConnectedDescriptorBuilder Builder;
  enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
    VT_BIASENABLED = 4,
    VT_TRANSPOSEWEIGHTSMATRIX = 6,
    VT_CONSTANTWEIGHTS = 8
  };
  bool biasEnabled() const {
    return GetField<uint8_t>(VT_BIASENABLED, 0) != 0;
  }
  bool transposeWeightsMatrix() const {
    return GetField<uint8_t>(VT_TRANSPOSEWEIGHTSMATRIX, 0) != 0;
  }
  bool constantWeights() const {
    return GetField<uint8_t>(VT_CONSTANTWEIGHTS, 1) != 0;
  }
  bool Verify(flatbuffers::Verifier &verifier) const {
    return VerifyTableStart(verifier) &&
           VerifyField<uint8_t>(verifier, VT_BIASENABLED) &&
           VerifyField<uint8_t>(verifier, VT_TRANSPOSEWEIGHTSMATRIX) &&
           VerifyField<uint8_t>(verifier, VT_CONSTANTWEIGHTS) &&
           verifier.EndTable();
  }
};

struct FullyConnectedDescriptorBuilder {
  typedef FullyConnectedDescriptor Table;
  flatbuffers::FlatBufferBuilder &fbb_;
  flatbuffers::uoffset_t start_;
  void add_biasEnabled(bool biasEnabled) {
    fbb_.AddElement<uint8_t>(FullyConnectedDescriptor::VT_BIASENABLED, static_cast<uint8_t>(biasEnabled), 0);
  }
  void add_transposeWeightsMatrix(bool transposeWeightsMatrix) {
    fbb_.AddElement<uint8_t>(FullyConnectedDescriptor::VT_TRANSPOSEWEIGHTSMATRIX, static_cast<uint8_t>(transposeWeightsMatrix), 0);
  }
  void add_constantWeights(bool constantWeights) {
    fbb_.AddElement<uint8_t>(FullyConnectedDescriptor::VT_CONSTANTWEIGHTS, static_cast<uint8_t>(constantWeights), 1);
  }
  explicit FullyConnectedDescriptorBuilder(flatbuffers::FlatBufferBuilder &_fbb)
        : fbb_(_fbb) {
    start_ = fbb_.StartTable();
  }
  FullyConnectedDescriptorBuilder &operator=(const FullyConnectedDescriptorBuilder &);
  flatbuffers::Offset<FullyConnectedDescriptor> Finish() {
    const auto end = fbb_.EndTable(start_);
    auto o = flatbuffers::Offset<FullyConnectedDescriptor>(end);
    return o;
  }
};

inline flatbuffers::Offset<FullyConnectedDescriptor> CreateFullyConnectedDescriptor(
    flatbuffers::FlatBufferBuilder &_fbb,
    bool biasEnabled = false,
    bool transposeWeightsMatrix = false,
    bool constantWeights = true) {
  FullyConnectedDescriptorBuilder builder_(_fbb);
  builder_.add_constantWeights(constantWeights);
  builder_.add_transposeWeightsMatrix(transposeWeightsMatrix);
  builder_.add_biasEnabled(biasEnabled);
  return builder_.Finish();
}

struct GatherLayer FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
  typedef GatherLayerBuilder Builder;
  enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
    VT_BASE = 4,
    VT_DESCRIPTOR = 6
  };
  const armnnSerializer::LayerBase *base() const {
    return GetPointer<const armnnSerializer::LayerBase *>(VT_BASE);
  }
  const armnnSerializer::GatherDescriptor *descriptor() const {
    return GetPointer<const armnnSerializer::GatherDescriptor *>(VT_DESCRIPTOR);
  }
  bool Verify(flatbuffers::Verifier &verifier) const {
    return VerifyTableStart(verifier) &&
           VerifyOffset(verifier, VT_BASE) &&
           verifier.VerifyTable(base()) &&
           VerifyOffset(verifier, VT_DESCRIPTOR) &&
           verifier.VerifyTable(descriptor()) &&
           verifier.EndTable();
  }
};

struct GatherLayerBuilder {
  typedef GatherLayer Table;
  flatbuffers::FlatBufferBuilder &fbb_;
  flatbuffers::uoffset_t start_;
  void add_base(flatbuffers::Offset<armnnSerializer::LayerBase> base) {
    fbb_.AddOffset(GatherLayer::VT_BASE, base);
  }
  void add_descriptor(flatbuffers::Offset<armnnSerializer::GatherDescriptor> descriptor) {
    fbb_.AddOffset(GatherLayer::VT_DESCRIPTOR, descriptor);
  }
  explicit GatherLayerBuilder(flatbuffers::FlatBufferBuilder &_fbb)
        : fbb_(_fbb) {
    start_ = fbb_.StartTable();
  }
  GatherLayerBuilder &operator=(const GatherLayerBuilder &);
  flatbuffers::Offset<GatherLayer> Finish() {
    const auto end = fbb_.EndTable(start_);
    auto o = flatbuffers::Offset<GatherLayer>(end);
    return o;
  }
};

inline flatbuffers::Offset<GatherLayer> CreateGatherLayer(
    flatbuffers::FlatBufferBuilder &_fbb,
    flatbuffers::Offset<armnnSerializer::LayerBase> base = 0,
    flatbuffers::Offset<armnnSerializer::GatherDescriptor> descriptor = 0) {
  GatherLayerBuilder builder_(_fbb);
  builder_.add_descriptor(descriptor);
  builder_.add_base(base);
  return builder_.Finish();
}

struct GatherDescriptor FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
  typedef GatherDescriptorBuilder 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 GatherDescriptorBuilder {
  typedef GatherDescriptor Table;
  flatbuffers::FlatBufferBuilder &fbb_;
  flatbuffers::uoffset_t start_;
  void add_axis(int32_t axis) {
    fbb_.AddElement<int32_t>(GatherDescriptor::VT_AXIS, axis, 0);
  }
  explicit GatherDescriptorBuilder(flatbuffers::FlatBufferBuilder &_fbb)
        : fbb_(_fbb) {
    start_ = fbb_.StartTable();
  }
  GatherDescriptorBuilder &operator=(const GatherDescriptorBuilder &);
  flatbuffers::Offset<GatherDescriptor> Finish() {
    const auto end = fbb_.EndTable(start_);
    auto o = flatbuffers::Offset<GatherDescriptor>(end);
    return o;
  }
};

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

/// @deprecated Use ComparisonLayer instead
struct GreaterLayer FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
  typedef GreaterLayerBuilder Builder;
  enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
    VT_BASE = 4
  };
  const armnnSerializer::LayerBase *base() const {
    return GetPointer<const armnnSerializer::LayerBase *>(VT_BASE);
  }
  bool Verify(flatbuffers::Verifier &verifier) const {
    return VerifyTableStart(verifier) &&
           VerifyOffset(verifier, VT_BASE) &&
           verifier.VerifyTable(base()) &&
           verifier.EndTable();
  }
};

struct GreaterLayerBuilder {
  typedef GreaterLayer Table;
  flatbuffers::FlatBufferBuilder &fbb_;
  flatbuffers::uoffset_t start_;
  void add_base(flatbuffers::Offset<armnnSerializer::LayerBase> base) {
    fbb_.AddOffset(GreaterLayer::VT_BASE, base);
  }
  explicit GreaterLayerBuilder(flatbuffers::FlatBufferBuilder &_fbb)
        : fbb_(_fbb) {
    start_ = fbb_.StartTable();
  }
  GreaterLayerBuilder &operator=(const GreaterLayerBuilder &);
  flatbuffers::Offset<GreaterLayer> Finish() {
    const auto end = fbb_.EndTable(start_);
    auto o = flatbuffers::Offset<GreaterLayer>(end);
    return o;
  }
};

inline flatbuffers::Offset<GreaterLayer> CreateGreaterLayer(
    flatbuffers::FlatBufferBuilder &_fbb,
    flatbuffers::Offset<armnnSerializer::LayerBase> base = 0) {
  GreaterLayerBuilder builder_(_fbb);
  builder_.add_base(base);
  return builder_.Finish();
}

struct InputLayer FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
  typedef InputLayerBuilder Builder;
  enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
    VT_BASE = 4
  };
  const armnnSerializer::BindableLayerBase *base() const {
    return GetPointer<const armnnSerializer::BindableLayerBase *>(VT_BASE);
  }
  bool Verify(flatbuffers::Verifier &verifier) const {
    return VerifyTableStart(verifier) &&
           VerifyOffset(verifier, VT_BASE) &&
           verifier.VerifyTable(base()) &&
           verifier.EndTable();
  }
};

struct InputLayerBuilder {
  typedef InputLayer Table;
  flatbuffers::FlatBufferBuilder &fbb_;
  flatbuffers::uoffset_t start_;
  void add_base(flatbuffers::Offset<armnnSerializer::BindableLayerBase> base) {
    fbb_.AddOffset(InputLayer::VT_BASE, base);
  }
  explicit InputLayerBuilder(flatbuffers::FlatBufferBuilder &_fbb)
        : fbb_(_fbb) {
    start_ = fbb_.StartTable();
  }
  InputLayerBuilder &operator=(const InputLayerBuilder &);
  flatbuffers::Offset<InputLayer> Finish() {
    const auto end = fbb_.EndTable(start_);
    auto o = flatbuffers::Offset<InputLayer>(end);
    return o;
  }
};

inline flatbuffers::Offset<InputLayer> CreateInputLayer(
    flatbuffers::FlatBufferBuilder &_fbb,
    flatbuffers::Offset<armnnSerializer::BindableLayerBase> base = 0) {
  InputLayerBuilder builder_(_fbb);
  builder_.add_base(base);
  return builder_.Finish();
}

struct InstanceNormalizationLayer FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
  typedef InstanceNormalizationLayerBuilder Builder;
  enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
    VT_BASE = 4,
    VT_DESCRIPTOR = 6
  };
  const armnnSerializer::LayerBase *base() const {
    return GetPointer<const armnnSerializer::LayerBase *>(VT_BASE);
  }
  const armnnSerializer::InstanceNormalizationDescriptor *descriptor() const {
    return GetPointer<const armnnSerializer::InstanceNormalizationDescriptor *>(VT_DESCRIPTOR);
  }
  bool Verify(flatbuffers::Verifier &verifier) const {
    return VerifyTableStart(verifier) &&
           VerifyOffset(verifier, VT_BASE) &&
           verifier.VerifyTable(base()) &&
           VerifyOffset(verifier, VT_DESCRIPTOR) &&
           verifier.VerifyTable(descriptor()) &&
           verifier.EndTable();
  }
};

struct InstanceNormalizationLayerBuilder {
  typedef InstanceNormalizationLayer Table;
  flatbuffers::FlatBufferBuilder &fbb_;
  flatbuffers::uoffset_t start_;
  void add_base(flatbuffers::Offset<armnnSerializer::LayerBase> base) {
    fbb_.AddOffset(InstanceNormalizationLayer::VT_BASE, base);
  }
  void add_descriptor(flatbuffers::Offset<armnnSerializer::InstanceNormalizationDescriptor> descriptor) {
    fbb_.AddOffset(InstanceNormalizationLayer::VT_DESCRIPTOR, descriptor);
  }
  explicit InstanceNormalizationLayerBuilder(flatbuffers::FlatBufferBuilder &_fbb)
        : fbb_(_fbb) {
    start_ = fbb_.StartTable();
  }
  InstanceNormalizationLayerBuilder &operator=(const InstanceNormalizationLayerBuilder &);
  flatbuffers::Offset<InstanceNormalizationLayer> Finish() {
    const auto end = fbb_.EndTable(start_);
    auto o = flatbuffers::Offset<InstanceNormalizationLayer>(end);
    return o;
  }
};

inline flatbuffers::Offset<InstanceNormalizationLayer> CreateInstanceNormalizationLayer(
    flatbuffers::FlatBufferBuilder &_fbb,
    flatbuffers::Offset<armnnSerializer::LayerBase> base = 0,
    flatbuffers::Offset<armnnSerializer::InstanceNormalizationDescriptor> descriptor = 0) {
  InstanceNormalizationLayerBuilder builder_(_fbb);
  builder_.add_descriptor(descriptor);
  builder_.add_base(base);
  return builder_.Finish();
}

struct InstanceNormalizationDescriptor FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
  typedef InstanceNormalizationDescriptorBuilder Builder;
  enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
    VT_GAMMA = 4,
    VT_BETA = 6,
    VT_EPS = 8,
    VT_DATALAYOUT = 10
  };
  float gamma() const {
    return GetField<float>(VT_GAMMA, 0.0f);
  }
  float beta() const {
    return GetField<float>(VT_BETA, 0.0f);
  }
  float eps() const {
    return GetField<float>(VT_EPS, 0.0f);
  }
  armnnSerializer::DataLayout dataLayout() const {
    return static_cast<armnnSerializer::DataLayout>(GetField<int8_t>(VT_DATALAYOUT, 0));
  }
  bool Verify(flatbuffers::Verifier &verifier) const {
    return VerifyTableStart(verifier) &&
           VerifyField<float>(verifier, VT_GAMMA) &&
           VerifyField<float>(verifier, VT_BETA) &&
           VerifyField<float>(verifier, VT_EPS) &&
           VerifyField<int8_t>(verifier, VT_DATALAYOUT) &&
           verifier.EndTable();
  }
};

struct InstanceNormalizationDescriptorBuilder {
  typedef InstanceNormalizationDescriptor Table;
  flatbuffers::FlatBufferBuilder &fbb_;
  flatbuffers::uoffset_t start_;
  void add_gamma(float gamma) {
    fbb_.AddElement<float>(InstanceNormalizationDescriptor::VT_GAMMA, gamma, 0.0f);
  }
  void add_beta(float beta) {
    fbb_.AddElement<float>(InstanceNormalizationDescriptor::VT_BETA, beta, 0.0f);
  }
  void add_eps(float eps) {
    fbb_.AddElement<float>(InstanceNormalizationDescriptor::VT_EPS, eps, 0.0f);
  }
  void add_dataLayout(armnnSerializer::DataLayout dataLayout) {
    fbb_.AddElement<int8_t>(InstanceNormalizationDescriptor::VT_DATALAYOUT, static_cast<int8_t>(dataLayout), 0);
  }
  explicit InstanceNormalizationDescriptorBuilder(flatbuffers::FlatBufferBuilder &_fbb)
        : fbb_(_fbb) {
    start_ = fbb_.StartTable();
  }
  InstanceNormalizationDescriptorBuilder &operator=(const InstanceNormalizationDescriptorBuilder &);
  flatbuffers::Offset<InstanceNormalizationDescriptor> Finish() {
    const auto end = fbb_.EndTable(start_);
    auto o = flatbuffers::Offset<InstanceNormalizationDescriptor>(end);
    return o;
  }
};

inline flatbuffers::Offset<InstanceNormalizationDescriptor> CreateInstanceNormalizationDescriptor(
    flatbuffers::FlatBufferBuilder &_fbb,
    float gamma = 0.0f,
    float beta = 0.0f,
    float eps = 0.0f,
    armnnSerializer::DataLayout dataLayout = armnnSerializer::DataLayout_NHWC) {
  InstanceNormalizationDescriptorBuilder builder_(_fbb);
  builder_.add_eps(eps);
  builder_.add_beta(beta);
  builder_.add_gamma(gamma);
  builder_.add_dataLayout(dataLayout);
  return builder_.Finish();
}

struct LogSoftmaxLayer FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
  typedef LogSoftmaxLayerBuilder Builder;
  enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
    VT_BASE = 4,
    VT_DESCRIPTOR = 6
  };
  const armnnSerializer::LayerBase *base() const {
    return GetPointer<const armnnSerializer::LayerBase *>(VT_BASE);
  }
  const armnnSerializer::LogSoftmaxDescriptor *descriptor() const {
    return GetPointer<const armnnSerializer::LogSoftmaxDescriptor *>(VT_DESCRIPTOR);
  }
  bool Verify(flatbuffers::Verifier &verifier) const {
    return VerifyTableStart(verifier) &&
           VerifyOffset(verifier, VT_BASE) &&
           verifier.VerifyTable(base()) &&
           VerifyOffset(verifier, VT_DESCRIPTOR) &&
           verifier.VerifyTable(descriptor()) &&
           verifier.EndTable();
  }
};

struct LogSoftmaxLayerBuilder {
  typedef LogSoftmaxLayer Table;
  flatbuffers::FlatBufferBuilder &fbb_;
  flatbuffers::uoffset_t start_;
  void add_base(flatbuffers::Offset<armnnSerializer::LayerBase> base) {
    fbb_.AddOffset(LogSoftmaxLayer::VT_BASE, base);
  }
  void add_descriptor(flatbuffers::Offset<armnnSerializer::LogSoftmaxDescriptor> descriptor) {
    fbb_.AddOffset(LogSoftmaxLayer::VT_DESCRIPTOR, descriptor);
  }
  explicit LogSoftmaxLayerBuilder(flatbuffers::FlatBufferBuilder &_fbb)
        : fbb_(_fbb) {
    start_ = fbb_.StartTable();
  }
  LogSoftmaxLayerBuilder &operator=(const LogSoftmaxLayerBuilder &);
  flatbuffers::Offset<LogSoftmaxLayer> Finish() {
    const auto end = fbb_.EndTable(start_);
    auto o = flatbuffers::Offset<LogSoftmaxLayer>(end);
    return o;
  }
};

inline flatbuffers::Offset<LogSoftmaxLayer> CreateLogSoftmaxLayer(
    flatbuffers::FlatBufferBuilder &_fbb,
    flatbuffers::Offset<armnnSerializer::LayerBase> base = 0,
    flatbuffers::Offset<armnnSerializer::LogSoftmaxDescriptor> descriptor = 0) {
  LogSoftmaxLayerBuilder builder_(_fbb);
  builder_.add_descriptor(descriptor);
  builder_.add_base(base);
  return builder_.Finish();
}

struct LogSoftmaxDescriptor FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
  typedef LogSoftmaxDescriptorBuilder Builder;
  enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
    VT_BETA = 4,
    VT_AXIS = 6
  };
  float beta() const {
    return GetField<float>(VT_BETA, 1.0f);
  }
  int32_t axis() const {
    return GetField<int32_t>(VT_AXIS, -1);
  }
  bool Verify(flatbuffers::Verifier &verifier) const {
    return VerifyTableStart(verifier) &&
           VerifyField<float>(verifier, VT_BETA) &&
           VerifyField<int32_t>(verifier, VT_AXIS) &&
           verifier.EndTable();
  }
};

struct LogSoftmaxDescriptorBuilder {
  typedef LogSoftmaxDescriptor Table;
  flatbuffers::FlatBufferBuilder &fbb_;
  flatbuffers::uoffset_t start_;
  void add_beta(float beta) {
    fbb_.AddElement<float>(LogSoftmaxDescriptor::VT_BETA, beta, 1.0f);
  }
  void add_axis(int32_t axis) {
    fbb_.AddElement<int32_t>(LogSoftmaxDescriptor::VT_AXIS, axis, -1);
  }
  explicit LogSoftmaxDescriptorBuilder(flatbuffers::FlatBufferBuilder &_fbb)
        : fbb_(_fbb) {
    start_ = fbb_.StartTable();
  }
  LogSoftmaxDescriptorBuilder &operator=(const LogSoftmaxDescriptorBuilder &);
  flatbuffers::Offset<LogSoftmaxDescriptor> Finish() {
    const auto end = fbb_.EndTable(start_);
    auto o = flatbuffers::Offset<LogSoftmaxDescriptor>(end);
    return o;
  }
};

inline flatbuffers::Offset<LogSoftmaxDescriptor> CreateLogSoftmaxDescriptor(
    flatbuffers::FlatBufferBuilder &_fbb,
    float beta = 1.0f,
    int32_t axis = -1) {
  LogSoftmaxDescriptorBuilder builder_(_fbb);
  builder_.add_axis(axis);
  builder_.add_beta(beta);
  return builder_.Finish();
}

struct L2NormalizationLayer FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
  typedef L2NormalizationLayerBuilder Builder;
  enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
    VT_BASE = 4,
    VT_DESCRIPTOR = 6
  };
  const armnnSerializer::LayerBase *base() const {
    return GetPointer<const armnnSerializer::LayerBase *>(VT_BASE);
  }
  const armnnSerializer::L2NormalizationDescriptor *descriptor() const {
    return GetPointer<const armnnSerializer::L2NormalizationDescriptor *>(VT_DESCRIPTOR);
  }
  bool Verify(flatbuffers::Verifier &verifier) const {
    return VerifyTableStart(verifier) &&
           VerifyOffset(verifier, VT_BASE) &&
           verifier.VerifyTable(base()) &&
           VerifyOffset(verifier, VT_DESCRIPTOR) &&
           verifier.VerifyTable(descriptor()) &&
           verifier.EndTable();
  }
};

struct L2NormalizationLayerBuilder {
  typedef L2NormalizationLayer Table;
  flatbuffers::FlatBufferBuilder &fbb_;
  flatbuffers::uoffset_t start_;
  void add_base(flatbuffers::Offset<armnnSerializer::LayerBase> base) {
    fbb_.AddOffset(L2NormalizationLayer::VT_BASE, base);
  }
  void add_descriptor(flatbuffers::Offset<armnnSerializer::L2NormalizationDescriptor> descriptor) {
    fbb_.AddOffset(L2NormalizationLayer::VT_DESCRIPTOR, descriptor);
  }
  explicit L2NormalizationLayerBuilder(flatbuffers::FlatBufferBuilder &_fbb)
        : fbb_(_fbb) {
    start_ = fbb_.StartTable();
  }
  L2NormalizationLayerBuilder &operator=(const L2NormalizationLayerBuilder &);
  flatbuffers::Offset<L2NormalizationLayer> Finish() {
    const auto end = fbb_.EndTable(start_);
    auto o = flatbuffers::Offset<L2NormalizationLayer>(end);
    return o;
  }
};

inline flatbuffers::Offset<L2NormalizationLayer> CreateL2NormalizationLayer(
    flatbuffers::FlatBufferBuilder &_fbb,
    flatbuffers::Offset<armnnSerializer::LayerBase> base = 0,
    flatbuffers::Offset<armnnSerializer::L2NormalizationDescriptor> descriptor = 0) {
  L2NormalizationLayerBuilder builder_(_fbb);
  builder_.add_descriptor(descriptor);
  builder_.add_base(base);
  return builder_.Finish();
}

struct L2NormalizationDescriptor FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
  typedef L2NormalizationDescriptorBuilder Builder;
  enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
    VT_DATALAYOUT = 4,
    VT_EPS = 6
  };
  armnnSerializer::DataLayout dataLayout() const {
    return static_cast<armnnSerializer::DataLayout>(GetField<int8_t>(VT_DATALAYOUT, 1));
  }
  float eps() const {
    return GetField<float>(VT_EPS, 1e-12f);
  }
  bool Verify(flatbuffers::Verifier &verifier) const {
    return VerifyTableStart(verifier) &&
           VerifyField<int8_t>(verifier, VT_DATALAYOUT) &&
           VerifyField<float>(verifier, VT_EPS) &&
           verifier.EndTable();
  }
};

struct L2NormalizationDescriptorBuilder {
  typedef L2NormalizationDescriptor Table;
  flatbuffers::FlatBufferBuilder &fbb_;
  flatbuffers::uoffset_t start_;
  void add_dataLayout(armnnSerializer::DataLayout dataLayout) {
    fbb_.AddElement<int8_t>(L2NormalizationDescriptor::VT_DATALAYOUT, static_cast<int8_t>(dataLayout), 1);
  }
  void add_eps(float eps) {
    fbb_.AddElement<float>(L2NormalizationDescriptor::VT_EPS, eps, 1e-12f);
  }
  explicit L2NormalizationDescriptorBuilder(flatbuffers::FlatBufferBuilder &_fbb)
        : fbb_(_fbb) {
    start_ = fbb_.StartTable();
  }
  L2NormalizationDescriptorBuilder &operator=(const L2NormalizationDescriptorBuilder &);
  flatbuffers::Offset<L2NormalizationDescriptor> Finish() {
    const auto end = fbb_.EndTable(start_);
    auto o = flatbuffers::Offset<L2NormalizationDescriptor>(end);
    return o;
  }
};

inline flatbuffers::Offset<L2NormalizationDescriptor> CreateL2NormalizationDescriptor(
    flatbuffers::FlatBufferBuilder &_fbb,
    armnnSerializer::DataLayout dataLayout = armnnSerializer::DataLayout_NCHW,
    float eps = 1e-12f) {
  L2NormalizationDescriptorBuilder builder_(_fbb);
  builder_.add_eps(eps);
  builder_.add_dataLayout(dataLayout);
  return builder_.Finish();
}

struct LogicalBinaryDescriptor FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
  typedef LogicalBinaryDescriptorBuilder Builder;
  enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
    VT_OPERATION = 4
  };
  armnnSerializer::LogicalBinaryOperation operation() const {
    return static_cast<armnnSerializer::LogicalBinaryOperation>(GetField<int8_t>(VT_OPERATION, 0));
  }
  bool Verify(flatbuffers::Verifier &verifier) const {
    return VerifyTableStart(verifier) &&
           VerifyField<int8_t>(verifier, VT_OPERATION) &&
           verifier.EndTable();
  }
};

struct LogicalBinaryDescriptorBuilder {
  typedef LogicalBinaryDescriptor Table;
  flatbuffers::FlatBufferBuilder &fbb_;
  flatbuffers::uoffset_t start_;
  void add_operation(armnnSerializer::LogicalBinaryOperation operation) {
    fbb_.AddElement<int8_t>(LogicalBinaryDescriptor::VT_OPERATION, static_cast<int8_t>(operation), 0);
  }
  explicit LogicalBinaryDescriptorBuilder(flatbuffers::FlatBufferBuilder &_fbb)
        : fbb_(_fbb) {
    start_ = fbb_.StartTable();
  }
  LogicalBinaryDescriptorBuilder &operator=(const LogicalBinaryDescriptorBuilder &);
  flatbuffers::Offset<LogicalBinaryDescriptor> Finish() {
    const auto end = fbb_.EndTable(start_);
    auto o = flatbuffers::Offset<LogicalBinaryDescriptor>(end);
    return o;
  }
};

inline flatbuffers::Offset<LogicalBinaryDescriptor> CreateLogicalBinaryDescriptor(
    flatbuffers::FlatBufferBuilder &_fbb,
    armnnSerializer::LogicalBinaryOperation operation = armnnSerializer::LogicalBinaryOperation_LogicalAnd) {
  LogicalBinaryDescriptorBuilder builder_(_fbb);
  builder_.add_operation(operation);
  return builder_.Finish();
}

struct LogicalBinaryLayer FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
  typedef LogicalBinaryLayerBuilder Builder;
  enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
    VT_BASE = 4,
    VT_DESCRIPTOR = 6
  };
  const armnnSerializer::LayerBase *base() const {
    return GetPointer<const armnnSerializer::LayerBase *>(VT_BASE);
  }
  const armnnSerializer::LogicalBinaryDescriptor *descriptor() const {
    return GetPointer<const armnnSerializer::LogicalBinaryDescriptor *>(VT_DESCRIPTOR);
  }
  bool Verify(flatbuffers::Verifier &verifier) const {
    return VerifyTableStart(verifier) &&
           VerifyOffset(verifier, VT_BASE) &&
           verifier.VerifyTable(base()) &&
           VerifyOffset(verifier, VT_DESCRIPTOR) &&
           verifier.VerifyTable(descriptor()) &&
           verifier.EndTable();
  }
};

struct LogicalBinaryLayerBuilder {
  typedef LogicalBinaryLayer Table;
  flatbuffers::FlatBufferBuilder &fbb_;
  flatbuffers::uoffset_t start_;
  void add_base(flatbuffers::Offset<armnnSerializer::LayerBase> base) {
    fbb_.AddOffset(LogicalBinaryLayer::VT_BASE, base);
  }
  void add_descriptor(flatbuffers::Offset<armnnSerializer::LogicalBinaryDescriptor> descriptor) {
    fbb_.AddOffset(LogicalBinaryLayer::VT_DESCRIPTOR, descriptor);
  }
  explicit LogicalBinaryLayerBuilder(flatbuffers::FlatBufferBuilder &_fbb)
        : fbb_(_fbb) {
    start_ = fbb_.StartTable();
  }
  LogicalBinaryLayerBuilder &operator=(const LogicalBinaryLayerBuilder &);
  flatbuffers::Offset<LogicalBinaryLayer> Finish() {
    const auto end = fbb_.EndTable(start_);
    auto o = flatbuffers::Offset<LogicalBinaryLayer>(end);
    return o;
  }
};

inline flatbuffers::Offset<LogicalBinaryLayer> CreateLogicalBinaryLayer(
    flatbuffers::FlatBufferBuilder &_fbb,
    flatbuffers::Offset<armnnSerializer::LayerBase> base = 0,
    flatbuffers::Offset<armnnSerializer::LogicalBinaryDescriptor> descriptor = 0) {
  LogicalBinaryLayerBuilder builder_(_fbb);
  builder_.add_descriptor(descriptor);
  builder_.add_base(base);
  return builder_.Finish();
}

struct MinimumLayer FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
  typedef MinimumLayerBuilder Builder;
  enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
    VT_BASE = 4
  };
  const armnnSerializer::LayerBase *base() const {
    return GetPointer<const armnnSerializer::LayerBase *>(VT_BASE);
  }
  bool Verify(flatbuffers::Verifier &verifier) const {
    return VerifyTableStart(verifier) &&
           VerifyOffset(verifier, VT_BASE) &&
           verifier.VerifyTable(base()) &&
           verifier.EndTable();
  }
};

struct MinimumLayerBuilder {
  typedef MinimumLayer Table;
  flatbuffers::FlatBufferBuilder &fbb_;
  flatbuffers::uoffset_t start_;
  void add_base(flatbuffers::Offset<armnnSerializer::LayerBase> base) {
    fbb_.AddOffset(MinimumLayer::VT_BASE, base);
  }
  explicit MinimumLayerBuilder(flatbuffers::FlatBufferBuilder &_fbb)
        : fbb_(_fbb) {
    start_ = fbb_.StartTable();
  }
  MinimumLayerBuilder &operator=(const MinimumLayerBuilder &);
  flatbuffers::Offset<MinimumLayer> Finish() {
    const auto end = fbb_.EndTable(start_);
    auto o = flatbuffers::Offset<MinimumLayer>(end);
    return o;
  }
};

inline flatbuffers::Offset<MinimumLayer> CreateMinimumLayer(
    flatbuffers::FlatBufferBuilder &_fbb,
    flatbuffers::Offset<armnnSerializer::LayerBase> base = 0) {
  MinimumLayerBuilder builder_(_fbb);
  builder_.add_base(base);
  return builder_.Finish();
}

struct MaximumLayer FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
  typedef MaximumLayerBuilder Builder;
  enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
    VT_BASE = 4
  };
  const armnnSerializer::LayerBase *base() const {
    return GetPointer<const armnnSerializer::LayerBase *>(VT_BASE);
  }
  bool Verify(flatbuffers::Verifier &verifier) const {
    return VerifyTableStart(verifier) &&
           VerifyOffset(verifier, VT_BASE) &&
           verifier.VerifyTable(base()) &&
           verifier.EndTable();
  }
};

struct MaximumLayerBuilder {
  typedef MaximumLayer Table;
  flatbuffers::FlatBufferBuilder &fbb_;
  flatbuffers::uoffset_t start_;
  void add_base(flatbuffers::Offset<armnnSerializer::LayerBase> base) {
    fbb_.AddOffset(MaximumLayer::VT_BASE, base);
  }
  explicit MaximumLayerBuilder(flatbuffers::FlatBufferBuilder &_fbb)
        : fbb_(_fbb) {
    start_ = fbb_.StartTable();
  }
  MaximumLayerBuilder &operator=(const MaximumLayerBuilder &);
  flatbuffers::Offset<MaximumLayer> Finish() {
    const auto end = fbb_.EndTable(start_);
    auto o = flatbuffers::Offset<MaximumLayer>(end);
    return o;
  }
};

inline flatbuffers::Offset<MaximumLayer> CreateMaximumLayer(
    flatbuffers::FlatBufferBuilder &_fbb,
    flatbuffers::Offset<armnnSerializer::LayerBase> base = 0) {
  MaximumLayerBuilder builder_(_fbb);
  builder_.add_base(base);
  return builder_.Finish();
}

struct MultiplicationLayer FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
  typedef MultiplicationLayerBuilder Builder;
  enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
    VT_BASE = 4
  };
  const armnnSerializer::LayerBase *base() const {
    return GetPointer<const armnnSerializer::LayerBase *>(VT_BASE);
  }
  bool Verify(flatbuffers::Verifier &verifier) const {
    return VerifyTableStart(verifier) &&
           VerifyOffset(verifier, VT_BASE) &&
           verifier.VerifyTable(base()) &&
           verifier.EndTable();
  }
};

struct MultiplicationLayerBuilder {
  typedef MultiplicationLayer Table;
  flatbuffers::FlatBufferBuilder &fbb_;
  flatbuffers::uoffset_t start_;
  void add_base(flatbuffers::Offset<armnnSerializer::LayerBase> base) {
    fbb_.AddOffset(MultiplicationLayer::VT_BASE, base);
  }
  explicit MultiplicationLayerBuilder(flatbuffers::FlatBufferBuilder &_fbb)
        : fbb_(_fbb) {
    start_ = fbb_.StartTable();
  }
  MultiplicationLayerBuilder &operator=(const MultiplicationLayerBuilder &);
  flatbuffers::Offset<MultiplicationLayer> Finish() {
    const auto end = fbb_.EndTable(start_);
    auto o = flatbuffers::Offset<MultiplicationLayer>(end);
    return o;
  }
};

inline flatbuffers::Offset<MultiplicationLayer> CreateMultiplicationLayer(
    flatbuffers::FlatBufferBuilder &_fbb,
    flatbuffers::Offset<armnnSerializer::LayerBase> base = 0) {
  MultiplicationLayerBuilder builder_(_fbb);
  builder_.add_base(base);
  return builder_.Finish();
}

struct Pooling2dLayer FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
  typedef Pooling2dLayerBuilder Builder;
  enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
    VT_BASE = 4,
    VT_DESCRIPTOR = 6
  };
  const armnnSerializer::LayerBase *base() const {
    return GetPointer<const armnnSerializer::LayerBase *>(VT_BASE);
  }
  const armnnSerializer::Pooling2dDescriptor *descriptor() const {
    return GetPointer<const armnnSerializer::Pooling2dDescriptor *>(VT_DESCRIPTOR);
  }
  bool Verify(flatbuffers::Verifier &verifier) const {
    return VerifyTableStart(verifier) &&
           VerifyOffset(verifier, VT_BASE) &&
           verifier.VerifyTable(base()) &&
           VerifyOffset(verifier, VT_DESCRIPTOR) &&
           verifier.VerifyTable(descriptor()) &&
           verifier.EndTable();
  }
};

struct Pooling2dLayerBuilder {
  typedef Pooling2dLayer Table;
  flatbuffers::FlatBufferBuilder &fbb_;
  flatbuffers::uoffset_t start_;
  void add_base(flatbuffers::Offset<armnnSerializer::LayerBase> base) {
    fbb_.AddOffset(Pooling2dLayer::VT_BASE, base);
  }
  void add_descriptor(flatbuffers::Offset<armnnSerializer::Pooling2dDescriptor> descriptor) {
    fbb_.AddOffset(Pooling2dLayer::VT_DESCRIPTOR, descriptor);
  }
  explicit Pooling2dLayerBuilder(flatbuffers::FlatBufferBuilder &_fbb)
        : fbb_(_fbb) {
    start_ = fbb_.StartTable();
  }
  Pooling2dLayerBuilder &operator=(const Pooling2dLayerBuilder &);
  flatbuffers::Offset<Pooling2dLayer> Finish() {
    const auto end = fbb_.EndTable(start_);
    auto o = flatbuffers::Offset<Pooling2dLayer>(end);
    return o;
  }
};

inline flatbuffers::Offset<Pooling2dLayer> CreatePooling2dLayer(
    flatbuffers::FlatBufferBuilder &_fbb,
    flatbuffers::Offset<armnnSerializer::LayerBase> base = 0,
    flatbuffers::Offset<armnnSerializer::Pooling2dDescriptor> descriptor = 0) {
  Pooling2dLayerBuilder builder_(_fbb);
  builder_.add_descriptor(descriptor);
  builder_.add_base(base);
  return builder_.Finish();
}

struct Pooling2dDescriptor FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
  typedef Pooling2dDescriptorBuilder Builder;
  enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
    VT_POOLTYPE = 4,
    VT_PADLEFT = 6,
    VT_PADRIGHT = 8,
    VT_PADTOP = 10,
    VT_PADBOTTOM = 12,
    VT_POOLWIDTH = 14,
    VT_POOLHEIGHT = 16,
    VT_STRIDEX = 18,
    VT_STRIDEY = 20,
    VT_OUTPUTSHAPEROUNDING = 22,
    VT_PADDINGMETHOD = 24,
    VT_DATALAYOUT = 26
  };
  armnnSerializer::PoolingAlgorithm poolType() const {
    return static_cast<armnnSerializer::PoolingAlgorithm>(GetField<int8_t>(VT_POOLTYPE, 0));
  }
  uint32_t padLeft() const {
    return GetField<uint32_t>(VT_PADLEFT, 0);
  }
  uint32_t padRight() const {
    return GetField<uint32_t>(VT_PADRIGHT, 0);
  }
  uint32_t padTop() const {
    return GetField<uint32_t>(VT_PADTOP, 0);
  }
  uint32_t padBottom() const {
    return GetField<uint32_t>(VT_PADBOTTOM, 0);
  }
  uint32_t poolWidth() const {
    return GetField<uint32_t>(VT_POOLWIDTH, 0);
  }
  uint32_t poolHeight() const {
    return GetField<uint32_t>(VT_POOLHEIGHT, 0);
  }
  uint32_t strideX() const {
    return GetField<uint32_t>(VT_STRIDEX, 0);
  }
  uint32_t strideY() const {
    return GetField<uint32_t>(VT_STRIDEY, 0);
  }
  armnnSerializer::OutputShapeRounding outputShapeRounding() const {
    return static_cast<armnnSerializer::OutputShapeRounding>(GetField<int8_t>(VT_OUTPUTSHAPEROUNDING, 0));
  }
  armnnSerializer::PaddingMethod paddingMethod() const {
    return static_cast<armnnSerializer::PaddingMethod>(GetField<int8_t>(VT_PADDINGMETHOD, 0));
  }
  armnnSerializer::DataLayout dataLayout() const {
    return static_cast<armnnSerializer::DataLayout>(GetField<int8_t>(VT_DATALAYOUT, 0));
  }
  bool Verify(flatbuffers::Verifier &verifier) const {
    return VerifyTableStart(verifier) &&
           VerifyField<int8_t>(verifier, VT_POOLTYPE) &&
           VerifyField<uint32_t>(verifier, VT_PADLEFT) &&
           VerifyField<uint32_t>(verifier, VT_PADRIGHT) &&
           VerifyField<uint32_t>(verifier, VT_PADTOP) &&
           VerifyField<uint32_t>(verifier, VT_PADBOTTOM) &&
           VerifyField<uint32_t>(verifier, VT_POOLWIDTH) &&
           VerifyField<uint32_t>(verifier, VT_POOLHEIGHT) &&
           VerifyField<uint32_t>(verifier, VT_STRIDEX) &&
           VerifyField<uint32_t>(verifier, VT_STRIDEY) &&
           VerifyField<int8_t>(verifier, VT_OUTPUTSHAPEROUNDING) &&
           VerifyField<int8_t>(verifier, VT_PADDINGMETHOD) &&
           VerifyField<int8_t>(verifier, VT_DATALAYOUT) &&
           verifier.EndTable();
  }
};

struct Pooling2dDescriptorBuilder {
  typedef Pooling2dDescriptor Table;
  flatbuffers::FlatBufferBuilder &fbb_;
  flatbuffers::uoffset_t start_;
  void add_poolType(armnnSerializer::PoolingAlgorithm poolType) {
    fbb_.AddElement<int8_t>(Pooling2dDescriptor::VT_POOLTYPE, static_cast<int8_t>(poolType), 0);
  }
  void add_padLeft(uint32_t padLeft) {
    fbb_.AddElement<uint32_t>(Pooling2dDescriptor::VT_PADLEFT, padLeft, 0);
  }
  void add_padRight(uint32_t padRight) {
    fbb_.AddElement<uint32_t>(Pooling2dDescriptor::VT_PADRIGHT, padRight, 0);
  }
  void add_padTop(uint32_t padTop) {
    fbb_.AddElement<uint32_t>(Pooling2dDescriptor::VT_PADTOP, padTop, 0);
  }
  void add_padBottom(uint32_t padBottom) {
    fbb_.AddElement<uint32_t>(Pooling2dDescriptor::VT_PADBOTTOM, padBottom, 0);
  }
  void add_poolWidth(uint32_t poolWidth) {
    fbb_.AddElement<uint32_t>(Pooling2dDescriptor::VT_POOLWIDTH, poolWidth, 0);
  }
  void add_poolHeight(uint32_t poolHeight) {
    fbb_.AddElement<uint32_t>(Pooling2dDescriptor::VT_POOLHEIGHT, poolHeight, 0);
  }
  void add_strideX(uint32_t strideX) {
    fbb_.AddElement<uint32_t>(Pooling2dDescriptor::VT_STRIDEX, strideX, 0);
  }
  void add_strideY(uint32_t strideY) {
    fbb_.AddElement<uint32_t>(Pooling2dDescriptor::VT_STRIDEY, strideY, 0);
  }
  void add_outputShapeRounding(armnnSerializer::OutputShapeRounding outputShapeRounding) {
    fbb_.AddElement<int8_t>(Pooling2dDescriptor::VT_OUTPUTSHAPEROUNDING, static_cast<int8_t>(outputShapeRounding), 0);
  }
  void add_paddingMethod(armnnSerializer::PaddingMethod paddingMethod) {
    fbb_.AddElement<int8_t>(Pooling2dDescriptor::VT_PADDINGMETHOD, static_cast<int8_t>(paddingMethod), 0);
  }
  void add_dataLayout(armnnSerializer::DataLayout dataLayout) {
    fbb_.AddElement<int8_t>(Pooling2dDescriptor::VT_DATALAYOUT, static_cast<int8_t>(dataLayout), 0);
  }
  explicit Pooling2dDescriptorBuilder(flatbuffers::FlatBufferBuilder &_fbb)
        : fbb_(_fbb) {
    start_ = fbb_.StartTable();
  }
  Pooling2dDescriptorBuilder &operator=(const Pooling2dDescriptorBuilder &);
  flatbuffers::Offset<Pooling2dDescriptor> Finish() {
    const auto end = fbb_.EndTable(start_);
    auto o = flatbuffers::Offset<Pooling2dDescriptor>(end);
    return o;
  }
};

inline flatbuffers::Offset<Pooling2dDescriptor> CreatePooling2dDescriptor(
    flatbuffers::FlatBufferBuilder &_fbb,
    armnnSerializer::PoolingAlgorithm poolType = armnnSerializer::PoolingAlgorithm_Max,
    uint32_t padLeft = 0,
    uint32_t padRight = 0,
    uint32_t padTop = 0,
    uint32_t padBottom = 0,
    uint32_t poolWidth = 0,
    uint32_t poolHeight = 0,
    uint32_t strideX = 0,
    uint32_t strideY = 0,
    armnnSerializer::OutputShapeRounding outputShapeRounding = armnnSerializer::OutputShapeRounding_Floor,
    armnnSerializer::PaddingMethod paddingMethod = armnnSerializer::PaddingMethod_IgnoreValue,
    armnnSerializer::DataLayout dataLayout = armnnSerializer::DataLayout_NHWC) {
  Pooling2dDescriptorBuilder builder_(_fbb);
  builder_.add_strideY(strideY);
  builder_.add_strideX(strideX);
  builder_.add_poolHeight(poolHeight);
  builder_.add_poolWidth(poolWidth);
  builder_.add_padBottom(padBottom);
  builder_.add_padTop(padTop);
  builder_.add_padRight(padRight);
  builder_.add_padLeft(padLeft);
  builder_.add_dataLayout(dataLayout);
  builder_.add_paddingMethod(paddingMethod);
  builder_.add_outputShapeRounding(outputShapeRounding);
  builder_.add_poolType(poolType);
  return builder_.Finish();
}

struct QuantizeLayer FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
  typedef QuantizeLayerBuilder Builder;
  enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
    VT_BASE = 4
  };
  const armnnSerializer::LayerBase *base() const {
    return GetPointer<const armnnSerializer::LayerBase *>(VT_BASE);
  }
  bool Verify(flatbuffers::Verifier &verifier) const {
    return VerifyTableStart(verifier) &&
           VerifyOffset(verifier, VT_BASE) &&
           verifier.VerifyTable(base()) &&
           verifier.EndTable();
  }
};

struct QuantizeLayerBuilder {
  typedef QuantizeLayer Table;
  flatbuffers::FlatBufferBuilder &fbb_;
  flatbuffers::uoffset_t start_;
  void add_base(flatbuffers::Offset<armnnSerializer::LayerBase> base) {
    fbb_.AddOffset(QuantizeLayer::VT_BASE, base);
  }
  explicit QuantizeLayerBuilder(flatbuffers::FlatBufferBuilder &_fbb)
        : fbb_(_fbb) {
    start_ = fbb_.StartTable();
  }
  QuantizeLayerBuilder &operator=(const QuantizeLayerBuilder &);
  flatbuffers::Offset<QuantizeLayer> Finish() {
    const auto end = fbb_.EndTable(start_);
    auto o = flatbuffers::Offset<QuantizeLayer>(end);
    return o;
  }
};

inline flatbuffers::Offset<QuantizeLayer> CreateQuantizeLayer(
    flatbuffers::FlatBufferBuilder &_fbb,
    flatbuffers::Offset<armnnSerializer::LayerBase> base = 0) {
  QuantizeLayerBuilder builder_(_fbb);
  builder_.add_base(base);
  return builder_.Finish();
}

struct SoftmaxLayer FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
  typedef SoftmaxLayerBuilder Builder;
  enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
    VT_BASE = 4,
    VT_DESCRIPTOR = 6
  };
  const armnnSerializer::LayerBase *base() const {
    return GetPointer<const armnnSerializer::LayerBase *>(VT_BASE);
  }
  const armnnSerializer::SoftmaxDescriptor *descriptor() const {
    return GetPointer<const armnnSerializer::SoftmaxDescriptor *>(VT_DESCRIPTOR);
  }
  bool Verify(flatbuffers::Verifier &verifier) const {
    return VerifyTableStart(verifier) &&
           VerifyOffset(verifier, VT_BASE) &&
           verifier.VerifyTable(base()) &&
           VerifyOffset(verifier, VT_DESCRIPTOR) &&
           verifier.VerifyTable(descriptor()) &&
           verifier.EndTable();
  }
};

struct SoftmaxLayerBuilder {
  typedef SoftmaxLayer Table;
  flatbuffers::FlatBufferBuilder &fbb_;
  flatbuffers::uoffset_t start_;
  void add_base(flatbuffers::Offset<armnnSerializer::LayerBase> base) {
    fbb_.AddOffset(SoftmaxLayer::VT_BASE, base);
  }
  void add_descriptor(flatbuffers::Offset<armnnSerializer::SoftmaxDescriptor> descriptor) {
    fbb_.AddOffset(SoftmaxLayer::VT_DESCRIPTOR, descriptor);
  }
  explicit SoftmaxLayerBuilder(flatbuffers::FlatBufferBuilder &_fbb)
        : fbb_(_fbb) {
    start_ = fbb_.StartTable();
  }
  SoftmaxLayerBuilder &operator=(const SoftmaxLayerBuilder &);
  flatbuffers::Offset<SoftmaxLayer> Finish() {
    const auto end = fbb_.EndTable(start_);
    auto o = flatbuffers::Offset<SoftmaxLayer>(end);
    return o;
  }
};

inline flatbuffers::Offset<SoftmaxLayer> CreateSoftmaxLayer(
    flatbuffers::FlatBufferBuilder &_fbb,
    flatbuffers::Offset<armnnSerializer::LayerBase> base = 0,
    flatbuffers::Offset<armnnSerializer::SoftmaxDescriptor> descriptor = 0) {
  SoftmaxLayerBuilder builder_(_fbb);
  builder_.add_descriptor(descriptor);
  builder_.add_base(base);
  return builder_.Finish();
}

struct SoftmaxDescriptor FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
  typedef SoftmaxDescriptorBuilder Builder;
  enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
    VT_BETA = 4
  };
  float beta() const {
    return GetField<float>(VT_BETA, 0.0f);
  }
  bool Verify(flatbuffers::Verifier &verifier) const {
    return VerifyTableStart(verifier) &&
           VerifyField<float>(verifier, VT_BETA) &&
           verifier.EndTable();
  }
};

struct SoftmaxDescriptorBuilder {
  typedef SoftmaxDescriptor Table;
  flatbuffers::FlatBufferBuilder &fbb_;
  flatbuffers::uoffset_t start_;
  void add_beta(float beta) {
    fbb_.AddElement<float>(SoftmaxDescriptor::VT_BETA, beta, 0.0f);
  }
  explicit SoftmaxDescriptorBuilder(flatbuffers::FlatBufferBuilder &_fbb)
        : fbb_(_fbb) {
    start_ = fbb_.StartTable();
  }
  SoftmaxDescriptorBuilder &operator=(const SoftmaxDescriptorBuilder &);
  flatbuffers::Offset<SoftmaxDescriptor> Finish() {
    const auto end = fbb_.EndTable(start_);
    auto o = flatbuffers::Offset<SoftmaxDescriptor>(end);
    return o;
  }
};

inline flatbuffers::Offset<SoftmaxDescriptor> CreateSoftmaxDescriptor(
    flatbuffers::FlatBufferBuilder &_fbb,
    float beta = 0.0f) {
  SoftmaxDescriptorBuilder builder_(_fbb);
  builder_.add_beta(beta);
  return builder_.Finish();
}

struct DepthwiseConvolution2dLayer FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
  typedef DepthwiseConvolution2dLayerBuilder Builder;
  enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
    VT_BASE = 4,
    VT_DESCRIPTOR = 6,
    VT_WEIGHTS = 8,
    VT_BIASES = 10
  };
  const armnnSerializer::LayerBase *base() const {
    return GetPointer<const armnnSerializer::LayerBase *>(VT_BASE);
  }
  const armnnSerializer::DepthwiseConvolution2dDescriptor *descriptor() const {
    return GetPointer<const armnnSerializer::DepthwiseConvolution2dDescriptor *>(VT_DESCRIPTOR);
  }
  const armnnSerializer::ConstTensor *weights() const {
    return GetPointer<const armnnSerializer::ConstTensor *>(VT_WEIGHTS);
  }
  const armnnSerializer::ConstTensor *biases() const {
    return GetPointer<const armnnSerializer::ConstTensor *>(VT_BIASES);
  }
  bool Verify(flatbuffers::Verifier &verifier) const {
    return VerifyTableStart(verifier) &&
           VerifyOffset(verifier, VT_BASE) &&
           verifier.VerifyTable(base()) &&
           VerifyOffset(verifier, VT_DESCRIPTOR) &&
           verifier.VerifyTable(descriptor()) &&
           VerifyOffset(verifier, VT_WEIGHTS) &&
           verifier.VerifyTable(weights()) &&
           VerifyOffset(verifier, VT_BIASES) &&
           verifier.VerifyTable(biases()) &&
           verifier.EndTable();
  }
};

struct DepthwiseConvolution2dLayerBuilder {
  typedef DepthwiseConvolution2dLayer Table;
  flatbuffers::FlatBufferBuilder &fbb_;
  flatbuffers::uoffset_t start_;
  void add_base(flatbuffers::Offset<armnnSerializer::LayerBase> base) {
    fbb_.AddOffset(DepthwiseConvolution2dLayer::VT_BASE, base);
  }
  void add_descriptor(flatbuffers::Offset<armnnSerializer::DepthwiseConvolution2dDescriptor> descriptor) {
    fbb_.AddOffset(DepthwiseConvolution2dLayer::VT_DESCRIPTOR, descriptor);
  }
  void add_weights(flatbuffers::Offset<armnnSerializer::ConstTensor> weights) {
    fbb_.AddOffset(DepthwiseConvolution2dLayer::VT_WEIGHTS, weights);
  }
  void add_biases(flatbuffers::Offset<armnnSerializer::ConstTensor> biases) {
    fbb_.AddOffset(DepthwiseConvolution2dLayer::VT_BIASES, biases);
  }
  explicit DepthwiseConvolution2dLayerBuilder(flatbuffers::FlatBufferBuilder &_fbb)
        : fbb_(_fbb) {
    start_ = fbb_.StartTable();
  }
  DepthwiseConvolution2dLayerBuilder &operator=(const DepthwiseConvolution2dLayerBuilder &);
  flatbuffers::Offset<DepthwiseConvolution2dLayer> Finish() {
    const auto end = fbb_.EndTable(start_);
    auto o = flatbuffers::Offset<DepthwiseConvolution2dLayer>(end);
    return o;
  }
};

inline flatbuffers::Offset<DepthwiseConvolution2dLayer> CreateDepthwiseConvolution2dLayer(
    flatbuffers::FlatBufferBuilder &_fbb,
    flatbuffers::Offset<armnnSerializer::LayerBase> base = 0,
    flatbuffers::Offset<armnnSerializer::DepthwiseConvolution2dDescriptor> descriptor = 0,
    flatbuffers::Offset<armnnSerializer::ConstTensor> weights = 0,
    flatbuffers::Offset<armnnSerializer::ConstTensor> biases = 0) {
  DepthwiseConvolution2dLayerBuilder builder_(_fbb);
  builder_.add_biases(biases);
  builder_.add_weights(weights);
  builder_.add_descriptor(descriptor);
  builder_.add_base(base);
  return builder_.Finish();
}

struct DepthwiseConvolution2dDescriptor FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
  typedef DepthwiseConvolution2dDescriptorBuilder Builder;
  enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
    VT_PADLEFT = 4,
    VT_PADRIGHT = 6,
    VT_PADTOP = 8,
    VT_PADBOTTOM = 10,
    VT_STRIDEX = 12,
    VT_STRIDEY = 14,
    VT_DILATIONX = 16,
    VT_DILATIONY = 18,
    VT_BIASENABLED = 20,
    VT_DATALAYOUT = 22
  };
  uint32_t padLeft() const {
    return GetField<uint32_t>(VT_PADLEFT, 0);
  }
  uint32_t padRight() const {
    return GetField<uint32_t>(VT_PADRIGHT, 0);
  }
  uint32_t padTop() const {
    return GetField<uint32_t>(VT_PADTOP, 0);
  }
  uint32_t padBottom() const {
    return GetField<uint32_t>(VT_PADBOTTOM, 0);
  }
  uint32_t strideX() const {
    return GetField<uint32_t>(VT_STRIDEX, 0);
  }
  uint32_t strideY() const {
    return GetField<uint32_t>(VT_STRIDEY, 0);
  }
  uint32_t dilationX() const {
    return GetField<uint32_t>(VT_DILATIONX, 1);
  }
  uint32_t dilationY() const {
    return GetField<uint32_t>(VT_DILATIONY, 1);
  }
  bool biasEnabled() const {
    return GetField<uint8_t>(VT_BIASENABLED, 0) != 0;
  }
  armnnSerializer::DataLayout dataLayout() const {
    return static_cast<armnnSerializer::DataLayout>(GetField<int8_t>(VT_DATALAYOUT, 1));
  }
  bool Verify(flatbuffers::Verifier &verifier) const {
    return VerifyTableStart(verifier) &&
           VerifyField<uint32_t>(verifier, VT_PADLEFT) &&
           VerifyField<uint32_t>(verifier, VT_PADRIGHT) &&
           VerifyField<uint32_t>(verifier, VT_PADTOP) &&
           VerifyField<uint32_t>(verifier, VT_PADBOTTOM) &&
           VerifyField<uint32_t>(verifier, VT_STRIDEX) &&
           VerifyField<uint32_t>(verifier, VT_STRIDEY) &&
           VerifyField<uint32_t>(verifier, VT_DILATIONX) &&
           VerifyField<uint32_t>(verifier, VT_DILATIONY) &&
           VerifyField<uint8_t>(verifier, VT_BIASENABLED) &&
           VerifyField<int8_t>(verifier, VT_DATALAYOUT) &&
           verifier.EndTable();
  }
};

struct DepthwiseConvolution2dDescriptorBuilder {
  typedef DepthwiseConvolution2dDescriptor Table;
  flatbuffers::FlatBufferBuilder &fbb_;
  flatbuffers::uoffset_t start_;
  void add_padLeft(uint32_t padLeft) {
    fbb_.AddElement<uint32_t>(DepthwiseConvolution2dDescriptor::VT_PADLEFT, padLeft, 0);
  }
  void add_padRight(uint32_t padRight) {
    fbb_.AddElement<uint32_t>(DepthwiseConvolution2dDescriptor::VT_PADRIGHT, padRight, 0);
  }
  void add_padTop(uint32_t padTop) {
    fbb_.AddElement<uint32_t>(DepthwiseConvolution2dDescriptor::VT_PADTOP, padTop, 0);
  }
  void add_padBottom(uint32_t padBottom) {
    fbb_.AddElement<uint32_t>(DepthwiseConvolution2dDescriptor::VT_PADBOTTOM, padBottom, 0);
  }
  void add_strideX(uint32_t strideX) {
    fbb_.AddElement<uint32_t>(DepthwiseConvolution2dDescriptor::VT_STRIDEX, strideX, 0);
  }
  void add_strideY(uint32_t strideY) {
    fbb_.AddElement<uint32_t>(DepthwiseConvolution2dDescriptor::VT_STRIDEY, strideY, 0);
  }
  void add_dilationX(uint32_t dilationX) {
    fbb_.AddElement<uint32_t>(DepthwiseConvolution2dDescriptor::VT_DILATIONX, dilationX, 1);
  }
  void add_dilationY(uint32_t dilationY) {
    fbb_.AddElement<uint32_t>(DepthwiseConvolution2dDescriptor::VT_DILATIONY, dilationY, 1);
  }
  void add_biasEnabled(bool biasEnabled) {
    fbb_.AddElement<uint8_t>(DepthwiseConvolution2dDescriptor::VT_BIASENABLED, static_cast<uint8_t>(biasEnabled), 0);
  }
  void add_dataLayout(armnnSerializer::DataLayout dataLayout) {
    fbb_.AddElement<int8_t>(DepthwiseConvolution2dDescriptor::VT_DATALAYOUT, static_cast<int8_t>(dataLayout), 1);
  }
  explicit DepthwiseConvolution2dDescriptorBuilder(flatbuffers::FlatBufferBuilder &_fbb)
        : fbb_(_fbb) {
    start_ = fbb_.StartTable();
  }
  DepthwiseConvolution2dDescriptorBuilder &operator=(const DepthwiseConvolution2dDescriptorBuilder &);
  flatbuffers::Offset<DepthwiseConvolution2dDescriptor> Finish() {
    const auto end = fbb_.EndTable(start_);
    auto o = flatbuffers::Offset<DepthwiseConvolution2dDescriptor>(end);
    return o;
  }
};

inline flatbuffers::Offset<DepthwiseConvolution2dDescriptor> CreateDepthwiseConvolution2dDescriptor(
    flatbuffers::FlatBufferBuilder &_fbb,
    uint32_t padLeft = 0,
    uint32_t padRight = 0,
    uint32_t padTop = 0,
    uint32_t padBottom = 0,
    uint32_t strideX = 0,
    uint32_t strideY = 0,
    uint32_t dilationX = 1,
    uint32_t dilationY = 1,
    bool biasEnabled = false,
    armnnSerializer::DataLayout dataLayout = armnnSerializer::DataLayout_NCHW) {
  DepthwiseConvolution2dDescriptorBuilder builder_(_fbb);
  builder_.add_dilationY(dilationY);
  builder_.add_dilationX(dilationX);
  builder_.add_strideY(strideY);
  builder_.add_strideX(strideX);
  builder_.add_padBottom(padBottom);
  builder_.add_padTop(padTop);
  builder_.add_padRight(padRight);
  builder_.add_padLeft(padLeft);
  builder_.add_dataLayout(dataLayout);
  builder_.add_biasEnabled(biasEnabled);
  return builder_.Finish();
}

struct OutputLayer FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
  typedef OutputLayerBuilder Builder;
  enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
    VT_BASE = 4
  };
  const armnnSerializer::BindableLayerBase *base() const {
    return GetPointer<const armnnSerializer::BindableLayerBase *>(VT_BASE);
  }
  bool Verify(flatbuffers::Verifier &verifier) const {
    return VerifyTableStart(verifier) &&
           VerifyOffset(verifier, VT_BASE) &&
           verifier.VerifyTable(base()) &&
           verifier.EndTable();
  }
};

struct OutputLayerBuilder {
  typedef OutputLayer Table;
  flatbuffers::FlatBufferBuilder &fbb_;
  flatbuffers::uoffset_t start_;
  void add_base(flatbuffers::Offset<armnnSerializer::BindableLayerBase> base) {
    fbb_.AddOffset(OutputLayer::VT_BASE, base);
  }
  explicit OutputLayerBuilder(flatbuffers::FlatBufferBuilder &_fbb)
        : fbb_(_fbb) {
    start_ = fbb_.StartTable();
  }
  OutputLayerBuilder &operator=(const OutputLayerBuilder &);
  flatbuffers::Offset<OutputLayer> Finish() {
    const auto end = fbb_.EndTable(start_);
    auto o = flatbuffers::Offset<OutputLayer>(end);
    return o;
  }
};

inline flatbuffers::Offset<OutputLayer> CreateOutputLayer(
    flatbuffers::FlatBufferBuilder &_fbb,
    flatbuffers::Offset<armnnSerializer::BindableLayerBase> base = 0) {
  OutputLayerBuilder builder_(_fbb);
  builder_.add_base(base);
  return builder_.Finish();
}

struct ReshapeLayer FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
  typedef ReshapeLayerBuilder Builder;
  enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
    VT_BASE = 4,
    VT_DESCRIPTOR = 6
  };
  const armnnSerializer::LayerBase *base() const {
    return GetPointer<const armnnSerializer::LayerBase *>(VT_BASE);
  }
  const armnnSerializer::ReshapeDescriptor *descriptor() const {
    return GetPointer<const armnnSerializer::ReshapeDescriptor *>(VT_DESCRIPTOR);
  }
  bool Verify(flatbuffers::Verifier &verifier) const {
    return VerifyTableStart(verifier) &&
           VerifyOffset(verifier, VT_BASE) &&
           verifier.VerifyTable(base()) &&
           VerifyOffset(verifier, VT_DESCRIPTOR) &&
           verifier.VerifyTable(descriptor()) &&
           verifier.EndTable();
  }
};

struct ReshapeLayerBuilder {
  typedef ReshapeLayer Table;
  flatbuffers::FlatBufferBuilder &fbb_;
  flatbuffers::uoffset_t start_;
  void add_base(flatbuffers::Offset<armnnSerializer::LayerBase> base) {
    fbb_.AddOffset(ReshapeLayer::VT_BASE, base);
  }
  void add_descriptor(flatbuffers::Offset<armnnSerializer::ReshapeDescriptor> descriptor) {
    fbb_.AddOffset(ReshapeLayer::VT_DESCRIPTOR, descriptor);
  }
  explicit ReshapeLayerBuilder(flatbuffers::FlatBufferBuilder &_fbb)
        : fbb_(_fbb) {
    start_ = fbb_.StartTable();
  }
  ReshapeLayerBuilder &operator=(const ReshapeLayerBuilder &);
  flatbuffers::Offset<ReshapeLayer> Finish() {
    const auto end = fbb_.EndTable(start_);
    auto o = flatbuffers::Offset<ReshapeLayer>(end);
    return o;
  }
};

inline flatbuffers::Offset<ReshapeLayer> CreateReshapeLayer(
    flatbuffers::FlatBufferBuilder &_fbb,
    flatbuffers::Offset<armnnSerializer::LayerBase> base = 0,
    flatbuffers::Offset<armnnSerializer::ReshapeDescriptor> descriptor = 0) {
  ReshapeLayerBuilder builder_(_fbb);
  builder_.add_descriptor(descriptor);
  builder_.add_base(base);
  return builder_.Finish();
}

struct ReshapeDescriptor FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
  typedef ReshapeDescriptorBuilder Builder;
  enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
    VT_TARGETSHAPE = 4
  };
  const flatbuffers::Vector<uint32_t> *targetShape() const {
    return GetPointer<const flatbuffers::Vector<uint32_t> *>(VT_TARGETSHAPE);
  }
  bool Verify(flatbuffers::Verifier &verifier) const {
    return VerifyTableStart(verifier) &&
           VerifyOffset(verifier, VT_TARGETSHAPE) &&
           verifier.VerifyVector(targetShape()) &&
           verifier.EndTable();
  }
};

struct ReshapeDescriptorBuilder {
  typedef ReshapeDescriptor Table;
  flatbuffers::FlatBufferBuilder &fbb_;
  flatbuffers::uoffset_t start_;
  void add_targetShape(flatbuffers::Offset<flatbuffers::Vector<uint32_t>> targetShape) {
    fbb_.AddOffset(ReshapeDescriptor::VT_TARGETSHAPE, targetShape);
  }
  explicit ReshapeDescriptorBuilder(flatbuffers::FlatBufferBuilder &_fbb)
        : fbb_(_fbb) {
    start_ = fbb_.StartTable();
  }
  ReshapeDescriptorBuilder &operator=(const ReshapeDescriptorBuilder &);
  flatbuffers::Offset<ReshapeDescriptor> Finish() {
    const auto end = fbb_.EndTable(start_);
    auto o = flatbuffers::Offset<ReshapeDescriptor>(end);
    return o;
  }
};

inline flatbuffers::Offset<ReshapeDescriptor> CreateReshapeDescriptor(
    flatbuffers::FlatBufferBuilder &_fbb,
    flatbuffers::Offset<flatbuffers::Vector<uint32_t>> targetShape = 0) {
  ReshapeDescriptorBuilder builder_(_fbb);
  builder_.add_targetShape(targetShape);
  return builder_.Finish();
}

inline flatbuffers::Offset<ReshapeDescriptor> CreateReshapeDescriptorDirect(
    flatbuffers::FlatBufferBuilder &_fbb,
    const std::vector<uint32_t> *targetShape = nullptr) {
  auto targetShape__ = targetShape ? _fbb.CreateVector<uint32_t>(*targetShape) : 0;
  return armnnSerializer::CreateReshapeDescriptor(
      _fbb,
      targetShape__);
}

struct PermuteLayer FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
  typedef PermuteLayerBuilder Builder;
  enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
    VT_BASE = 4,
    VT_DESCRIPTOR = 6
  };
  const armnnSerializer::LayerBase *base() const {
    return GetPointer<const armnnSerializer::LayerBase *>(VT_BASE);
  }
  const armnnSerializer::PermuteDescriptor *descriptor() const {
    return GetPointer<const armnnSerializer::PermuteDescriptor *>(VT_DESCRIPTOR);
  }
  bool Verify(flatbuffers::Verifier &verifier) const {
    return VerifyTableStart(verifier) &&
           VerifyOffset(verifier, VT_BASE) &&
           verifier.VerifyTable(base()) &&
           VerifyOffset(verifier, VT_DESCRIPTOR) &&
           verifier.VerifyTable(descriptor()) &&
           verifier.EndTable();
  }
};

struct PermuteLayerBuilder {
  typedef PermuteLayer Table;
  flatbuffers::FlatBufferBuilder &fbb_;
  flatbuffers::uoffset_t start_;
  void add_base(flatbuffers::Offset<armnnSerializer::LayerBase> base) {
    fbb_.AddOffset(PermuteLayer::VT_BASE, base);
  }
  void add_descriptor(flatbuffers::Offset<armnnSerializer::PermuteDescriptor> descriptor) {
    fbb_.AddOffset(PermuteLayer::VT_DESCRIPTOR, descriptor);
  }
  explicit PermuteLayerBuilder(flatbuffers::FlatBufferBuilder &_fbb)
        : fbb_(_fbb) {
    start_ = fbb_.StartTable();
  }
  PermuteLayerBuilder &operator=(const PermuteLayerBuilder &);
  flatbuffers::Offset<PermuteLayer> Finish() {
    const auto end = fbb_.EndTable(start_);
    auto o = flatbuffers::Offset<PermuteLayer>(end);
    return o;
  }
};

inline flatbuffers::Offset<PermuteLayer> CreatePermuteLayer(
    flatbuffers::FlatBufferBuilder &_fbb,
    flatbuffers::Offset<armnnSerializer::LayerBase> base = 0,
    flatbuffers::Offset<armnnSerializer::PermuteDescriptor> descriptor = 0) {
  PermuteLayerBuilder builder_(_fbb);
  builder_.add_descriptor(descriptor);
  builder_.add_base(base);
  return builder_.Finish();
}

struct PermuteDescriptor FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
  typedef PermuteDescriptorBuilder Builder;
  enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
    VT_DIMMAPPINGS = 4
  };
  const flatbuffers::Vector<uint32_t> *dimMappings() const {
    return GetPointer<const flatbuffers::Vector<uint32_t> *>(VT_DIMMAPPINGS);
  }
  bool Verify(flatbuffers::Verifier &verifier) const {
    return VerifyTableStart(verifier) &&
           VerifyOffset(verifier, VT_DIMMAPPINGS) &&
           verifier.VerifyVector(dimMappings()) &&
           verifier.EndTable();
  }
};

struct PermuteDescriptorBuilder {
  typedef PermuteDescriptor Table;
  flatbuffers::FlatBufferBuilder &fbb_;
  flatbuffers::uoffset_t start_;
  void add_dimMappings(flatbuffers::Offset<flatbuffers::Vector<uint32_t>> dimMappings) {
    fbb_.AddOffset(PermuteDescriptor::VT_DIMMAPPINGS, dimMappings);
  }
  explicit PermuteDescriptorBuilder(flatbuffers::FlatBufferBuilder &_fbb)
        : fbb_(_fbb) {
    start_ = fbb_.StartTable();
  }
  PermuteDescriptorBuilder &operator=(const PermuteDescriptorBuilder &);
  flatbuffers::Offset<PermuteDescriptor> Finish() {
    const auto end = fbb_.EndTable(start_);
    auto o = flatbuffers::Offset<PermuteDescriptor>(end);
    return o;
  }
};

inline flatbuffers::Offset<PermuteDescriptor> CreatePermuteDescriptor(
    flatbuffers::FlatBufferBuilder &_fbb,
    flatbuffers::Offset<flatbuffers::Vector<uint32_t>> dimMappings = 0) {
  PermuteDescriptorBuilder builder_(_fbb);
  builder_.add_dimMappings(dimMappings);
  return builder_.Finish();
}

inline flatbuffers::Offset<PermuteDescriptor> CreatePermuteDescriptorDirect(
    flatbuffers::FlatBufferBuilder &_fbb,
    const std::vector<uint32_t> *dimMappings = nullptr) {
  auto dimMappings__ = dimMappings ? _fbb.CreateVector<uint32_t>(*dimMappings) : 0;
  return armnnSerializer::CreatePermuteDescriptor(
      _fbb,
      dimMappings__);
}

struct ShapeLayer FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
  typedef ShapeLayerBuilder Builder;
  enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
    VT_BASE = 4
  };
  const armnnSerializer::LayerBase *base() const {
    return GetPointer<const armnnSerializer::LayerBase *>(VT_BASE);
  }
  bool Verify(flatbuffers::Verifier &verifier) const {
    return VerifyTableStart(verifier) &&
           VerifyOffset(verifier, VT_BASE) &&
           verifier.VerifyTable(base()) &&
           verifier.EndTable();
  }
};

struct ShapeLayerBuilder {
  typedef ShapeLayer Table;
  flatbuffers::FlatBufferBuilder &fbb_;
  flatbuffers::uoffset_t start_;
  void add_base(flatbuffers::Offset<armnnSerializer::LayerBase> base) {
    fbb_.AddOffset(ShapeLayer::VT_BASE, base);
  }
  explicit ShapeLayerBuilder(flatbuffers::FlatBufferBuilder &_fbb)
        : fbb_(_fbb) {
    start_ = fbb_.StartTable();
  }
  ShapeLayerBuilder &operator=(const ShapeLayerBuilder &);
  flatbuffers::Offset<ShapeLayer> Finish() {
    const auto end = fbb_.EndTable(start_);
    auto o = flatbuffers::Offset<ShapeLayer>(end);
    return o;
  }
};

inline flatbuffers::Offset<ShapeLayer> CreateShapeLayer(
    flatbuffers::FlatBufferBuilder &_fbb,
    flatbuffers::Offset<armnnSerializer::LayerBase> base = 0) {
  ShapeLayerBuilder builder_(_fbb);
  builder_.add_base(base);
  return builder_.Finish();
}

struct SpaceToBatchNdLayer FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
  typedef SpaceToBatchNdLayerBuilder Builder;
  enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
    VT_BASE = 4,
    VT_DESCRIPTOR = 6
  };
  const armnnSerializer::LayerBase *base() const {
    return GetPointer<const armnnSerializer::LayerBase *>(VT_BASE);
  }
  const armnnSerializer::SpaceToBatchNdDescriptor *descriptor() const {
    return GetPointer<const armnnSerializer::SpaceToBatchNdDescriptor *>(VT_DESCRIPTOR);
  }
  bool Verify(flatbuffers::Verifier &verifier) const {
    return VerifyTableStart(verifier) &&
           VerifyOffset(verifier, VT_BASE) &&
           verifier.VerifyTable(base()) &&
           VerifyOffset(verifier, VT_DESCRIPTOR) &&
           verifier.VerifyTable(descriptor()) &&
           verifier.EndTable();
  }
};

struct SpaceToBatchNdLayerBuilder {
  typedef SpaceToBatchNdLayer Table;
  flatbuffers::FlatBufferBuilder &fbb_;
  flatbuffers::uoffset_t start_;
  void add_base(flatbuffers::Offset<armnnSerializer::LayerBase> base) {
    fbb_.AddOffset(SpaceToBatchNdLayer::VT_BASE, base);
  }
  void add_descriptor(flatbuffers::Offset<armnnSerializer::SpaceToBatchNdDescriptor> descriptor) {
    fbb_.AddOffset(SpaceToBatchNdLayer::VT_DESCRIPTOR, descriptor);
  }
  explicit SpaceToBatchNdLayerBuilder(flatbuffers::FlatBufferBuilder &_fbb)
        : fbb_(_fbb) {
    start_ = fbb_.StartTable();
  }
  SpaceToBatchNdLayerBuilder &operator=(const SpaceToBatchNdLayerBuilder &);
  flatbuffers::Offset<SpaceToBatchNdLayer> Finish() {
    const auto end = fbb_.EndTable(start_);
    auto o = flatbuffers::Offset<SpaceToBatchNdLayer>(end);
    return o;
  }
};

inline flatbuffers::Offset<SpaceToBatchNdLayer> CreateSpaceToBatchNdLayer(
    flatbuffers::FlatBufferBuilder &_fbb,
    flatbuffers::Offset<armnnSerializer::LayerBase> base = 0,
    flatbuffers::Offset<armnnSerializer::SpaceToBatchNdDescriptor> descriptor = 0) {
  SpaceToBatchNdLayerBuilder builder_(_fbb);
  builder_.add_descriptor(descriptor);
  builder_.add_base(base);
  return builder_.Finish();
}

struct SpaceToBatchNdDescriptor FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
  typedef SpaceToBatchNdDescriptorBuilder Builder;
  enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
    VT_BLOCKSHAPE = 4,
    VT_PADLIST = 6,
    VT_DATALAYOUT = 8
  };
  const flatbuffers::Vector<uint32_t> *blockShape() const {
    return GetPointer<const flatbuffers::Vector<uint32_t> *>(VT_BLOCKSHAPE);
  }
  const flatbuffers::Vector<uint32_t> *padList() const {
    return GetPointer<const flatbuffers::Vector<uint32_t> *>(VT_PADLIST);
  }
  armnnSerializer::DataLayout dataLayout() const {
    return static_cast<armnnSerializer::DataLayout>(GetField<int8_t>(VT_DATALAYOUT, 0));
  }
  bool Verify(flatbuffers::Verifier &verifier) const {
    return VerifyTableStart(verifier) &&
           VerifyOffset(verifier, VT_BLOCKSHAPE) &&
           verifier.VerifyVector(blockShape()) &&
           VerifyOffset(verifier, VT_PADLIST) &&
           verifier.VerifyVector(padList()) &&
           VerifyField<int8_t>(verifier, VT_DATALAYOUT) &&
           verifier.EndTable();
  }
};

struct SpaceToBatchNdDescriptorBuilder {
  typedef SpaceToBatchNdDescriptor Table;
  flatbuffers::FlatBufferBuilder &fbb_;
  flatbuffers::uoffset_t start_;
  void add_blockShape(flatbuffers::Offset<flatbuffers::Vector<uint32_t>> blockShape) {
    fbb_.AddOffset(SpaceToBatchNdDescriptor::VT_BLOCKSHAPE, blockShape);
  }
  void add_padList(flatbuffers::Offset<flatbuffers::Vector<uint32_t>> padList) {
    fbb_.AddOffset(SpaceToBatchNdDescriptor::VT_PADLIST, padList);
  }
  void add_dataLayout(armnnSerializer::DataLayout dataLayout) {
    fbb_.AddElement<int8_t>(SpaceToBatchNdDescriptor::VT_DATALAYOUT, static_cast<int8_t>(dataLayout), 0);
  }
  explicit SpaceToBatchNdDescriptorBuilder(flatbuffers::FlatBufferBuilder &_fbb)
        : fbb_(_fbb) {
    start_ = fbb_.StartTable();
  }
  SpaceToBatchNdDescriptorBuilder &operator=(const SpaceToBatchNdDescriptorBuilder &);
  flatbuffers::Offset<SpaceToBatchNdDescriptor> Finish() {
    const auto end = fbb_.EndTable(start_);
    auto o = flatbuffers::Offset<SpaceToBatchNdDescriptor>(end);
    return o;
  }
};

inline flatbuffers::Offset<SpaceToBatchNdDescriptor> CreateSpaceToBatchNdDescriptor(
    flatbuffers::FlatBufferBuilder &_fbb,
    flatbuffers::Offset<flatbuffers::Vector<uint32_t>> blockShape = 0,
    flatbuffers::Offset<flatbuffers::Vector<uint32_t>> padList = 0,
    armnnSerializer::DataLayout dataLayout = armnnSerializer::DataLayout_NHWC) {
  SpaceToBatchNdDescriptorBuilder builder_(_fbb);
  builder_.add_padList(padList);
  builder_.add_blockShape(blockShape);
  builder_.add_dataLayout(dataLayout);
  return builder_.Finish();
}

inline flatbuffers::Offset<SpaceToBatchNdDescriptor> CreateSpaceToBatchNdDescriptorDirect(
    flatbuffers::FlatBufferBuilder &_fbb,
    const std::vector<uint32_t> *blockShape = nullptr,
    const std::vector<uint32_t> *padList = nullptr,
    armnnSerializer::DataLayout dataLayout = armnnSerializer::DataLayout_NHWC) {
  auto blockShape__ = blockShape ? _fbb.CreateVector<uint32_t>(*blockShape) : 0;
  auto padList__ = padList ? _fbb.CreateVector<uint32_t>(*padList) : 0;
  return armnnSerializer::CreateSpaceToBatchNdDescriptor(
      _fbb,
      blockShape__,
      padList__,
      dataLayout);
}

struct SpaceToDepthLayer FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
  typedef SpaceToDepthLayerBuilder Builder;
  enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
    VT_BASE = 4,
    VT_DESCRIPTOR = 6
  };
  const armnnSerializer::LayerBase *base() const {
    return GetPointer<const armnnSerializer::LayerBase *>(VT_BASE);
  }
  const armnnSerializer::SpaceToDepthDescriptor *descriptor() const {
    return GetPointer<const armnnSerializer::SpaceToDepthDescriptor *>(VT_DESCRIPTOR);
  }
  bool Verify(flatbuffers::Verifier &verifier) const {
    return VerifyTableStart(verifier) &&
           VerifyOffset(verifier, VT_BASE) &&
           verifier.VerifyTable(base()) &&
           VerifyOffset(verifier, VT_DESCRIPTOR) &&
           verifier.VerifyTable(descriptor()) &&
           verifier.EndTable();
  }
};

struct SpaceToDepthLayerBuilder {
  typedef SpaceToDepthLayer Table;
  flatbuffers::FlatBufferBuilder &fbb_;
  flatbuffers::uoffset_t start_;
  void add_base(flatbuffers::Offset<armnnSerializer::LayerBase> base) {
    fbb_.AddOffset(SpaceToDepthLayer::VT_BASE, base);
  }
  void add_descriptor(flatbuffers::Offset<armnnSerializer::SpaceToDepthDescriptor> descriptor) {
    fbb_.AddOffset(SpaceToDepthLayer::VT_DESCRIPTOR, descriptor);
  }
  explicit SpaceToDepthLayerBuilder(flatbuffers::FlatBufferBuilder &_fbb)
        : fbb_(_fbb) {
    start_ = fbb_.StartTable();
  }
  SpaceToDepthLayerBuilder &operator=(const SpaceToDepthLayerBuilder &);
  flatbuffers::Offset<SpaceToDepthLayer> Finish() {
    const auto end = fbb_.EndTable(start_);
    auto o = flatbuffers::Offset<SpaceToDepthLayer>(end);
    return o;
  }
};

inline flatbuffers::Offset<SpaceToDepthLayer> CreateSpaceToDepthLayer(
    flatbuffers::FlatBufferBuilder &_fbb,
    flatbuffers::Offset<armnnSerializer::LayerBase> base = 0,
    flatbuffers::Offset<armnnSerializer::SpaceToDepthDescriptor> descriptor = 0) {
  SpaceToDepthLayerBuilder builder_(_fbb);
  builder_.add_descriptor(descriptor);
  builder_.add_base(base);
  return builder_.Finish();
}

struct SpaceToDepthDescriptor FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
  typedef SpaceToDepthDescriptorBuilder Builder;
  enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
    VT_BLOCKSIZE = 4,
    VT_DATALAYOUT = 6
  };
  uint32_t blockSize() const {
    return GetField<uint32_t>(VT_BLOCKSIZE, 0);
  }
  armnnSerializer::DataLayout dataLayout() const {
    return static_cast<armnnSerializer::DataLayout>(GetField<int8_t>(VT_DATALAYOUT, 0));
  }
  bool Verify(flatbuffers::Verifier &verifier) const {
    return VerifyTableStart(verifier) &&
           VerifyField<uint32_t>(verifier, VT_BLOCKSIZE) &&
           VerifyField<int8_t>(verifier, VT_DATALAYOUT) &&
           verifier.EndTable();
  }
};

struct SpaceToDepthDescriptorBuilder {
  typedef SpaceToDepthDescriptor Table;
  flatbuffers::FlatBufferBuilder &fbb_;
  flatbuffers::uoffset_t start_;
  void add_blockSize(uint32_t blockSize) {
    fbb_.AddElement<uint32_t>(SpaceToDepthDescriptor::VT_BLOCKSIZE, blockSize, 0);
  }
  void add_dataLayout(armnnSerializer::DataLayout dataLayout) {
    fbb_.AddElement<int8_t>(SpaceToDepthDescriptor::VT_DATALAYOUT, static_cast<int8_t>(dataLayout), 0);
  }
  explicit SpaceToDepthDescriptorBuilder(flatbuffers::FlatBufferBuilder &_fbb)
        : fbb_(_fbb) {
    start_ = fbb_.StartTable();
  }
  SpaceToDepthDescriptorBuilder &operator=(const SpaceToDepthDescriptorBuilder &);
  flatbuffers::Offset<SpaceToDepthDescriptor> Finish() {
    const auto end = fbb_.EndTable(start_);
    auto o = flatbuffers::Offset<SpaceToDepthDescriptor>(end);
    return o;
  }
};

inline flatbuffers::Offset<SpaceToDepthDescriptor> CreateSpaceToDepthDescriptor(
    flatbuffers::FlatBufferBuilder &_fbb,
    uint32_t blockSize = 0,
    armnnSerializer::DataLayout dataLayout = armnnSerializer::DataLayout_NHWC) {
  SpaceToDepthDescriptorBuilder builder_(_fbb);
  builder_.add_blockSize(blockSize);
  builder_.add_dataLayout(dataLayout);
  return builder_.Finish();
}

struct SubtractionLayer FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
  typedef SubtractionLayerBuilder Builder;
  enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
    VT_BASE = 4
  };
  const armnnSerializer::LayerBase *base() const {
    return GetPointer<const armnnSerializer::LayerBase *>(VT_BASE);
  }
  bool Verify(flatbuffers::Verifier &verifier) const {
    return VerifyTableStart(verifier) &&
           VerifyOffset(verifier, VT_BASE) &&
           verifier.VerifyTable(base()) &&
           verifier.EndTable();
  }
};

struct SubtractionLayerBuilder {
  typedef SubtractionLayer Table;
  flatbuffers::FlatBufferBuilder &fbb_;
  flatbuffers::uoffset_t start_;
  void add_base(flatbuffers::Offset<armnnSerializer::LayerBase> base) {
    fbb_.AddOffset(SubtractionLayer::VT_BASE, base);
  }
  explicit SubtractionLayerBuilder(flatbuffers::FlatBufferBuilder &_fbb)
        : fbb_(_fbb) {
    start_ = fbb_.StartTable();
  }
  SubtractionLayerBuilder &operator=(const SubtractionLayerBuilder &);
  flatbuffers::Offset<SubtractionLayer> Finish() {
    const auto end = fbb_.EndTable(start_);
    auto o = flatbuffers::Offset<SubtractionLayer>(end);
    return o;
  }
};

inline flatbuffers::Offset<SubtractionLayer> CreateSubtractionLayer(
    flatbuffers::FlatBufferBuilder &_fbb,
    flatbuffers::Offset<armnnSerializer::LayerBase> base = 0) {
  SubtractionLayerBuilder builder_(_fbb);
  builder_.add_base(base);
  return builder_.Finish();
}

struct BatchToSpaceNdLayer FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
  typedef BatchToSpaceNdLayerBuilder Builder;
  enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
    VT_BASE = 4,
    VT_DESCRIPTOR = 6
  };
  const armnnSerializer::LayerBase *base() const {
    return GetPointer<const armnnSerializer::LayerBase *>(VT_BASE);
  }
  const armnnSerializer::BatchToSpaceNdDescriptor *descriptor() const {
    return GetPointer<const armnnSerializer::BatchToSpaceNdDescriptor *>(VT_DESCRIPTOR);
  }
  bool Verify(flatbuffers::Verifier &verifier) const {
    return VerifyTableStart(verifier) &&
           VerifyOffset(verifier, VT_BASE) &&
           verifier.VerifyTable(base()) &&
           VerifyOffset(verifier, VT_DESCRIPTOR) &&
           verifier.VerifyTable(descriptor()) &&
           verifier.EndTable();
  }
};

struct BatchToSpaceNdLayerBuilder {
  typedef BatchToSpaceNdLayer Table;
  flatbuffers::FlatBufferBuilder &fbb_;
  flatbuffers::uoffset_t start_;
  void add_base(flatbuffers::Offset<armnnSerializer::LayerBase> base) {
    fbb_.AddOffset(BatchToSpaceNdLayer::VT_BASE, base);
  }
  void add_descriptor(flatbuffers::Offset<armnnSerializer::BatchToSpaceNdDescriptor> descriptor) {
    fbb_.AddOffset(BatchToSpaceNdLayer::VT_DESCRIPTOR, descriptor);
  }
  explicit BatchToSpaceNdLayerBuilder(flatbuffers::FlatBufferBuilder &_fbb)
        : fbb_(_fbb) {
    start_ = fbb_.StartTable();
  }
  BatchToSpaceNdLayerBuilder &operator=(const BatchToSpaceNdLayerBuilder &);
  flatbuffers::Offset<BatchToSpaceNdLayer> Finish() {
    const auto end = fbb_.EndTable(start_);
    auto o = flatbuffers::Offset<BatchToSpaceNdLayer>(end);
    return o;
  }
};

inline flatbuffers::Offset<BatchToSpaceNdLayer> CreateBatchToSpaceNdLayer(
    flatbuffers::FlatBufferBuilder &_fbb,
    flatbuffers::Offset<armnnSerializer::LayerBase> base = 0,
    flatbuffers::Offset<armnnSerializer::BatchToSpaceNdDescriptor> descriptor = 0) {
  BatchToSpaceNdLayerBuilder builder_(_fbb);
  builder_.add_descriptor(descriptor);
  builder_.add_base(base);
  return builder_.Finish();
}

struct BatchToSpaceNdDescriptor FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
  typedef BatchToSpaceNdDescriptorBuilder Builder;
  enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
    VT_BLOCKSHAPE = 4,
    VT_CROPS = 6,
    VT_DATALAYOUT = 8
  };
  const flatbuffers::Vector<uint32_t> *blockShape() const {
    return GetPointer<const flatbuffers::Vector<uint32_t> *>(VT_BLOCKSHAPE);
  }
  const flatbuffers::Vector<uint32_t> *crops() const {
    return GetPointer<const flatbuffers::Vector<uint32_t> *>(VT_CROPS);
  }
  armnnSerializer::DataLayout dataLayout() const {
    return static_cast<armnnSerializer::DataLayout>(GetField<int8_t>(VT_DATALAYOUT, 0));
  }
  bool Verify(flatbuffers::Verifier &verifier) const {
    return VerifyTableStart(verifier) &&
           VerifyOffset(verifier, VT_BLOCKSHAPE) &&
           verifier.VerifyVector(blockShape()) &&
           VerifyOffset(verifier, VT_CROPS) &&
           verifier.VerifyVector(crops()) &&
           VerifyField<int8_t>(verifier, VT_DATALAYOUT) &&
           verifier.EndTable();
  }
};

struct BatchToSpaceNdDescriptorBuilder {
  typedef BatchToSpaceNdDescriptor Table;
  flatbuffers::FlatBufferBuilder &fbb_;
  flatbuffers::uoffset_t start_;
  void add_blockShape(flatbuffers::Offset<flatbuffers::Vector<uint32_t>> blockShape) {
    fbb_.AddOffset(BatchToSpaceNdDescriptor::VT_BLOCKSHAPE, blockShape);
  }
  void add_crops(flatbuffers::Offset<flatbuffers::Vector<uint32_t>> crops) {
    fbb_.AddOffset(BatchToSpaceNdDescriptor::VT_CROPS, crops);
  }
  void add_dataLayout(armnnSerializer::DataLayout dataLayout) {
    fbb_.AddElement<int8_t>(BatchToSpaceNdDescriptor::VT_DATALAYOUT, static_cast<int8_t>(dataLayout), 0);
  }
  explicit BatchToSpaceNdDescriptorBuilder(flatbuffers::FlatBufferBuilder &_fbb)
        : fbb_(_fbb) {
    start_ = fbb_.StartTable();
  }
  BatchToSpaceNdDescriptorBuilder &operator=(const BatchToSpaceNdDescriptorBuilder &);
  flatbuffers::Offset<BatchToSpaceNdDescriptor> Finish() {
    const auto end = fbb_.EndTable(start_);
    auto o = flatbuffers::Offset<BatchToSpaceNdDescriptor>(end);
    return o;
  }
};

inline flatbuffers::Offset<BatchToSpaceNdDescriptor> CreateBatchToSpaceNdDescriptor(
    flatbuffers::FlatBufferBuilder &_fbb,
    flatbuffers::Offset<flatbuffers::Vector<uint32_t>> blockShape = 0,
    flatbuffers::Offset<flatbuffers::Vector<uint32_t>> crops = 0,
    armnnSerializer::DataLayout dataLayout = armnnSerializer::DataLayout_NHWC) {
  BatchToSpaceNdDescriptorBuilder builder_(_fbb);
  builder_.add_crops(crops);
  builder_.add_blockShape(blockShape);
  builder_.add_dataLayout(dataLayout);
  return builder_.Finish();
}

inline flatbuffers::Offset<BatchToSpaceNdDescriptor> CreateBatchToSpaceNdDescriptorDirect(
    flatbuffers::FlatBufferBuilder &_fbb,
    const std::vector<uint32_t> *blockShape = nullptr,
    const std::vector<uint32_t> *crops = nullptr,
    armnnSerializer::DataLayout dataLayout = armnnSerializer::DataLayout_NHWC) {
  auto blockShape__ = blockShape ? _fbb.CreateVector<uint32_t>(*blockShape) : 0;
  auto crops__ = crops ? _fbb.CreateVector<uint32_t>(*crops) : 0;
  return armnnSerializer::CreateBatchToSpaceNdDescriptor(
      _fbb,
      blockShape__,
      crops__,
      dataLayout);
}

struct NormalizationLayer FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
  typedef NormalizationLayerBuilder Builder;
  enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
    VT_BASE = 4,
    VT_DESCRIPTOR = 6
  };
  const armnnSerializer::LayerBase *base() const {
    return GetPointer<const armnnSerializer::LayerBase *>(VT_BASE);
  }
  const armnnSerializer::NormalizationDescriptor *descriptor() const {
    return GetPointer<const armnnSerializer::NormalizationDescriptor *>(VT_DESCRIPTOR);
  }
  bool Verify(flatbuffers::Verifier &verifier) const {
    return VerifyTableStart(verifier) &&
           VerifyOffset(verifier, VT_BASE) &&
           verifier.VerifyTable(base()) &&
           VerifyOffset(verifier, VT_DESCRIPTOR) &&
           verifier.VerifyTable(descriptor()) &&
           verifier.EndTable();
  }
};

struct NormalizationLayerBuilder {
  typedef NormalizationLayer Table;
  flatbuffers::FlatBufferBuilder &fbb_;
  flatbuffers::uoffset_t start_;
  void add_base(flatbuffers::Offset<armnnSerializer::LayerBase> base) {
    fbb_.AddOffset(NormalizationLayer::VT_BASE, base);
  }
  void add_descriptor(flatbuffers::Offset<armnnSerializer::NormalizationDescriptor> descriptor) {
    fbb_.AddOffset(NormalizationLayer::VT_DESCRIPTOR, descriptor);
  }
  explicit NormalizationLayerBuilder(flatbuffers::FlatBufferBuilder &_fbb)
        : fbb_(_fbb) {
    start_ = fbb_.StartTable();
  }
  NormalizationLayerBuilder &operator=(const NormalizationLayerBuilder &);
  flatbuffers::Offset<NormalizationLayer> Finish() {
    const auto end = fbb_.EndTable(start_);
    auto o = flatbuffers::Offset<NormalizationLayer>(end);
    return o;
  }
};

inline flatbuffers::Offset<NormalizationLayer> CreateNormalizationLayer(
    flatbuffers::FlatBufferBuilder &_fbb,
    flatbuffers::Offset<armnnSerializer::LayerBase> base = 0,
    flatbuffers::Offset<armnnSerializer::NormalizationDescriptor> descriptor = 0) {
  NormalizationLayerBuilder builder_(_fbb);
  builder_.add_descriptor(descriptor);
  builder_.add_base(base);
  return builder_.Finish();
}

struct NormalizationDescriptor FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
  typedef NormalizationDescriptorBuilder Builder;
  enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
    VT_NORMCHANNELTYPE = 4,
    VT_NORMMETHODTYPE = 6,
    VT_NORMSIZE = 8,
    VT_ALPHA = 10,
    VT_BETA = 12,
    VT_K = 14,
    VT_DATALAYOUT = 16
  };
  armnnSerializer::NormalizationAlgorithmChannel normChannelType() const {
    return static_cast<armnnSerializer::NormalizationAlgorithmChannel>(GetField<int8_t>(VT_NORMCHANNELTYPE, 0));
  }
  armnnSerializer::NormalizationAlgorithmMethod normMethodType() const {
    return static_cast<armnnSerializer::NormalizationAlgorithmMethod>(GetField<int8_t>(VT_NORMMETHODTYPE, 0));
  }
  uint32_t normSize() const {
    return GetField<uint32_t>(VT_NORMSIZE, 0);
  }
  float alpha() const {
    return GetField<float>(VT_ALPHA, 0.0f);
  }
  float beta() const {
    return GetField<float>(VT_BETA, 0.0f);
  }
  float k() const {
    return GetField<float>(VT_K, 0.0f);
  }
  armnnSerializer::DataLayout dataLayout() const {
    return static_cast<armnnSerializer::DataLayout>(GetField<int8_t>(VT_DATALAYOUT, 1));
  }
  bool Verify(flatbuffers::Verifier &verifier) const {
    return VerifyTableStart(verifier) &&
           VerifyField<int8_t>(verifier, VT_NORMCHANNELTYPE) &&
           VerifyField<int8_t>(verifier, VT_NORMMETHODTYPE) &&
           VerifyField<uint32_t>(verifier, VT_NORMSIZE) &&
           VerifyField<float>(verifier, VT_ALPHA) &&
           VerifyField<float>(verifier, VT_BETA) &&
           VerifyField<float>(verifier, VT_K) &&
           VerifyField<int8_t>(verifier, VT_DATALAYOUT) &&
           verifier.EndTable();
  }
};

struct NormalizationDescriptorBuilder {
  typedef NormalizationDescriptor Table;
  flatbuffers::FlatBufferBuilder &fbb_;
  flatbuffers::uoffset_t start_;
  void add_normChannelType(armnnSerializer::NormalizationAlgorithmChannel normChannelType) {
    fbb_.AddElement<int8_t>(NormalizationDescriptor::VT_NORMCHANNELTYPE, static_cast<int8_t>(normChannelType), 0);
  }
  void add_normMethodType(armnnSerializer::NormalizationAlgorithmMethod normMethodType) {
    fbb_.AddElement<int8_t>(NormalizationDescriptor::VT_NORMMETHODTYPE, static_cast<int8_t>(normMethodType), 0);
  }
  void add_normSize(uint32_t normSize) {
    fbb_.AddElement<uint32_t>(NormalizationDescriptor::VT_NORMSIZE, normSize, 0);
  }
  void add_alpha(float alpha) {
    fbb_.AddElement<float>(NormalizationDescriptor::VT_ALPHA, alpha, 0.0f);
  }
  void add_beta(float beta) {
    fbb_.AddElement<float>(NormalizationDescriptor::VT_BETA, beta, 0.0f);
  }
  void add_k(float k) {
    fbb_.AddElement<float>(NormalizationDescriptor::VT_K, k, 0.0f);
  }
  void add_dataLayout(armnnSerializer::DataLayout dataLayout) {
    fbb_.AddElement<int8_t>(NormalizationDescriptor::VT_DATALAYOUT, static_cast<int8_t>(dataLayout), 1);
  }
  explicit NormalizationDescriptorBuilder(flatbuffers::FlatBufferBuilder &_fbb)
        : fbb_(_fbb) {
    start_ = fbb_.StartTable();
  }
  NormalizationDescriptorBuilder &operator=(const NormalizationDescriptorBuilder &);
  flatbuffers::Offset<NormalizationDescriptor> Finish() {
    const auto end = fbb_.EndTable(start_);
    auto o = flatbuffers::Offset<NormalizationDescriptor>(end);
    return o;
  }
};

inline flatbuffers::Offset<NormalizationDescriptor> CreateNormalizationDescriptor(
    flatbuffers::FlatBufferBuilder &_fbb,
    armnnSerializer::NormalizationAlgorithmChannel normChannelType = armnnSerializer::NormalizationAlgorithmChannel_Across,
    armnnSerializer::NormalizationAlgorithmMethod normMethodType = armnnSerializer::NormalizationAlgorithmMethod_LocalBrightness,
    uint32_t normSize = 0,
    float alpha = 0.0f,
    float beta = 0.0f,
    float k = 0.0f,
    armnnSerializer::DataLayout dataLayout = armnnSerializer::DataLayout_NCHW) {
  NormalizationDescriptorBuilder builder_(_fbb);
  builder_.add_k(k);
  builder_.add_beta(beta);
  builder_.add_alpha(alpha);
  builder_.add_normSize(normSize);
  builder_.add_dataLayout(dataLayout);
  builder_.add_normMethodType(normMethodType);
  builder_.add_normChannelType(normChannelType);
  return builder_.Finish();
}

struct MeanLayer FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
  typedef MeanLayerBuilder Builder;
  enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
    VT_BASE = 4,
    VT_DESCRIPTOR = 6
  };
  const armnnSerializer::LayerBase *base() const {
    return GetPointer<const armnnSerializer::LayerBase *>(VT_BASE);
  }
  const armnnSerializer::MeanDescriptor *descriptor() const {
    return GetPointer<const armnnSerializer::MeanDescriptor *>(VT_DESCRIPTOR);
  }
  bool Verify(flatbuffers::Verifier &verifier) const {
    return VerifyTableStart(verifier) &&
           VerifyOffset(verifier, VT_BASE) &&
           verifier.VerifyTable(base()) &&
           VerifyOffset(verifier, VT_DESCRIPTOR) &&
           verifier.VerifyTable(descriptor()) &&
           verifier.EndTable();
  }
};

struct MeanLayerBuilder {
  typedef MeanLayer Table;
  flatbuffers::FlatBufferBuilder &fbb_;
  flatbuffers::uoffset_t start_;
  void add_base(flatbuffers::Offset<armnnSerializer::LayerBase> base) {
    fbb_.AddOffset(MeanLayer::VT_BASE, base);
  }
  void add_descriptor(flatbuffers::Offset<armnnSerializer::MeanDescriptor> descriptor) {
    fbb_.AddOffset(MeanLayer::VT_DESCRIPTOR, descriptor);
  }
  explicit MeanLayerBuilder(flatbuffers::FlatBufferBuilder &_fbb)
        : fbb_(_fbb) {
    start_ = fbb_.StartTable();
  }
  MeanLayerBuilder &operator=(const MeanLayerBuilder &);
  flatbuffers::Offset<MeanLayer> Finish() {
    const auto end = fbb_.EndTable(start_);
    auto o = flatbuffers::Offset<MeanLayer>(end);
    return o;
  }
};

inline flatbuffers::Offset<MeanLayer> CreateMeanLayer(
    flatbuffers::FlatBufferBuilder &_fbb,
    flatbuffers::Offset<armnnSerializer::LayerBase> base = 0,
    flatbuffers::Offset<armnnSerializer::MeanDescriptor> descriptor = 0) {
  MeanLayerBuilder builder_(_fbb);
  builder_.add_descriptor(descriptor);
  builder_.add_base(base);
  return builder_.Finish();
}

struct MeanDescriptor FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
  typedef MeanDescriptorBuilder Builder;
  enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
    VT_AXIS = 4,
    VT_KEEPDIMS = 6
  };
  const flatbuffers::Vector<uint32_t> *axis() const {
    return GetPointer<const flatbuffers::Vector<uint32_t> *>(VT_AXIS);
  }
  bool keepDims() const {
    return GetField<uint8_t>(VT_KEEPDIMS, 0) != 0;
  }
  bool Verify(flatbuffers::Verifier &verifier) const {
    return VerifyTableStart(verifier) &&
           VerifyOffset(verifier, VT_AXIS) &&
           verifier.VerifyVector(axis()) &&
           VerifyField<uint8_t>(verifier, VT_KEEPDIMS) &&
           verifier.EndTable();
  }
};

struct MeanDescriptorBuilder {
  typedef MeanDescriptor Table;
  flatbuffers::FlatBufferBuilder &fbb_;
  flatbuffers::uoffset_t start_;
  void add_axis(flatbuffers::Offset<flatbuffers::Vector<uint32_t>> axis) {
    fbb_.AddOffset(MeanDescriptor::VT_AXIS, axis);
  }
  void add_keepDims(bool keepDims) {
    fbb_.AddElement<uint8_t>(MeanDescriptor::VT_KEEPDIMS, static_cast<uint8_t>(keepDims), 0);
  }
  explicit MeanDescriptorBuilder(flatbuffers::FlatBufferBuilder &_fbb)
        : fbb_(_fbb) {
    start_ = fbb_.StartTable();
  }
  MeanDescriptorBuilder &operator=(const MeanDescriptorBuilder &);
  flatbuffers::Offset<MeanDescriptor> Finish() {
    const auto end = fbb_.EndTable(start_);
    auto o = flatbuffers::Offset<MeanDescriptor>(end);
    return o;
  }
};

inline flatbuffers::Offset<MeanDescriptor> CreateMeanDescriptor(
    flatbuffers::FlatBufferBuilder &_fbb,
    flatbuffers::Offset<flatbuffers::Vector<uint32_t>> axis = 0,
    bool keepDims = false) {
  MeanDescriptorBuilder builder_(_fbb);
  builder_.add_axis(axis);
  builder_.add_keepDims(keepDims);
  return builder_.Finish();
}

inline flatbuffers::Offset<MeanDescriptor> CreateMeanDescriptorDirect(
    flatbuffers::FlatBufferBuilder &_fbb,
    const std::vector<uint32_t> *axis = nullptr,
    bool keepDims = false) {
  auto axis__ = axis ? _fbb.CreateVector<uint32_t>(*axis) : 0;
  return armnnSerializer::CreateMeanDescriptor(
      _fbb,
      axis__,
      keepDims);
}

struct PadLayer FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
  typedef PadLayerBuilder Builder;
  enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
    VT_BASE = 4,
    VT_DESCRIPTOR = 6
  };
  const armnnSerializer::LayerBase *base() const {
    return GetPointer<const armnnSerializer::LayerBase *>(VT_BASE);
  }
  const armnnSerializer::PadDescriptor *descriptor() const {
    return GetPointer<const armnnSerializer::PadDescriptor *>(VT_DESCRIPTOR);
  }
  bool Verify(flatbuffers::Verifier &verifier) const {
    return VerifyTableStart(verifier) &&
           VerifyOffset(verifier, VT_BASE) &&
           verifier.VerifyTable(base()) &&
           VerifyOffset(verifier, VT_DESCRIPTOR) &&
           verifier.VerifyTable(descriptor()) &&
           verifier.EndTable();
  }
};

struct PadLayerBuilder {
  typedef PadLayer Table;
  flatbuffers::FlatBufferBuilder &fbb_;
  flatbuffers::uoffset_t start_;
  void add_base(flatbuffers::Offset<armnnSerializer::LayerBase> base) {
    fbb_.AddOffset(PadLayer::VT_BASE, base);
  }
  void add_descriptor(flatbuffers::Offset<armnnSerializer::PadDescriptor> descriptor) {
    fbb_.AddOffset(PadLayer::VT_DESCRIPTOR, descriptor);
  }
  explicit PadLayerBuilder(flatbuffers::FlatBufferBuilder &_fbb)
        : fbb_(_fbb) {
    start_ = fbb_.StartTable();
  }
  PadLayerBuilder &operator=(const PadLayerBuilder &);
  flatbuffers::Offset<PadLayer> Finish() {
    const auto end = fbb_.EndTable(start_);
    auto o = flatbuffers::Offset<PadLayer>(end);
    return o;
  }
};

inline flatbuffers::Offset<PadLayer> CreatePadLayer(
    flatbuffers::FlatBufferBuilder &_fbb,
    flatbuffers::Offset<armnnSerializer::LayerBase> base = 0,
    flatbuffers::Offset<armnnSerializer::PadDescriptor> descriptor = 0) {
  PadLayerBuilder builder_(_fbb);
  builder_.add_descriptor(descriptor);
  builder_.add_base(base);
  return builder_.Finish();
}

struct PadDescriptor FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
  typedef PadDescriptorBuilder Builder;
  enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
    VT_PADLIST = 4,
    VT_PADVALUE = 6
  };
  const flatbuffers::Vector<uint32_t> *padList() const {
    return GetPointer<const flatbuffers::Vector<uint32_t> *>(VT_PADLIST);
  }
  float padValue() const {
    return GetField<float>(VT_PADVALUE, 0.0f);
  }
  bool Verify(flatbuffers::Verifier &verifier) const {
    return VerifyTableStart(verifier) &&
           VerifyOffset(verifier, VT_PADLIST) &&
           verifier.VerifyVector(padList()) &&
           VerifyField<float>(verifier, VT_PADVALUE) &&
           verifier.EndTable();
  }
};

struct PadDescriptorBuilder {
  typedef PadDescriptor Table;
  flatbuffers::FlatBufferBuilder &fbb_;
  flatbuffers::uoffset_t start_;
  void add_padList(flatbuffers::Offset<flatbuffers::Vector<uint32_t>> padList) {
    fbb_.AddOffset(PadDescriptor::VT_PADLIST, padList);
  }
  void add_padValue(float padValue) {
    fbb_.AddElement<float>(PadDescriptor::VT_PADVALUE, padValue, 0.0f);
  }
  explicit PadDescriptorBuilder(flatbuffers::FlatBufferBuilder &_fbb)
        : fbb_(_fbb) {
    start_ = fbb_.StartTable();
  }
  PadDescriptorBuilder &operator=(const PadDescriptorBuilder &);
  flatbuffers::Offset<PadDescriptor> Finish() {
    const auto end = fbb_.EndTable(start_);
    auto o = flatbuffers::Offset<PadDescriptor>(end);
    return o;
  }
};

inline flatbuffers::Offset<PadDescriptor> CreatePadDescriptor(
    flatbuffers::FlatBufferBuilder &_fbb,
    flatbuffers::Offset<flatbuffers::Vector<uint32_t>> padList = 0,
    float padValue = 0.0f) {
  PadDescriptorBuilder builder_(_fbb);
  builder_.add_padValue(padValue);
  builder_.add_padList(padList);
  return builder_.Finish();
}

inline flatbuffers::Offset<PadDescriptor> CreatePadDescriptorDirect(
    flatbuffers::FlatBufferBuilder &_fbb,
    const std::vector<uint32_t> *padList = nullptr,
    float padValue = 0.0f) {
  auto padList__ = padList ? _fbb.CreateVector<uint32_t>(*padList) : 0;
  return armnnSerializer::CreatePadDescriptor(
      _fbb,
      padList__,
      padValue);
}

/// @deprecated Use ElementwiseUnaryLayer instead
struct RsqrtLayer FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
  typedef RsqrtLayerBuilder Builder;
  enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
    VT_BASE = 4
  };
  const armnnSerializer::LayerBase *base() const {
    return GetPointer<const armnnSerializer::LayerBase *>(VT_BASE);
  }
  bool Verify(flatbuffers::Verifier &verifier) const {
    return VerifyTableStart(verifier) &&
           VerifyOffset(verifier, VT_BASE) &&
           verifier.VerifyTable(base()) &&
           verifier.EndTable();
  }
};

struct RsqrtLayerBuilder {
  typedef RsqrtLayer Table;
  flatbuffers::FlatBufferBuilder &fbb_;
  flatbuffers::uoffset_t start_;
  void add_base(flatbuffers::Offset<armnnSerializer::LayerBase> base) {
    fbb_.AddOffset(RsqrtLayer::VT_BASE, base);
  }
  explicit RsqrtLayerBuilder(flatbuffers::FlatBufferBuilder &_fbb)
        : fbb_(_fbb) {
    start_ = fbb_.StartTable();
  }
  RsqrtLayerBuilder &operator=(const RsqrtLayerBuilder &);
  flatbuffers::Offset<RsqrtLayer> Finish() {
    const auto end = fbb_.EndTable(start_);
    auto o = flatbuffers::Offset<RsqrtLayer>(end);
    return o;
  }
};

inline flatbuffers::Offset<RsqrtLayer> CreateRsqrtLayer(
    flatbuffers::FlatBufferBuilder &_fbb,
    flatbuffers::Offset<armnnSerializer::LayerBase> base = 0) {
  RsqrtLayerBuilder builder_(_fbb);
  builder_.add_base(base);
  return builder_.Finish();
}

struct BatchNormalizationLayer FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
  typedef BatchNormalizationLayerBuilder Builder;
  enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
    VT_BASE = 4,
    VT_DESCRIPTOR = 6,
    VT_MEAN = 8,
    VT_VARIANCE = 10,
    VT_BETA = 12,
    VT_GAMMA = 14
  };
  const armnnSerializer::LayerBase *base() const {
    return GetPointer<const armnnSerializer::LayerBase *>(VT_BASE);
  }
  const armnnSerializer::BatchNormalizationDescriptor *descriptor() const {
    return GetPointer<const armnnSerializer::BatchNormalizationDescriptor *>(VT_DESCRIPTOR);
  }
  const armnnSerializer::ConstTensor *mean() const {
    return GetPointer<const armnnSerializer::ConstTensor *>(VT_MEAN);
  }
  const armnnSerializer::ConstTensor *variance() const {
    return GetPointer<const armnnSerializer::ConstTensor *>(VT_VARIANCE);
  }
  const armnnSerializer::ConstTensor *beta() const {
    return GetPointer<const armnnSerializer::ConstTensor *>(VT_BETA);
  }
  const armnnSerializer::ConstTensor *gamma() const {
    return GetPointer<const armnnSerializer::ConstTensor *>(VT_GAMMA);
  }
  bool Verify(flatbuffers::Verifier &verifier) const {
    return VerifyTableStart(verifier) &&
           VerifyOffset(verifier, VT_BASE) &&
           verifier.VerifyTable(base()) &&
           VerifyOffset(verifier, VT_DESCRIPTOR) &&
           verifier.VerifyTable(descriptor()) &&
           VerifyOffset(verifier, VT_MEAN) &&
           verifier.VerifyTable(mean()) &&
           VerifyOffset(verifier, VT_VARIANCE) &&
           verifier.VerifyTable(variance()) &&
           VerifyOffset(verifier, VT_BETA) &&
           verifier.VerifyTable(beta()) &&
           VerifyOffset(verifier, VT_GAMMA) &&
           verifier.VerifyTable(gamma()) &&
           verifier.EndTable();
  }
};

struct BatchNormalizationLayerBuilder {
  typedef BatchNormalizationLayer Table;
  flatbuffers::FlatBufferBuilder &fbb_;
  flatbuffers::uoffset_t start_;
  void add_base(flatbuffers::Offset<armnnSerializer::LayerBase> base) {
    fbb_.AddOffset(BatchNormalizationLayer::VT_BASE, base);
  }
  void add_descriptor(flatbuffers::Offset<armnnSerializer::BatchNormalizationDescriptor> descriptor) {
    fbb_.AddOffset(BatchNormalizationLayer::VT_DESCRIPTOR, descriptor);
  }
  void add_mean(flatbuffers::Offset<armnnSerializer::ConstTensor> mean) {
    fbb_.AddOffset(BatchNormalizationLayer::VT_MEAN, mean);
  }
  void add_variance(flatbuffers::Offset<armnnSerializer::ConstTensor> variance) {
    fbb_.AddOffset(BatchNormalizationLayer::VT_VARIANCE, variance);
  }
  void add_beta(flatbuffers::Offset<armnnSerializer::ConstTensor> beta) {
    fbb_.AddOffset(BatchNormalizationLayer::VT_BETA, beta);
  }
  void add_gamma(flatbuffers::Offset<armnnSerializer::ConstTensor> gamma) {
    fbb_.AddOffset(BatchNormalizationLayer::VT_GAMMA, gamma);
  }
  explicit BatchNormalizationLayerBuilder(flatbuffers::FlatBufferBuilder &_fbb)
        : fbb_(_fbb) {
    start_ = fbb_.StartTable();
  }
  BatchNormalizationLayerBuilder &operator=(const BatchNormalizationLayerBuilder &);
  flatbuffers::Offset<BatchNormalizationLayer> Finish() {
    const auto end = fbb_.EndTable(start_);
    auto o = flatbuffers::Offset<BatchNormalizationLayer>(end);
    return o;
  }
};

inline flatbuffers::Offset<BatchNormalizationLayer> CreateBatchNormalizationLayer(
    flatbuffers::FlatBufferBuilder &_fbb,
    flatbuffers::Offset<armnnSerializer::LayerBase> base = 0,
    flatbuffers::Offset<armnnSerializer::BatchNormalizationDescriptor> descriptor = 0,
    flatbuffers::Offset<armnnSerializer::ConstTensor> mean = 0,
    flatbuffers::Offset<armnnSerializer::ConstTensor> variance = 0,
    flatbuffers::Offset<armnnSerializer::ConstTensor> beta = 0,
    flatbuffers::Offset<armnnSerializer::ConstTensor> gamma = 0) {
  BatchNormalizationLayerBuilder builder_(_fbb);
  builder_.add_gamma(gamma);
  builder_.add_beta(beta);
  builder_.add_variance(variance);
  builder_.add_mean(mean);
  builder_.add_descriptor(descriptor);
  builder_.add_base(base);
  return builder_.Finish();
}

struct BatchNormalizationDescriptor FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
  typedef BatchNormalizationDescriptorBuilder Builder;
  enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
    VT_EPS = 4,
    VT_DATALAYOUT = 6
  };
  float eps() const {
    return GetField<float>(VT_EPS, 0.0f);
  }
  armnnSerializer::DataLayout dataLayout() const {
    return static_cast<armnnSerializer::DataLayout>(GetField<int8_t>(VT_DATALAYOUT, 0));
  }
  bool Verify(flatbuffers::Verifier &verifier) const {
    return VerifyTableStart(verifier) &&
           VerifyField<float>(verifier, VT_EPS) &&
           VerifyField<int8_t>(verifier, VT_DATALAYOUT) &&
           verifier.EndTable();
  }
};

struct BatchNormalizationDescriptorBuilder {
  typedef BatchNormalizationDescriptor Table;
  flatbuffers::FlatBufferBuilder &fbb_;
  flatbuffers::uoffset_t start_;
  void add_eps(float eps) {
    fbb_.AddElement<float>(BatchNormalizationDescriptor::VT_EPS, eps, 0.0f);
  }
  void add_dataLayout(armnnSerializer::DataLayout dataLayout) {
    fbb_.AddElement<int8_t>(BatchNormalizationDescriptor::VT_DATALAYOUT, static_cast<int8_t>(dataLayout), 0);
  }
  explicit BatchNormalizationDescriptorBuilder(flatbuffers::FlatBufferBuilder &_fbb)
        : fbb_(_fbb) {
    start_ = fbb_.StartTable();
  }
  BatchNormalizationDescriptorBuilder &operator=(const BatchNormalizationDescriptorBuilder &);
  flatbuffers::Offset<BatchNormalizationDescriptor> Finish() {
    const auto end = fbb_.EndTable(start_);
    auto o = flatbuffers::Offset<BatchNormalizationDescriptor>(end);
    return o;
  }
};

inline flatbuffers::Offset<BatchNormalizationDescriptor> CreateBatchNormalizationDescriptor(
    flatbuffers::FlatBufferBuilder &_fbb,
    float eps = 0.0f,
    armnnSerializer::DataLayout dataLayout = armnnSerializer::DataLayout_NHWC) {
  BatchNormalizationDescriptorBuilder builder_(_fbb);
  builder_.add_eps(eps);
  builder_.add_dataLayout(dataLayout);
  return builder_.Finish();
}

/// @deprecated Use ResizeLayer instead
struct ResizeBilinearLayer FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
  typedef ResizeBilinearLayerBuilder Builder;
  enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
    VT_BASE = 4,
    VT_DESCRIPTOR = 6
  };
  const armnnSerializer::LayerBase *base() const {
    return GetPointer<const armnnSerializer::LayerBase *>(VT_BASE);
  }
  const armnnSerializer::ResizeBilinearDescriptor *descriptor() const {
    return GetPointer<const armnnSerializer::ResizeBilinearDescriptor *>(VT_DESCRIPTOR);
  }
  bool Verify(flatbuffers::Verifier &verifier) const {
    return VerifyTableStart(verifier) &&
           VerifyOffset(verifier, VT_BASE) &&
           verifier.VerifyTable(base()) &&
           VerifyOffset(verifier, VT_DESCRIPTOR) &&
           verifier.VerifyTable(descriptor()) &&
           verifier.EndTable();
  }
};

struct ResizeBilinearLayerBuilder {
  typedef ResizeBilinearLayer Table;
  flatbuffers::FlatBufferBuilder &fbb_;
  flatbuffers::uoffset_t start_;
  void add_base(flatbuffers::Offset<armnnSerializer::LayerBase> base) {
    fbb_.AddOffset(ResizeBilinearLayer::VT_BASE, base);
  }
  void add_descriptor(flatbuffers::Offset<armnnSerializer::ResizeBilinearDescriptor> descriptor) {
    fbb_.AddOffset(ResizeBilinearLayer::VT_DESCRIPTOR, descriptor);
  }
  explicit ResizeBilinearLayerBuilder(flatbuffers::FlatBufferBuilder &_fbb)
        : fbb_(_fbb) {
    start_ = fbb_.StartTable();
  }
  ResizeBilinearLayerBuilder &operator=(const ResizeBilinearLayerBuilder &);
  flatbuffers::Offset<ResizeBilinearLayer> Finish() {
    const auto end = fbb_.EndTable(start_);
    auto o = flatbuffers::Offset<ResizeBilinearLayer>(end);
    return o;
  }
};

inline flatbuffers::Offset<ResizeBilinearLayer> CreateResizeBilinearLayer(
    flatbuffers::FlatBufferBuilder &_fbb,
    flatbuffers::Offset<armnnSerializer::LayerBase> base = 0,
    flatbuffers::Offset<armnnSerializer::ResizeBilinearDescriptor> descriptor = 0) {
  ResizeBilinearLayerBuilder builder_(_fbb);
  builder_.add_descriptor(descriptor);
  builder_.add_base(base);
  return builder_.Finish();
}

struct ResizeBilinearDescriptor FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
  typedef ResizeBilinearDescriptorBuilder Builder;
  enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
    VT_TARGETWIDTH = 4,
    VT_TARGETHEIGHT = 6,
    VT_DATALAYOUT = 8,
    VT_ALIGNCORNERS = 10,
    VT_HALFPIXELCENTERS = 12
  };
  uint32_t targetWidth() const {
    return GetField<uint32_t>(VT_TARGETWIDTH, 0);
  }
  uint32_t targetHeight() const {
    return GetField<uint32_t>(VT_TARGETHEIGHT, 0);
  }
  armnnSerializer::DataLayout dataLayout() const {
    return static_cast<armnnSerializer::DataLayout>(GetField<int8_t>(VT_DATALAYOUT, 0));
  }
  bool alignCorners() const {
    return GetField<uint8_t>(VT_ALIGNCORNERS, 0) != 0;
  }
  bool halfPixelCenters() const {
    return GetField<uint8_t>(VT_HALFPIXELCENTERS, 0) != 0;
  }
  bool Verify(flatbuffers::Verifier &verifier) const {
    return VerifyTableStart(verifier) &&
           VerifyField<uint32_t>(verifier, VT_TARGETWIDTH) &&
           VerifyField<uint32_t>(verifier, VT_TARGETHEIGHT) &&
           VerifyField<int8_t>(verifier, VT_DATALAYOUT) &&
           VerifyField<uint8_t>(verifier, VT_ALIGNCORNERS) &&
           VerifyField<uint8_t>(verifier, VT_HALFPIXELCENTERS) &&
           verifier.EndTable();
  }
};

struct ResizeBilinearDescriptorBuilder {
  typedef ResizeBilinearDescriptor Table;
  flatbuffers::FlatBufferBuilder &fbb_;
  flatbuffers::uoffset_t start_;
  void add_targetWidth(uint32_t targetWidth) {
    fbb_.AddElement<uint32_t>(ResizeBilinearDescriptor::VT_TARGETWIDTH, targetWidth, 0);
  }
  void add_targetHeight(uint32_t targetHeight) {
    fbb_.AddElement<uint32_t>(ResizeBilinearDescriptor::VT_TARGETHEIGHT, targetHeight, 0);
  }
  void add_dataLayout(armnnSerializer::DataLayout dataLayout) {
    fbb_.AddElement<int8_t>(ResizeBilinearDescriptor::VT_DATALAYOUT, static_cast<int8_t>(dataLayout), 0);
  }
  void add_alignCorners(bool alignCorners) {
    fbb_.AddElement<uint8_t>(ResizeBilinearDescriptor::VT_ALIGNCORNERS, static_cast<uint8_t>(alignCorners), 0);
  }
  void add_halfPixelCenters(bool halfPixelCenters) {
    fbb_.AddElement<uint8_t>(ResizeBilinearDescriptor::VT_HALFPIXELCENTERS, static_cast<uint8_t>(halfPixelCenters), 0);
  }
  explicit ResizeBilinearDescriptorBuilder(flatbuffers::FlatBufferBuilder &_fbb)
        : fbb_(_fbb) {
    start_ = fbb_.StartTable();
  }
  ResizeBilinearDescriptorBuilder &operator=(const ResizeBilinearDescriptorBuilder &);
  flatbuffers::Offset<ResizeBilinearDescriptor> Finish() {
    const auto end = fbb_.EndTable(start_);
    auto o = flatbuffers::Offset<ResizeBilinearDescriptor>(end);
    return o;
  }
};

inline flatbuffers::Offset<ResizeBilinearDescriptor> CreateResizeBilinearDescriptor(
    flatbuffers::FlatBufferBuilder &_fbb,
    uint32_t targetWidth = 0,
    uint32_t targetHeight = 0,
    armnnSerializer::DataLayout dataLayout = armnnSerializer::DataLayout_NHWC,
    bool alignCorners = false,
    bool halfPixelCenters = false) {
  ResizeBilinearDescriptorBuilder builder_(_fbb);
  builder_.add_targetHeight(targetHeight);
  builder_.add_targetWidth(targetWidth);
  builder_.add_halfPixelCenters(halfPixelCenters);
  builder_.add_alignCorners(alignCorners);
  builder_.add_dataLayout(dataLayout);
  return builder_.Finish();
}

struct SliceLayer FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
  typedef SliceLayerBuilder Builder;
  enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
    VT_BASE = 4,
    VT_DESCRIPTOR = 6
  };
  const armnnSerializer::LayerBase *base() const {
    return GetPointer<const armnnSerializer::LayerBase *>(VT_BASE);
  }
  const armnnSerializer::SliceDescriptor *descriptor() const {
    return GetPointer<const armnnSerializer::SliceDescriptor *>(VT_DESCRIPTOR);
  }
  bool Verify(flatbuffers::Verifier &verifier) const {
    return VerifyTableStart(verifier) &&
           VerifyOffset(verifier, VT_BASE) &&
           verifier.VerifyTable(base()) &&
           VerifyOffset(verifier, VT_DESCRIPTOR) &&
           verifier.VerifyTable(descriptor()) &&
           verifier.EndTable();
  }
};

struct SliceLayerBuilder {
  typedef SliceLayer Table;
  flatbuffers::FlatBufferBuilder &fbb_;
  flatbuffers::uoffset_t start_;
  void add_base(flatbuffers::Offset<armnnSerializer::LayerBase> base) {
    fbb_.AddOffset(SliceLayer::VT_BASE, base);
  }
  void add_descriptor(flatbuffers::Offset<armnnSerializer::SliceDescriptor> descriptor) {
    fbb_.AddOffset(SliceLayer::VT_DESCRIPTOR, descriptor);
  }
  explicit SliceLayerBuilder(flatbuffers::FlatBufferBuilder &_fbb)
        : fbb_(_fbb) {
    start_ = fbb_.StartTable();
  }
  SliceLayerBuilder &operator=(const SliceLayerBuilder &);
  flatbuffers::Offset<SliceLayer> Finish() {
    const auto end = fbb_.EndTable(start_);
    auto o = flatbuffers::Offset<SliceLayer>(end);
    return o;
  }
};

inline flatbuffers::Offset<SliceLayer> CreateSliceLayer(
    flatbuffers::FlatBufferBuilder &_fbb,
    flatbuffers::Offset<armnnSerializer::LayerBase> base = 0,
    flatbuffers::Offset<armnnSerializer::SliceDescriptor> descriptor = 0) {
  SliceLayerBuilder builder_(_fbb);
  builder_.add_descriptor(descriptor);
  builder_.add_base(base);
  return builder_.Finish();
}

struct SliceDescriptor FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
  typedef SliceDescriptorBuilder Builder;
  enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
    VT_BEGIN = 4,
    VT_SIZE = 6
  };
  const flatbuffers::Vector<uint32_t> *begin() const {
    return GetPointer<const flatbuffers::Vector<uint32_t> *>(VT_BEGIN);
  }
  const flatbuffers::Vector<uint32_t> *size() const {
    return GetPointer<const flatbuffers::Vector<uint32_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 SliceDescriptorBuilder {
  typedef SliceDescriptor Table;
  flatbuffers::FlatBufferBuilder &fbb_;
  flatbuffers::uoffset_t start_;
  void add_begin(flatbuffers::Offset<flatbuffers::Vector<uint32_t>> begin) {
    fbb_.AddOffset(SliceDescriptor::VT_BEGIN, begin);
  }
  void add_size(flatbuffers::Offset<flatbuffers::Vector<uint32_t>> size) {
    fbb_.AddOffset(SliceDescriptor::VT_SIZE, size);
  }
  explicit SliceDescriptorBuilder(flatbuffers::FlatBufferBuilder &_fbb)
        : fbb_(_fbb) {
    start_ = fbb_.StartTable();
  }
  SliceDescriptorBuilder &operator=(const SliceDescriptorBuilder &);
  flatbuffers::Offset<SliceDescriptor> Finish() {
    const auto end = fbb_.EndTable(start_);
    auto o = flatbuffers::Offset<SliceDescriptor>(end);
    return o;
  }
};

inline flatbuffers::Offset<SliceDescriptor> CreateSliceDescriptor(
    flatbuffers::FlatBufferBuilder &_fbb,
    flatbuffers::Offset<flatbuffers::Vector<uint32_t>> begin = 0,
    flatbuffers::Offset<flatbuffers::Vector<uint32_t>> size = 0) {
  SliceDescriptorBuilder builder_(_fbb);
  builder_.add_size(size);
  builder_.add_begin(begin);
  return builder_.Finish();
}

inline flatbuffers::Offset<SliceDescriptor> CreateSliceDescriptorDirect(
    flatbuffers::FlatBufferBuilder &_fbb,
    const std::vector<uint32_t> *begin = nullptr,
    const std::vector<uint32_t> *size = nullptr) {
  auto begin__ = begin ? _fbb.CreateVector<uint32_t>(*begin) : 0;
  auto size__ = size ? _fbb.CreateVector<uint32_t>(*size) : 0;
  return armnnSerializer::CreateSliceDescriptor(
      _fbb,
      begin__,
      size__);
}

struct StridedSliceLayer FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
  typedef StridedSliceLayerBuilder Builder;
  enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
    VT_BASE = 4,
    VT_DESCRIPTOR = 6
  };
  const armnnSerializer::LayerBase *base() const {
    return GetPointer<const armnnSerializer::LayerBase *>(VT_BASE);
  }
  const armnnSerializer::StridedSliceDescriptor *descriptor() const {
    return GetPointer<const armnnSerializer::StridedSliceDescriptor *>(VT_DESCRIPTOR);
  }
  bool Verify(flatbuffers::Verifier &verifier) const {
    return VerifyTableStart(verifier) &&
           VerifyOffset(verifier, VT_BASE) &&
           verifier.VerifyTable(base()) &&
           VerifyOffset(verifier, VT_DESCRIPTOR) &&
           verifier.VerifyTable(descriptor()) &&
           verifier.EndTable();
  }
};

struct StridedSliceLayerBuilder {
  typedef StridedSliceLayer Table;
  flatbuffers::FlatBufferBuilder &fbb_;
  flatbuffers::uoffset_t start_;
  void add_base(flatbuffers::Offset<armnnSerializer::LayerBase> base) {
    fbb_.AddOffset(StridedSliceLayer::VT_BASE, base);
  }
  void add_descriptor(flatbuffers::Offset<armnnSerializer::StridedSliceDescriptor> descriptor) {
    fbb_.AddOffset(StridedSliceLayer::VT_DESCRIPTOR, descriptor);
  }
  explicit StridedSliceLayerBuilder(flatbuffers::FlatBufferBuilder &_fbb)
        : fbb_(_fbb) {
    start_ = fbb_.StartTable();
  }
  StridedSliceLayerBuilder &operator=(const StridedSliceLayerBuilder &);
  flatbuffers::Offset<StridedSliceLayer> Finish() {
    const auto end = fbb_.EndTable(start_);
    auto o = flatbuffers::Offset<StridedSliceLayer>(end);
    return o;
  }
};

inline flatbuffers::Offset<StridedSliceLayer> CreateStridedSliceLayer(
    flatbuffers::FlatBufferBuilder &_fbb,
    flatbuffers::Offset<armnnSerializer::LayerBase> base = 0,
    flatbuffers::Offset<armnnSerializer::StridedSliceDescriptor> descriptor = 0) {
  StridedSliceLayerBuilder builder_(_fbb);
  builder_.add_descriptor(descriptor);
  builder_.add_base(base);
  return builder_.Finish();
}

struct StridedSliceDescriptor FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
  typedef StridedSliceDescriptorBuilder Builder;
  enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
    VT_BEGIN = 4,
    VT_END = 6,
    VT_STRIDE = 8,
    VT_BEGINMASK = 10,
    VT_ENDMASK = 12,
    VT_SHRINKAXISMASK = 14,
    VT_ELLIPSISMASK = 16,
    VT_NEWAXISMASK = 18,
    VT_DATALAYOUT = 20
  };
  const flatbuffers::Vector<int32_t> *begin() const {
    return GetPointer<const flatbuffers::Vector<int32_t> *>(VT_BEGIN);
  }
  const flatbuffers::Vector<int32_t> *end() const {
    return GetPointer<const flatbuffers::Vector<int32_t> *>(VT_END);
  }
  const flatbuffers::Vector<int32_t> *stride() const {
    return GetPointer<const flatbuffers::Vector<int32_t> *>(VT_STRIDE);
  }
  int32_t beginMask() const {
    return GetField<int32_t>(VT_BEGINMASK, 0);
  }
  int32_t endMask() const {
    return GetField<int32_t>(VT_ENDMASK, 0);
  }
  int32_t shrinkAxisMask() const {
    return GetField<int32_t>(VT_SHRINKAXISMASK, 0);
  }
  int32_t ellipsisMask() const {
    return GetField<int32_t>(VT_ELLIPSISMASK, 0);
  }
  int32_t newAxisMask() const {
    return GetField<int32_t>(VT_NEWAXISMASK, 0);
  }
  armnnSerializer::DataLayout dataLayout() const {
    return static_cast<armnnSerializer::DataLayout>(GetField<int8_t>(VT_DATALAYOUT, 0));
  }
  bool Verify(flatbuffers::Verifier &verifier) const {
    return VerifyTableStart(verifier) &&
           VerifyOffset(verifier, VT_BEGIN) &&
           verifier.VerifyVector(begin()) &&
           VerifyOffset(verifier, VT_END) &&
           verifier.VerifyVector(end()) &&
           VerifyOffset(verifier, VT_STRIDE) &&
           verifier.VerifyVector(stride()) &&
           VerifyField<int32_t>(verifier, VT_BEGINMASK) &&
           VerifyField<int32_t>(verifier, VT_ENDMASK) &&
           VerifyField<int32_t>(verifier, VT_SHRINKAXISMASK) &&
           VerifyField<int32_t>(verifier, VT_ELLIPSISMASK) &&
           VerifyField<int32_t>(verifier, VT_NEWAXISMASK) &&
           VerifyField<int8_t>(verifier, VT_DATALAYOUT) &&
           verifier.EndTable();
  }
};

struct StridedSliceDescriptorBuilder {
  typedef StridedSliceDescriptor Table;
  flatbuffers::FlatBufferBuilder &fbb_;
  flatbuffers::uoffset_t start_;
  void add_begin(flatbuffers::Offset<flatbuffers::Vector<int32_t>> begin) {
    fbb_.AddOffset(StridedSliceDescriptor::VT_BEGIN, begin);
  }
  void add_end(flatbuffers::Offset<flatbuffers::Vector<int32_t>> end) {
    fbb_.AddOffset(StridedSliceDescriptor::VT_END, end);
  }
  void add_stride(flatbuffers::Offset<flatbuffers::Vector<int32_t>> stride) {
    fbb_.AddOffset(StridedSliceDescriptor::VT_STRIDE, stride);
  }
  void add_beginMask(int32_t beginMask) {
    fbb_.AddElement<int32_t>(StridedSliceDescriptor::VT_BEGINMASK, beginMask, 0);
  }
  void add_endMask(int32_t endMask) {
    fbb_.AddElement<int32_t>(StridedSliceDescriptor::VT_ENDMASK, endMask, 0);
  }
  void add_shrinkAxisMask(int32_t shrinkAxisMask) {
    fbb_.AddElement<int32_t>(StridedSliceDescriptor::VT_SHRINKAXISMASK, shrinkAxisMask, 0);
  }
  void add_ellipsisMask(int32_t ellipsisMask) {
    fbb_.AddElement<int32_t>(StridedSliceDescriptor::VT_ELLIPSISMASK, ellipsisMask, 0);
  }
  void add_newAxisMask(int32_t newAxisMask) {
    fbb_.AddElement<int32_t>(StridedSliceDescriptor::VT_NEWAXISMASK, newAxisMask, 0);
  }
  void add_dataLayout(armnnSerializer::DataLayout dataLayout) {
    fbb_.AddElement<int8_t>(StridedSliceDescriptor::VT_DATALAYOUT, static_cast<int8_t>(dataLayout), 0);
  }
  explicit StridedSliceDescriptorBuilder(flatbuffers::FlatBufferBuilder &_fbb)
        : fbb_(_fbb) {
    start_ = fbb_.StartTable();
  }
  StridedSliceDescriptorBuilder &operator=(const StridedSliceDescriptorBuilder &);
  flatbuffers::Offset<StridedSliceDescriptor> Finish() {
    const auto end = fbb_.EndTable(start_);
    auto o = flatbuffers::Offset<StridedSliceDescriptor>(end);
    return o;
  }
};

inline flatbuffers::Offset<StridedSliceDescriptor> CreateStridedSliceDescriptor(
    flatbuffers::FlatBufferBuilder &_fbb,
    flatbuffers::Offset<flatbuffers::Vector<int32_t>> begin = 0,
    flatbuffers::Offset<flatbuffers::Vector<int32_t>> end = 0,
    flatbuffers::Offset<flatbuffers::Vector<int32_t>> stride = 0,
    int32_t beginMask = 0,
    int32_t endMask = 0,
    int32_t shrinkAxisMask = 0,
    int32_t ellipsisMask = 0,
    int32_t newAxisMask = 0,
    armnnSerializer::DataLayout dataLayout = armnnSerializer::DataLayout_NHWC) {
  StridedSliceDescriptorBuilder builder_(_fbb);
  builder_.add_newAxisMask(newAxisMask);
  builder_.add_ellipsisMask(ellipsisMask);
  builder_.add_shrinkAxisMask(shrinkAxisMask);
  builder_.add_endMask(endMask);
  builder_.add_beginMask(beginMask);
  builder_.add_stride(stride);
  builder_.add_end(end);
  builder_.add_begin(begin);
  builder_.add_dataLayout(dataLayout);
  return builder_.Finish();
}

inline flatbuffers::Offset<StridedSliceDescriptor> CreateStridedSliceDescriptorDirect(
    flatbuffers::FlatBufferBuilder &_fbb,
    const std::vector<int32_t> *begin = nullptr,
    const std::vector<int32_t> *end = nullptr,
    const std::vector<int32_t> *stride = nullptr,
    int32_t beginMask = 0,
    int32_t endMask = 0,
    int32_t shrinkAxisMask = 0,
    int32_t ellipsisMask = 0,
    int32_t newAxisMask = 0,
    armnnSerializer::DataLayout dataLayout = armnnSerializer::DataLayout_NHWC) {
  auto begin__ = begin ? _fbb.CreateVector<int32_t>(*begin) : 0;
  auto end__ = end ? _fbb.CreateVector<int32_t>(*end) : 0;
  auto stride__ = stride ? _fbb.CreateVector<int32_t>(*stride) : 0;
  return armnnSerializer::CreateStridedSliceDescriptor(
      _fbb,
      begin__,
      end__,
      stride__,
      beginMask,
      endMask,
      shrinkAxisMask,
      ellipsisMask,
      newAxisMask,
      dataLayout);
}

struct ConcatLayer FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
  typedef ConcatLayerBuilder Builder;
  enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
    VT_BASE = 4,
    VT_DESCRIPTOR = 6
  };
  const armnnSerializer::LayerBase *base() const {
    return GetPointer<const armnnSerializer::LayerBase *>(VT_BASE);
  }
  const armnnSerializer::OriginsDescriptor *descriptor() const {
    return GetPointer<const armnnSerializer::OriginsDescriptor *>(VT_DESCRIPTOR);
  }
  bool Verify(flatbuffers::Verifier &verifier) const {
    return VerifyTableStart(verifier) &&
           VerifyOffset(verifier, VT_BASE) &&
           verifier.VerifyTable(base()) &&
           VerifyOffset(verifier, VT_DESCRIPTOR) &&
           verifier.VerifyTable(descriptor()) &&
           verifier.EndTable();
  }
};

struct ConcatLayerBuilder {
  typedef ConcatLayer Table;
  flatbuffers::FlatBufferBuilder &fbb_;
  flatbuffers::uoffset_t start_;
  void add_base(flatbuffers::Offset<armnnSerializer::LayerBase> base) {
    fbb_.AddOffset(ConcatLayer::VT_BASE, base);
  }
  void add_descriptor(flatbuffers::Offset<armnnSerializer::OriginsDescriptor> descriptor) {
    fbb_.AddOffset(ConcatLayer::VT_DESCRIPTOR, descriptor);
  }
  explicit ConcatLayerBuilder(flatbuffers::FlatBufferBuilder &_fbb)
        : fbb_(_fbb) {
    start_ = fbb_.StartTable();
  }
  ConcatLayerBuilder &operator=(const ConcatLayerBuilder &);
  flatbuffers::Offset<ConcatLayer> Finish() {
    const auto end = fbb_.EndTable(start_);
    auto o = flatbuffers::Offset<ConcatLayer>(end);
    return o;
  }
};

inline flatbuffers::Offset<ConcatLayer> CreateConcatLayer(
    flatbuffers::FlatBufferBuilder &_fbb,
    flatbuffers::Offset<armnnSerializer::LayerBase> base = 0,
    flatbuffers::Offset<armnnSerializer::OriginsDescriptor> descriptor = 0) {
  ConcatLayerBuilder builder_(_fbb);
  builder_.add_descriptor(descriptor);
  builder_.add_base(base);
  return builder_.Finish();
}

/// @deprecated Use ConcatLayer instead
struct MergerLayer FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
  typedef MergerLayerBuilder Builder;
  enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
    VT_BASE = 4,
    VT_DESCRIPTOR = 6
  };
  const armnnSerializer::LayerBase *base() const {
    return GetPointer<const armnnSerializer::LayerBase *>(VT_BASE);
  }
  const armnnSerializer::OriginsDescriptor *descriptor() const {
    return GetPointer<const armnnSerializer::OriginsDescriptor *>(VT_DESCRIPTOR);
  }
  bool Verify(flatbuffers::Verifier &verifier) const {
    return VerifyTableStart(verifier) &&
           VerifyOffset(verifier, VT_BASE) &&
           verifier.VerifyTable(base()) &&
           VerifyOffset(verifier, VT_DESCRIPTOR) &&
           verifier.VerifyTable(descriptor()) &&
           verifier.EndTable();
  }
};

struct MergerLayerBuilder {
  typedef MergerLayer Table;
  flatbuffers::FlatBufferBuilder &fbb_;
  flatbuffers::uoffset_t start_;
  void add_base(flatbuffers::Offset<armnnSerializer::LayerBase> base) {
    fbb_.AddOffset(MergerLayer::VT_BASE, base);
  }
  void add_descriptor(flatbuffers::Offset<armnnSerializer::OriginsDescriptor> descriptor) {
    fbb_.AddOffset(MergerLayer::VT_DESCRIPTOR, descriptor);
  }
  explicit MergerLayerBuilder(flatbuffers::FlatBufferBuilder &_fbb)
        : fbb_(_fbb) {
    start_ = fbb_.StartTable();
  }
  MergerLayerBuilder &operator=(const MergerLayerBuilder &);
  flatbuffers::Offset<MergerLayer> Finish() {
    const auto end = fbb_.EndTable(start_);
    auto o = flatbuffers::Offset<MergerLayer>(end);
    return o;
  }
};

inline flatbuffers::Offset<MergerLayer> CreateMergerLayer(
    flatbuffers::FlatBufferBuilder &_fbb,
    flatbuffers::Offset<armnnSerializer::LayerBase> base = 0,
    flatbuffers::Offset<armnnSerializer::OriginsDescriptor> descriptor = 0) {
  MergerLayerBuilder builder_(_fbb);
  builder_.add_descriptor(descriptor);
  builder_.add_base(base);
  return builder_.Finish();
}

struct UintVector FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
  typedef UintVectorBuilder Builder;
  enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
    VT_DATA = 4
  };
  const flatbuffers::Vector<uint32_t> *data() const {
    return GetPointer<const flatbuffers::Vector<uint32_t> *>(VT_DATA);
  }
  bool Verify(flatbuffers::Verifier &verifier) const {
    return VerifyTableStart(verifier) &&
           VerifyOffset(verifier, VT_DATA) &&
           verifier.VerifyVector(data()) &&
           verifier.EndTable();
  }
};

struct UintVectorBuilder {
  typedef UintVector Table;
  flatbuffers::FlatBufferBuilder &fbb_;
  flatbuffers::uoffset_t start_;
  void add_data(flatbuffers::Offset<flatbuffers::Vector<uint32_t>> data) {
    fbb_.AddOffset(UintVector::VT_DATA, data);
  }
  explicit UintVectorBuilder(flatbuffers::FlatBufferBuilder &_fbb)
        : fbb_(_fbb) {
    start_ = fbb_.StartTable();
  }
  UintVectorBuilder &operator=(const UintVectorBuilder &);
  flatbuffers::Offset<UintVector> Finish() {
    const auto end = fbb_.EndTable(start_);
    auto o = flatbuffers::Offset<UintVector>(end);
    return o;
  }
};

inline flatbuffers::Offset<UintVector> CreateUintVector(
    flatbuffers::FlatBufferBuilder &_fbb,
    flatbuffers::Offset<flatbuffers::Vector<uint32_t>> data = 0) {
  UintVectorBuilder builder_(_fbb);
  builder_.add_data(data);
  return builder_.Finish();
}

inline flatbuffers::Offset<UintVector> CreateUintVectorDirect(
    flatbuffers::FlatBufferBuilder &_fbb,
    const std::vector<uint32_t> *data = nullptr) {
  auto data__ = data ? _fbb.CreateVector<uint32_t>(*data) : 0;
  return armnnSerializer::CreateUintVector(
      _fbb,
      data__);
}

struct OriginsDescriptor FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
  typedef OriginsDescriptorBuilder Builder;
  enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
    VT_CONCATAXIS = 4,
    VT_NUMVIEWS = 6,
    VT_NUMDIMENSIONS = 8,
    VT_VIEWORIGINS = 10
  };
  uint32_t concatAxis() const {
    return GetField<uint32_t>(VT_CONCATAXIS, 0);
  }
  uint32_t numViews() const {
    return GetField<uint32_t>(VT_NUMVIEWS, 0);
  }
  uint32_t numDimensions() const {
    return GetField<uint32_t>(VT_NUMDIMENSIONS, 0);
  }
  const flatbuffers::Vector<flatbuffers::Offset<armnnSerializer::UintVector>> *viewOrigins() const {
    return GetPointer<const flatbuffers::Vector<flatbuffers::Offset<armnnSerializer::UintVector>> *>(VT_VIEWORIGINS);
  }
  bool Verify(flatbuffers::Verifier &verifier) const {
    return VerifyTableStart(verifier) &&
           VerifyField<uint32_t>(verifier, VT_CONCATAXIS) &&
           VerifyField<uint32_t>(verifier, VT_NUMVIEWS) &&
           VerifyField<uint32_t>(verifier, VT_NUMDIMENSIONS) &&
           VerifyOffset(verifier, VT_VIEWORIGINS) &&
           verifier.VerifyVector(viewOrigins()) &&
           verifier.VerifyVectorOfTables(viewOrigins()) &&
           verifier.EndTable();
  }
};

struct OriginsDescriptorBuilder {
  typedef OriginsDescriptor Table;
  flatbuffers::FlatBufferBuilder &fbb_;
  flatbuffers::uoffset_t start_;
  void add_concatAxis(uint32_t concatAxis) {
    fbb_.AddElement<uint32_t>(OriginsDescriptor::VT_CONCATAXIS, concatAxis, 0);
  }
  void add_numViews(uint32_t numViews) {
    fbb_.AddElement<uint32_t>(OriginsDescriptor::VT_NUMVIEWS, numViews, 0);
  }
  void add_numDimensions(uint32_t numDimensions) {
    fbb_.AddElement<uint32_t>(OriginsDescriptor::VT_NUMDIMENSIONS, numDimensions, 0);
  }
  void add_viewOrigins(flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<armnnSerializer::UintVector>>> viewOrigins) {
    fbb_.AddOffset(OriginsDescriptor::VT_VIEWORIGINS, viewOrigins);
  }
  explicit OriginsDescriptorBuilder(flatbuffers::FlatBufferBuilder &_fbb)
        : fbb_(_fbb) {
    start_ = fbb_.StartTable();
  }
  OriginsDescriptorBuilder &operator=(const OriginsDescriptorBuilder &);
  flatbuffers::Offset<OriginsDescriptor> Finish() {
    const auto end = fbb_.EndTable(start_);
    auto o = flatbuffers::Offset<OriginsDescriptor>(end);
    return o;
  }
};

inline flatbuffers::Offset<OriginsDescriptor> CreateOriginsDescriptor(
    flatbuffers::FlatBufferBuilder &_fbb,
    uint32_t concatAxis = 0,
    uint32_t numViews = 0,
    uint32_t numDimensions = 0,
    flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<armnnSerializer::UintVector>>> viewOrigins = 0) {
  OriginsDescriptorBuilder builder_(_fbb);
  builder_.add_viewOrigins(viewOrigins);
  builder_.add_numDimensions(numDimensions);
  builder_.add_numViews(numViews);
  builder_.add_concatAxis(concatAxis);
  return builder_.Finish();
}

inline flatbuffers::Offset<OriginsDescriptor> CreateOriginsDescriptorDirect(
    flatbuffers::FlatBufferBuilder &_fbb,
    uint32_t concatAxis = 0,
    uint32_t numViews = 0,
    uint32_t numDimensions = 0,
    const std::vector<flatbuffers::Offset<armnnSerializer::UintVector>> *viewOrigins = nullptr) {
  auto viewOrigins__ = viewOrigins ? _fbb.CreateVector<flatbuffers::Offset<armnnSerializer::UintVector>>(*viewOrigins) : 0;
  return armnnSerializer::CreateOriginsDescriptor(
      _fbb,
      concatAxis,
      numViews,
      numDimensions,
      viewOrigins__);
}

struct ViewsDescriptor FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
  typedef ViewsDescriptorBuilder Builder;
  enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
    VT_ORIGINS = 4,
    VT_VIEWSIZES = 6
  };
  const armnnSerializer::OriginsDescriptor *origins() const {
    return GetPointer<const armnnSerializer::OriginsDescriptor *>(VT_ORIGINS);
  }
  const flatbuffers::Vector<flatbuffers::Offset<armnnSerializer::UintVector>> *viewSizes() const {
    return GetPointer<const flatbuffers::Vector<flatbuffers::Offset<armnnSerializer::UintVector>> *>(VT_VIEWSIZES);
  }
  bool Verify(flatbuffers::Verifier &verifier) const {
    return VerifyTableStart(verifier) &&
           VerifyOffset(verifier, VT_ORIGINS) &&
           verifier.VerifyTable(origins()) &&
           VerifyOffset(verifier, VT_VIEWSIZES) &&
           verifier.VerifyVector(viewSizes()) &&
           verifier.VerifyVectorOfTables(viewSizes()) &&
           verifier.EndTable();
  }
};

struct ViewsDescriptorBuilder {
  typedef ViewsDescriptor Table;
  flatbuffers::FlatBufferBuilder &fbb_;
  flatbuffers::uoffset_t start_;
  void add_origins(flatbuffers::Offset<armnnSerializer::OriginsDescriptor> origins) {
    fbb_.AddOffset(ViewsDescriptor::VT_ORIGINS, origins);
  }
  void add_viewSizes(flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<armnnSerializer::UintVector>>> viewSizes) {
    fbb_.AddOffset(ViewsDescriptor::VT_VIEWSIZES, viewSizes);
  }
  explicit ViewsDescriptorBuilder(flatbuffers::FlatBufferBuilder &_fbb)
        : fbb_(_fbb) {
    start_ = fbb_.StartTable();
  }
  ViewsDescriptorBuilder &operator=(const ViewsDescriptorBuilder &);
  flatbuffers::Offset<ViewsDescriptor> Finish() {
    const auto end = fbb_.EndTable(start_);
    auto o = flatbuffers::Offset<ViewsDescriptor>(end);
    return o;
  }
};

inline flatbuffers::Offset<ViewsDescriptor> CreateViewsDescriptor(
    flatbuffers::FlatBufferBuilder &_fbb,
    flatbuffers::Offset<armnnSerializer::OriginsDescriptor> origins = 0,
    flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<armnnSerializer::UintVector>>> viewSizes = 0) {
  ViewsDescriptorBuilder builder_(_fbb);
  builder_.add_viewSizes(viewSizes);
  builder_.add_origins(origins);
  return builder_.Finish();
}

inline flatbuffers::Offset<ViewsDescriptor> CreateViewsDescriptorDirect(
    flatbuffers::FlatBufferBuilder &_fbb,
    flatbuffers::Offset<armnnSerializer::OriginsDescriptor> origins = 0,
    const std::vector<flatbuffers::Offset<armnnSerializer::UintVector>> *viewSizes = nullptr) {
  auto viewSizes__ = viewSizes ? _fbb.CreateVector<flatbuffers::Offset<armnnSerializer::UintVector>>(*viewSizes) : 0;
  return armnnSerializer::CreateViewsDescriptor(
      _fbb,
      origins,
      viewSizes__);
}

struct SplitterLayer FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
  typedef SplitterLayerBuilder Builder;
  enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
    VT_BASE = 4,
    VT_DESCRIPTOR = 6
  };
  const armnnSerializer::LayerBase *base() const {
    return GetPointer<const armnnSerializer::LayerBase *>(VT_BASE);
  }
  const armnnSerializer::ViewsDescriptor *descriptor() const {
    return GetPointer<const armnnSerializer::ViewsDescriptor *>(VT_DESCRIPTOR);
  }
  bool Verify(flatbuffers::Verifier &verifier) const {
    return VerifyTableStart(verifier) &&
           VerifyOffset(verifier, VT_BASE) &&
           verifier.VerifyTable(base()) &&
           VerifyOffset(verifier, VT_DESCRIPTOR) &&
           verifier.VerifyTable(descriptor()) &&
           verifier.EndTable();
  }
};

struct SplitterLayerBuilder {
  typedef SplitterLayer Table;
  flatbuffers::FlatBufferBuilder &fbb_;
  flatbuffers::uoffset_t start_;
  void add_base(flatbuffers::Offset<armnnSerializer::LayerBase> base) {
    fbb_.AddOffset(SplitterLayer::VT_BASE, base);
  }
  void add_descriptor(flatbuffers::Offset<armnnSerializer::ViewsDescriptor> descriptor) {
    fbb_.AddOffset(SplitterLayer::VT_DESCRIPTOR, descriptor);
  }
  explicit SplitterLayerBuilder(flatbuffers::FlatBufferBuilder &_fbb)
        : fbb_(_fbb) {
    start_ = fbb_.StartTable();
  }
  SplitterLayerBuilder &operator=(const SplitterLayerBuilder &);
  flatbuffers::Offset<SplitterLayer> Finish() {
    const auto end = fbb_.EndTable(start_);
    auto o = flatbuffers::Offset<SplitterLayer>(end);
    return o;
  }
};

inline flatbuffers::Offset<SplitterLayer> CreateSplitterLayer(
    flatbuffers::FlatBufferBuilder &_fbb,
    flatbuffers::Offset<armnnSerializer::LayerBase> base = 0,
    flatbuffers::Offset<armnnSerializer::ViewsDescriptor> descriptor = 0) {
  SplitterLayerBuilder builder_(_fbb);
  builder_.add_descriptor(descriptor);
  builder_.add_base(base);
  return builder_.Finish();
}

struct DetectionPostProcessLayer FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
  typedef DetectionPostProcessLayerBuilder Builder;
  enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
    VT_BASE = 4,
    VT_DESCRIPTOR = 6,
    VT_ANCHORS = 8
  };
  const armnnSerializer::LayerBase *base() const {
    return GetPointer<const armnnSerializer::LayerBase *>(VT_BASE);
  }
  const armnnSerializer::DetectionPostProcessDescriptor *descriptor() const {
    return GetPointer<const armnnSerializer::DetectionPostProcessDescriptor *>(VT_DESCRIPTOR);
  }
  const armnnSerializer::ConstTensor *anchors() const {
    return GetPointer<const armnnSerializer::ConstTensor *>(VT_ANCHORS);
  }
  bool Verify(flatbuffers::Verifier &verifier) const {
    return VerifyTableStart(verifier) &&
           VerifyOffset(verifier, VT_BASE) &&
           verifier.VerifyTable(base()) &&
           VerifyOffset(verifier, VT_DESCRIPTOR) &&
           verifier.VerifyTable(descriptor()) &&
           VerifyOffset(verifier, VT_ANCHORS) &&
           verifier.VerifyTable(anchors()) &&
           verifier.EndTable();
  }
};

struct DetectionPostProcessLayerBuilder {
  typedef DetectionPostProcessLayer Table;
  flatbuffers::FlatBufferBuilder &fbb_;
  flatbuffers::uoffset_t start_;
  void add_base(flatbuffers::Offset<armnnSerializer::LayerBase> base) {
    fbb_.AddOffset(DetectionPostProcessLayer::VT_BASE, base);
  }
  void add_descriptor(flatbuffers::Offset<armnnSerializer::DetectionPostProcessDescriptor> descriptor) {
    fbb_.AddOffset(DetectionPostProcessLayer::VT_DESCRIPTOR, descriptor);
  }
  void add_anchors(flatbuffers::Offset<armnnSerializer::ConstTensor> anchors) {
    fbb_.AddOffset(DetectionPostProcessLayer::VT_ANCHORS, anchors);
  }
  explicit DetectionPostProcessLayerBuilder(flatbuffers::FlatBufferBuilder &_fbb)
        : fbb_(_fbb) {
    start_ = fbb_.StartTable();
  }
  DetectionPostProcessLayerBuilder &operator=(const DetectionPostProcessLayerBuilder &);
  flatbuffers::Offset<DetectionPostProcessLayer> Finish() {
    const auto end = fbb_.EndTable(start_);
    auto o = flatbuffers::Offset<DetectionPostProcessLayer>(end);
    return o;
  }
};

inline flatbuffers::Offset<DetectionPostProcessLayer> CreateDetectionPostProcessLayer(
    flatbuffers::FlatBufferBuilder &_fbb,
    flatbuffers::Offset<armnnSerializer::LayerBase> base = 0,
    flatbuffers::Offset<armnnSerializer::DetectionPostProcessDescriptor> descriptor = 0,
    flatbuffers::Offset<armnnSerializer::ConstTensor> anchors = 0) {
  DetectionPostProcessLayerBuilder builder_(_fbb);
  builder_.add_anchors(anchors);
  builder_.add_descriptor(descriptor);
  builder_.add_base(base);
  return builder_.Finish();
}

struct DetectionPostProcessDescriptor FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
  typedef DetectionPostProcessDescriptorBuilder Builder;
  enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
    VT_MAXDETECTIONS = 4,
    VT_MAXCLASSESPERDETECTION = 6,
    VT_DETECTIONSPERCLASS = 8,
    VT_NMSSCORETHRESHOLD = 10,
    VT_NMSIOUTHRESHOLD = 12,
    VT_NUMCLASSES = 14,
    VT_USEREGULARNMS = 16,
    VT_SCALEX = 18,
    VT_SCALEY = 20,
    VT_SCALEW = 22,
    VT_SCALEH = 24
  };
  uint32_t maxDetections() const {
    return GetField<uint32_t>(VT_MAXDETECTIONS, 0);
  }
  uint32_t maxClassesPerDetection() const {
    return GetField<uint32_t>(VT_MAXCLASSESPERDETECTION, 0);
  }
  uint32_t detectionsPerClass() const {
    return GetField<uint32_t>(VT_DETECTIONSPERCLASS, 0);
  }
  float nmsScoreThreshold() const {
    return GetField<float>(VT_NMSSCORETHRESHOLD, 0.0f);
  }
  float nmsIouThreshold() const {
    return GetField<float>(VT_NMSIOUTHRESHOLD, 0.0f);
  }
  uint32_t numClasses() const {
    return GetField<uint32_t>(VT_NUMCLASSES, 0);
  }
  bool useRegularNms() const {
    return GetField<uint8_t>(VT_USEREGULARNMS, 0) != 0;
  }
  float scaleX() const {
    return GetField<float>(VT_SCALEX, 0.0f);
  }
  float scaleY() const {
    return GetField<float>(VT_SCALEY, 0.0f);
  }
  float scaleW() const {
    return GetField<float>(VT_SCALEW, 0.0f);
  }
  float scaleH() const {
    return GetField<float>(VT_SCALEH, 0.0f);
  }
  bool Verify(flatbuffers::Verifier &verifier) const {
    return VerifyTableStart(verifier) &&
           VerifyField<uint32_t>(verifier, VT_MAXDETECTIONS) &&
           VerifyField<uint32_t>(verifier, VT_MAXCLASSESPERDETECTION) &&
           VerifyField<uint32_t>(verifier, VT_DETECTIONSPERCLASS) &&
           VerifyField<float>(verifier, VT_NMSSCORETHRESHOLD) &&
           VerifyField<float>(verifier, VT_NMSIOUTHRESHOLD) &&
           VerifyField<uint32_t>(verifier, VT_NUMCLASSES) &&
           VerifyField<uint8_t>(verifier, VT_USEREGULARNMS) &&
           VerifyField<float>(verifier, VT_SCALEX) &&
           VerifyField<float>(verifier, VT_SCALEY) &&
           VerifyField<float>(verifier, VT_SCALEW) &&
           VerifyField<float>(verifier, VT_SCALEH) &&
           verifier.EndTable();
  }
};

struct DetectionPostProcessDescriptorBuilder {
  typedef DetectionPostProcessDescriptor Table;
  flatbuffers::FlatBufferBuilder &fbb_;
  flatbuffers::uoffset_t start_;
  void add_maxDetections(uint32_t maxDetections) {
    fbb_.AddElement<uint32_t>(DetectionPostProcessDescriptor::VT_MAXDETECTIONS, maxDetections, 0);
  }
  void add_maxClassesPerDetection(uint32_t maxClassesPerDetection) {
    fbb_.AddElement<uint32_t>(DetectionPostProcessDescriptor::VT_MAXCLASSESPERDETECTION, maxClassesPerDetection, 0);
  }
  void add_detectionsPerClass(uint32_t detectionsPerClass) {
    fbb_.AddElement<uint32_t>(DetectionPostProcessDescriptor::VT_DETECTIONSPERCLASS, detectionsPerClass, 0);
  }
  void add_nmsScoreThreshold(float nmsScoreThreshold) {
    fbb_.AddElement<float>(DetectionPostProcessDescriptor::VT_NMSSCORETHRESHOLD, nmsScoreThreshold, 0.0f);
  }
  void add_nmsIouThreshold(float nmsIouThreshold) {
    fbb_.AddElement<float>(DetectionPostProcessDescriptor::VT_NMSIOUTHRESHOLD, nmsIouThreshold, 0.0f);
  }
  void add_numClasses(uint32_t numClasses) {
    fbb_.AddElement<uint32_t>(DetectionPostProcessDescriptor::VT_NUMCLASSES, numClasses, 0);
  }
  void add_useRegularNms(bool useRegularNms) {
    fbb_.AddElement<uint8_t>(DetectionPostProcessDescriptor::VT_USEREGULARNMS, static_cast<uint8_t>(useRegularNms), 0);
  }
  void add_scaleX(float scaleX) {
    fbb_.AddElement<float>(DetectionPostProcessDescriptor::VT_SCALEX, scaleX, 0.0f);
  }
  void add_scaleY(float scaleY) {
    fbb_.AddElement<float>(DetectionPostProcessDescriptor::VT_SCALEY, scaleY, 0.0f);
  }
  void add_scaleW(float scaleW) {
    fbb_.AddElement<float>(DetectionPostProcessDescriptor::VT_SCALEW, scaleW, 0.0f);
  }
  void add_scaleH(float scaleH) {
    fbb_.AddElement<float>(DetectionPostProcessDescriptor::VT_SCALEH, scaleH, 0.0f);
  }
  explicit DetectionPostProcessDescriptorBuilder(flatbuffers::FlatBufferBuilder &_fbb)
        : fbb_(_fbb) {
    start_ = fbb_.StartTable();
  }
  DetectionPostProcessDescriptorBuilder &operator=(const DetectionPostProcessDescriptorBuilder &);
  flatbuffers::Offset<DetectionPostProcessDescriptor> Finish() {
    const auto end = fbb_.EndTable(start_);
    auto o = flatbuffers::Offset<DetectionPostProcessDescriptor>(end);
    return o;
  }
};

inline flatbuffers::Offset<DetectionPostProcessDescriptor> CreateDetectionPostProcessDescriptor(
    flatbuffers::FlatBufferBuilder &_fbb,
    uint32_t maxDetections = 0,
    uint32_t maxClassesPerDetection = 0,
    uint32_t detectionsPerClass = 0,
    float nmsScoreThreshold = 0.0f,
    float nmsIouThreshold = 0.0f,
    uint32_t numClasses = 0,
    bool useRegularNms = false,
    float scaleX = 0.0f,
    float scaleY = 0.0f,
    float scaleW = 0.0f,
    float scaleH = 0.0f) {
  DetectionPostProcessDescriptorBuilder builder_(_fbb);
  builder_.add_scaleH(scaleH);
  builder_.add_scaleW(scaleW);
  builder_.add_scaleY(scaleY);
  builder_.add_scaleX(scaleX);
  builder_.add_numClasses(numClasses);
  builder_.add_nmsIouThreshold(nmsIouThreshold);
  builder_.add_nmsScoreThreshold(nmsScoreThreshold);
  builder_.add_detectionsPerClass(detectionsPerClass);
  builder_.add_maxClassesPerDetection(maxClassesPerDetection);
  builder_.add_maxDetections(maxDetections);
  builder_.add_useRegularNms(useRegularNms);
  return builder_.Finish();
}

struct LstmInputParams FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
  typedef LstmInputParamsBuilder Builder;
  enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
    VT_INPUTTOFORGETWEIGHTS = 4,
    VT_INPUTTOCELLWEIGHTS = 6,
    VT_INPUTTOOUTPUTWEIGHTS = 8,
    VT_RECURRENTTOFORGETWEIGHTS = 10,
    VT_RECURRENTTOCELLWEIGHTS = 12,
    VT_RECURRENTTOOUTPUTWEIGHTS = 14,
    VT_FORGETGATEBIAS = 16,
    VT_CELLBIAS = 18,
    VT_OUTPUTGATEBIAS = 20,
    VT_INPUTTOINPUTWEIGHTS = 22,
    VT_RECURRENTTOINPUTWEIGHTS = 24,
    VT_CELLTOINPUTWEIGHTS = 26,
    VT_INPUTGATEBIAS = 28,
    VT_PROJECTIONWEIGHTS = 30,
    VT_PROJECTIONBIAS = 32,
    VT_CELLTOFORGETWEIGHTS = 34,
    VT_CELLTOOUTPUTWEIGHTS = 36,
    VT_INPUTLAYERNORMWEIGHTS = 38,
    VT_FORGETLAYERNORMWEIGHTS = 40,
    VT_CELLLAYERNORMWEIGHTS = 42,
    VT_OUTPUTLAYERNORMWEIGHTS = 44
  };
  const armnnSerializer::ConstTensor *inputToForgetWeights() const {
    return GetPointer<const armnnSerializer::ConstTensor *>(VT_INPUTTOFORGETWEIGHTS);
  }
  const armnnSerializer::ConstTensor *inputToCellWeights() const {
    return GetPointer<const armnnSerializer::ConstTensor *>(VT_INPUTTOCELLWEIGHTS);
  }
  const armnnSerializer::ConstTensor *inputToOutputWeights() const {
    return GetPointer<const armnnSerializer::ConstTensor *>(VT_INPUTTOOUTPUTWEIGHTS);
  }
  const armnnSerializer::ConstTensor *recurrentToForgetWeights() const {
    return GetPointer<const armnnSerializer::ConstTensor *>(VT_RECURRENTTOFORGETWEIGHTS);
  }
  const armnnSerializer::ConstTensor *recurrentToCellWeights() const {
    return GetPointer<const armnnSerializer::ConstTensor *>(VT_RECURRENTTOCELLWEIGHTS);
  }
  const armnnSerializer::ConstTensor *recurrentToOutputWeights() const {
    return GetPointer<const armnnSerializer::ConstTensor *>(VT_RECURRENTTOOUTPUTWEIGHTS);
  }
  const armnnSerializer::ConstTensor *forgetGateBias() const {
    return GetPointer<const armnnSerializer::ConstTensor *>(VT_FORGETGATEBIAS);
  }
  const armnnSerializer::ConstTensor *cellBias() const {
    return GetPointer<const armnnSerializer::ConstTensor *>(VT_CELLBIAS);
  }
  const armnnSerializer::ConstTensor *outputGateBias() const {
    return GetPointer<const armnnSerializer::ConstTensor *>(VT_OUTPUTGATEBIAS);
  }
  const armnnSerializer::ConstTensor *inputToInputWeights() const {
    return GetPointer<const armnnSerializer::ConstTensor *>(VT_INPUTTOINPUTWEIGHTS);
  }
  const armnnSerializer::ConstTensor *recurrentToInputWeights() const {
    return GetPointer<const armnnSerializer::ConstTensor *>(VT_RECURRENTTOINPUTWEIGHTS);
  }
  const armnnSerializer::ConstTensor *cellToInputWeights() const {
    return GetPointer<const armnnSerializer::ConstTensor *>(VT_CELLTOINPUTWEIGHTS);
  }
  const armnnSerializer::ConstTensor *inputGateBias() const {
    return GetPointer<const armnnSerializer::ConstTensor *>(VT_INPUTGATEBIAS);
  }
  const armnnSerializer::ConstTensor *projectionWeights() const {
    return GetPointer<const armnnSerializer::ConstTensor *>(VT_PROJECTIONWEIGHTS);
  }
  const armnnSerializer::ConstTensor *projectionBias() const {
    return GetPointer<const armnnSerializer::ConstTensor *>(VT_PROJECTIONBIAS);
  }
  const armnnSerializer::ConstTensor *cellToForgetWeights() const {
    return GetPointer<const armnnSerializer::ConstTensor *>(VT_CELLTOFORGETWEIGHTS);
  }
  const armnnSerializer::ConstTensor *cellToOutputWeights() const {
    return GetPointer<const armnnSerializer::ConstTensor *>(VT_CELLTOOUTPUTWEIGHTS);
  }
  const armnnSerializer::ConstTensor *inputLayerNormWeights() const {
    return GetPointer<const armnnSerializer::ConstTensor *>(VT_INPUTLAYERNORMWEIGHTS);
  }
  const armnnSerializer::ConstTensor *forgetLayerNormWeights() const {
    return GetPointer<const armnnSerializer::ConstTensor *>(VT_FORGETLAYERNORMWEIGHTS);
  }
  const armnnSerializer::ConstTensor *cellLayerNormWeights() const {
    return GetPointer<const armnnSerializer::ConstTensor *>(VT_CELLLAYERNORMWEIGHTS);
  }
  const armnnSerializer::ConstTensor *outputLayerNormWeights() const {
    return GetPointer<const armnnSerializer::ConstTensor *>(VT_OUTPUTLAYERNORMWEIGHTS);
  }
  bool Verify(flatbuffers::Verifier &verifier) const {
    return VerifyTableStart(verifier) &&
           VerifyOffset(verifier, VT_INPUTTOFORGETWEIGHTS) &&
           verifier.VerifyTable(inputToForgetWeights()) &&
           VerifyOffset(verifier, VT_INPUTTOCELLWEIGHTS) &&
           verifier.VerifyTable(inputToCellWeights()) &&
           VerifyOffset(verifier, VT_INPUTTOOUTPUTWEIGHTS) &&
           verifier.VerifyTable(inputToOutputWeights()) &&
           VerifyOffset(verifier, VT_RECURRENTTOFORGETWEIGHTS) &&
           verifier.VerifyTable(recurrentToForgetWeights()) &&
           VerifyOffset(verifier, VT_RECURRENTTOCELLWEIGHTS) &&
           verifier.VerifyTable(recurrentToCellWeights()) &&
           VerifyOffset(verifier, VT_RECURRENTTOOUTPUTWEIGHTS) &&
           verifier.VerifyTable(recurrentToOutputWeights()) &&
           VerifyOffset(verifier, VT_FORGETGATEBIAS) &&
           verifier.VerifyTable(forgetGateBias()) &&
           VerifyOffset(verifier, VT_CELLBIAS) &&
           verifier.VerifyTable(cellBias()) &&
           VerifyOffset(verifier, VT_OUTPUTGATEBIAS) &&
           verifier.VerifyTable(outputGateBias()) &&
           VerifyOffset(verifier, VT_INPUTTOINPUTWEIGHTS) &&
           verifier.VerifyTable(inputToInputWeights()) &&
           VerifyOffset(verifier, VT_RECURRENTTOINPUTWEIGHTS) &&
           verifier.VerifyTable(recurrentToInputWeights()) &&
           VerifyOffset(verifier, VT_CELLTOINPUTWEIGHTS) &&
           verifier.VerifyTable(cellToInputWeights()) &&
           VerifyOffset(verifier, VT_INPUTGATEBIAS) &&
           verifier.VerifyTable(inputGateBias()) &&
           VerifyOffset(verifier, VT_PROJECTIONWEIGHTS) &&
           verifier.VerifyTable(projectionWeights()) &&
           VerifyOffset(verifier, VT_PROJECTIONBIAS) &&
           verifier.VerifyTable(projectionBias()) &&
           VerifyOffset(verifier, VT_CELLTOFORGETWEIGHTS) &&
           verifier.VerifyTable(cellToForgetWeights()) &&
           VerifyOffset(verifier, VT_CELLTOOUTPUTWEIGHTS) &&
           verifier.VerifyTable(cellToOutputWeights()) &&
           VerifyOffset(verifier, VT_INPUTLAYERNORMWEIGHTS) &&
           verifier.VerifyTable(inputLayerNormWeights()) &&
           VerifyOffset(verifier, VT_FORGETLAYERNORMWEIGHTS) &&
           verifier.VerifyTable(forgetLayerNormWeights()) &&
           VerifyOffset(verifier, VT_CELLLAYERNORMWEIGHTS) &&
           verifier.VerifyTable(cellLayerNormWeights()) &&
           VerifyOffset(verifier, VT_OUTPUTLAYERNORMWEIGHTS) &&
           verifier.VerifyTable(outputLayerNormWeights()) &&
           verifier.EndTable();
  }
};

struct LstmInputParamsBuilder {
  typedef LstmInputParams Table;
  flatbuffers::FlatBufferBuilder &fbb_;
  flatbuffers::uoffset_t start_;
  void add_inputToForgetWeights(flatbuffers::Offset<armnnSerializer::ConstTensor> inputToForgetWeights) {
    fbb_.AddOffset(LstmInputParams::VT_INPUTTOFORGETWEIGHTS, inputToForgetWeights);
  }
  void add_inputToCellWeights(flatbuffers::Offset<armnnSerializer::ConstTensor> inputToCellWeights) {
    fbb_.AddOffset(LstmInputParams::VT_INPUTTOCELLWEIGHTS, inputToCellWeights);
  }
  void add_inputToOutputWeights(flatbuffers::Offset<armnnSerializer::ConstTensor> inputToOutputWeights) {
    fbb_.AddOffset(LstmInputParams::VT_INPUTTOOUTPUTWEIGHTS, inputToOutputWeights);
  }
  void add_recurrentToForgetWeights(flatbuffers::Offset<armnnSerializer::ConstTensor> recurrentToForgetWeights) {
    fbb_.AddOffset(LstmInputParams::VT_RECURRENTTOFORGETWEIGHTS, recurrentToForgetWeights);
  }
  void add_recurrentToCellWeights(flatbuffers::Offset<armnnSerializer::ConstTensor> recurrentToCellWeights) {
    fbb_.AddOffset(LstmInputParams::VT_RECURRENTTOCELLWEIGHTS, recurrentToCellWeights);
  }
  void add_recurrentToOutputWeights(flatbuffers::Offset<armnnSerializer::ConstTensor> recurrentToOutputWeights) {
    fbb_.AddOffset(LstmInputParams::VT_RECURRENTTOOUTPUTWEIGHTS, recurrentToOutputWeights);
  }
  void add_forgetGateBias(flatbuffers::Offset<armnnSerializer::ConstTensor> forgetGateBias) {
    fbb_.AddOffset(LstmInputParams::VT_FORGETGATEBIAS, forgetGateBias);
  }
  void add_cellBias(flatbuffers::Offset<armnnSerializer::ConstTensor> cellBias) {
    fbb_.AddOffset(LstmInputParams::VT_CELLBIAS, cellBias);
  }
  void add_outputGateBias(flatbuffers::Offset<armnnSerializer::ConstTensor> outputGateBias) {
    fbb_.AddOffset(LstmInputParams::VT_OUTPUTGATEBIAS, outputGateBias);
  }
  void add_inputToInputWeights(flatbuffers::Offset<armnnSerializer::ConstTensor> inputToInputWeights) {
    fbb_.AddOffset(LstmInputParams::VT_INPUTTOINPUTWEIGHTS, inputToInputWeights);
  }
  void add_recurrentToInputWeights(flatbuffers::Offset<armnnSerializer::ConstTensor> recurrentToInputWeights) {
    fbb_.AddOffset(LstmInputParams::VT_RECURRENTTOINPUTWEIGHTS, recurrentToInputWeights);
  }
  void add_cellToInputWeights(flatbuffers::Offset<armnnSerializer::ConstTensor> cellToInputWeights) {
    fbb_.AddOffset(LstmInputParams::VT_CELLTOINPUTWEIGHTS, cellToInputWeights);
  }
  void add_inputGateBias(flatbuffers::Offset<armnnSerializer::ConstTensor> inputGateBias) {
    fbb_.AddOffset(LstmInputParams::VT_INPUTGATEBIAS, inputGateBias);
  }
  void add_projectionWeights(flatbuffers::Offset<armnnSerializer::ConstTensor> projectionWeights) {
    fbb_.AddOffset(LstmInputParams::VT_PROJECTIONWEIGHTS, projectionWeights);
  }
  void add_projectionBias(flatbuffers::Offset<armnnSerializer::ConstTensor> projectionBias) {
    fbb_.AddOffset(LstmInputParams::VT_PROJECTIONBIAS, projectionBias);
  }
  void add_cellToForgetWeights(flatbuffers::Offset<armnnSerializer::ConstTensor> cellToForgetWeights) {
    fbb_.AddOffset(LstmInputParams::VT_CELLTOFORGETWEIGHTS, cellToForgetWeights);
  }
  void add_cellToOutputWeights(flatbuffers::Offset<armnnSerializer::ConstTensor> cellToOutputWeights) {
    fbb_.AddOffset(LstmInputParams::VT_CELLTOOUTPUTWEIGHTS, cellToOutputWeights);
  }
  void add_inputLayerNormWeights(flatbuffers::Offset<armnnSerializer::ConstTensor> inputLayerNormWeights) {
    fbb_.AddOffset(LstmInputParams::VT_INPUTLAYERNORMWEIGHTS, inputLayerNormWeights);
  }
  void add_forgetLayerNormWeights(flatbuffers::Offset<armnnSerializer::ConstTensor> forgetLayerNormWeights) {
    fbb_.AddOffset(LstmInputParams::VT_FORGETLAYERNORMWEIGHTS, forgetLayerNormWeights);
  }
  void add_cellLayerNormWeights(flatbuffers::Offset<armnnSerializer::ConstTensor> cellLayerNormWeights) {
    fbb_.AddOffset(LstmInputParams::VT_CELLLAYERNORMWEIGHTS, cellLayerNormWeights);
  }
  void add_outputLayerNormWeights(flatbuffers::Offset<armnnSerializer::ConstTensor> outputLayerNormWeights) {
    fbb_.AddOffset(LstmInputParams::VT_OUTPUTLAYERNORMWEIGHTS, outputLayerNormWeights);
  }
  explicit LstmInputParamsBuilder(flatbuffers::FlatBufferBuilder &_fbb)
        : fbb_(_fbb) {
    start_ = fbb_.StartTable();
  }
  LstmInputParamsBuilder &operator=(const LstmInputParamsBuilder &);
  flatbuffers::Offset<LstmInputParams> Finish() {
    const auto end = fbb_.EndTable(start_);
    auto o = flatbuffers::Offset<LstmInputParams>(end);
    return o;
  }
};

inline flatbuffers::Offset<LstmInputParams> CreateLstmInputParams(
    flatbuffers::FlatBufferBuilder &_fbb,
    flatbuffers::Offset<armnnSerializer::ConstTensor> inputToForgetWeights = 0,
    flatbuffers::Offset<armnnSerializer::ConstTensor> inputToCellWeights = 0,
    flatbuffers::Offset<armnnSerializer::ConstTensor> inputToOutputWeights = 0,
    flatbuffers::Offset<armnnSerializer::ConstTensor> recurrentToForgetWeights = 0,
    flatbuffers::Offset<armnnSerializer::ConstTensor> recurrentToCellWeights = 0,
    flatbuffers::Offset<armnnSerializer::ConstTensor> recurrentToOutputWeights = 0,
    flatbuffers::Offset<armnnSerializer::ConstTensor> forgetGateBias = 0,
    flatbuffers::Offset<armnnSerializer::ConstTensor> cellBias = 0,
    flatbuffers::Offset<armnnSerializer::ConstTensor> outputGateBias = 0,
    flatbuffers::Offset<armnnSerializer::ConstTensor> inputToInputWeights = 0,
    flatbuffers::Offset<armnnSerializer::ConstTensor> recurrentToInputWeights = 0,
    flatbuffers::Offset<armnnSerializer::ConstTensor> cellToInputWeights = 0,
    flatbuffers::Offset<armnnSerializer::ConstTensor> inputGateBias = 0,
    flatbuffers::Offset<armnnSerializer::ConstTensor> projectionWeights = 0,
    flatbuffers::Offset<armnnSerializer::ConstTensor> projectionBias = 0,
    flatbuffers::Offset<armnnSerializer::ConstTensor> cellToForgetWeights = 0,
    flatbuffers::Offset<armnnSerializer::ConstTensor> cellToOutputWeights = 0,
    flatbuffers::Offset<armnnSerializer::ConstTensor> inputLayerNormWeights = 0,
    flatbuffers::Offset<armnnSerializer::ConstTensor> forgetLayerNormWeights = 0,
    flatbuffers::Offset<armnnSerializer::ConstTensor> cellLayerNormWeights = 0,
    flatbuffers::Offset<armnnSerializer::ConstTensor> outputLayerNormWeights = 0) {
  LstmInputParamsBuilder builder_(_fbb);
  builder_.add_outputLayerNormWeights(outputLayerNormWeights);
  builder_.add_cellLayerNormWeights(cellLayerNormWeights);
  builder_.add_forgetLayerNormWeights(forgetLayerNormWeights);
  builder_.add_inputLayerNormWeights(inputLayerNormWeights);
  builder_.add_cellToOutputWeights(cellToOutputWeights);
  builder_.add_cellToForgetWeights(cellToForgetWeights);
  builder_.add_projectionBias(projectionBias);
  builder_.add_projectionWeights(projectionWeights);
  builder_.add_inputGateBias(inputGateBias);
  builder_.add_cellToInputWeights(cellToInputWeights);
  builder_.add_recurrentToInputWeights(recurrentToInputWeights);
  builder_.add_inputToInputWeights(inputToInputWeights);
  builder_.add_outputGateBias(outputGateBias);
  builder_.add_cellBias(cellBias);
  builder_.add_forgetGateBias(forgetGateBias);
  builder_.add_recurrentToOutputWeights(recurrentToOutputWeights);
  builder_.add_recurrentToCellWeights(recurrentToCellWeights);
  builder_.add_recurrentToForgetWeights(recurrentToForgetWeights);
  builder_.add_inputToOutputWeights(inputToOutputWeights);
  builder_.add_inputToCellWeights(inputToCellWeights);
  builder_.add_inputToForgetWeights(inputToForgetWeights);
  return builder_.Finish();
}

struct LstmDescriptor FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
  typedef LstmDescriptorBuilder Builder;
  enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
    VT_ACTIVATIONFUNC = 4,
    VT_CLIPPINGTHRESCELL = 6,
    VT_CLIPPINGTHRESPROJ = 8,
    VT_CIFGENABLED = 10,
    VT_PEEPHOLEENABLED = 12,
    VT_PROJECTIONENABLED = 14,
    VT_LAYERNORMENABLED = 16
  };
  uint32_t activationFunc() const {
    return GetField<uint32_t>(VT_ACTIVATIONFUNC, 0);
  }
  float clippingThresCell() const {
    return GetField<float>(VT_CLIPPINGTHRESCELL, 0.0f);
  }
  float clippingThresProj() const {
    return GetField<float>(VT_CLIPPINGTHRESPROJ, 0.0f);
  }
  bool cifgEnabled() const {
    return GetField<uint8_t>(VT_CIFGENABLED, 1) != 0;
  }
  bool peepholeEnabled() const {
    return GetField<uint8_t>(VT_PEEPHOLEENABLED, 0) != 0;
  }
  bool projectionEnabled() const {
    return GetField<uint8_t>(VT_PROJECTIONENABLED, 0) != 0;
  }
  bool layerNormEnabled() const {
    return GetField<uint8_t>(VT_LAYERNORMENABLED, 0) != 0;
  }
  bool Verify(flatbuffers::Verifier &verifier) const {
    return VerifyTableStart(verifier) &&
           VerifyField<uint32_t>(verifier, VT_ACTIVATIONFUNC) &&
           VerifyField<float>(verifier, VT_CLIPPINGTHRESCELL) &&
           VerifyField<float>(verifier, VT_CLIPPINGTHRESPROJ) &&
           VerifyField<uint8_t>(verifier, VT_CIFGENABLED) &&
           VerifyField<uint8_t>(verifier, VT_PEEPHOLEENABLED) &&
           VerifyField<uint8_t>(verifier, VT_PROJECTIONENABLED) &&
           VerifyField<uint8_t>(verifier, VT_LAYERNORMENABLED) &&
           verifier.EndTable();
  }
};

struct LstmDescriptorBuilder {
  typedef LstmDescriptor Table;
  flatbuffers::FlatBufferBuilder &fbb_;
  flatbuffers::uoffset_t start_;
  void add_activationFunc(uint32_t activationFunc) {
    fbb_.AddElement<uint32_t>(LstmDescriptor::VT_ACTIVATIONFUNC, activationFunc, 0);
  }
  void add_clippingThresCell(float clippingThresCell) {
    fbb_.AddElement<float>(LstmDescriptor::VT_CLIPPINGTHRESCELL, clippingThresCell, 0.0f);
  }
  void add_clippingThresProj(float clippingThresProj) {
    fbb_.AddElement<float>(LstmDescriptor::VT_CLIPPINGTHRESPROJ, clippingThresProj, 0.0f);
  }
  void add_cifgEnabled(bool cifgEnabled) {
    fbb_.AddElement<uint8_t>(LstmDescriptor::VT_CIFGENABLED, static_cast<uint8_t>(cifgEnabled), 1);
  }
  void add_peepholeEnabled(bool peepholeEnabled) {
    fbb_.AddElement<uint8_t>(LstmDescriptor::VT_PEEPHOLEENABLED, static_cast<uint8_t>(peepholeEnabled), 0);
  }
  void add_projectionEnabled(bool projectionEnabled) {
    fbb_.AddElement<uint8_t>(LstmDescriptor::VT_PROJECTIONENABLED, static_cast<uint8_t>(projectionEnabled), 0);
  }
  void add_layerNormEnabled(bool layerNormEnabled) {
    fbb_.AddElement<uint8_t>(LstmDescriptor::VT_LAYERNORMENABLED, static_cast<uint8_t>(layerNormEnabled), 0);
  }
  explicit LstmDescriptorBuilder(flatbuffers::FlatBufferBuilder &_fbb)
        : fbb_(_fbb) {
    start_ = fbb_.StartTable();
  }
  LstmDescriptorBuilder &operator=(const LstmDescriptorBuilder &);
  flatbuffers::Offset<LstmDescriptor> Finish() {
    const auto end = fbb_.EndTable(start_);
    auto o = flatbuffers::Offset<LstmDescriptor>(end);
    return o;
  }
};

inline flatbuffers::Offset<LstmDescriptor> CreateLstmDescriptor(
    flatbuffers::FlatBufferBuilder &_fbb,
    uint32_t activationFunc = 0,
    float clippingThresCell = 0.0f,
    float clippingThresProj = 0.0f,
    bool cifgEnabled = true,
    bool peepholeEnabled = false,
    bool projectionEnabled = false,
    bool layerNormEnabled = false) {
  LstmDescriptorBuilder builder_(_fbb);
  builder_.add_clippingThresProj(clippingThresProj);
  builder_.add_clippingThresCell(clippingThresCell);
  builder_.add_activationFunc(activationFunc);
  builder_.add_layerNormEnabled(layerNormEnabled);
  builder_.add_projectionEnabled(projectionEnabled);
  builder_.add_peepholeEnabled(peepholeEnabled);
  builder_.add_cifgEnabled(cifgEnabled);
  return builder_.Finish();
}

struct LstmLayer FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
  typedef LstmLayerBuilder Builder;
  enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
    VT_BASE = 4,
    VT_DESCRIPTOR = 6,
    VT_INPUTPARAMS = 8
  };
  const armnnSerializer::LayerBase *base() const {
    return GetPointer<const armnnSerializer::LayerBase *>(VT_BASE);
  }
  const armnnSerializer::LstmDescriptor *descriptor() const {
    return GetPointer<const armnnSerializer::LstmDescriptor *>(VT_DESCRIPTOR);
  }
  const armnnSerializer::LstmInputParams *inputParams() const {
    return GetPointer<const armnnSerializer::LstmInputParams *>(VT_INPUTPARAMS);
  }
  bool Verify(flatbuffers::Verifier &verifier) const {
    return VerifyTableStart(verifier) &&
           VerifyOffset(verifier, VT_BASE) &&
           verifier.VerifyTable(base()) &&
           VerifyOffset(verifier, VT_DESCRIPTOR) &&
           verifier.VerifyTable(descriptor()) &&
           VerifyOffset(verifier, VT_INPUTPARAMS) &&
           verifier.VerifyTable(inputParams()) &&
           verifier.EndTable();
  }
};

struct LstmLayerBuilder {
  typedef LstmLayer Table;
  flatbuffers::FlatBufferBuilder &fbb_;
  flatbuffers::uoffset_t start_;
  void add_base(flatbuffers::Offset<armnnSerializer::LayerBase> base) {
    fbb_.AddOffset(LstmLayer::VT_BASE, base);
  }
  void add_descriptor(flatbuffers::Offset<armnnSerializer::LstmDescriptor> descriptor) {
    fbb_.AddOffset(LstmLayer::VT_DESCRIPTOR, descriptor);
  }
  void add_inputParams(flatbuffers::Offset<armnnSerializer::LstmInputParams> inputParams) {
    fbb_.AddOffset(LstmLayer::VT_INPUTPARAMS, inputParams);
  }
  explicit LstmLayerBuilder(flatbuffers::FlatBufferBuilder &_fbb)
        : fbb_(_fbb) {
    start_ = fbb_.StartTable();
  }
  LstmLayerBuilder &operator=(const LstmLayerBuilder &);
  flatbuffers::Offset<LstmLayer> Finish() {
    const auto end = fbb_.EndTable(start_);
    auto o = flatbuffers::Offset<LstmLayer>(end);
    return o;
  }
};

inline flatbuffers::Offset<LstmLayer> CreateLstmLayer(
    flatbuffers::FlatBufferBuilder &_fbb,
    flatbuffers::Offset<armnnSerializer::LayerBase> base = 0,
    flatbuffers::Offset<armnnSerializer::LstmDescriptor> descriptor = 0,
    flatbuffers::Offset<armnnSerializer::LstmInputParams> inputParams = 0) {
  LstmLayerBuilder builder_(_fbb);
  builder_.add_inputParams(inputParams);
  builder_.add_descriptor(descriptor);
  builder_.add_base(base);
  return builder_.Finish();
}

struct QLstmInputParams FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
  typedef QLstmInputParamsBuilder Builder;
  enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
    VT_INPUTTOFORGETWEIGHTS = 4,
    VT_INPUTTOCELLWEIGHTS = 6,
    VT_INPUTTOOUTPUTWEIGHTS = 8,
    VT_RECURRENTTOFORGETWEIGHTS = 10,
    VT_RECURRENTTOCELLWEIGHTS = 12,
    VT_RECURRENTTOOUTPUTWEIGHTS = 14,
    VT_FORGETGATEBIAS = 16,
    VT_CELLBIAS = 18,
    VT_OUTPUTGATEBIAS = 20,
    VT_INPUTTOINPUTWEIGHTS = 22,
    VT_RECURRENTTOINPUTWEIGHTS = 24,
    VT_INPUTGATEBIAS = 26,
    VT_PROJECTIONWEIGHTS = 28,
    VT_PROJECTIONBIAS = 30,
    VT_CELLTOINPUTWEIGHTS = 32,
    VT_CELLTOFORGETWEIGHTS = 34,
    VT_CELLTOOUTPUTWEIGHTS = 36,
    VT_INPUTLAYERNORMWEIGHTS = 38,
    VT_FORGETLAYERNORMWEIGHTS = 40,
    VT_CELLLAYERNORMWEIGHTS = 42,
    VT_OUTPUTLAYERNORMWEIGHTS = 44
  };
  const armnnSerializer::ConstTensor *inputToForgetWeights() const {
    return GetPointer<const armnnSerializer::ConstTensor *>(VT_INPUTTOFORGETWEIGHTS);
  }
  const armnnSerializer::ConstTensor *inputToCellWeights() const {
    return GetPointer<const armnnSerializer::ConstTensor *>(VT_INPUTTOCELLWEIGHTS);
  }
  const armnnSerializer::ConstTensor *inputToOutputWeights() const {
    return GetPointer<const armnnSerializer::ConstTensor *>(VT_INPUTTOOUTPUTWEIGHTS);
  }
  const armnnSerializer::ConstTensor *recurrentToForgetWeights() const {
    return GetPointer<const armnnSerializer::ConstTensor *>(VT_RECURRENTTOFORGETWEIGHTS);
  }
  const armnnSerializer::ConstTensor *recurrentToCellWeights() const {
    return GetPointer<const armnnSerializer::ConstTensor *>(VT_RECURRENTTOCELLWEIGHTS);
  }
  const armnnSerializer::ConstTensor *recurrentToOutputWeights() const {
    return GetPointer<const armnnSerializer::ConstTensor *>(VT_RECURRENTTOOUTPUTWEIGHTS);
  }
  const armnnSerializer::ConstTensor *forgetGateBias() const {
    return GetPointer<const armnnSerializer::ConstTensor *>(VT_FORGETGATEBIAS);
  }
  const armnnSerializer::ConstTensor *cellBias() const {
    return GetPointer<const armnnSerializer::ConstTensor *>(VT_CELLBIAS);
  }
  const armnnSerializer::ConstTensor *outputGateBias() const {
    return GetPointer<const armnnSerializer::ConstTensor *>(VT_OUTPUTGATEBIAS);
  }
  const armnnSerializer::ConstTensor *inputToInputWeights() const {
    return GetPointer<const armnnSerializer::ConstTensor *>(VT_INPUTTOINPUTWEIGHTS);
  }
  const armnnSerializer::ConstTensor *recurrentToInputWeights() const {
    return GetPointer<const armnnSerializer::ConstTensor *>(VT_RECURRENTTOINPUTWEIGHTS);
  }
  const armnnSerializer::ConstTensor *inputGateBias() const {
    return GetPointer<const armnnSerializer::ConstTensor *>(VT_INPUTGATEBIAS);
  }
  const armnnSerializer::ConstTensor *projectionWeights() const {
    return GetPointer<const armnnSerializer::ConstTensor *>(VT_PROJECTIONWEIGHTS);
  }
  const armnnSerializer::ConstTensor *projectionBias() const {
    return GetPointer<const armnnSerializer::ConstTensor *>(VT_PROJECTIONBIAS);
  }
  const armnnSerializer::ConstTensor *cellToInputWeights() const {
    return GetPointer<const armnnSerializer::ConstTensor *>(VT_CELLTOINPUTWEIGHTS);
  }
  const armnnSerializer::ConstTensor *cellToForgetWeights() const {
    return GetPointer<const armnnSerializer::ConstTensor *>(VT_CELLTOFORGETWEIGHTS);
  }
  const armnnSerializer::ConstTensor *cellToOutputWeights() const {
    return GetPointer<const armnnSerializer::ConstTensor *>(VT_CELLTOOUTPUTWEIGHTS);
  }
  const armnnSerializer::ConstTensor *inputLayerNormWeights() const {
    return GetPointer<const armnnSerializer::ConstTensor *>(VT_INPUTLAYERNORMWEIGHTS);
  }
  const armnnSerializer::ConstTensor *forgetLayerNormWeights() const {
    return GetPointer<const armnnSerializer::ConstTensor *>(VT_FORGETLAYERNORMWEIGHTS);
  }
  const armnnSerializer::ConstTensor *cellLayerNormWeights() const {
    return GetPointer<const armnnSerializer::ConstTensor *>(VT_CELLLAYERNORMWEIGHTS);
  }
  const armnnSerializer::ConstTensor *outputLayerNormWeights() const {
    return GetPointer<const armnnSerializer::ConstTensor *>(VT_OUTPUTLAYERNORMWEIGHTS);
  }
  bool Verify(flatbuffers::Verifier &verifier) const {
    return VerifyTableStart(verifier) &&
           VerifyOffset(verifier, VT_INPUTTOFORGETWEIGHTS) &&
           verifier.VerifyTable(inputToForgetWeights()) &&
           VerifyOffset(verifier, VT_INPUTTOCELLWEIGHTS) &&
           verifier.VerifyTable(inputToCellWeights()) &&
           VerifyOffset(verifier, VT_INPUTTOOUTPUTWEIGHTS) &&
           verifier.VerifyTable(inputToOutputWeights()) &&
           VerifyOffset(verifier, VT_RECURRENTTOFORGETWEIGHTS) &&
           verifier.VerifyTable(recurrentToForgetWeights()) &&
           VerifyOffset(verifier, VT_RECURRENTTOCELLWEIGHTS) &&
           verifier.VerifyTable(recurrentToCellWeights()) &&
           VerifyOffset(verifier, VT_RECURRENTTOOUTPUTWEIGHTS) &&
           verifier.VerifyTable(recurrentToOutputWeights()) &&
           VerifyOffset(verifier, VT_FORGETGATEBIAS) &&
           verifier.VerifyTable(forgetGateBias()) &&
           VerifyOffset(verifier, VT_CELLBIAS) &&
           verifier.VerifyTable(cellBias()) &&
           VerifyOffset(verifier, VT_OUTPUTGATEBIAS) &&
           verifier.VerifyTable(outputGateBias()) &&
           VerifyOffset(verifier, VT_INPUTTOINPUTWEIGHTS) &&
           verifier.VerifyTable(inputToInputWeights()) &&
           VerifyOffset(verifier, VT_RECURRENTTOINPUTWEIGHTS) &&
           verifier.VerifyTable(recurrentToInputWeights()) &&
           VerifyOffset(verifier, VT_INPUTGATEBIAS) &&
           verifier.VerifyTable(inputGateBias()) &&
           VerifyOffset(verifier, VT_PROJECTIONWEIGHTS) &&
           verifier.VerifyTable(projectionWeights()) &&
           VerifyOffset(verifier, VT_PROJECTIONBIAS) &&
           verifier.VerifyTable(projectionBias()) &&
           VerifyOffset(verifier, VT_CELLTOINPUTWEIGHTS) &&
           verifier.VerifyTable(cellToInputWeights()) &&
           VerifyOffset(verifier, VT_CELLTOFORGETWEIGHTS) &&
           verifier.VerifyTable(cellToForgetWeights()) &&
           VerifyOffset(verifier, VT_CELLTOOUTPUTWEIGHTS) &&
           verifier.VerifyTable(cellToOutputWeights()) &&
           VerifyOffset(verifier, VT_INPUTLAYERNORMWEIGHTS) &&
           verifier.VerifyTable(inputLayerNormWeights()) &&
           VerifyOffset(verifier, VT_FORGETLAYERNORMWEIGHTS) &&
           verifier.VerifyTable(forgetLayerNormWeights()) &&
           VerifyOffset(verifier, VT_CELLLAYERNORMWEIGHTS) &&
           verifier.VerifyTable(cellLayerNormWeights()) &&
           VerifyOffset(verifier, VT_OUTPUTLAYERNORMWEIGHTS) &&
           verifier.VerifyTable(outputLayerNormWeights()) &&
           verifier.EndTable();
  }
};

struct QLstmInputParamsBuilder {
  typedef QLstmInputParams Table;
  flatbuffers::FlatBufferBuilder &fbb_;
  flatbuffers::uoffset_t start_;
  void add_inputToForgetWeights(flatbuffers::Offset<armnnSerializer::ConstTensor> inputToForgetWeights) {
    fbb_.AddOffset(QLstmInputParams::VT_INPUTTOFORGETWEIGHTS, inputToForgetWeights);
  }
  void add_inputToCellWeights(flatbuffers::Offset<armnnSerializer::ConstTensor> inputToCellWeights) {
    fbb_.AddOffset(QLstmInputParams::VT_INPUTTOCELLWEIGHTS, inputToCellWeights);
  }
  void add_inputToOutputWeights(flatbuffers::Offset<armnnSerializer::ConstTensor> inputToOutputWeights) {
    fbb_.AddOffset(QLstmInputParams::VT_INPUTTOOUTPUTWEIGHTS, inputToOutputWeights);
  }
  void add_recurrentToForgetWeights(flatbuffers::Offset<armnnSerializer::ConstTensor> recurrentToForgetWeights) {
    fbb_.AddOffset(QLstmInputParams::VT_RECURRENTTOFORGETWEIGHTS, recurrentToForgetWeights);
  }
  void add_recurrentToCellWeights(flatbuffers::Offset<armnnSerializer::ConstTensor> recurrentToCellWeights) {
    fbb_.AddOffset(QLstmInputParams::VT_RECURRENTTOCELLWEIGHTS, recurrentToCellWeights);
  }
  void add_recurrentToOutputWeights(flatbuffers::Offset<armnnSerializer::ConstTensor> recurrentToOutputWeights) {
    fbb_.AddOffset(QLstmInputParams::VT_RECURRENTTOOUTPUTWEIGHTS, recurrentToOutputWeights);
  }
  void add_forgetGateBias(flatbuffers::Offset<armnnSerializer::ConstTensor> forgetGateBias) {
    fbb_.AddOffset(QLstmInputParams::VT_FORGETGATEBIAS, forgetGateBias);
  }
  void add_cellBias(flatbuffers::Offset<armnnSerializer::ConstTensor> cellBias) {
    fbb_.AddOffset(QLstmInputParams::VT_CELLBIAS, cellBias);
  }
  void add_outputGateBias(flatbuffers::Offset<armnnSerializer::ConstTensor> outputGateBias) {
    fbb_.AddOffset(QLstmInputParams::VT_OUTPUTGATEBIAS, outputGateBias);
  }
  void add_inputToInputWeights(flatbuffers::Offset<armnnSerializer::ConstTensor> inputToInputWeights) {
    fbb_.AddOffset(QLstmInputParams::VT_INPUTTOINPUTWEIGHTS, inputToInputWeights);
  }
  void add_recurrentToInputWeights(flatbuffers::Offset<armnnSerializer::ConstTensor> recurrentToInputWeights) {
    fbb_.AddOffset(QLstmInputParams::VT_RECURRENTTOINPUTWEIGHTS, recurrentToInputWeights);
  }
  void add_inputGateBias(flatbuffers::Offset<armnnSerializer::ConstTensor> inputGateBias) {
    fbb_.AddOffset(QLstmInputParams::VT_INPUTGATEBIAS, inputGateBias);
  }
  void add_projectionWeights(flatbuffers::Offset<armnnSerializer::ConstTensor> projectionWeights) {
    fbb_.AddOffset(QLstmInputParams::VT_PROJECTIONWEIGHTS, projectionWeights);
  }
  void add_projectionBias(flatbuffers::Offset<armnnSerializer::ConstTensor> projectionBias) {
    fbb_.AddOffset(QLstmInputParams::VT_PROJECTIONBIAS, projectionBias);
  }
  void add_cellToInputWeights(flatbuffers::Offset<armnnSerializer::ConstTensor> cellToInputWeights) {
    fbb_.AddOffset(QLstmInputParams::VT_CELLTOINPUTWEIGHTS, cellToInputWeights);
  }
  void add_cellToForgetWeights(flatbuffers::Offset<armnnSerializer::ConstTensor> cellToForgetWeights) {
    fbb_.AddOffset(QLstmInputParams::VT_CELLTOFORGETWEIGHTS, cellToForgetWeights);
  }
  void add_cellToOutputWeights(flatbuffers::Offset<armnnSerializer::ConstTensor> cellToOutputWeights) {
    fbb_.AddOffset(QLstmInputParams::VT_CELLTOOUTPUTWEIGHTS, cellToOutputWeights);
  }
  void add_inputLayerNormWeights(flatbuffers::Offset<armnnSerializer::ConstTensor> inputLayerNormWeights) {
    fbb_.AddOffset(QLstmInputParams::VT_INPUTLAYERNORMWEIGHTS, inputLayerNormWeights);
  }
  void add_forgetLayerNormWeights(flatbuffers::Offset<armnnSerializer::ConstTensor> forgetLayerNormWeights) {
    fbb_.AddOffset(QLstmInputParams::VT_FORGETLAYERNORMWEIGHTS, forgetLayerNormWeights);
  }
  void add_cellLayerNormWeights(flatbuffers::Offset<armnnSerializer::ConstTensor> cellLayerNormWeights) {
    fbb_.AddOffset(QLstmInputParams::VT_CELLLAYERNORMWEIGHTS, cellLayerNormWeights);
  }
  void add_outputLayerNormWeights(flatbuffers::Offset<armnnSerializer::ConstTensor> outputLayerNormWeights) {
    fbb_.AddOffset(QLstmInputParams::VT_OUTPUTLAYERNORMWEIGHTS, outputLayerNormWeights);
  }
  explicit QLstmInputParamsBuilder(flatbuffers::FlatBufferBuilder &_fbb)
        : fbb_(_fbb) {
    start_ = fbb_.StartTable();
  }
  QLstmInputParamsBuilder &operator=(const QLstmInputParamsBuilder &);
  flatbuffers::Offset<QLstmInputParams> Finish() {
    const auto end = fbb_.EndTable(start_);
    auto o = flatbuffers::Offset<QLstmInputParams>(end);
    return o;
  }
};

inline flatbuffers::Offset<QLstmInputParams> CreateQLstmInputParams(
    flatbuffers::FlatBufferBuilder &_fbb,
    flatbuffers::Offset<armnnSerializer::ConstTensor> inputToForgetWeights = 0,
    flatbuffers::Offset<armnnSerializer::ConstTensor> inputToCellWeights = 0,
    flatbuffers::Offset<armnnSerializer::ConstTensor> inputToOutputWeights = 0,
    flatbuffers::Offset<armnnSerializer::ConstTensor> recurrentToForgetWeights = 0,
    flatbuffers::Offset<armnnSerializer::ConstTensor> recurrentToCellWeights = 0,
    flatbuffers::Offset<armnnSerializer::ConstTensor> recurrentToOutputWeights = 0,
    flatbuffers::Offset<armnnSerializer::ConstTensor> forgetGateBias = 0,
    flatbuffers::Offset<armnnSerializer::ConstTensor> cellBias = 0,
    flatbuffers::Offset<armnnSerializer::ConstTensor> outputGateBias = 0,
    flatbuffers::Offset<armnnSerializer::ConstTensor> inputToInputWeights = 0,
    flatbuffers::Offset<armnnSerializer::ConstTensor> recurrentToInputWeights = 0,
    flatbuffers::Offset<armnnSerializer::ConstTensor> inputGateBias = 0,
    flatbuffers::Offset<armnnSerializer::ConstTensor> projectionWeights = 0,
    flatbuffers::Offset<armnnSerializer::ConstTensor> projectionBias = 0,
    flatbuffers::Offset<armnnSerializer::ConstTensor> cellToInputWeights = 0,
    flatbuffers::Offset<armnnSerializer::ConstTensor> cellToForgetWeights = 0,
    flatbuffers::Offset<armnnSerializer::ConstTensor> cellToOutputWeights = 0,
    flatbuffers::Offset<armnnSerializer::ConstTensor> inputLayerNormWeights = 0,
    flatbuffers::Offset<armnnSerializer::ConstTensor> forgetLayerNormWeights = 0,
    flatbuffers::Offset<armnnSerializer::ConstTensor> cellLayerNormWeights = 0,
    flatbuffers::Offset<armnnSerializer::ConstTensor> outputLayerNormWeights = 0) {
  QLstmInputParamsBuilder builder_(_fbb);
  builder_.add_outputLayerNormWeights(outputLayerNormWeights);
  builder_.add_cellLayerNormWeights(cellLayerNormWeights);
  builder_.add_forgetLayerNormWeights(forgetLayerNormWeights);
  builder_.add_inputLayerNormWeights(inputLayerNormWeights);
  builder_.add_cellToOutputWeights(cellToOutputWeights);
  builder_.add_cellToForgetWeights(cellToForgetWeights);
  builder_.add_cellToInputWeights(cellToInputWeights);
  builder_.add_projectionBias(projectionBias);
  builder_.add_projectionWeights(projectionWeights);
  builder_.add_inputGateBias(inputGateBias);
  builder_.add_recurrentToInputWeights(recurrentToInputWeights);
  builder_.add_inputToInputWeights(inputToInputWeights);
  builder_.add_outputGateBias(outputGateBias);
  builder_.add_cellBias(cellBias);
  builder_.add_forgetGateBias(forgetGateBias);
  builder_.add_recurrentToOutputWeights(recurrentToOutputWeights);
  builder_.add_recurrentToCellWeights(recurrentToCellWeights);
  builder_.add_recurrentToForgetWeights(recurrentToForgetWeights);
  builder_.add_inputToOutputWeights(inputToOutputWeights);
  builder_.add_inputToCellWeights(inputToCellWeights);
  builder_.add_inputToForgetWeights(inputToForgetWeights);
  return builder_.Finish();
}

struct QLstmDescriptor FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
  typedef QLstmDescriptorBuilder Builder;
  enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
    VT_CIFGENABLED = 4,
    VT_PEEPHOLEENABLED = 6,
    VT_PROJECTIONENABLED = 8,
    VT_LAYERNORMENABLED = 10,
    VT_CELLCLIP = 12,
    VT_PROJECTIONCLIP = 14,
    VT_INPUTINTERMEDIATESCALE = 16,
    VT_FORGETINTERMEDIATESCALE = 18,
    VT_CELLINTERMEDIATESCALE = 20,
    VT_OUTPUTINTERMEDIATESCALE = 22,
    VT_HIDDENSTATEZEROPOINT = 24,
    VT_HIDDENSTATESCALE = 26
  };
  bool cifgEnabled() const {
    return GetField<uint8_t>(VT_CIFGENABLED, 1) != 0;
  }
  bool peepholeEnabled() const {
    return GetField<uint8_t>(VT_PEEPHOLEENABLED, 0) != 0;
  }
  bool projectionEnabled() const {
    return GetField<uint8_t>(VT_PROJECTIONENABLED, 0) != 0;
  }
  bool layerNormEnabled() const {
    return GetField<uint8_t>(VT_LAYERNORMENABLED, 0) != 0;
  }
  float cellClip() const {
    return GetField<float>(VT_CELLCLIP, 0.0f);
  }
  float projectionClip() const {
    return GetField<float>(VT_PROJECTIONCLIP, 0.0f);
  }
  float inputIntermediateScale() const {
    return GetField<float>(VT_INPUTINTERMEDIATESCALE, 0.0f);
  }
  float forgetIntermediateScale() const {
    return GetField<float>(VT_FORGETINTERMEDIATESCALE, 0.0f);
  }
  float cellIntermediateScale() const {
    return GetField<float>(VT_CELLINTERMEDIATESCALE, 0.0f);
  }
  float outputIntermediateScale() const {
    return GetField<float>(VT_OUTPUTINTERMEDIATESCALE, 0.0f);
  }
  int32_t hiddenStateZeroPoint() const {
    return GetField<int32_t>(VT_HIDDENSTATEZEROPOINT, 0);
  }
  float hiddenStateScale() const {
    return GetField<float>(VT_HIDDENSTATESCALE, 0.0f);
  }
  bool Verify(flatbuffers::Verifier &verifier) const {
    return VerifyTableStart(verifier) &&
           VerifyField<uint8_t>(verifier, VT_CIFGENABLED) &&
           VerifyField<uint8_t>(verifier, VT_PEEPHOLEENABLED) &&
           VerifyField<uint8_t>(verifier, VT_PROJECTIONENABLED) &&
           VerifyField<uint8_t>(verifier, VT_LAYERNORMENABLED) &&
           VerifyField<float>(verifier, VT_CELLCLIP) &&
           VerifyField<float>(verifier, VT_PROJECTIONCLIP) &&
           VerifyField<float>(verifier, VT_INPUTINTERMEDIATESCALE) &&
           VerifyField<float>(verifier, VT_FORGETINTERMEDIATESCALE) &&
           VerifyField<float>(verifier, VT_CELLINTERMEDIATESCALE) &&
           VerifyField<float>(verifier, VT_OUTPUTINTERMEDIATESCALE) &&
           VerifyField<int32_t>(verifier, VT_HIDDENSTATEZEROPOINT) &&
           VerifyField<float>(verifier, VT_HIDDENSTATESCALE) &&
           verifier.EndTable();
  }
};

struct QLstmDescriptorBuilder {
  typedef QLstmDescriptor Table;
  flatbuffers::FlatBufferBuilder &fbb_;
  flatbuffers::uoffset_t start_;
  void add_cifgEnabled(bool cifgEnabled) {
    fbb_.AddElement<uint8_t>(QLstmDescriptor::VT_CIFGENABLED, static_cast<uint8_t>(cifgEnabled), 1);
  }
  void add_peepholeEnabled(bool peepholeEnabled) {
    fbb_.AddElement<uint8_t>(QLstmDescriptor::VT_PEEPHOLEENABLED, static_cast<uint8_t>(peepholeEnabled), 0);
  }
  void add_projectionEnabled(bool projectionEnabled) {
    fbb_.AddElement<uint8_t>(QLstmDescriptor::VT_PROJECTIONENABLED, static_cast<uint8_t>(projectionEnabled), 0);
  }
  void add_layerNormEnabled(bool layerNormEnabled) {
    fbb_.AddElement<uint8_t>(QLstmDescriptor::VT_LAYERNORMENABLED, static_cast<uint8_t>(layerNormEnabled), 0);
  }
  void add_cellClip(float cellClip) {
    fbb_.AddElement<float>(QLstmDescriptor::VT_CELLCLIP, cellClip, 0.0f);
  }
  void add_projectionClip(float projectionClip) {
    fbb_.AddElement<float>(QLstmDescriptor::VT_PROJECTIONCLIP, projectionClip, 0.0f);
  }
  void add_inputIntermediateScale(float inputIntermediateScale) {
    fbb_.AddElement<float>(QLstmDescriptor::VT_INPUTINTERMEDIATESCALE, inputIntermediateScale, 0.0f);
  }
  void add_forgetIntermediateScale(float forgetIntermediateScale) {
    fbb_.AddElement<float>(QLstmDescriptor::VT_FORGETINTERMEDIATESCALE, forgetIntermediateScale, 0.0f);
  }
  void add_cellIntermediateScale(float cellIntermediateScale) {
    fbb_.AddElement<float>(QLstmDescriptor::VT_CELLINTERMEDIATESCALE, cellIntermediateScale, 0.0f);
  }
  void add_outputIntermediateScale(float outputIntermediateScale) {
    fbb_.AddElement<float>(QLstmDescriptor::VT_OUTPUTINTERMEDIATESCALE, outputIntermediateScale, 0.0f);
  }
  void add_hiddenStateZeroPoint(int32_t hiddenStateZeroPoint) {
    fbb_.AddElement<int32_t>(QLstmDescriptor::VT_HIDDENSTATEZEROPOINT, hiddenStateZeroPoint, 0);
  }
  void add_hiddenStateScale(float hiddenStateScale) {
    fbb_.AddElement<float>(QLstmDescriptor::VT_HIDDENSTATESCALE, hiddenStateScale, 0.0f);
  }
  explicit QLstmDescriptorBuilder(flatbuffers::FlatBufferBuilder &_fbb)
        : fbb_(_fbb) {
    start_ = fbb_.StartTable();
  }
  QLstmDescriptorBuilder &operator=(const QLstmDescriptorBuilder &);
  flatbuffers::Offset<QLstmDescriptor> Finish() {
    const auto end = fbb_.EndTable(start_);
    auto o = flatbuffers::Offset<QLstmDescriptor>(end);
    return o;
  }
};

inline flatbuffers::Offset<QLstmDescriptor> CreateQLstmDescriptor(
    flatbuffers::FlatBufferBuilder &_fbb,
    bool cifgEnabled = true,
    bool peepholeEnabled = false,
    bool projectionEnabled = false,
    bool layerNormEnabled = false,
    float cellClip = 0.0f,
    float projectionClip = 0.0f,
    float inputIntermediateScale = 0.0f,
    float forgetIntermediateScale = 0.0f,
    float cellIntermediateScale = 0.0f,
    float outputIntermediateScale = 0.0f,
    int32_t hiddenStateZeroPoint = 0,
    float hiddenStateScale = 0.0f) {
  QLstmDescriptorBuilder builder_(_fbb);
  builder_.add_hiddenStateScale(hiddenStateScale);
  builder_.add_hiddenStateZeroPoint(hiddenStateZeroPoint);
  builder_.add_outputIntermediateScale(outputIntermediateScale);
  builder_.add_cellIntermediateScale(cellIntermediateScale);
  builder_.add_forgetIntermediateScale(forgetIntermediateScale);
  builder_.add_inputIntermediateScale(inputIntermediateScale);
  builder_.add_projectionClip(projectionClip);
  builder_.add_cellClip(cellClip);
  builder_.add_layerNormEnabled(layerNormEnabled);
  builder_.add_projectionEnabled(projectionEnabled);
  builder_.add_peepholeEnabled(peepholeEnabled);
  builder_.add_cifgEnabled(cifgEnabled);
  return builder_.Finish();
}

struct QLstmLayer FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
  typedef QLstmLayerBuilder Builder;
  enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
    VT_BASE = 4,
    VT_DESCRIPTOR = 6,
    VT_INPUTPARAMS = 8
  };
  const armnnSerializer::LayerBase *base() const {
    return GetPointer<const armnnSerializer::LayerBase *>(VT_BASE);
  }
  const armnnSerializer::QLstmDescriptor *descriptor() const {
    return GetPointer<const armnnSerializer::QLstmDescriptor *>(VT_DESCRIPTOR);
  }
  const armnnSerializer::QLstmInputParams *inputParams() const {
    return GetPointer<const armnnSerializer::QLstmInputParams *>(VT_INPUTPARAMS);
  }
  bool Verify(flatbuffers::Verifier &verifier) const {
    return VerifyTableStart(verifier) &&
           VerifyOffset(verifier, VT_BASE) &&
           verifier.VerifyTable(base()) &&
           VerifyOffset(verifier, VT_DESCRIPTOR) &&
           verifier.VerifyTable(descriptor()) &&
           VerifyOffset(verifier, VT_INPUTPARAMS) &&
           verifier.VerifyTable(inputParams()) &&
           verifier.EndTable();
  }
};

struct QLstmLayerBuilder {
  typedef QLstmLayer Table;
  flatbuffers::FlatBufferBuilder &fbb_;
  flatbuffers::uoffset_t start_;
  void add_base(flatbuffers::Offset<armnnSerializer::LayerBase> base) {
    fbb_.AddOffset(QLstmLayer::VT_BASE, base);
  }
  void add_descriptor(flatbuffers::Offset<armnnSerializer::QLstmDescriptor> descriptor) {
    fbb_.AddOffset(QLstmLayer::VT_DESCRIPTOR, descriptor);
  }
  void add_inputParams(flatbuffers::Offset<armnnSerializer::QLstmInputParams> inputParams) {
    fbb_.AddOffset(QLstmLayer::VT_INPUTPARAMS, inputParams);
  }
  explicit QLstmLayerBuilder(flatbuffers::FlatBufferBuilder &_fbb)
        : fbb_(_fbb) {
    start_ = fbb_.StartTable();
  }
  QLstmLayerBuilder &operator=(const QLstmLayerBuilder &);
  flatbuffers::Offset<QLstmLayer> Finish() {
    const auto end = fbb_.EndTable(start_);
    auto o = flatbuffers::Offset<QLstmLayer>(end);
    return o;
  }
};

inline flatbuffers::Offset<QLstmLayer> CreateQLstmLayer(
    flatbuffers::FlatBufferBuilder &_fbb,
    flatbuffers::Offset<armnnSerializer::LayerBase> base = 0,
    flatbuffers::Offset<armnnSerializer::QLstmDescriptor> descriptor = 0,
    flatbuffers::Offset<armnnSerializer::QLstmInputParams> inputParams = 0) {
  QLstmLayerBuilder builder_(_fbb);
  builder_.add_inputParams(inputParams);
  builder_.add_descriptor(descriptor);
  builder_.add_base(base);
  return builder_.Finish();
}

struct QuantizedLstmInputParams FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
  typedef QuantizedLstmInputParamsBuilder Builder;
  enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
    VT_INPUTTOINPUTWEIGHTS = 4,
    VT_INPUTTOFORGETWEIGHTS = 6,
    VT_INPUTTOCELLWEIGHTS = 8,
    VT_INPUTTOOUTPUTWEIGHTS = 10,
    VT_RECURRENTTOINPUTWEIGHTS = 12,
    VT_RECURRENTTOFORGETWEIGHTS = 14,
    VT_RECURRENTTOCELLWEIGHTS = 16,
    VT_RECURRENTTOOUTPUTWEIGHTS = 18,
    VT_INPUTGATEBIAS = 20,
    VT_FORGETGATEBIAS = 22,
    VT_CELLBIAS = 24,
    VT_OUTPUTGATEBIAS = 26
  };
  const armnnSerializer::ConstTensor *inputToInputWeights() const {
    return GetPointer<const armnnSerializer::ConstTensor *>(VT_INPUTTOINPUTWEIGHTS);
  }
  const armnnSerializer::ConstTensor *inputToForgetWeights() const {
    return GetPointer<const armnnSerializer::ConstTensor *>(VT_INPUTTOFORGETWEIGHTS);
  }
  const armnnSerializer::ConstTensor *inputToCellWeights() const {
    return GetPointer<const armnnSerializer::ConstTensor *>(VT_INPUTTOCELLWEIGHTS);
  }
  const armnnSerializer::ConstTensor *inputToOutputWeights() const {
    return GetPointer<const armnnSerializer::ConstTensor *>(VT_INPUTTOOUTPUTWEIGHTS);
  }
  const armnnSerializer::ConstTensor *recurrentToInputWeights() const {
    return GetPointer<const armnnSerializer::ConstTensor *>(VT_RECURRENTTOINPUTWEIGHTS);
  }
  const armnnSerializer::ConstTensor *recurrentToForgetWeights() const {
    return GetPointer<const armnnSerializer::ConstTensor *>(VT_RECURRENTTOFORGETWEIGHTS);
  }
  const armnnSerializer::ConstTensor *recurrentToCellWeights() const {
    return GetPointer<const armnnSerializer::ConstTensor *>(VT_RECURRENTTOCELLWEIGHTS);
  }
  const armnnSerializer::ConstTensor *recurrentToOutputWeights() const {
    return GetPointer<const armnnSerializer::ConstTensor *>(VT_RECURRENTTOOUTPUTWEIGHTS);
  }
  const armnnSerializer::ConstTensor *inputGateBias() const {
    return GetPointer<const armnnSerializer::ConstTensor *>(VT_INPUTGATEBIAS);
  }
  const armnnSerializer::ConstTensor *forgetGateBias() const {
    return GetPointer<const armnnSerializer::ConstTensor *>(VT_FORGETGATEBIAS);
  }
  const armnnSerializer::ConstTensor *cellBias() const {
    return GetPointer<const armnnSerializer::ConstTensor *>(VT_CELLBIAS);
  }
  const armnnSerializer::ConstTensor *outputGateBias() const {
    return GetPointer<const armnnSerializer::ConstTensor *>(VT_OUTPUTGATEBIAS);
  }
  bool Verify(flatbuffers::Verifier &verifier) const {
    return VerifyTableStart(verifier) &&
           VerifyOffset(verifier, VT_INPUTTOINPUTWEIGHTS) &&
           verifier.VerifyTable(inputToInputWeights()) &&
           VerifyOffset(verifier, VT_INPUTTOFORGETWEIGHTS) &&
           verifier.VerifyTable(inputToForgetWeights()) &&
           VerifyOffset(verifier, VT_INPUTTOCELLWEIGHTS) &&
           verifier.VerifyTable(inputToCellWeights()) &&
           VerifyOffset(verifier, VT_INPUTTOOUTPUTWEIGHTS) &&
           verifier.VerifyTable(inputToOutputWeights()) &&
           VerifyOffset(verifier, VT_RECURRENTTOINPUTWEIGHTS) &&
           verifier.VerifyTable(recurrentToInputWeights()) &&
           VerifyOffset(verifier, VT_RECURRENTTOFORGETWEIGHTS) &&
           verifier.VerifyTable(recurrentToForgetWeights()) &&
           VerifyOffset(verifier, VT_RECURRENTTOCELLWEIGHTS) &&
           verifier.VerifyTable(recurrentToCellWeights()) &&
           VerifyOffset(verifier, VT_RECURRENTTOOUTPUTWEIGHTS) &&
           verifier.VerifyTable(recurrentToOutputWeights()) &&
           VerifyOffset(verifier, VT_INPUTGATEBIAS) &&
           verifier.VerifyTable(inputGateBias()) &&
           VerifyOffset(verifier, VT_FORGETGATEBIAS) &&
           verifier.VerifyTable(forgetGateBias()) &&
           VerifyOffset(verifier, VT_CELLBIAS) &&
           verifier.VerifyTable(cellBias()) &&
           VerifyOffset(verifier, VT_OUTPUTGATEBIAS) &&
           verifier.VerifyTable(outputGateBias()) &&
           verifier.EndTable();
  }
};

struct QuantizedLstmInputParamsBuilder {
  typedef QuantizedLstmInputParams Table;
  flatbuffers::FlatBufferBuilder &fbb_;
  flatbuffers::uoffset_t start_;
  void add_inputToInputWeights(flatbuffers::Offset<armnnSerializer::ConstTensor> inputToInputWeights) {
    fbb_.AddOffset(QuantizedLstmInputParams::VT_INPUTTOINPUTWEIGHTS, inputToInputWeights);
  }
  void add_inputToForgetWeights(flatbuffers::Offset<armnnSerializer::ConstTensor> inputToForgetWeights) {
    fbb_.AddOffset(QuantizedLstmInputParams::VT_INPUTTOFORGETWEIGHTS, inputToForgetWeights);
  }
  void add_inputToCellWeights(flatbuffers::Offset<armnnSerializer::ConstTensor> inputToCellWeights) {
    fbb_.AddOffset(QuantizedLstmInputParams::VT_INPUTTOCELLWEIGHTS, inputToCellWeights);
  }
  void add_inputToOutputWeights(flatbuffers::Offset<armnnSerializer::ConstTensor> inputToOutputWeights) {
    fbb_.AddOffset(QuantizedLstmInputParams::VT_INPUTTOOUTPUTWEIGHTS, inputToOutputWeights);
  }
  void add_recurrentToInputWeights(flatbuffers::Offset<armnnSerializer::ConstTensor> recurrentToInputWeights) {
    fbb_.AddOffset(QuantizedLstmInputParams::VT_RECURRENTTOINPUTWEIGHTS, recurrentToInputWeights);
  }
  void add_recurrentToForgetWeights(flatbuffers::Offset<armnnSerializer::ConstTensor> recurrentToForgetWeights) {
    fbb_.AddOffset(QuantizedLstmInputParams::VT_RECURRENTTOFORGETWEIGHTS, recurrentToForgetWeights);
  }
  void add_recurrentToCellWeights(flatbuffers::Offset<armnnSerializer::ConstTensor> recurrentToCellWeights) {
    fbb_.AddOffset(QuantizedLstmInputParams::VT_RECURRENTTOCELLWEIGHTS, recurrentToCellWeights);
  }
  void add_recurrentToOutputWeights(flatbuffers::Offset<armnnSerializer::ConstTensor> recurrentToOutputWeights) {
    fbb_.AddOffset(QuantizedLstmInputParams::VT_RECURRENTTOOUTPUTWEIGHTS, recurrentToOutputWeights);
  }
  void add_inputGateBias(flatbuffers::Offset<armnnSerializer::ConstTensor> inputGateBias) {
    fbb_.AddOffset(QuantizedLstmInputParams::VT_INPUTGATEBIAS, inputGateBias);
  }
  void add_forgetGateBias(flatbuffers::Offset<armnnSerializer::ConstTensor> forgetGateBias) {
    fbb_.AddOffset(QuantizedLstmInputParams::VT_FORGETGATEBIAS, forgetGateBias);
  }
  void add_cellBias(flatbuffers::Offset<armnnSerializer::ConstTensor> cellBias) {
    fbb_.AddOffset(QuantizedLstmInputParams::VT_CELLBIAS, cellBias);
  }
  void add_outputGateBias(flatbuffers::Offset<armnnSerializer::ConstTensor> outputGateBias) {
    fbb_.AddOffset(QuantizedLstmInputParams::VT_OUTPUTGATEBIAS, outputGateBias);
  }
  explicit QuantizedLstmInputParamsBuilder(flatbuffers::FlatBufferBuilder &_fbb)
        : fbb_(_fbb) {
    start_ = fbb_.StartTable();
  }
  QuantizedLstmInputParamsBuilder &operator=(const QuantizedLstmInputParamsBuilder &);
  flatbuffers::Offset<QuantizedLstmInputParams> Finish() {
    const auto end = fbb_.EndTable(start_);
    auto o = flatbuffers::Offset<QuantizedLstmInputParams>(end);
    return o;
  }
};

inline flatbuffers::Offset<QuantizedLstmInputParams> CreateQuantizedLstmInputParams(
    flatbuffers::FlatBufferBuilder &_fbb,
    flatbuffers::Offset<armnnSerializer::ConstTensor> inputToInputWeights = 0,
    flatbuffers::Offset<armnnSerializer::ConstTensor> inputToForgetWeights = 0,
    flatbuffers::Offset<armnnSerializer::ConstTensor> inputToCellWeights = 0,
    flatbuffers::Offset<armnnSerializer::ConstTensor> inputToOutputWeights = 0,
    flatbuffers::Offset<armnnSerializer::ConstTensor> recurrentToInputWeights = 0,
    flatbuffers::Offset<armnnSerializer::ConstTensor> recurrentToForgetWeights = 0,
    flatbuffers::Offset<armnnSerializer::ConstTensor> recurrentToCellWeights = 0,
    flatbuffers::Offset<armnnSerializer::ConstTensor> recurrentToOutputWeights = 0,
    flatbuffers::Offset<armnnSerializer::ConstTensor> inputGateBias = 0,
    flatbuffers::Offset<armnnSerializer::ConstTensor> forgetGateBias = 0,
    flatbuffers::Offset<armnnSerializer::ConstTensor> cellBias = 0,
    flatbuffers::Offset<armnnSerializer::ConstTensor> outputGateBias = 0) {
  QuantizedLstmInputParamsBuilder builder_(_fbb);
  builder_.add_outputGateBias(outputGateBias);
  builder_.add_cellBias(cellBias);
  builder_.add_forgetGateBias(forgetGateBias);
  builder_.add_inputGateBias(inputGateBias);
  builder_.add_recurrentToOutputWeights(recurrentToOutputWeights);
  builder_.add_recurrentToCellWeights(recurrentToCellWeights);
  builder_.add_recurrentToForgetWeights(recurrentToForgetWeights);
  builder_.add_recurrentToInputWeights(recurrentToInputWeights);
  builder_.add_inputToOutputWeights(inputToOutputWeights);
  builder_.add_inputToCellWeights(inputToCellWeights);
  builder_.add_inputToForgetWeights(inputToForgetWeights);
  builder_.add_inputToInputWeights(inputToInputWeights);
  return builder_.Finish();
}

struct QuantizedLstmLayer FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
  typedef QuantizedLstmLayerBuilder Builder;
  enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
    VT_BASE = 4,
    VT_INPUTPARAMS = 6
  };
  const armnnSerializer::LayerBase *base() const {
    return GetPointer<const armnnSerializer::LayerBase *>(VT_BASE);
  }
  const armnnSerializer::QuantizedLstmInputParams *inputParams() const {
    return GetPointer<const armnnSerializer::QuantizedLstmInputParams *>(VT_INPUTPARAMS);
  }
  bool Verify(flatbuffers::Verifier &verifier) const {
    return VerifyTableStart(verifier) &&
           VerifyOffset(verifier, VT_BASE) &&
           verifier.VerifyTable(base()) &&
           VerifyOffset(verifier, VT_INPUTPARAMS) &&
           verifier.VerifyTable(inputParams()) &&
           verifier.EndTable();
  }
};

struct QuantizedLstmLayerBuilder {
  typedef QuantizedLstmLayer Table;
  flatbuffers::FlatBufferBuilder &fbb_;
  flatbuffers::uoffset_t start_;
  void add_base(flatbuffers::Offset<armnnSerializer::LayerBase> base) {
    fbb_.AddOffset(QuantizedLstmLayer::VT_BASE, base);
  }
  void add_inputParams(flatbuffers::Offset<armnnSerializer::QuantizedLstmInputParams> inputParams) {
    fbb_.AddOffset(QuantizedLstmLayer::VT_INPUTPARAMS, inputParams);
  }
  explicit QuantizedLstmLayerBuilder(flatbuffers::FlatBufferBuilder &_fbb)
        : fbb_(_fbb) {
    start_ = fbb_.StartTable();
  }
  QuantizedLstmLayerBuilder &operator=(const QuantizedLstmLayerBuilder &);
  flatbuffers::Offset<QuantizedLstmLayer> Finish() {
    const auto end = fbb_.EndTable(start_);
    auto o = flatbuffers::Offset<QuantizedLstmLayer>(end);
    return o;
  }
};

inline flatbuffers::Offset<QuantizedLstmLayer> CreateQuantizedLstmLayer(
    flatbuffers::FlatBufferBuilder &_fbb,
    flatbuffers::Offset<armnnSerializer::LayerBase> base = 0,
    flatbuffers::Offset<armnnSerializer::QuantizedLstmInputParams> inputParams = 0) {
  QuantizedLstmLayerBuilder builder_(_fbb);
  builder_.add_inputParams(inputParams);
  builder_.add_base(base);
  return builder_.Finish();
}

struct DequantizeLayer FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
  typedef DequantizeLayerBuilder Builder;
  enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
    VT_BASE = 4
  };
  const armnnSerializer::LayerBase *base() const {
    return GetPointer<const armnnSerializer::LayerBase *>(VT_BASE);
  }
  bool Verify(flatbuffers::Verifier &verifier) const {
    return VerifyTableStart(verifier) &&
           VerifyOffset(verifier, VT_BASE) &&
           verifier.VerifyTable(base()) &&
           verifier.EndTable();
  }
};

struct DequantizeLayerBuilder {
  typedef DequantizeLayer Table;
  flatbuffers::FlatBufferBuilder &fbb_;
  flatbuffers::uoffset_t start_;
  void add_base(flatbuffers::Offset<armnnSerializer::LayerBase> base) {
    fbb_.AddOffset(DequantizeLayer::VT_BASE, base);
  }
  explicit DequantizeLayerBuilder(flatbuffers::FlatBufferBuilder &_fbb)
        : fbb_(_fbb) {
    start_ = fbb_.StartTable();
  }
  DequantizeLayerBuilder &operator=(const DequantizeLayerBuilder &);
  flatbuffers::Offset<DequantizeLayer> Finish() {
    const auto end = fbb_.EndTable(start_);
    auto o = flatbuffers::Offset<DequantizeLayer>(end);
    return o;
  }
};

inline flatbuffers::Offset<DequantizeLayer> CreateDequantizeLayer(
    flatbuffers::FlatBufferBuilder &_fbb,
    flatbuffers::Offset<armnnSerializer::LayerBase> base = 0) {
  DequantizeLayerBuilder builder_(_fbb);
  builder_.add_base(base);
  return builder_.Finish();
}

struct MergeLayer FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
  typedef MergeLayerBuilder Builder;
  enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
    VT_BASE = 4
  };
  const armnnSerializer::LayerBase *base() const {
    return GetPointer<const armnnSerializer::LayerBase *>(VT_BASE);
  }
  bool Verify(flatbuffers::Verifier &verifier) const {
    return VerifyTableStart(verifier) &&
           VerifyOffset(verifier, VT_BASE) &&
           verifier.VerifyTable(base()) &&
           verifier.EndTable();
  }
};

struct MergeLayerBuilder {
  typedef MergeLayer Table;
  flatbuffers::FlatBufferBuilder &fbb_;
  flatbuffers::uoffset_t start_;
  void add_base(flatbuffers::Offset<armnnSerializer::LayerBase> base) {
    fbb_.AddOffset(MergeLayer::VT_BASE, base);
  }
  explicit MergeLayerBuilder(flatbuffers::FlatBufferBuilder &_fbb)
        : fbb_(_fbb) {
    start_ = fbb_.StartTable();
  }
  MergeLayerBuilder &operator=(const MergeLayerBuilder &);
  flatbuffers::Offset<MergeLayer> Finish() {
    const auto end = fbb_.EndTable(start_);
    auto o = flatbuffers::Offset<MergeLayer>(end);
    return o;
  }
};

inline flatbuffers::Offset<MergeLayer> CreateMergeLayer(
    flatbuffers::FlatBufferBuilder &_fbb,
    flatbuffers::Offset<armnnSerializer::LayerBase> base = 0) {
  MergeLayerBuilder builder_(_fbb);
  builder_.add_base(base);
  return builder_.Finish();
}

struct SwitchLayer FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
  typedef SwitchLayerBuilder Builder;
  enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
    VT_BASE = 4
  };
  const armnnSerializer::LayerBase *base() const {
    return GetPointer<const armnnSerializer::LayerBase *>(VT_BASE);
  }
  bool Verify(flatbuffers::Verifier &verifier) const {
    return VerifyTableStart(verifier) &&
           VerifyOffset(verifier, VT_BASE) &&
           verifier.VerifyTable(base()) &&
           verifier.EndTable();
  }
};

struct SwitchLayerBuilder {
  typedef SwitchLayer Table;
  flatbuffers::FlatBufferBuilder &fbb_;
  flatbuffers::uoffset_t start_;
  void add_base(flatbuffers::Offset<armnnSerializer::LayerBase> base) {
    fbb_.AddOffset(SwitchLayer::VT_BASE, base);
  }
  explicit SwitchLayerBuilder(flatbuffers::FlatBufferBuilder &_fbb)
        : fbb_(_fbb) {
    start_ = fbb_.StartTable();
  }
  SwitchLayerBuilder &operator=(const SwitchLayerBuilder &);
  flatbuffers::Offset<SwitchLayer> Finish() {
    const auto end = fbb_.EndTable(start_);
    auto o = flatbuffers::Offset<SwitchLayer>(end);
    return o;
  }
};

inline flatbuffers::Offset<SwitchLayer> CreateSwitchLayer(
    flatbuffers::FlatBufferBuilder &_fbb,
    flatbuffers::Offset<armnnSerializer::LayerBase> base = 0) {
  SwitchLayerBuilder builder_(_fbb);
  builder_.add_base(base);
  return builder_.Finish();
}

struct PreluLayer FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
  typedef PreluLayerBuilder Builder;
  enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
    VT_BASE = 4
  };
  const armnnSerializer::LayerBase *base() const {
    return GetPointer<const armnnSerializer::LayerBase *>(VT_BASE);
  }
  bool Verify(flatbuffers::Verifier &verifier) const {
    return VerifyTableStart(verifier) &&
           VerifyOffset(verifier, VT_BASE) &&
           verifier.VerifyTable(base()) &&
           verifier.EndTable();
  }
};

struct PreluLayerBuilder {
  typedef PreluLayer Table;
  flatbuffers::FlatBufferBuilder &fbb_;
  flatbuffers::uoffset_t start_;
  void add_base(flatbuffers::Offset<armnnSerializer::LayerBase> base) {
    fbb_.AddOffset(PreluLayer::VT_BASE, base);
  }
  explicit PreluLayerBuilder(flatbuffers::FlatBufferBuilder &_fbb)
        : fbb_(_fbb) {
    start_ = fbb_.StartTable();
  }
  PreluLayerBuilder &operator=(const PreluLayerBuilder &);
  flatbuffers::Offset<PreluLayer> Finish() {
    const auto end = fbb_.EndTable(start_);
    auto o = flatbuffers::Offset<PreluLayer>(end);
    return o;
  }
};

inline flatbuffers::Offset<PreluLayer> CreatePreluLayer(
    flatbuffers::FlatBufferBuilder &_fbb,
    flatbuffers::Offset<armnnSerializer::LayerBase> base = 0) {
  PreluLayerBuilder builder_(_fbb);
  builder_.add_base(base);
  return builder_.Finish();
}

struct TransposeConvolution2dLayer FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
  typedef TransposeConvolution2dLayerBuilder Builder;
  enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
    VT_BASE = 4,
    VT_DESCRIPTOR = 6,
    VT_WEIGHTS = 8,
    VT_BIASES = 10
  };
  const armnnSerializer::LayerBase *base() const {
    return GetPointer<const armnnSerializer::LayerBase *>(VT_BASE);
  }
  const armnnSerializer::TransposeConvolution2dDescriptor *descriptor() const {
    return GetPointer<const armnnSerializer::TransposeConvolution2dDescriptor *>(VT_DESCRIPTOR);
  }
  const armnnSerializer::ConstTensor *weights() const {
    return GetPointer<const armnnSerializer::ConstTensor *>(VT_WEIGHTS);
  }
  const armnnSerializer::ConstTensor *biases() const {
    return GetPointer<const armnnSerializer::ConstTensor *>(VT_BIASES);
  }
  bool Verify(flatbuffers::Verifier &verifier) const {
    return VerifyTableStart(verifier) &&
           VerifyOffset(verifier, VT_BASE) &&
           verifier.VerifyTable(base()) &&
           VerifyOffset(verifier, VT_DESCRIPTOR) &&
           verifier.VerifyTable(descriptor()) &&
           VerifyOffset(verifier, VT_WEIGHTS) &&
           verifier.VerifyTable(weights()) &&
           VerifyOffset(verifier, VT_BIASES) &&
           verifier.VerifyTable(biases()) &&
           verifier.EndTable();
  }
};

struct TransposeConvolution2dLayerBuilder {
  typedef TransposeConvolution2dLayer Table;
  flatbuffers::FlatBufferBuilder &fbb_;
  flatbuffers::uoffset_t start_;
  void add_base(flatbuffers::Offset<armnnSerializer::LayerBase> base) {
    fbb_.AddOffset(TransposeConvolution2dLayer::VT_BASE, base);
  }
  void add_descriptor(flatbuffers::Offset<armnnSerializer::TransposeConvolution2dDescriptor> descriptor) {
    fbb_.AddOffset(TransposeConvolution2dLayer::VT_DESCRIPTOR, descriptor);
  }
  void add_weights(flatbuffers::Offset<armnnSerializer::ConstTensor> weights) {
    fbb_.AddOffset(TransposeConvolution2dLayer::VT_WEIGHTS, weights);
  }
  void add_biases(flatbuffers::Offset<armnnSerializer::ConstTensor> biases) {
    fbb_.AddOffset(TransposeConvolution2dLayer::VT_BIASES, biases);
  }
  explicit TransposeConvolution2dLayerBuilder(flatbuffers::FlatBufferBuilder &_fbb)
        : fbb_(_fbb) {
    start_ = fbb_.StartTable();
  }
  TransposeConvolution2dLayerBuilder &operator=(const TransposeConvolution2dLayerBuilder &);
  flatbuffers::Offset<TransposeConvolution2dLayer> Finish() {
    const auto end = fbb_.EndTable(start_);
    auto o = flatbuffers::Offset<TransposeConvolution2dLayer>(end);
    return o;
  }
};

inline flatbuffers::Offset<TransposeConvolution2dLayer> CreateTransposeConvolution2dLayer(
    flatbuffers::FlatBufferBuilder &_fbb,
    flatbuffers::Offset<armnnSerializer::LayerBase> base = 0,
    flatbuffers::Offset<armnnSerializer::TransposeConvolution2dDescriptor> descriptor = 0,
    flatbuffers::Offset<armnnSerializer::ConstTensor> weights = 0,
    flatbuffers::Offset<armnnSerializer::ConstTensor> biases = 0) {
  TransposeConvolution2dLayerBuilder builder_(_fbb);
  builder_.add_biases(biases);
  builder_.add_weights(weights);
  builder_.add_descriptor(descriptor);
  builder_.add_base(base);
  return builder_.Finish();
}

struct TransposeConvolution2dDescriptor FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
  typedef TransposeConvolution2dDescriptorBuilder Builder;
  enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
    VT_PADLEFT = 4,
    VT_PADRIGHT = 6,
    VT_PADTOP = 8,
    VT_PADBOTTOM = 10,
    VT_STRIDEX = 12,
    VT_STRIDEY = 14,
    VT_BIASENABLED = 16,
    VT_DATALAYOUT = 18
  };
  uint32_t padLeft() const {
    return GetField<uint32_t>(VT_PADLEFT, 0);
  }
  uint32_t padRight() const {
    return GetField<uint32_t>(VT_PADRIGHT, 0);
  }
  uint32_t padTop() const {
    return GetField<uint32_t>(VT_PADTOP, 0);
  }
  uint32_t padBottom() const {
    return GetField<uint32_t>(VT_PADBOTTOM, 0);
  }
  uint32_t strideX() const {
    return GetField<uint32_t>(VT_STRIDEX, 0);
  }
  uint32_t strideY() const {
    return GetField<uint32_t>(VT_STRIDEY, 0);
  }
  bool biasEnabled() const {
    return GetField<uint8_t>(VT_BIASENABLED, 0) != 0;
  }
  armnnSerializer::DataLayout dataLayout() const {
    return static_cast<armnnSerializer::DataLayout>(GetField<int8_t>(VT_DATALAYOUT, 1));
  }
  bool Verify(flatbuffers::Verifier &verifier) const {
    return VerifyTableStart(verifier) &&
           VerifyField<uint32_t>(verifier, VT_PADLEFT) &&
           VerifyField<uint32_t>(verifier, VT_PADRIGHT) &&
           VerifyField<uint32_t>(verifier, VT_PADTOP) &&
           VerifyField<uint32_t>(verifier, VT_PADBOTTOM) &&
           VerifyField<uint32_t>(verifier, VT_STRIDEX) &&
           VerifyField<uint32_t>(verifier, VT_STRIDEY) &&
           VerifyField<uint8_t>(verifier, VT_BIASENABLED) &&
           VerifyField<int8_t>(verifier, VT_DATALAYOUT) &&
           verifier.EndTable();
  }
};

struct TransposeConvolution2dDescriptorBuilder {
  typedef TransposeConvolution2dDescriptor Table;
  flatbuffers::FlatBufferBuilder &fbb_;
  flatbuffers::uoffset_t start_;
  void add_padLeft(uint32_t padLeft) {
    fbb_.AddElement<uint32_t>(TransposeConvolution2dDescriptor::VT_PADLEFT, padLeft, 0);
  }
  void add_padRight(uint32_t padRight) {
    fbb_.AddElement<uint32_t>(TransposeConvolution2dDescriptor::VT_PADRIGHT, padRight, 0);
  }
  void add_padTop(uint32_t padTop) {
    fbb_.AddElement<uint32_t>(TransposeConvolution2dDescriptor::VT_PADTOP, padTop, 0);
  }
  void add_padBottom(uint32_t padBottom) {
    fbb_.AddElement<uint32_t>(TransposeConvolution2dDescriptor::VT_PADBOTTOM, padBottom, 0);
  }
  void add_strideX(uint32_t strideX) {
    fbb_.AddElement<uint32_t>(TransposeConvolution2dDescriptor::VT_STRIDEX, strideX, 0);
  }
  void add_strideY(uint32_t strideY) {
    fbb_.AddElement<uint32_t>(TransposeConvolution2dDescriptor::VT_STRIDEY, strideY, 0);
  }
  void add_biasEnabled(bool biasEnabled) {
    fbb_.AddElement<uint8_t>(TransposeConvolution2dDescriptor::VT_BIASENABLED, static_cast<uint8_t>(biasEnabled), 0);
  }
  void add_dataLayout(armnnSerializer::DataLayout dataLayout) {
    fbb_.AddElement<int8_t>(TransposeConvolution2dDescriptor::VT_DATALAYOUT, static_cast<int8_t>(dataLayout), 1);
  }
  explicit TransposeConvolution2dDescriptorBuilder(flatbuffers::FlatBufferBuilder &_fbb)
        : fbb_(_fbb) {
    start_ = fbb_.StartTable();
  }
  TransposeConvolution2dDescriptorBuilder &operator=(const TransposeConvolution2dDescriptorBuilder &);
  flatbuffers::Offset<TransposeConvolution2dDescriptor> Finish() {
    const auto end = fbb_.EndTable(start_);
    auto o = flatbuffers::Offset<TransposeConvolution2dDescriptor>(end);
    return o;
  }
};

inline flatbuffers::Offset<TransposeConvolution2dDescriptor> CreateTransposeConvolution2dDescriptor(
    flatbuffers::FlatBufferBuilder &_fbb,
    uint32_t padLeft = 0,
    uint32_t padRight = 0,
    uint32_t padTop = 0,
    uint32_t padBottom = 0,
    uint32_t strideX = 0,
    uint32_t strideY = 0,
    bool biasEnabled = false,
    armnnSerializer::DataLayout dataLayout = armnnSerializer::DataLayout_NCHW) {
  TransposeConvolution2dDescriptorBuilder builder_(_fbb);
  builder_.add_strideY(strideY);
  builder_.add_strideX(strideX);
  builder_.add_padBottom(padBottom);
  builder_.add_padTop(padTop);
  builder_.add_padRight(padRight);
  builder_.add_padLeft(padLeft);
  builder_.add_dataLayout(dataLayout);
  builder_.add_biasEnabled(biasEnabled);
  return builder_.Finish();
}

struct TransposeLayer FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
  typedef TransposeLayerBuilder Builder;
  enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
    VT_BASE = 4,
    VT_DESCRIPTOR = 6
  };
  const armnnSerializer::LayerBase *base() const {
    return GetPointer<const armnnSerializer::LayerBase *>(VT_BASE);
  }
  const armnnSerializer::TransposeDescriptor *descriptor() const {
    return GetPointer<const armnnSerializer::TransposeDescriptor *>(VT_DESCRIPTOR);
  }
  bool Verify(flatbuffers::Verifier &verifier) const {
    return VerifyTableStart(verifier) &&
           VerifyOffset(verifier, VT_BASE) &&
           verifier.VerifyTable(base()) &&
           VerifyOffset(verifier, VT_DESCRIPTOR) &&
           verifier.VerifyTable(descriptor()) &&
           verifier.EndTable();
  }
};

struct TransposeLayerBuilder {
  typedef TransposeLayer Table;
  flatbuffers::FlatBufferBuilder &fbb_;
  flatbuffers::uoffset_t start_;
  void add_base(flatbuffers::Offset<armnnSerializer::LayerBase> base) {
    fbb_.AddOffset(TransposeLayer::VT_BASE, base);
  }
  void add_descriptor(flatbuffers::Offset<armnnSerializer::TransposeDescriptor> descriptor) {
    fbb_.AddOffset(TransposeLayer::VT_DESCRIPTOR, descriptor);
  }
  explicit TransposeLayerBuilder(flatbuffers::FlatBufferBuilder &_fbb)
        : fbb_(_fbb) {
    start_ = fbb_.StartTable();
  }
  TransposeLayerBuilder &operator=(const TransposeLayerBuilder &);
  flatbuffers::Offset<TransposeLayer> Finish() {
    const auto end = fbb_.EndTable(start_);
    auto o = flatbuffers::Offset<TransposeLayer>(end);
    return o;
  }
};

inline flatbuffers::Offset<TransposeLayer> CreateTransposeLayer(
    flatbuffers::FlatBufferBuilder &_fbb,
    flatbuffers::Offset<armnnSerializer::LayerBase> base = 0,
    flatbuffers::Offset<armnnSerializer::TransposeDescriptor> descriptor = 0) {
  TransposeLayerBuilder builder_(_fbb);
  builder_.add_descriptor(descriptor);
  builder_.add_base(base);
  return builder_.Finish();
}

struct TransposeDescriptor FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
  typedef TransposeDescriptorBuilder Builder;
  enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
    VT_DIMMAPPINGS = 4
  };
  const flatbuffers::Vector<uint32_t> *dimMappings() const {
    return GetPointer<const flatbuffers::Vector<uint32_t> *>(VT_DIMMAPPINGS);
  }
  bool Verify(flatbuffers::Verifier &verifier) const {
    return VerifyTableStart(verifier) &&
           VerifyOffset(verifier, VT_DIMMAPPINGS) &&
           verifier.VerifyVector(dimMappings()) &&
           verifier.EndTable();
  }
};

struct TransposeDescriptorBuilder {
  typedef TransposeDescriptor Table;
  flatbuffers::FlatBufferBuilder &fbb_;
  flatbuffers::uoffset_t start_;
  void add_dimMappings(flatbuffers::Offset<flatbuffers::Vector<uint32_t>> dimMappings) {
    fbb_.AddOffset(TransposeDescriptor::VT_DIMMAPPINGS, dimMappings);
  }
  explicit TransposeDescriptorBuilder(flatbuffers::FlatBufferBuilder &_fbb)
        : fbb_(_fbb) {
    start_ = fbb_.StartTable();
  }
  TransposeDescriptorBuilder &operator=(const TransposeDescriptorBuilder &);
  flatbuffers::Offset<TransposeDescriptor> Finish() {
    const auto end = fbb_.EndTable(start_);
    auto o = flatbuffers::Offset<TransposeDescriptor>(end);
    return o;
  }
};

inline flatbuffers::Offset<TransposeDescriptor> CreateTransposeDescriptor(
    flatbuffers::FlatBufferBuilder &_fbb,
    flatbuffers::Offset<flatbuffers::Vector<uint32_t>> dimMappings = 0) {
  TransposeDescriptorBuilder builder_(_fbb);
  builder_.add_dimMappings(dimMappings);
  return builder_.Finish();
}

inline flatbuffers::Offset<TransposeDescriptor> CreateTransposeDescriptorDirect(
    flatbuffers::FlatBufferBuilder &_fbb,
    const std::vector<uint32_t> *dimMappings = nullptr) {
  auto dimMappings__ = dimMappings ? _fbb.CreateVector<uint32_t>(*dimMappings) : 0;
  return armnnSerializer::CreateTransposeDescriptor(
      _fbb,
      dimMappings__);
}

struct ResizeLayer FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
  typedef ResizeLayerBuilder Builder;
  enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
    VT_BASE = 4,
    VT_DESCRIPTOR = 6
  };
  const armnnSerializer::LayerBase *base() const {
    return GetPointer<const armnnSerializer::LayerBase *>(VT_BASE);
  }
  const armnnSerializer::ResizeDescriptor *descriptor() const {
    return GetPointer<const armnnSerializer::ResizeDescriptor *>(VT_DESCRIPTOR);
  }
  bool Verify(flatbuffers::Verifier &verifier) const {
    return VerifyTableStart(verifier) &&
           VerifyOffset(verifier, VT_BASE) &&
           verifier.VerifyTable(base()) &&
           VerifyOffset(verifier, VT_DESCRIPTOR) &&
           verifier.VerifyTable(descriptor()) &&
           verifier.EndTable();
  }
};

struct ResizeLayerBuilder {
  typedef ResizeLayer Table;
  flatbuffers::FlatBufferBuilder &fbb_;
  flatbuffers::uoffset_t start_;
  void add_base(flatbuffers::Offset<armnnSerializer::LayerBase> base) {
    fbb_.AddOffset(ResizeLayer::VT_BASE, base);
  }
  void add_descriptor(flatbuffers::Offset<armnnSerializer::ResizeDescriptor> descriptor) {
    fbb_.AddOffset(ResizeLayer::VT_DESCRIPTOR, descriptor);
  }
  explicit ResizeLayerBuilder(flatbuffers::FlatBufferBuilder &_fbb)
        : fbb_(_fbb) {
    start_ = fbb_.StartTable();
  }
  ResizeLayerBuilder &operator=(const ResizeLayerBuilder &);
  flatbuffers::Offset<ResizeLayer> Finish() {
    const auto end = fbb_.EndTable(start_);
    auto o = flatbuffers::Offset<ResizeLayer>(end);
    return o;
  }
};

inline flatbuffers::Offset<ResizeLayer> CreateResizeLayer(
    flatbuffers::FlatBufferBuilder &_fbb,
    flatbuffers::Offset<armnnSerializer::LayerBase> base = 0,
    flatbuffers::Offset<armnnSerializer::ResizeDescriptor> descriptor = 0) {
  ResizeLayerBuilder builder_(_fbb);
  builder_.add_descriptor(descriptor);
  builder_.add_base(base);
  return builder_.Finish();
}

struct ResizeDescriptor FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
  typedef ResizeDescriptorBuilder Builder;
  enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
    VT_TARGETHEIGHT = 4,
    VT_TARGETWIDTH = 6,
    VT_METHOD = 8,
    VT_DATALAYOUT = 10,
    VT_ALIGNCORNERS = 12,
    VT_HALFPIXELCENTERS = 14
  };
  uint32_t targetHeight() const {
    return GetField<uint32_t>(VT_TARGETHEIGHT, 0);
  }
  uint32_t targetWidth() const {
    return GetField<uint32_t>(VT_TARGETWIDTH, 0);
  }
  armnnSerializer::ResizeMethod method() const {
    return static_cast<armnnSerializer::ResizeMethod>(GetField<int8_t>(VT_METHOD, 0));
  }
  armnnSerializer::DataLayout dataLayout() const {
    return static_cast<armnnSerializer::DataLayout>(GetField<int8_t>(VT_DATALAYOUT, 0));
  }
  bool alignCorners() const {
    return GetField<uint8_t>(VT_ALIGNCORNERS, 0) != 0;
  }
  bool halfPixelCenters() const {
    return GetField<uint8_t>(VT_HALFPIXELCENTERS, 0) != 0;
  }
  bool Verify(flatbuffers::Verifier &verifier) const {
    return VerifyTableStart(verifier) &&
           VerifyField<uint32_t>(verifier, VT_TARGETHEIGHT) &&
           VerifyField<uint32_t>(verifier, VT_TARGETWIDTH) &&
           VerifyField<int8_t>(verifier, VT_METHOD) &&
           VerifyField<int8_t>(verifier, VT_DATALAYOUT) &&
           VerifyField<uint8_t>(verifier, VT_ALIGNCORNERS) &&
           VerifyField<uint8_t>(verifier, VT_HALFPIXELCENTERS) &&
           verifier.EndTable();
  }
};

struct ResizeDescriptorBuilder {
  typedef ResizeDescriptor Table;
  flatbuffers::FlatBufferBuilder &fbb_;
  flatbuffers::uoffset_t start_;
  void add_targetHeight(uint32_t targetHeight) {
    fbb_.AddElement<uint32_t>(ResizeDescriptor::VT_TARGETHEIGHT, targetHeight, 0);
  }
  void add_targetWidth(uint32_t targetWidth) {
    fbb_.AddElement<uint32_t>(ResizeDescriptor::VT_TARGETWIDTH, targetWidth, 0);
  }
  void add_method(armnnSerializer::ResizeMethod method) {
    fbb_.AddElement<int8_t>(ResizeDescriptor::VT_METHOD, static_cast<int8_t>(method), 0);
  }
  void add_dataLayout(armnnSerializer::DataLayout dataLayout) {
    fbb_.AddElement<int8_t>(ResizeDescriptor::VT_DATALAYOUT, static_cast<int8_t>(dataLayout), 0);
  }
  void add_alignCorners(bool alignCorners) {
    fbb_.AddElement<uint8_t>(ResizeDescriptor::VT_ALIGNCORNERS, static_cast<uint8_t>(alignCorners), 0);
  }
  void add_halfPixelCenters(bool halfPixelCenters) {
    fbb_.AddElement<uint8_t>(ResizeDescriptor::VT_HALFPIXELCENTERS, static_cast<uint8_t>(halfPixelCenters), 0);
  }
  explicit ResizeDescriptorBuilder(flatbuffers::FlatBufferBuilder &_fbb)
        : fbb_(_fbb) {
    start_ = fbb_.StartTable();
  }
  ResizeDescriptorBuilder &operator=(const ResizeDescriptorBuilder &);
  flatbuffers::Offset<ResizeDescriptor> Finish() {
    const auto end = fbb_.EndTable(start_);
    auto o = flatbuffers::Offset<ResizeDescriptor>(end);
    return o;
  }
};

inline flatbuffers::Offset<ResizeDescriptor> CreateResizeDescriptor(
    flatbuffers::FlatBufferBuilder &_fbb,
    uint32_t targetHeight = 0,
    uint32_t targetWidth = 0,
    armnnSerializer::ResizeMethod method = armnnSerializer::ResizeMethod_NearestNeighbor,
    armnnSerializer::DataLayout dataLayout = armnnSerializer::DataLayout_NHWC,
    bool alignCorners = false,
    bool halfPixelCenters = false) {
  ResizeDescriptorBuilder builder_(_fbb);
  builder_.add_targetWidth(targetWidth);
  builder_.add_targetHeight(targetHeight);
  builder_.add_halfPixelCenters(halfPixelCenters);
  builder_.add_alignCorners(alignCorners);
  builder_.add_dataLayout(dataLayout);
  builder_.add_method(method);
  return builder_.Finish();
}

struct StackLayer FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
  typedef StackLayerBuilder Builder;
  enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
    VT_BASE = 4,
    VT_DESCRIPTOR = 6
  };
  const armnnSerializer::LayerBase *base() const {
    return GetPointer<const armnnSerializer::LayerBase *>(VT_BASE);
  }
  const armnnSerializer::StackDescriptor *descriptor() const {
    return GetPointer<const armnnSerializer::StackDescriptor *>(VT_DESCRIPTOR);
  }
  bool Verify(flatbuffers::Verifier &verifier) const {
    return VerifyTableStart(verifier) &&
           VerifyOffset(verifier, VT_BASE) &&
           verifier.VerifyTable(base()) &&
           VerifyOffset(verifier, VT_DESCRIPTOR) &&
           verifier.VerifyTable(descriptor()) &&
           verifier.EndTable();
  }
};

struct StackLayerBuilder {
  typedef StackLayer Table;
  flatbuffers::FlatBufferBuilder &fbb_;
  flatbuffers::uoffset_t start_;
  void add_base(flatbuffers::Offset<armnnSerializer::LayerBase> base) {
    fbb_.AddOffset(StackLayer::VT_BASE, base);
  }
  void add_descriptor(flatbuffers::Offset<armnnSerializer::StackDescriptor> descriptor) {
    fbb_.AddOffset(StackLayer::VT_DESCRIPTOR, descriptor);
  }
  explicit StackLayerBuilder(flatbuffers::FlatBufferBuilder &_fbb)
        : fbb_(_fbb) {
    start_ = fbb_.StartTable();
  }
  StackLayerBuilder &operator=(const StackLayerBuilder &);
  flatbuffers::Offset<StackLayer> Finish() {
    const auto end = fbb_.EndTable(start_);
    auto o = flatbuffers::Offset<StackLayer>(end);
    return o;
  }
};

inline flatbuffers::Offset<StackLayer> CreateStackLayer(
    flatbuffers::FlatBufferBuilder &_fbb,
    flatbuffers::Offset<armnnSerializer::LayerBase> base = 0,
    flatbuffers::Offset<armnnSerializer::StackDescriptor> descriptor = 0) {
  StackLayerBuilder builder_(_fbb);
  builder_.add_descriptor(descriptor);
  builder_.add_base(base);
  return builder_.Finish();
}

struct StackDescriptor FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
  typedef StackDescriptorBuilder Builder;
  enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
    VT_AXIS = 4,
    VT_NUMINPUTS = 6,
    VT_INPUTSHAPE = 8
  };
  uint32_t axis() const {
    return GetField<uint32_t>(VT_AXIS, 0);
  }
  uint32_t numInputs() const {
    return GetField<uint32_t>(VT_NUMINPUTS, 0);
  }
  const flatbuffers::Vector<uint32_t> *inputShape() const {
    return GetPointer<const flatbuffers::Vector<uint32_t> *>(VT_INPUTSHAPE);
  }
  bool Verify(flatbuffers::Verifier &verifier) const {
    return VerifyTableStart(verifier) &&
           VerifyField<uint32_t>(verifier, VT_AXIS) &&
           VerifyField<uint32_t>(verifier, VT_NUMINPUTS) &&
           VerifyOffset(verifier, VT_INPUTSHAPE) &&
           verifier.VerifyVector(inputShape()) &&
           verifier.EndTable();
  }
};

struct StackDescriptorBuilder {
  typedef StackDescriptor Table;
  flatbuffers::FlatBufferBuilder &fbb_;
  flatbuffers::uoffset_t start_;
  void add_axis(uint32_t axis) {
    fbb_.AddElement<uint32_t>(StackDescriptor::VT_AXIS, axis, 0);
  }
  void add_numInputs(uint32_t numInputs) {
    fbb_.AddElement<uint32_t>(StackDescriptor::VT_NUMINPUTS, numInputs, 0);
  }
  void add_inputShape(flatbuffers::Offset<flatbuffers::Vector<uint32_t>> inputShape) {
    fbb_.AddOffset(StackDescriptor::VT_INPUTSHAPE, inputShape);
  }
  explicit StackDescriptorBuilder(flatbuffers::FlatBufferBuilder &_fbb)
        : fbb_(_fbb) {
    start_ = fbb_.StartTable();
  }
  StackDescriptorBuilder &operator=(const StackDescriptorBuilder &);
  flatbuffers::Offset<StackDescriptor> Finish() {
    const auto end = fbb_.EndTable(start_);
    auto o = flatbuffers::Offset<StackDescriptor>(end);
    return o;
  }
};

inline flatbuffers::Offset<StackDescriptor> CreateStackDescriptor(
    flatbuffers::FlatBufferBuilder &_fbb,
    uint32_t axis = 0,
    uint32_t numInputs = 0,
    flatbuffers::Offset<flatbuffers::Vector<uint32_t>> inputShape = 0) {
  StackDescriptorBuilder builder_(_fbb);
  builder_.add_inputShape(inputShape);
  builder_.add_numInputs(numInputs);
  builder_.add_axis(axis);
  return builder_.Finish();
}

inline flatbuffers::Offset<StackDescriptor> CreateStackDescriptorDirect(
    flatbuffers::FlatBufferBuilder &_fbb,
    uint32_t axis = 0,
    uint32_t numInputs = 0,
    const std::vector<uint32_t> *inputShape = nullptr) {
  auto inputShape__ = inputShape ? _fbb.CreateVector<uint32_t>(*inputShape) : 0;
  return armnnSerializer::CreateStackDescriptor(
      _fbb,
      axis,
      numInputs,
      inputShape__);
}

struct StandInDescriptor FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
  typedef StandInDescriptorBuilder Builder;
  enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
    VT_NUMINPUTS = 4,
    VT_NUMOUTPUTS = 6
  };
  uint32_t numInputs() const {
    return GetField<uint32_t>(VT_NUMINPUTS, 0);
  }
  uint32_t numOutputs() const {
    return GetField<uint32_t>(VT_NUMOUTPUTS, 0);
  }
  bool Verify(flatbuffers::Verifier &verifier) const {
    return VerifyTableStart(verifier) &&
           VerifyField<uint32_t>(verifier, VT_NUMINPUTS) &&
           VerifyField<uint32_t>(verifier, VT_NUMOUTPUTS) &&
           verifier.EndTable();
  }
};

struct StandInDescriptorBuilder {
  typedef StandInDescriptor Table;
  flatbuffers::FlatBufferBuilder &fbb_;
  flatbuffers::uoffset_t start_;
  void add_numInputs(uint32_t numInputs) {
    fbb_.AddElement<uint32_t>(StandInDescriptor::VT_NUMINPUTS, numInputs, 0);
  }
  void add_numOutputs(uint32_t numOutputs) {
    fbb_.AddElement<uint32_t>(StandInDescriptor::VT_NUMOUTPUTS, numOutputs, 0);
  }
  explicit StandInDescriptorBuilder(flatbuffers::FlatBufferBuilder &_fbb)
        : fbb_(_fbb) {
    start_ = fbb_.StartTable();
  }
  StandInDescriptorBuilder &operator=(const StandInDescriptorBuilder &);
  flatbuffers::Offset<StandInDescriptor> Finish() {
    const auto end = fbb_.EndTable(start_);
    auto o = flatbuffers::Offset<StandInDescriptor>(end);
    return o;
  }
};

inline flatbuffers::Offset<StandInDescriptor> CreateStandInDescriptor(
    flatbuffers::FlatBufferBuilder &_fbb,
    uint32_t numInputs = 0,
    uint32_t numOutputs = 0) {
  StandInDescriptorBuilder builder_(_fbb);
  builder_.add_numOutputs(numOutputs);
  builder_.add_numInputs(numInputs);
  return builder_.Finish();
}

struct StandInLayer FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
  typedef StandInLayerBuilder Builder;
  enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
    VT_BASE = 4,
    VT_DESCRIPTOR = 6
  };
  const armnnSerializer::LayerBase *base() const {
    return GetPointer<const armnnSerializer::LayerBase *>(VT_BASE);
  }
  const armnnSerializer::StandInDescriptor *descriptor() const {
    return GetPointer<const armnnSerializer::StandInDescriptor *>(VT_DESCRIPTOR);
  }
  bool Verify(flatbuffers::Verifier &verifier) const {
    return VerifyTableStart(verifier) &&
           VerifyOffset(verifier, VT_BASE) &&
           verifier.VerifyTable(base()) &&
           VerifyOffset(verifier, VT_DESCRIPTOR) &&
           verifier.VerifyTable(descriptor()) &&
           verifier.EndTable();
  }
};

struct StandInLayerBuilder {
  typedef StandInLayer Table;
  flatbuffers::FlatBufferBuilder &fbb_;
  flatbuffers::uoffset_t start_;
  void add_base(flatbuffers::Offset<armnnSerializer::LayerBase> base) {
    fbb_.AddOffset(StandInLayer::VT_BASE, base);
  }
  void add_descriptor(flatbuffers::Offset<armnnSerializer::StandInDescriptor> descriptor) {
    fbb_.AddOffset(StandInLayer::VT_DESCRIPTOR, descriptor);
  }
  explicit StandInLayerBuilder(flatbuffers::FlatBufferBuilder &_fbb)
        : fbb_(_fbb) {
    start_ = fbb_.StartTable();
  }
  StandInLayerBuilder &operator=(const StandInLayerBuilder &);
  flatbuffers::Offset<StandInLayer> Finish() {
    const auto end = fbb_.EndTable(start_);
    auto o = flatbuffers::Offset<StandInLayer>(end);
    return o;
  }
};

inline flatbuffers::Offset<StandInLayer> CreateStandInLayer(
    flatbuffers::FlatBufferBuilder &_fbb,
    flatbuffers::Offset<armnnSerializer::LayerBase> base = 0,
    flatbuffers::Offset<armnnSerializer::StandInDescriptor> descriptor = 0) {
  StandInLayerBuilder builder_(_fbb);
  builder_.add_descriptor(descriptor);
  builder_.add_base(base);
  return builder_.Finish();
}

struct RankLayer FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
  typedef RankLayerBuilder Builder;
  enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
    VT_BASE = 4
  };
  const armnnSerializer::LayerBase *base() const {
    return GetPointer<const armnnSerializer::LayerBase *>(VT_BASE);
  }
  bool Verify(flatbuffers::Verifier &verifier) const {
    return VerifyTableStart(verifier) &&
           VerifyOffset(verifier, VT_BASE) &&
           verifier.VerifyTable(base()) &&
           verifier.EndTable();
  }
};

struct RankLayerBuilder {
  typedef RankLayer Table;
  flatbuffers::FlatBufferBuilder &fbb_;
  flatbuffers::uoffset_t start_;
  void add_base(flatbuffers::Offset<armnnSerializer::LayerBase> base) {
    fbb_.AddOffset(RankLayer::VT_BASE, base);
  }
  explicit RankLayerBuilder(flatbuffers::FlatBufferBuilder &_fbb)
        : fbb_(_fbb) {
    start_ = fbb_.StartTable();
  }
  RankLayerBuilder &operator=(const RankLayerBuilder &);
  flatbuffers::Offset<RankLayer> Finish() {
    const auto end = fbb_.EndTable(start_);
    auto o = flatbuffers::Offset<RankLayer>(end);
    return o;
  }
};

inline flatbuffers::Offset<RankLayer> CreateRankLayer(
    flatbuffers::FlatBufferBuilder &_fbb,
    flatbuffers::Offset<armnnSerializer::LayerBase> base = 0) {
  RankLayerBuilder builder_(_fbb);
  builder_.add_base(base);
  return builder_.Finish();
}

struct ReduceLayer FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
  typedef ReduceLayerBuilder Builder;
  enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
    VT_BASE = 4,
    VT_DESCRIPTOR = 6
  };
  const armnnSerializer::LayerBase *base() const {
    return GetPointer<const armnnSerializer::LayerBase *>(VT_BASE);
  }
  const armnnSerializer::ReduceDescriptor *descriptor() const {
    return GetPointer<const armnnSerializer::ReduceDescriptor *>(VT_DESCRIPTOR);
  }
  bool Verify(flatbuffers::Verifier &verifier) const {
    return VerifyTableStart(verifier) &&
           VerifyOffset(verifier, VT_BASE) &&
           verifier.VerifyTable(base()) &&
           VerifyOffset(verifier, VT_DESCRIPTOR) &&
           verifier.VerifyTable(descriptor()) &&
           verifier.EndTable();
  }
};

struct ReduceLayerBuilder {
  typedef ReduceLayer Table;
  flatbuffers::FlatBufferBuilder &fbb_;
  flatbuffers::uoffset_t start_;
  void add_base(flatbuffers::Offset<armnnSerializer::LayerBase> base) {
    fbb_.AddOffset(ReduceLayer::VT_BASE, base);
  }
  void add_descriptor(flatbuffers::Offset<armnnSerializer::ReduceDescriptor> descriptor) {
    fbb_.AddOffset(ReduceLayer::VT_DESCRIPTOR, descriptor);
  }
  explicit ReduceLayerBuilder(flatbuffers::FlatBufferBuilder &_fbb)
        : fbb_(_fbb) {
    start_ = fbb_.StartTable();
  }
  ReduceLayerBuilder &operator=(const ReduceLayerBuilder &);
  flatbuffers::Offset<ReduceLayer> Finish() {
    const auto end = fbb_.EndTable(start_);
    auto o = flatbuffers::Offset<ReduceLayer>(end);
    return o;
  }
};

inline flatbuffers::Offset<ReduceLayer> CreateReduceLayer(
    flatbuffers::FlatBufferBuilder &_fbb,
    flatbuffers::Offset<armnnSerializer::LayerBase> base = 0,
    flatbuffers::Offset<armnnSerializer::ReduceDescriptor> descriptor = 0) {
  ReduceLayerBuilder builder_(_fbb);
  builder_.add_descriptor(descriptor);
  builder_.add_base(base);
  return builder_.Finish();
}

struct ReduceDescriptor FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
  typedef ReduceDescriptorBuilder Builder;
  enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
    VT_KEEPDIMS = 4,
    VT_AXIS = 6,
    VT_REDUCEOPERATION = 8
  };
  bool keepDims() const {
    return GetField<uint8_t>(VT_KEEPDIMS, 0) != 0;
  }
  const flatbuffers::Vector<uint32_t> *axis() const {
    return GetPointer<const flatbuffers::Vector<uint32_t> *>(VT_AXIS);
  }
  armnnSerializer::ReduceOperation reduceOperation() const {
    return static_cast<armnnSerializer::ReduceOperation>(GetField<int8_t>(VT_REDUCEOPERATION, 0));
  }
  bool Verify(flatbuffers::Verifier &verifier) const {
    return VerifyTableStart(verifier) &&
           VerifyField<uint8_t>(verifier, VT_KEEPDIMS) &&
           VerifyOffset(verifier, VT_AXIS) &&
           verifier.VerifyVector(axis()) &&
           VerifyField<int8_t>(verifier, VT_REDUCEOPERATION) &&
           verifier.EndTable();
  }
};

struct ReduceDescriptorBuilder {
  typedef ReduceDescriptor Table;
  flatbuffers::FlatBufferBuilder &fbb_;
  flatbuffers::uoffset_t start_;
  void add_keepDims(bool keepDims) {
    fbb_.AddElement<uint8_t>(ReduceDescriptor::VT_KEEPDIMS, static_cast<uint8_t>(keepDims), 0);
  }
  void add_axis(flatbuffers::Offset<flatbuffers::Vector<uint32_t>> axis) {
    fbb_.AddOffset(ReduceDescriptor::VT_AXIS, axis);
  }
  void add_reduceOperation(armnnSerializer::ReduceOperation reduceOperation) {
    fbb_.AddElement<int8_t>(ReduceDescriptor::VT_REDUCEOPERATION, static_cast<int8_t>(reduceOperation), 0);
  }
  explicit ReduceDescriptorBuilder(flatbuffers::FlatBufferBuilder &_fbb)
        : fbb_(_fbb) {
    start_ = fbb_.StartTable();
  }
  ReduceDescriptorBuilder &operator=(const ReduceDescriptorBuilder &);
  flatbuffers::Offset<ReduceDescriptor> Finish() {
    const auto end = fbb_.EndTable(start_);
    auto o = flatbuffers::Offset<ReduceDescriptor>(end);
    return o;
  }
};

inline flatbuffers::Offset<ReduceDescriptor> CreateReduceDescriptor(
    flatbuffers::FlatBufferBuilder &_fbb,
    bool keepDims = false,
    flatbuffers::Offset<flatbuffers::Vector<uint32_t>> axis = 0,
    armnnSerializer::ReduceOperation reduceOperation = armnnSerializer::ReduceOperation_Sum) {
  ReduceDescriptorBuilder builder_(_fbb);
  builder_.add_axis(axis);
  builder_.add_reduceOperation(reduceOperation);
  builder_.add_keepDims(keepDims);
  return builder_.Finish();
}

inline flatbuffers::Offset<ReduceDescriptor> CreateReduceDescriptorDirect(
    flatbuffers::FlatBufferBuilder &_fbb,
    bool keepDims = false,
    const std::vector<uint32_t> *axis = nullptr,
    armnnSerializer::ReduceOperation reduceOperation = armnnSerializer::ReduceOperation_Sum) {
  auto axis__ = axis ? _fbb.CreateVector<uint32_t>(*axis) : 0;
  return armnnSerializer::CreateReduceDescriptor(
      _fbb,
      keepDims,
      axis__,
      reduceOperation);
}

struct AnyLayer FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
  typedef AnyLayerBuilder Builder;
  enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
    VT_LAYER_TYPE = 4,
    VT_LAYER = 6
  };
  armnnSerializer::Layer layer_type() const {
    return static_cast<armnnSerializer::Layer>(GetField<uint8_t>(VT_LAYER_TYPE, 0));
  }
  const void *layer() const {
    return GetPointer<const void *>(VT_LAYER);
  }
  template<typename T> const T *layer_as() const;
  const armnnSerializer::ActivationLayer *layer_as_ActivationLayer() const {
    return layer_type() == armnnSerializer::Layer_ActivationLayer ? static_cast<const armnnSerializer::ActivationLayer *>(layer()) : nullptr;
  }
  const armnnSerializer::AdditionLayer *layer_as_AdditionLayer() const {
    return layer_type() == armnnSerializer::Layer_AdditionLayer ? static_cast<const armnnSerializer::AdditionLayer *>(layer()) : nullptr;
  }
  const armnnSerializer::BatchToSpaceNdLayer *layer_as_BatchToSpaceNdLayer() const {
    return layer_type() == armnnSerializer::Layer_BatchToSpaceNdLayer ? static_cast<const armnnSerializer::BatchToSpaceNdLayer *>(layer()) : nullptr;
  }
  const armnnSerializer::BatchNormalizationLayer *layer_as_BatchNormalizationLayer() const {
    return layer_type() == armnnSerializer::Layer_BatchNormalizationLayer ? static_cast<const armnnSerializer::BatchNormalizationLayer *>(layer()) : nullptr;
  }
  const armnnSerializer::ConstantLayer *layer_as_ConstantLayer() const {
    return layer_type() == armnnSerializer::Layer_ConstantLayer ? static_cast<const armnnSerializer::ConstantLayer *>(layer()) : nullptr;
  }
  const armnnSerializer::Convolution2dLayer *layer_as_Convolution2dLayer() const {
    return layer_type() == armnnSerializer::Layer_Convolution2dLayer ? static_cast<const armnnSerializer::Convolution2dLayer *>(layer()) : nullptr;
  }
  const armnnSerializer::DepthwiseConvolution2dLayer *layer_as_DepthwiseConvolution2dLayer() const {
    return layer_type() == armnnSerializer::Layer_DepthwiseConvolution2dLayer ? static_cast<const armnnSerializer::DepthwiseConvolution2dLayer *>(layer()) : nullptr;
  }
  const armnnSerializer::FullyConnectedLayer *layer_as_FullyConnectedLayer() const {
    return layer_type() == armnnSerializer::Layer_FullyConnectedLayer ? static_cast<const armnnSerializer::FullyConnectedLayer *>(layer()) : nullptr;
  }
  const armnnSerializer::InputLayer *layer_as_InputLayer() const {
    return layer_type() == armnnSerializer::Layer_InputLayer ? static_cast<const armnnSerializer::InputLayer *>(layer()) : nullptr;
  }
  const armnnSerializer::MultiplicationLayer *layer_as_MultiplicationLayer() const {
    return layer_type() == armnnSerializer::Layer_MultiplicationLayer ? static_cast<const armnnSerializer::MultiplicationLayer *>(layer()) : nullptr;
  }
  const armnnSerializer::OutputLayer *layer_as_OutputLayer() const {
    return layer_type() == armnnSerializer::Layer_OutputLayer ? static_cast<const armnnSerializer::OutputLayer *>(layer()) : nullptr;
  }
  const armnnSerializer::PermuteLayer *layer_as_PermuteLayer() const {
    return layer_type() == armnnSerializer::Layer_PermuteLayer ? static_cast<const armnnSerializer::PermuteLayer *>(layer()) : nullptr;
  }
  const armnnSerializer::Pooling2dLayer *layer_as_Pooling2dLayer() const {
    return layer_type() == armnnSerializer::Layer_Pooling2dLayer ? static_cast<const armnnSerializer::Pooling2dLayer *>(layer()) : nullptr;
  }
  const armnnSerializer::ReshapeLayer *layer_as_ReshapeLayer() const {
    return layer_type() == armnnSerializer::Layer_ReshapeLayer ? static_cast<const armnnSerializer::ReshapeLayer *>(layer()) : nullptr;
  }
  const armnnSerializer::SoftmaxLayer *layer_as_SoftmaxLayer() const {
    return layer_type() == armnnSerializer::Layer_SoftmaxLayer ? static_cast<const armnnSerializer::SoftmaxLayer *>(layer()) : nullptr;
  }
  const armnnSerializer::SpaceToBatchNdLayer *layer_as_SpaceToBatchNdLayer() const {
    return layer_type() == armnnSerializer::Layer_SpaceToBatchNdLayer ? static_cast<const armnnSerializer::SpaceToBatchNdLayer *>(layer()) : nullptr;
  }
  const armnnSerializer::DivisionLayer *layer_as_DivisionLayer() const {
    return layer_type() == armnnSerializer::Layer_DivisionLayer ? static_cast<const armnnSerializer::DivisionLayer *>(layer()) : nullptr;
  }
  const armnnSerializer::MinimumLayer *layer_as_MinimumLayer() const {
    return layer_type() == armnnSerializer::Layer_MinimumLayer ? static_cast<const armnnSerializer::MinimumLayer *>(layer()) : nullptr;
  }
  const armnnSerializer::EqualLayer *layer_as_EqualLayer() const {
    return layer_type() == armnnSerializer::Layer_EqualLayer ? static_cast<const armnnSerializer::EqualLayer *>(layer()) : nullptr;
  }
  const armnnSerializer::MaximumLayer *layer_as_MaximumLayer() const {
    return layer_type() == armnnSerializer::Layer_MaximumLayer ? static_cast<const armnnSerializer::MaximumLayer *>(layer()) : nullptr;
  }
  const armnnSerializer::NormalizationLayer *layer_as_NormalizationLayer() const {
    return layer_type() == armnnSerializer::Layer_NormalizationLayer ? static_cast<const armnnSerializer::NormalizationLayer *>(layer()) : nullptr;
  }
  const armnnSerializer::PadLayer *layer_as_PadLayer() const {
    return layer_type() == armnnSerializer::Layer_PadLayer ? static_cast<const armnnSerializer::PadLayer *>(layer()) : nullptr;
  }
  const armnnSerializer::RsqrtLayer *layer_as_RsqrtLayer() const {
    return layer_type() == armnnSerializer::Layer_RsqrtLayer ? static_cast<const armnnSerializer::RsqrtLayer *>(layer()) : nullptr;
  }
  const armnnSerializer::FloorLayer *layer_as_FloorLayer() const {
    return layer_type() == armnnSerializer::Layer_FloorLayer ? static_cast<const armnnSerializer::FloorLayer *>(layer()) : nullptr;
  }
  const armnnSerializer::GreaterLayer *layer_as_GreaterLayer() const {
    return layer_type() == armnnSerializer::Layer_GreaterLayer ? static_cast<const armnnSerializer::GreaterLayer *>(layer()) : nullptr;
  }
  const armnnSerializer::ResizeBilinearLayer *layer_as_ResizeBilinearLayer() const {
    return layer_type() == armnnSerializer::Layer_ResizeBilinearLayer ? static_cast<const armnnSerializer::ResizeBilinearLayer *>(layer()) : nullptr;
  }
  const armnnSerializer::SubtractionLayer *layer_as_SubtractionLayer() const {
    return layer_type() == armnnSerializer::Layer_SubtractionLayer ? static_cast<const armnnSerializer::SubtractionLayer *>(layer()) : nullptr;
  }
  const armnnSerializer::StridedSliceLayer *layer_as_StridedSliceLayer() const {
    return layer_type() == armnnSerializer::Layer_StridedSliceLayer ? static_cast<const armnnSerializer::StridedSliceLayer *>(layer()) : nullptr;
  }
  const armnnSerializer::GatherLayer *layer_as_GatherLayer() const {
    return layer_type() == armnnSerializer::Layer_GatherLayer ? static_cast<const armnnSerializer::GatherLayer *>(layer()) : nullptr;
  }
  const armnnSerializer::MeanLayer *layer_as_MeanLayer() const {
    return layer_type() == armnnSerializer::Layer_MeanLayer ? static_cast<const armnnSerializer::MeanLayer *>(layer()) : nullptr;
  }
  const armnnSerializer::MergerLayer *layer_as_MergerLayer() const {
    return layer_type() == armnnSerializer::Layer_MergerLayer ? static_cast<const armnnSerializer::MergerLayer *>(layer()) : nullptr;
  }
  const armnnSerializer::L2NormalizationLayer *layer_as_L2NormalizationLayer() const {
    return layer_type() == armnnSerializer::Layer_L2NormalizationLayer ? static_cast<const armnnSerializer::L2NormalizationLayer *>(layer()) : nullptr;
  }
  const armnnSerializer::SplitterLayer *layer_as_SplitterLayer() const {
    return layer_type() == armnnSerializer::Layer_SplitterLayer ? static_cast<const armnnSerializer::SplitterLayer *>(layer()) : nullptr;
  }
  const armnnSerializer::DetectionPostProcessLayer *layer_as_DetectionPostProcessLayer() const {
    return layer_type() == armnnSerializer::Layer_DetectionPostProcessLayer ? static_cast<const armnnSerializer::DetectionPostProcessLayer *>(layer()) : nullptr;
  }
  const armnnSerializer::LstmLayer *layer_as_LstmLayer() const {
    return layer_type() == armnnSerializer::Layer_LstmLayer ? static_cast<const armnnSerializer::LstmLayer *>(layer()) : nullptr;
  }
  const armnnSerializer::QuantizedLstmLayer *layer_as_QuantizedLstmLayer() const {
    return layer_type() == armnnSerializer::Layer_QuantizedLstmLayer ? static_cast<const armnnSerializer::QuantizedLstmLayer *>(layer()) : nullptr;
  }
  const armnnSerializer::QuantizeLayer *layer_as_QuantizeLayer() const {
    return layer_type() == armnnSerializer::Layer_QuantizeLayer ? static_cast<const armnnSerializer::QuantizeLayer *>(layer()) : nullptr;
  }
  const armnnSerializer::DequantizeLayer *layer_as_DequantizeLayer() const {
    return layer_type() == armnnSerializer::Layer_DequantizeLayer ? static_cast<const armnnSerializer::DequantizeLayer *>(layer()) : nullptr;
  }
  const armnnSerializer::MergeLayer *layer_as_MergeLayer() const {
    return layer_type() == armnnSerializer::Layer_MergeLayer ? static_cast<const armnnSerializer::MergeLayer *>(layer()) : nullptr;
  }
  const armnnSerializer::SwitchLayer *layer_as_SwitchLayer() const {
    return layer_type() == armnnSerializer::Layer_SwitchLayer ? static_cast<const armnnSerializer::SwitchLayer *>(layer()) : nullptr;
  }
  const armnnSerializer::ConcatLayer *layer_as_ConcatLayer() const {
    return layer_type() == armnnSerializer::Layer_ConcatLayer ? static_cast<const armnnSerializer::ConcatLayer *>(layer()) : nullptr;
  }
  const armnnSerializer::SpaceToDepthLayer *layer_as_SpaceToDepthLayer() const {
    return layer_type() == armnnSerializer::Layer_SpaceToDepthLayer ? static_cast<const armnnSerializer::SpaceToDepthLayer *>(layer()) : nullptr;
  }
  const armnnSerializer::PreluLayer *layer_as_PreluLayer() const {
    return layer_type() == armnnSerializer::Layer_PreluLayer ? static_cast<const armnnSerializer::PreluLayer *>(layer()) : nullptr;
  }
  const armnnSerializer::TransposeConvolution2dLayer *layer_as_TransposeConvolution2dLayer() const {
    return layer_type() == armnnSerializer::Layer_TransposeConvolution2dLayer ? static_cast<const armnnSerializer::TransposeConvolution2dLayer *>(layer()) : nullptr;
  }
  const armnnSerializer::ResizeLayer *layer_as_ResizeLayer() const {
    return layer_type() == armnnSerializer::Layer_ResizeLayer ? static_cast<const armnnSerializer::ResizeLayer *>(layer()) : nullptr;
  }
  const armnnSerializer::StackLayer *layer_as_StackLayer() const {
    return layer_type() == armnnSerializer::Layer_StackLayer ? static_cast<const armnnSerializer::StackLayer *>(layer()) : nullptr;
  }
  const armnnSerializer::AbsLayer *layer_as_AbsLayer() const {
    return layer_type() == armnnSerializer::Layer_AbsLayer ? static_cast<const armnnSerializer::AbsLayer *>(layer()) : nullptr;
  }
  const armnnSerializer::ArgMinMaxLayer *layer_as_ArgMinMaxLayer() const {
    return layer_type() == armnnSerializer::Layer_ArgMinMaxLayer ? static_cast<const armnnSerializer::ArgMinMaxLayer *>(layer()) : nullptr;
  }
  const armnnSerializer::SliceLayer *layer_as_SliceLayer() const {
    return layer_type() == armnnSerializer::Layer_SliceLayer ? static_cast<const armnnSerializer::SliceLayer *>(layer()) : nullptr;
  }
  const armnnSerializer::DepthToSpaceLayer *layer_as_DepthToSpaceLayer() const {
    return layer_type() == armnnSerializer::Layer_DepthToSpaceLayer ? static_cast<const armnnSerializer::DepthToSpaceLayer *>(layer()) : nullptr;
  }
  const armnnSerializer::InstanceNormalizationLayer *layer_as_InstanceNormalizationLayer() const {
    return layer_type() == armnnSerializer::Layer_InstanceNormalizationLayer ? static_cast<const armnnSerializer::InstanceNormalizationLayer *>(layer()) : nullptr;
  }
  const armnnSerializer::LogSoftmaxLayer *layer_as_LogSoftmaxLayer() const {
    return layer_type() == armnnSerializer::Layer_LogSoftmaxLayer ? static_cast<const armnnSerializer::LogSoftmaxLayer *>(layer()) : nullptr;
  }
  const armnnSerializer::ComparisonLayer *layer_as_ComparisonLayer() const {
    return layer_type() == armnnSerializer::Layer_ComparisonLayer ? static_cast<const armnnSerializer::ComparisonLayer *>(layer()) : nullptr;
  }
  const armnnSerializer::StandInLayer *layer_as_StandInLayer() const {
    return layer_type() == armnnSerializer::Layer_StandInLayer ? static_cast<const armnnSerializer::StandInLayer *>(layer()) : nullptr;
  }
  const armnnSerializer::ElementwiseUnaryLayer *layer_as_ElementwiseUnaryLayer() const {
    return layer_type() == armnnSerializer::Layer_ElementwiseUnaryLayer ? static_cast<const armnnSerializer::ElementwiseUnaryLayer *>(layer()) : nullptr;
  }
  const armnnSerializer::TransposeLayer *layer_as_TransposeLayer() const {
    return layer_type() == armnnSerializer::Layer_TransposeLayer ? static_cast<const armnnSerializer::TransposeLayer *>(layer()) : nullptr;
  }
  const armnnSerializer::QLstmLayer *layer_as_QLstmLayer() const {
    return layer_type() == armnnSerializer::Layer_QLstmLayer ? static_cast<const armnnSerializer::QLstmLayer *>(layer()) : nullptr;
  }
  const armnnSerializer::FillLayer *layer_as_FillLayer() const {
    return layer_type() == armnnSerializer::Layer_FillLayer ? static_cast<const armnnSerializer::FillLayer *>(layer()) : nullptr;
  }
  const armnnSerializer::RankLayer *layer_as_RankLayer() const {
    return layer_type() == armnnSerializer::Layer_RankLayer ? static_cast<const armnnSerializer::RankLayer *>(layer()) : nullptr;
  }
  const armnnSerializer::LogicalBinaryLayer *layer_as_LogicalBinaryLayer() const {
    return layer_type() == armnnSerializer::Layer_LogicalBinaryLayer ? static_cast<const armnnSerializer::LogicalBinaryLayer *>(layer()) : nullptr;
  }
  const armnnSerializer::ReduceLayer *layer_as_ReduceLayer() const {
    return layer_type() == armnnSerializer::Layer_ReduceLayer ? static_cast<const armnnSerializer::ReduceLayer *>(layer()) : nullptr;
  }
  const armnnSerializer::CastLayer *layer_as_CastLayer() const {
    return layer_type() == armnnSerializer::Layer_CastLayer ? static_cast<const armnnSerializer::CastLayer *>(layer()) : nullptr;
  }
  const armnnSerializer::ShapeLayer *layer_as_ShapeLayer() const {
    return layer_type() == armnnSerializer::Layer_ShapeLayer ? static_cast<const armnnSerializer::ShapeLayer *>(layer()) : nullptr;
  }
  bool Verify(flatbuffers::Verifier &verifier) const {
    return VerifyTableStart(verifier) &&
           VerifyField<uint8_t>(verifier, VT_LAYER_TYPE) &&
           VerifyOffset(verifier, VT_LAYER) &&
           VerifyLayer(verifier, layer(), layer_type()) &&
           verifier.EndTable();
  }
};

template<> inline const armnnSerializer::ActivationLayer *AnyLayer::layer_as<armnnSerializer::ActivationLayer>() const {
  return layer_as_ActivationLayer();
}

template<> inline const armnnSerializer::AdditionLayer *AnyLayer::layer_as<armnnSerializer::AdditionLayer>() const {
  return layer_as_AdditionLayer();
}

template<> inline const armnnSerializer::BatchToSpaceNdLayer *AnyLayer::layer_as<armnnSerializer::BatchToSpaceNdLayer>() const {
  return layer_as_BatchToSpaceNdLayer();
}

template<> inline const armnnSerializer::BatchNormalizationLayer *AnyLayer::layer_as<armnnSerializer::BatchNormalizationLayer>() const {
  return layer_as_BatchNormalizationLayer();
}

template<> inline const armnnSerializer::ConstantLayer *AnyLayer::layer_as<armnnSerializer::ConstantLayer>() const {
  return layer_as_ConstantLayer();
}

template<> inline const armnnSerializer::Convolution2dLayer *AnyLayer::layer_as<armnnSerializer::Convolution2dLayer>() const {
  return layer_as_Convolution2dLayer();
}

template<> inline const armnnSerializer::DepthwiseConvolution2dLayer *AnyLayer::layer_as<armnnSerializer::DepthwiseConvolution2dLayer>() const {
  return layer_as_DepthwiseConvolution2dLayer();
}

template<> inline const armnnSerializer::FullyConnectedLayer *AnyLayer::layer_as<armnnSerializer::FullyConnectedLayer>() const {
  return layer_as_FullyConnectedLayer();
}

template<> inline const armnnSerializer::InputLayer *AnyLayer::layer_as<armnnSerializer::InputLayer>() const {
  return layer_as_InputLayer();
}

template<> inline const armnnSerializer::MultiplicationLayer *AnyLayer::layer_as<armnnSerializer::MultiplicationLayer>() const {
  return layer_as_MultiplicationLayer();
}

template<> inline const armnnSerializer::OutputLayer *AnyLayer::layer_as<armnnSerializer::OutputLayer>() const {
  return layer_as_OutputLayer();
}

template<> inline const armnnSerializer::PermuteLayer *AnyLayer::layer_as<armnnSerializer::PermuteLayer>() const {
  return layer_as_PermuteLayer();
}

template<> inline const armnnSerializer::Pooling2dLayer *AnyLayer::layer_as<armnnSerializer::Pooling2dLayer>() const {
  return layer_as_Pooling2dLayer();
}

template<> inline const armnnSerializer::ReshapeLayer *AnyLayer::layer_as<armnnSerializer::ReshapeLayer>() const {
  return layer_as_ReshapeLayer();
}

template<> inline const armnnSerializer::SoftmaxLayer *AnyLayer::layer_as<armnnSerializer::SoftmaxLayer>() const {
  return layer_as_SoftmaxLayer();
}

template<> inline const armnnSerializer::SpaceToBatchNdLayer *AnyLayer::layer_as<armnnSerializer::SpaceToBatchNdLayer>() const {
  return layer_as_SpaceToBatchNdLayer();
}

template<> inline const armnnSerializer::DivisionLayer *AnyLayer::layer_as<armnnSerializer::DivisionLayer>() const {
  return layer_as_DivisionLayer();
}

template<> inline const armnnSerializer::MinimumLayer *AnyLayer::layer_as<armnnSerializer::MinimumLayer>() const {
  return layer_as_MinimumLayer();
}

template<> inline const armnnSerializer::EqualLayer *AnyLayer::layer_as<armnnSerializer::EqualLayer>() const {
  return layer_as_EqualLayer();
}

template<> inline const armnnSerializer::MaximumLayer *AnyLayer::layer_as<armnnSerializer::MaximumLayer>() const {
  return layer_as_MaximumLayer();
}

template<> inline const armnnSerializer::NormalizationLayer *AnyLayer::layer_as<armnnSerializer::NormalizationLayer>() const {
  return layer_as_NormalizationLayer();
}

template<> inline const armnnSerializer::PadLayer *AnyLayer::layer_as<armnnSerializer::PadLayer>() const {
  return layer_as_PadLayer();
}

template<> inline const armnnSerializer::RsqrtLayer *AnyLayer::layer_as<armnnSerializer::RsqrtLayer>() const {
  return layer_as_RsqrtLayer();
}

template<> inline const armnnSerializer::FloorLayer *AnyLayer::layer_as<armnnSerializer::FloorLayer>() const {
  return layer_as_FloorLayer();
}

template<> inline const armnnSerializer::GreaterLayer *AnyLayer::layer_as<armnnSerializer::GreaterLayer>() const {
  return layer_as_GreaterLayer();
}

template<> inline const armnnSerializer::ResizeBilinearLayer *AnyLayer::layer_as<armnnSerializer::ResizeBilinearLayer>() const {
  return layer_as_ResizeBilinearLayer();
}

template<> inline const armnnSerializer::SubtractionLayer *AnyLayer::layer_as<armnnSerializer::SubtractionLayer>() const {
  return layer_as_SubtractionLayer();
}

template<> inline const armnnSerializer::StridedSliceLayer *AnyLayer::layer_as<armnnSerializer::StridedSliceLayer>() const {
  return layer_as_StridedSliceLayer();
}

template<> inline const armnnSerializer::GatherLayer *AnyLayer::layer_as<armnnSerializer::GatherLayer>() const {
  return layer_as_GatherLayer();
}

template<> inline const armnnSerializer::MeanLayer *AnyLayer::layer_as<armnnSerializer::MeanLayer>() const {
  return layer_as_MeanLayer();
}

template<> inline const armnnSerializer::MergerLayer *AnyLayer::layer_as<armnnSerializer::MergerLayer>() const {
  return layer_as_MergerLayer();
}

template<> inline const armnnSerializer::L2NormalizationLayer *AnyLayer::layer_as<armnnSerializer::L2NormalizationLayer>() const {
  return layer_as_L2NormalizationLayer();
}

template<> inline const armnnSerializer::SplitterLayer *AnyLayer::layer_as<armnnSerializer::SplitterLayer>() const {
  return layer_as_SplitterLayer();
}

template<> inline const armnnSerializer::DetectionPostProcessLayer *AnyLayer::layer_as<armnnSerializer::DetectionPostProcessLayer>() const {
  return layer_as_DetectionPostProcessLayer();
}

template<> inline const armnnSerializer::LstmLayer *AnyLayer::layer_as<armnnSerializer::LstmLayer>() const {
  return layer_as_LstmLayer();
}

template<> inline const armnnSerializer::QuantizedLstmLayer *AnyLayer::layer_as<armnnSerializer::QuantizedLstmLayer>() const {
  return layer_as_QuantizedLstmLayer();
}

template<> inline const armnnSerializer::QuantizeLayer *AnyLayer::layer_as<armnnSerializer::QuantizeLayer>() const {
  return layer_as_QuantizeLayer();
}

template<> inline const armnnSerializer::DequantizeLayer *AnyLayer::layer_as<armnnSerializer::DequantizeLayer>() const {
  return layer_as_DequantizeLayer();
}

template<> inline const armnnSerializer::MergeLayer *AnyLayer::layer_as<armnnSerializer::MergeLayer>() const {
  return layer_as_MergeLayer();
}

template<> inline const armnnSerializer::SwitchLayer *AnyLayer::layer_as<armnnSerializer::SwitchLayer>() const {
  return layer_as_SwitchLayer();
}

template<> inline const armnnSerializer::ConcatLayer *AnyLayer::layer_as<armnnSerializer::ConcatLayer>() const {
  return layer_as_ConcatLayer();
}

template<> inline const armnnSerializer::SpaceToDepthLayer *AnyLayer::layer_as<armnnSerializer::SpaceToDepthLayer>() const {
  return layer_as_SpaceToDepthLayer();
}

template<> inline const armnnSerializer::PreluLayer *AnyLayer::layer_as<armnnSerializer::PreluLayer>() const {
  return layer_as_PreluLayer();
}

template<> inline const armnnSerializer::TransposeConvolution2dLayer *AnyLayer::layer_as<armnnSerializer::TransposeConvolution2dLayer>() const {
  return layer_as_TransposeConvolution2dLayer();
}

template<> inline const armnnSerializer::ResizeLayer *AnyLayer::layer_as<armnnSerializer::ResizeLayer>() const {
  return layer_as_ResizeLayer();
}

template<> inline const armnnSerializer::StackLayer *AnyLayer::layer_as<armnnSerializer::StackLayer>() const {
  return layer_as_StackLayer();
}

template<> inline const armnnSerializer::AbsLayer *AnyLayer::layer_as<armnnSerializer::AbsLayer>() const {
  return layer_as_AbsLayer();
}

template<> inline const armnnSerializer::ArgMinMaxLayer *AnyLayer::layer_as<armnnSerializer::ArgMinMaxLayer>() const {
  return layer_as_ArgMinMaxLayer();
}

template<> inline const armnnSerializer::SliceLayer *AnyLayer::layer_as<armnnSerializer::SliceLayer>() const {
  return layer_as_SliceLayer();
}

template<> inline const armnnSerializer::DepthToSpaceLayer *AnyLayer::layer_as<armnnSerializer::DepthToSpaceLayer>() const {
  return layer_as_DepthToSpaceLayer();
}

template<> inline const armnnSerializer::InstanceNormalizationLayer *AnyLayer::layer_as<armnnSerializer::InstanceNormalizationLayer>() const {
  return layer_as_InstanceNormalizationLayer();
}

template<> inline const armnnSerializer::LogSoftmaxLayer *AnyLayer::layer_as<armnnSerializer::LogSoftmaxLayer>() const {
  return layer_as_LogSoftmaxLayer();
}

template<> inline const armnnSerializer::ComparisonLayer *AnyLayer::layer_as<armnnSerializer::ComparisonLayer>() const {
  return layer_as_ComparisonLayer();
}

template<> inline const armnnSerializer::StandInLayer *AnyLayer::layer_as<armnnSerializer::StandInLayer>() const {
  return layer_as_StandInLayer();
}

template<> inline const armnnSerializer::ElementwiseUnaryLayer *AnyLayer::layer_as<armnnSerializer::ElementwiseUnaryLayer>() const {
  return layer_as_ElementwiseUnaryLayer();
}

template<> inline const armnnSerializer::TransposeLayer *AnyLayer::layer_as<armnnSerializer::TransposeLayer>() const {
  return layer_as_TransposeLayer();
}

template<> inline const armnnSerializer::QLstmLayer *AnyLayer::layer_as<armnnSerializer::QLstmLayer>() const {
  return layer_as_QLstmLayer();
}

template<> inline const armnnSerializer::FillLayer *AnyLayer::layer_as<armnnSerializer::FillLayer>() const {
  return layer_as_FillLayer();
}

template<> inline const armnnSerializer::RankLayer *AnyLayer::layer_as<armnnSerializer::RankLayer>() const {
  return layer_as_RankLayer();
}

template<> inline const armnnSerializer::LogicalBinaryLayer *AnyLayer::layer_as<armnnSerializer::LogicalBinaryLayer>() const {
  return layer_as_LogicalBinaryLayer();
}

template<> inline const armnnSerializer::ReduceLayer *AnyLayer::layer_as<armnnSerializer::ReduceLayer>() const {
  return layer_as_ReduceLayer();
}

template<> inline const armnnSerializer::CastLayer *AnyLayer::layer_as<armnnSerializer::CastLayer>() const {
  return layer_as_CastLayer();
}

template<> inline const armnnSerializer::ShapeLayer *AnyLayer::layer_as<armnnSerializer::ShapeLayer>() const {
  return layer_as_ShapeLayer();
}

struct AnyLayerBuilder {
  typedef AnyLayer Table;
  flatbuffers::FlatBufferBuilder &fbb_;
  flatbuffers::uoffset_t start_;
  void add_layer_type(armnnSerializer::Layer layer_type) {
    fbb_.AddElement<uint8_t>(AnyLayer::VT_LAYER_TYPE, static_cast<uint8_t>(layer_type), 0);
  }
  void add_layer(flatbuffers::Offset<void> layer) {
    fbb_.AddOffset(AnyLayer::VT_LAYER, layer);
  }
  explicit AnyLayerBuilder(flatbuffers::FlatBufferBuilder &_fbb)
        : fbb_(_fbb) {
    start_ = fbb_.StartTable();
  }
  AnyLayerBuilder &operator=(const AnyLayerBuilder &);
  flatbuffers::Offset<AnyLayer> Finish() {
    const auto end = fbb_.EndTable(start_);
    auto o = flatbuffers::Offset<AnyLayer>(end);
    return o;
  }
};

inline flatbuffers::Offset<AnyLayer> CreateAnyLayer(
    flatbuffers::FlatBufferBuilder &_fbb,
    armnnSerializer::Layer layer_type = armnnSerializer::Layer_NONE,
    flatbuffers::Offset<void> layer = 0) {
  AnyLayerBuilder builder_(_fbb);
  builder_.add_layer(layer);
  builder_.add_layer_type(layer_type);
  return builder_.Finish();
}

struct FeatureCompatibilityVersions FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
  typedef FeatureCompatibilityVersionsBuilder Builder;
  enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
    VT_BINDINGIDSSCHEME = 4,
    VT_WEIGHTSLAYOUTSCHEME = 6
  };
  uint32_t bindingIdsScheme() const {
    return GetField<uint32_t>(VT_BINDINGIDSSCHEME, 0);
  }
  uint32_t weightsLayoutScheme() const {
    return GetField<uint32_t>(VT_WEIGHTSLAYOUTSCHEME, 0);
  }
  bool Verify(flatbuffers::Verifier &verifier) const {
    return VerifyTableStart(verifier) &&
           VerifyField<uint32_t>(verifier, VT_BINDINGIDSSCHEME) &&
           VerifyField<uint32_t>(verifier, VT_WEIGHTSLAYOUTSCHEME) &&
           verifier.EndTable();
  }
};

struct FeatureCompatibilityVersionsBuilder {
  typedef FeatureCompatibilityVersions Table;
  flatbuffers::FlatBufferBuilder &fbb_;
  flatbuffers::uoffset_t start_;
  void add_bindingIdsScheme(uint32_t bindingIdsScheme) {
    fbb_.AddElement<uint32_t>(FeatureCompatibilityVersions::VT_BINDINGIDSSCHEME, bindingIdsScheme, 0);
  }
  void add_weightsLayoutScheme(uint32_t weightsLayoutScheme) {
    fbb_.AddElement<uint32_t>(FeatureCompatibilityVersions::VT_WEIGHTSLAYOUTSCHEME, weightsLayoutScheme, 0);
  }
  explicit FeatureCompatibilityVersionsBuilder(flatbuffers::FlatBufferBuilder &_fbb)
        : fbb_(_fbb) {
    start_ = fbb_.StartTable();
  }
  FeatureCompatibilityVersionsBuilder &operator=(const FeatureCompatibilityVersionsBuilder &);
  flatbuffers::Offset<FeatureCompatibilityVersions> Finish() {
    const auto end = fbb_.EndTable(start_);
    auto o = flatbuffers::Offset<FeatureCompatibilityVersions>(end);
    return o;
  }
};

inline flatbuffers::Offset<FeatureCompatibilityVersions> CreateFeatureCompatibilityVersions(
    flatbuffers::FlatBufferBuilder &_fbb,
    uint32_t bindingIdsScheme = 0,
    uint32_t weightsLayoutScheme = 0) {
  FeatureCompatibilityVersionsBuilder builder_(_fbb);
  builder_.add_weightsLayoutScheme(weightsLayoutScheme);
  builder_.add_bindingIdsScheme(bindingIdsScheme);
  return builder_.Finish();
}

struct SerializedGraph FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
  typedef SerializedGraphBuilder Builder;
  enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
    VT_LAYERS = 4,
    VT_INPUTIDS = 6,
    VT_OUTPUTIDS = 8,
    VT_FEATUREVERSIONS = 10
  };
  const flatbuffers::Vector<flatbuffers::Offset<armnnSerializer::AnyLayer>> *layers() const {
    return GetPointer<const flatbuffers::Vector<flatbuffers::Offset<armnnSerializer::AnyLayer>> *>(VT_LAYERS);
  }
  const flatbuffers::Vector<int32_t> *inputIds() const {
    return GetPointer<const flatbuffers::Vector<int32_t> *>(VT_INPUTIDS);
  }
  const flatbuffers::Vector<int32_t> *outputIds() const {
    return GetPointer<const flatbuffers::Vector<int32_t> *>(VT_OUTPUTIDS);
  }
  const armnnSerializer::FeatureCompatibilityVersions *featureVersions() const {
    return GetPointer<const armnnSerializer::FeatureCompatibilityVersions *>(VT_FEATUREVERSIONS);
  }
  bool Verify(flatbuffers::Verifier &verifier) const {
    return VerifyTableStart(verifier) &&
           VerifyOffset(verifier, VT_LAYERS) &&
           verifier.VerifyVector(layers()) &&
           verifier.VerifyVectorOfTables(layers()) &&
           VerifyOffset(verifier, VT_INPUTIDS) &&
           verifier.VerifyVector(inputIds()) &&
           VerifyOffset(verifier, VT_OUTPUTIDS) &&
           verifier.VerifyVector(outputIds()) &&
           VerifyOffset(verifier, VT_FEATUREVERSIONS) &&
           verifier.VerifyTable(featureVersions()) &&
           verifier.EndTable();
  }
};

struct SerializedGraphBuilder {
  typedef SerializedGraph Table;
  flatbuffers::FlatBufferBuilder &fbb_;
  flatbuffers::uoffset_t start_;
  void add_layers(flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<armnnSerializer::AnyLayer>>> layers) {
    fbb_.AddOffset(SerializedGraph::VT_LAYERS, layers);
  }
  void add_inputIds(flatbuffers::Offset<flatbuffers::Vector<int32_t>> inputIds) {
    fbb_.AddOffset(SerializedGraph::VT_INPUTIDS, inputIds);
  }
  void add_outputIds(flatbuffers::Offset<flatbuffers::Vector<int32_t>> outputIds) {
    fbb_.AddOffset(SerializedGraph::VT_OUTPUTIDS, outputIds);
  }
  void add_featureVersions(flatbuffers::Offset<armnnSerializer::FeatureCompatibilityVersions> featureVersions) {
    fbb_.AddOffset(SerializedGraph::VT_FEATUREVERSIONS, featureVersions);
  }
  explicit SerializedGraphBuilder(flatbuffers::FlatBufferBuilder &_fbb)
        : fbb_(_fbb) {
    start_ = fbb_.StartTable();
  }
  SerializedGraphBuilder &operator=(const SerializedGraphBuilder &);
  flatbuffers::Offset<SerializedGraph> Finish() {
    const auto end = fbb_.EndTable(start_);
    auto o = flatbuffers::Offset<SerializedGraph>(end);
    return o;
  }
};

inline flatbuffers::Offset<SerializedGraph> CreateSerializedGraph(
    flatbuffers::FlatBufferBuilder &_fbb,
    flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<armnnSerializer::AnyLayer>>> layers = 0,
    flatbuffers::Offset<flatbuffers::Vector<int32_t>> inputIds = 0,
    flatbuffers::Offset<flatbuffers::Vector<int32_t>> outputIds = 0,
    flatbuffers::Offset<armnnSerializer::FeatureCompatibilityVersions> featureVersions = 0) {
  SerializedGraphBuilder builder_(_fbb);
  builder_.add_featureVersions(featureVersions);
  builder_.add_outputIds(outputIds);
  builder_.add_inputIds(inputIds);
  builder_.add_layers(layers);
  return builder_.Finish();
}

inline flatbuffers::Offset<SerializedGraph> CreateSerializedGraphDirect(
    flatbuffers::FlatBufferBuilder &_fbb,
    const std::vector<flatbuffers::Offset<armnnSerializer::AnyLayer>> *layers = nullptr,
    const std::vector<int32_t> *inputIds = nullptr,
    const std::vector<int32_t> *outputIds = nullptr,
    flatbuffers::Offset<armnnSerializer::FeatureCompatibilityVersions> featureVersions = 0) {
  auto layers__ = layers ? _fbb.CreateVector<flatbuffers::Offset<armnnSerializer::AnyLayer>>(*layers) : 0;
  auto inputIds__ = inputIds ? _fbb.CreateVector<int32_t>(*inputIds) : 0;
  auto outputIds__ = outputIds ? _fbb.CreateVector<int32_t>(*outputIds) : 0;
  return armnnSerializer::CreateSerializedGraph(
      _fbb,
      layers__,
      inputIds__,
      outputIds__,
      featureVersions);
}

inline bool VerifyConstTensorData(flatbuffers::Verifier &verifier, const void *obj, ConstTensorData type) {
  switch (type) {
    case ConstTensorData_NONE: {
      return true;
    }
    case ConstTensorData_ByteData: {
      auto ptr = reinterpret_cast<const armnnSerializer::ByteData *>(obj);
      return verifier.VerifyTable(ptr);
    }
    case ConstTensorData_ShortData: {
      auto ptr = reinterpret_cast<const armnnSerializer::ShortData *>(obj);
      return verifier.VerifyTable(ptr);
    }
    case ConstTensorData_IntData: {
      auto ptr = reinterpret_cast<const armnnSerializer::IntData *>(obj);
      return verifier.VerifyTable(ptr);
    }
    case ConstTensorData_LongData: {
      auto ptr = reinterpret_cast<const armnnSerializer::LongData *>(obj);
      return verifier.VerifyTable(ptr);
    }
    default: return true;
  }
}

inline bool VerifyConstTensorDataVector(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 (!VerifyConstTensorData(
        verifier,  values->Get(i), types->GetEnum<ConstTensorData>(i))) {
      return false;
    }
  }
  return true;
}

inline bool VerifyLayer(flatbuffers::Verifier &verifier, const void *obj, Layer type) {
  switch (type) {
    case Layer_NONE: {
      return true;
    }
    case Layer_ActivationLayer: {
      auto ptr = reinterpret_cast<const armnnSerializer::ActivationLayer *>(obj);
      return verifier.VerifyTable(ptr);
    }
    case Layer_AdditionLayer: {
      auto ptr = reinterpret_cast<const armnnSerializer::AdditionLayer *>(obj);
      return verifier.VerifyTable(ptr);
    }
    case Layer_BatchToSpaceNdLayer: {
      auto ptr = reinterpret_cast<const armnnSerializer::BatchToSpaceNdLayer *>(obj);
      return verifier.VerifyTable(ptr);
    }
    case Layer_BatchNormalizationLayer: {
      auto ptr = reinterpret_cast<const armnnSerializer::BatchNormalizationLayer *>(obj);
      return verifier.VerifyTable(ptr);
    }
    case Layer_ConstantLayer: {
      auto ptr = reinterpret_cast<const armnnSerializer::ConstantLayer *>(obj);
      return verifier.VerifyTable(ptr);
    }
    case Layer_Convolution2dLayer: {
      auto ptr = reinterpret_cast<const armnnSerializer::Convolution2dLayer *>(obj);
      return verifier.VerifyTable(ptr);
    }
    case Layer_DepthwiseConvolution2dLayer: {
      auto ptr = reinterpret_cast<const armnnSerializer::DepthwiseConvolution2dLayer *>(obj);
      return verifier.VerifyTable(ptr);
    }
    case Layer_FullyConnectedLayer: {
      auto ptr = reinterpret_cast<const armnnSerializer::FullyConnectedLayer *>(obj);
      return verifier.VerifyTable(ptr);
    }
    case Layer_InputLayer: {
      auto ptr = reinterpret_cast<const armnnSerializer::InputLayer *>(obj);
      return verifier.VerifyTable(ptr);
    }
    case Layer_MultiplicationLayer: {
      auto ptr = reinterpret_cast<const armnnSerializer::MultiplicationLayer *>(obj);
      return verifier.VerifyTable(ptr);
    }
    case Layer_OutputLayer: {
      auto ptr = reinterpret_cast<const armnnSerializer::OutputLayer *>(obj);
      return verifier.VerifyTable(ptr);
    }
    case Layer_PermuteLayer: {
      auto ptr = reinterpret_cast<const armnnSerializer::PermuteLayer *>(obj);
      return verifier.VerifyTable(ptr);
    }
    case Layer_Pooling2dLayer: {
      auto ptr = reinterpret_cast<const armnnSerializer::Pooling2dLayer *>(obj);
      return verifier.VerifyTable(ptr);
    }
    case Layer_ReshapeLayer: {
      auto ptr = reinterpret_cast<const armnnSerializer::ReshapeLayer *>(obj);
      return verifier.VerifyTable(ptr);
    }
    case Layer_SoftmaxLayer: {
      auto ptr = reinterpret_cast<const armnnSerializer::SoftmaxLayer *>(obj);
      return verifier.VerifyTable(ptr);
    }
    case Layer_SpaceToBatchNdLayer: {
      auto ptr = reinterpret_cast<const armnnSerializer::SpaceToBatchNdLayer *>(obj);
      return verifier.VerifyTable(ptr);
    }
    case Layer_DivisionLayer: {
      auto ptr = reinterpret_cast<const armnnSerializer::DivisionLayer *>(obj);
      return verifier.VerifyTable(ptr);
    }
    case Layer_MinimumLayer: {
      auto ptr = reinterpret_cast<const armnnSerializer::MinimumLayer *>(obj);
      return verifier.VerifyTable(ptr);
    }
    case Layer_EqualLayer: {
      auto ptr = reinterpret_cast<const armnnSerializer::EqualLayer *>(obj);
      return verifier.VerifyTable(ptr);
    }
    case Layer_MaximumLayer: {
      auto ptr = reinterpret_cast<const armnnSerializer::MaximumLayer *>(obj);
      return verifier.VerifyTable(ptr);
    }
    case Layer_NormalizationLayer: {
      auto ptr = reinterpret_cast<const armnnSerializer::NormalizationLayer *>(obj);
      return verifier.VerifyTable(ptr);
    }
    case Layer_PadLayer: {
      auto ptr = reinterpret_cast<const armnnSerializer::PadLayer *>(obj);
      return verifier.VerifyTable(ptr);
    }
    case Layer_RsqrtLayer: {
      auto ptr = reinterpret_cast<const armnnSerializer::RsqrtLayer *>(obj);
      return verifier.VerifyTable(ptr);
    }
    case Layer_FloorLayer: {
      auto ptr = reinterpret_cast<const armnnSerializer::FloorLayer *>(obj);
      return verifier.VerifyTable(ptr);
    }
    case Layer_GreaterLayer: {
      auto ptr = reinterpret_cast<const armnnSerializer::GreaterLayer *>(obj);
      return verifier.VerifyTable(ptr);
    }
    case Layer_ResizeBilinearLayer: {
      auto ptr = reinterpret_cast<const armnnSerializer::ResizeBilinearLayer *>(obj);
      return verifier.VerifyTable(ptr);
    }
    case Layer_SubtractionLayer: {
      auto ptr = reinterpret_cast<const armnnSerializer::SubtractionLayer *>(obj);
      return verifier.VerifyTable(ptr);
    }
    case Layer_StridedSliceLayer: {
      auto ptr = reinterpret_cast<const armnnSerializer::StridedSliceLayer *>(obj);
      return verifier.VerifyTable(ptr);
    }
    case Layer_GatherLayer: {
      auto ptr = reinterpret_cast<const armnnSerializer::GatherLayer *>(obj);
      return verifier.VerifyTable(ptr);
    }
    case Layer_MeanLayer: {
      auto ptr = reinterpret_cast<const armnnSerializer::MeanLayer *>(obj);
      return verifier.VerifyTable(ptr);
    }
    case Layer_MergerLayer: {
      auto ptr = reinterpret_cast<const armnnSerializer::MergerLayer *>(obj);
      return verifier.VerifyTable(ptr);
    }
    case Layer_L2NormalizationLayer: {
      auto ptr = reinterpret_cast<const armnnSerializer::L2NormalizationLayer *>(obj);
      return verifier.VerifyTable(ptr);
    }
    case Layer_SplitterLayer: {
      auto ptr = reinterpret_cast<const armnnSerializer::SplitterLayer *>(obj);
      return verifier.VerifyTable(ptr);
    }
    case Layer_DetectionPostProcessLayer: {
      auto ptr = reinterpret_cast<const armnnSerializer::DetectionPostProcessLayer *>(obj);
      return verifier.VerifyTable(ptr);
    }
    case Layer_LstmLayer: {
      auto ptr = reinterpret_cast<const armnnSerializer::LstmLayer *>(obj);
      return verifier.VerifyTable(ptr);
    }
    case Layer_QuantizedLstmLayer: {
      auto ptr = reinterpret_cast<const armnnSerializer::QuantizedLstmLayer *>(obj);
      return verifier.VerifyTable(ptr);
    }
    case Layer_QuantizeLayer: {
      auto ptr = reinterpret_cast<const armnnSerializer::QuantizeLayer *>(obj);
      return verifier.VerifyTable(ptr);
    }
    case Layer_DequantizeLayer: {
      auto ptr = reinterpret_cast<const armnnSerializer::DequantizeLayer *>(obj);
      return verifier.VerifyTable(ptr);
    }
    case Layer_MergeLayer: {
      auto ptr = reinterpret_cast<const armnnSerializer::MergeLayer *>(obj);
      return verifier.VerifyTable(ptr);
    }
    case Layer_SwitchLayer: {
      auto ptr = reinterpret_cast<const armnnSerializer::SwitchLayer *>(obj);
      return verifier.VerifyTable(ptr);
    }
    case Layer_ConcatLayer: {
      auto ptr = reinterpret_cast<const armnnSerializer::ConcatLayer *>(obj);
      return verifier.VerifyTable(ptr);
    }
    case Layer_SpaceToDepthLayer: {
      auto ptr = reinterpret_cast<const armnnSerializer::SpaceToDepthLayer *>(obj);
      return verifier.VerifyTable(ptr);
    }
    case Layer_PreluLayer: {
      auto ptr = reinterpret_cast<const armnnSerializer::PreluLayer *>(obj);
      return verifier.VerifyTable(ptr);
    }
    case Layer_TransposeConvolution2dLayer: {
      auto ptr = reinterpret_cast<const armnnSerializer::TransposeConvolution2dLayer *>(obj);
      return verifier.VerifyTable(ptr);
    }
    case Layer_ResizeLayer: {
      auto ptr = reinterpret_cast<const armnnSerializer::ResizeLayer *>(obj);
      return verifier.VerifyTable(ptr);
    }
    case Layer_StackLayer: {
      auto ptr = reinterpret_cast<const armnnSerializer::StackLayer *>(obj);
      return verifier.VerifyTable(ptr);
    }
    case Layer_AbsLayer: {
      auto ptr = reinterpret_cast<const armnnSerializer::AbsLayer *>(obj);
      return verifier.VerifyTable(ptr);
    }
    case Layer_ArgMinMaxLayer: {
      auto ptr = reinterpret_cast<const armnnSerializer::ArgMinMaxLayer *>(obj);
      return verifier.VerifyTable(ptr);
    }
    case Layer_SliceLayer: {
      auto ptr = reinterpret_cast<const armnnSerializer::SliceLayer *>(obj);
      return verifier.VerifyTable(ptr);
    }
    case Layer_DepthToSpaceLayer: {
      auto ptr = reinterpret_cast<const armnnSerializer::DepthToSpaceLayer *>(obj);
      return verifier.VerifyTable(ptr);
    }
    case Layer_InstanceNormalizationLayer: {
      auto ptr = reinterpret_cast<const armnnSerializer::InstanceNormalizationLayer *>(obj);
      return verifier.VerifyTable(ptr);
    }
    case Layer_LogSoftmaxLayer: {
      auto ptr = reinterpret_cast<const armnnSerializer::LogSoftmaxLayer *>(obj);
      return verifier.VerifyTable(ptr);
    }
    case Layer_ComparisonLayer: {
      auto ptr = reinterpret_cast<const armnnSerializer::ComparisonLayer *>(obj);
      return verifier.VerifyTable(ptr);
    }
    case Layer_StandInLayer: {
      auto ptr = reinterpret_cast<const armnnSerializer::StandInLayer *>(obj);
      return verifier.VerifyTable(ptr);
    }
    case Layer_ElementwiseUnaryLayer: {
      auto ptr = reinterpret_cast<const armnnSerializer::ElementwiseUnaryLayer *>(obj);
      return verifier.VerifyTable(ptr);
    }
    case Layer_TransposeLayer: {
      auto ptr = reinterpret_cast<const armnnSerializer::TransposeLayer *>(obj);
      return verifier.VerifyTable(ptr);
    }
    case Layer_QLstmLayer: {
      auto ptr = reinterpret_cast<const armnnSerializer::QLstmLayer *>(obj);
      return verifier.VerifyTable(ptr);
    }
    case Layer_FillLayer: {
      auto ptr = reinterpret_cast<const armnnSerializer::FillLayer *>(obj);
      return verifier.VerifyTable(ptr);
    }
    case Layer_RankLayer: {
      auto ptr = reinterpret_cast<const armnnSerializer::RankLayer *>(obj);
      return verifier.VerifyTable(ptr);
    }
    case Layer_LogicalBinaryLayer: {
      auto ptr = reinterpret_cast<const armnnSerializer::LogicalBinaryLayer *>(obj);
      return verifier.VerifyTable(ptr);
    }
    case Layer_ReduceLayer: {
      auto ptr = reinterpret_cast<const armnnSerializer::ReduceLayer *>(obj);
      return verifier.VerifyTable(ptr);
    }
    case Layer_CastLayer: {
      auto ptr = reinterpret_cast<const armnnSerializer::CastLayer *>(obj);
      return verifier.VerifyTable(ptr);
    }
    case Layer_ShapeLayer: {
      auto ptr = reinterpret_cast<const armnnSerializer::ShapeLayer *>(obj);
      return verifier.VerifyTable(ptr);
    }
    default: return true;
  }
}

inline bool VerifyLayerVector(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 (!VerifyLayer(
        verifier,  values->Get(i), types->GetEnum<Layer>(i))) {
      return false;
    }
  }
  return true;
}

inline const armnnSerializer::SerializedGraph *GetSerializedGraph(const void *buf) {
  return flatbuffers::GetRoot<armnnSerializer::SerializedGraph>(buf);
}

inline const armnnSerializer::SerializedGraph *GetSizePrefixedSerializedGraph(const void *buf) {
  return flatbuffers::GetSizePrefixedRoot<armnnSerializer::SerializedGraph>(buf);
}

inline const char *SerializedGraphIdentifier() {
  return "ARMN";
}

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

inline bool VerifySerializedGraphBuffer(
    flatbuffers::Verifier &verifier) {
  return verifier.VerifyBuffer<armnnSerializer::SerializedGraph>(SerializedGraphIdentifier());
}

inline bool VerifySizePrefixedSerializedGraphBuffer(
    flatbuffers::Verifier &verifier) {
  return verifier.VerifySizePrefixedBuffer<armnnSerializer::SerializedGraph>(SerializedGraphIdentifier());
}

inline const char *SerializedGraphExtension() {
  return "armnn";
}

inline void FinishSerializedGraphBuffer(
    flatbuffers::FlatBufferBuilder &fbb,
    flatbuffers::Offset<armnnSerializer::SerializedGraph> root) {
  fbb.Finish(root, SerializedGraphIdentifier());
}

inline void FinishSizePrefixedSerializedGraphBuffer(
    flatbuffers::FlatBufferBuilder &fbb,
    flatbuffers::Offset<armnnSerializer::SerializedGraph> root) {
  fbb.FinishSizePrefixed(root, SerializedGraphIdentifier());
}

}  // namespace armnnSerializer

#endif  // FLATBUFFERS_GENERATED_ARMNNSCHEMA_ARMNNSERIALIZER_H_
