//
// 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 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 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_MIN = DataType_Float16,
  DataType_MAX = DataType_QSymmS8
};

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

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

inline const char *EnumNameDataType(DataType e) {
  if (flatbuffers::IsOutRange(e, DataType_Float16, DataType_QSymmS8)) 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_MIN = LayerType_Addition,
  LayerType_MAX = LayerType_Reduce
};

inline const LayerType (&EnumValuesLayerType())[61] {
  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
  };
  return values;
}

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

inline const char *EnumNameLayerType(LayerType e) {
  if (flatbuffers::IsOutRange(e, LayerType_Addition, LayerType_Reduce)) 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_MIN = UnaryOperation_Abs,
  UnaryOperation_MAX = UnaryOperation_LogicalNot
};

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

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

inline const char *EnumNameUnaryOperation(UnaryOperation e) {
  if (flatbuffers::IsOutRange(e, UnaryOperation_Abs, UnaryOperation_LogicalNot)) 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_MIN = Layer_NONE,
  Layer_MAX = Layer_ReduceLayer
};

inline const Layer (&EnumValuesLayer())[62] {
  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
  };
  return values;
}

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

inline const char *EnumNameLayer(Layer e) {
  if (flatbuffers::IsOutRange(e, Layer_NONE, Layer_ReduceLayer)) 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;
};

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 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
  };
  bool biasEnabled() const {
    return GetField<uint8_t>(VT_BIASENABLED, 0) != 0;
  }
  bool transposeWeightsMatrix() const {
    return GetField<uint8_t>(VT_TRANSPOSEWEIGHTSMATRIX, 0) != 0;
  }
  bool Verify(flatbuffers::Verifier &verifier) const {
    return VerifyTableStart(verifier) &&
           VerifyField<uint8_t>(verifier, VT_BIASENABLED) &&
           VerifyField<uint8_t>(verifier, VT_TRANSPOSEWEIGHTSMATRIX) &&
           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);
  }
  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) {
  FullyConnectedDescriptorBuilder builder_(_fbb);
  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 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;
  }
  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();
}

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
  };
  uint32_t bindingIdsScheme() const {
    return GetField<uint32_t>(VT_BINDINGIDSSCHEME, 0);
  }
  bool Verify(flatbuffers::Verifier &verifier) const {
    return VerifyTableStart(verifier) &&
           VerifyField<uint32_t>(verifier, VT_BINDINGIDSSCHEME) &&
           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);
  }
  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) {
  FeatureCompatibilityVersionsBuilder builder_(_fbb);
  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);
    }
    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_
