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


#ifndef FLATBUFFERS_GENERATED_ARMNNSCHEMA_ARMNNSERIALIZER_H_
#define FLATBUFFERS_GENERATED_ARMNNSCHEMA_ARMNNSERIALIZER_H_

#include "flatbuffers/flatbuffers.h"

namespace armnnSerializer {

struct TensorInfo;
struct TensorInfoBuilder;

struct Connection;

struct ByteData;
struct ByteDataBuilder;

struct ShortData;
struct ShortDataBuilder;

struct IntData;
struct IntDataBuilder;

struct LongData;
struct LongDataBuilder;

struct ConstTensor;
struct ConstTensorBuilder;

struct InputSlot;
struct InputSlotBuilder;

struct OutputSlot;
struct OutputSlotBuilder;

struct LayerBase;
struct LayerBaseBuilder;

struct BindableLayerBase;
struct BindableLayerBaseBuilder;

struct AbsLayer;
struct AbsLayerBuilder;

struct ActivationLayer;
struct ActivationLayerBuilder;

struct ActivationDescriptor;
struct ActivationDescriptorBuilder;

struct AdditionLayer;
struct AdditionLayerBuilder;

struct ArgMinMaxLayer;
struct ArgMinMaxLayerBuilder;

struct ArgMinMaxDescriptor;
struct ArgMinMaxDescriptorBuilder;

struct CastLayer;
struct CastLayerBuilder;

struct ChannelShuffleLayer;
struct ChannelShuffleLayerBuilder;

struct ChannelShuffleDescriptor;
struct ChannelShuffleDescriptorBuilder;

struct ComparisonDescriptor;
struct ComparisonDescriptorBuilder;

struct ComparisonLayer;
struct ComparisonLayerBuilder;

struct ConstantLayer;
struct ConstantLayerBuilder;

struct Convolution2dLayer;
struct Convolution2dLayerBuilder;

struct Convolution2dDescriptor;
struct Convolution2dDescriptorBuilder;

struct Convolution3dLayer;
struct Convolution3dLayerBuilder;

struct Convolution3dDescriptor;
struct Convolution3dDescriptorBuilder;

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 GatherNdLayer;
struct GatherNdLayerBuilder;

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 Pooling3dLayer;
struct Pooling3dLayerBuilder;

struct Pooling2dDescriptor;
struct Pooling2dDescriptorBuilder;

struct Pooling3dDescriptor;
struct Pooling3dDescriptorBuilder;

struct QuantizeLayer;
struct QuantizeLayerBuilder;

struct SoftmaxLayer;
struct SoftmaxLayerBuilder;

struct SoftmaxDescriptor;
struct SoftmaxDescriptorBuilder;

struct DepthwiseConvolution2dLayer;
struct DepthwiseConvolution2dLayerBuilder;

struct DepthwiseConvolution2dDescriptor;
struct DepthwiseConvolution2dDescriptorBuilder;

struct OutputLayer;
struct OutputLayerBuilder;

struct ReshapeLayer;
struct ReshapeLayerBuilder;

struct ReshapeDescriptor;
struct ReshapeDescriptorBuilder;

struct PermuteLayer;
struct PermuteLayerBuilder;

struct PermuteDescriptor;
struct PermuteDescriptorBuilder;

struct ShapeLayer;
struct ShapeLayerBuilder;

struct SpaceToBatchNdLayer;
struct SpaceToBatchNdLayerBuilder;

struct SpaceToBatchNdDescriptor;
struct SpaceToBatchNdDescriptorBuilder;

struct SpaceToDepthLayer;
struct SpaceToDepthLayerBuilder;

struct SpaceToDepthDescriptor;
struct SpaceToDepthDescriptorBuilder;

struct SubtractionLayer;
struct SubtractionLayerBuilder;

struct BatchToSpaceNdLayer;
struct BatchToSpaceNdLayerBuilder;

struct BatchToSpaceNdDescriptor;
struct BatchToSpaceNdDescriptorBuilder;

struct NormalizationLayer;
struct NormalizationLayerBuilder;

struct NormalizationDescriptor;
struct NormalizationDescriptorBuilder;

struct MeanLayer;
struct MeanLayerBuilder;

struct MeanDescriptor;
struct MeanDescriptorBuilder;

struct PadLayer;
struct PadLayerBuilder;

struct PadDescriptor;
struct PadDescriptorBuilder;

struct RsqrtLayer;
struct RsqrtLayerBuilder;

struct BatchNormalizationLayer;
struct BatchNormalizationLayerBuilder;

struct BatchNormalizationDescriptor;
struct BatchNormalizationDescriptorBuilder;

struct ResizeBilinearLayer;
struct ResizeBilinearLayerBuilder;

struct ResizeBilinearDescriptor;
struct ResizeBilinearDescriptorBuilder;

struct SliceLayer;
struct SliceLayerBuilder;

struct SliceDescriptor;
struct SliceDescriptorBuilder;

struct StridedSliceLayer;
struct StridedSliceLayerBuilder;

struct StridedSliceDescriptor;
struct StridedSliceDescriptorBuilder;

struct ConcatLayer;
struct ConcatLayerBuilder;

struct MergerLayer;
struct MergerLayerBuilder;

struct UintVector;
struct UintVectorBuilder;

struct OriginsDescriptor;
struct OriginsDescriptorBuilder;

struct ViewsDescriptor;
struct ViewsDescriptorBuilder;

struct SplitterLayer;
struct SplitterLayerBuilder;

struct DetectionPostProcessLayer;
struct DetectionPostProcessLayerBuilder;

struct DetectionPostProcessDescriptor;
struct DetectionPostProcessDescriptorBuilder;

struct LstmInputParams;
struct LstmInputParamsBuilder;

struct LstmDescriptor;
struct LstmDescriptorBuilder;

struct LstmLayer;
struct LstmLayerBuilder;

struct QLstmInputParams;
struct QLstmInputParamsBuilder;

struct QLstmDescriptor;
struct QLstmDescriptorBuilder;

struct QLstmLayer;
struct QLstmLayerBuilder;

struct QuantizedLstmInputParams;
struct QuantizedLstmInputParamsBuilder;

struct QuantizedLstmLayer;
struct QuantizedLstmLayerBuilder;

struct DequantizeLayer;
struct DequantizeLayerBuilder;

struct MergeLayer;
struct MergeLayerBuilder;

struct SwitchLayer;
struct SwitchLayerBuilder;

struct PreluLayer;
struct PreluLayerBuilder;

struct TransposeConvolution2dLayer;
struct TransposeConvolution2dLayerBuilder;

struct TransposeConvolution2dDescriptor;
struct TransposeConvolution2dDescriptorBuilder;

struct TransposeLayer;
struct TransposeLayerBuilder;

struct TransposeDescriptor;
struct TransposeDescriptorBuilder;

struct ResizeLayer;
struct ResizeLayerBuilder;

struct ResizeDescriptor;
struct ResizeDescriptorBuilder;

struct StackLayer;
struct StackLayerBuilder;

struct StackDescriptor;
struct StackDescriptorBuilder;

struct StandInDescriptor;
struct StandInDescriptorBuilder;

struct StandInLayer;
struct StandInLayerBuilder;

struct RankLayer;
struct RankLayerBuilder;

struct ReduceLayer;
struct ReduceLayerBuilder;

struct ReduceDescriptor;
struct ReduceDescriptorBuilder;

struct UnidirectionalSequenceLstmDescriptor;
struct UnidirectionalSequenceLstmDescriptorBuilder;

struct UnidirectionalSequenceLstmLayer;
struct UnidirectionalSequenceLstmLayerBuilder;

struct AnyLayer;
struct AnyLayerBuilder;

struct FeatureCompatibilityVersions;
struct FeatureCompatibilityVersionsBuilder;

struct SerializedGraph;
struct SerializedGraphBuilder;

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

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

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

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

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

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

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

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

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

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

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

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

enum DataLayout {
  DataLayout_NHWC = 0,
  DataLayout_NCHW = 1,
  DataLayout_NDHWC = 2,
  DataLayout_NCDHW = 3,
  DataLayout_MIN = DataLayout_NHWC,
  DataLayout_MAX = DataLayout_NCDHW
};

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

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

inline const char *EnumNameDataLayout(DataLayout e) {
  if (flatbuffers::IsOutRange(e, DataLayout_NHWC, DataLayout_NCDHW)) 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_Prod = 4,
  ReduceOperation_MIN = ReduceOperation_Sum,
  ReduceOperation_MAX = ReduceOperation_Prod
};

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

enum PaddingMode {
  PaddingMode_Constant = 0,
  PaddingMode_Reflect = 1,
  PaddingMode_Symmetric = 2,
  PaddingMode_MIN = PaddingMode_Constant,
  PaddingMode_MAX = PaddingMode_Symmetric
};

inline const PaddingMode (&EnumValuesPaddingMode())[3] {
  static const PaddingMode values[] = {
    PaddingMode_Constant,
    PaddingMode_Reflect,
    PaddingMode_Symmetric
  };
  return values;
}

inline const char * const *EnumNamesPaddingMode() {
  static const char * const names[4] = {
    "Constant",
    "Reflect",
    "Symmetric",
    nullptr
  };
  return names;
}

inline const char *EnumNamePaddingMode(PaddingMode e) {
  if (flatbuffers::IsOutRange(e, PaddingMode_Constant, PaddingMode_Symmetric)) return "";
  const size_t index = static_cast<size_t>(e);
  return EnumNamesPaddingMode()[index];
}

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

template<> struct LayerTraits<armnnSerializer::UnidirectionalSequenceLstmLayer> {
  static const Layer enum_value = Layer_UnidirectionalSequenceLstmLayer;
};

template<> struct LayerTraits<armnnSerializer::ChannelShuffleLayer> {
  static const Layer enum_value = Layer_ChannelShuffleLayer;
};

template<> struct LayerTraits<armnnSerializer::Convolution3dLayer> {
  static const Layer enum_value = Layer_Convolution3dLayer;
};

template<> struct LayerTraits<armnnSerializer::Pooling3dLayer> {
  static const Layer enum_value = Layer_Pooling3dLayer;
};

template<> struct LayerTraits<armnnSerializer::GatherNdLayer> {
  static const Layer enum_value = Layer_GatherNdLayer;
};

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,
    VT_ISCONSTANT = 20
  };
  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 isConstant() const {
    return GetField<uint8_t>(VT_ISCONSTANT, 0) != 0;
  }
  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()) &&
           VerifyField<uint8_t>(verifier, VT_ISCONSTANT) &&
           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);
  }
  void add_isConstant(bool isConstant) {
    fbb_.AddElement<uint8_t>(TensorInfo::VT_ISCONSTANT, static_cast<uint8_t>(isConstant), 0);
  }
  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,
    bool isConstant = false) {
  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_isConstant(isConstant);
  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,
    bool isConstant = false) {
  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__,
      isConstant);
}

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

struct ChannelShuffleLayer FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
  typedef ChannelShuffleLayerBuilder 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::ChannelShuffleDescriptor *descriptor() const {
    return GetPointer<const armnnSerializer::ChannelShuffleDescriptor *>(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 ChannelShuffleLayerBuilder {
  typedef ChannelShuffleLayer Table;
  flatbuffers::FlatBufferBuilder &fbb_;
  flatbuffers::uoffset_t start_;
  void add_base(flatbuffers::Offset<armnnSerializer::LayerBase> base) {
    fbb_.AddOffset(ChannelShuffleLayer::VT_BASE, base);
  }
  void add_descriptor(flatbuffers::Offset<armnnSerializer::ChannelShuffleDescriptor> descriptor) {
    fbb_.AddOffset(ChannelShuffleLayer::VT_DESCRIPTOR, descriptor);
  }
  explicit ChannelShuffleLayerBuilder(flatbuffers::FlatBufferBuilder &_fbb)
        : fbb_(_fbb) {
    start_ = fbb_.StartTable();
  }
  ChannelShuffleLayerBuilder &operator=(const ChannelShuffleLayerBuilder &);
  flatbuffers::Offset<ChannelShuffleLayer> Finish() {
    const auto end = fbb_.EndTable(start_);
    auto o = flatbuffers::Offset<ChannelShuffleLayer>(end);
    return o;
  }
};

inline flatbuffers::Offset<ChannelShuffleLayer> CreateChannelShuffleLayer(
    flatbuffers::FlatBufferBuilder &_fbb,
    flatbuffers::Offset<armnnSerializer::LayerBase> base = 0,
    flatbuffers::Offset<armnnSerializer::ChannelShuffleDescriptor> descriptor = 0) {
  ChannelShuffleLayerBuilder builder_(_fbb);
  builder_.add_descriptor(descriptor);
  builder_.add_base(base);
  return builder_.Finish();
}

struct ChannelShuffleDescriptor FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
  typedef ChannelShuffleDescriptorBuilder Builder;
  enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
    VT_AXIS = 4,
    VT_NUMGROUPS = 6
  };
  uint32_t axis() const {
    return GetField<uint32_t>(VT_AXIS, 0);
  }
  uint32_t numGroups() const {
    return GetField<uint32_t>(VT_NUMGROUPS, 0);
  }
  bool Verify(flatbuffers::Verifier &verifier) const {
    return VerifyTableStart(verifier) &&
           VerifyField<uint32_t>(verifier, VT_AXIS) &&
           VerifyField<uint32_t>(verifier, VT_NUMGROUPS) &&
           verifier.EndTable();
  }
};

struct ChannelShuffleDescriptorBuilder {
  typedef ChannelShuffleDescriptor Table;
  flatbuffers::FlatBufferBuilder &fbb_;
  flatbuffers::uoffset_t start_;
  void add_axis(uint32_t axis) {
    fbb_.AddElement<uint32_t>(ChannelShuffleDescriptor::VT_AXIS, axis, 0);
  }
  void add_numGroups(uint32_t numGroups) {
    fbb_.AddElement<uint32_t>(ChannelShuffleDescriptor::VT_NUMGROUPS, numGroups, 0);
  }
  explicit ChannelShuffleDescriptorBuilder(flatbuffers::FlatBufferBuilder &_fbb)
        : fbb_(_fbb) {
    start_ = fbb_.StartTable();
  }
  ChannelShuffleDescriptorBuilder &operator=(const ChannelShuffleDescriptorBuilder &);
  flatbuffers::Offset<ChannelShuffleDescriptor> Finish() {
    const auto end = fbb_.EndTable(start_);
    auto o = flatbuffers::Offset<ChannelShuffleDescriptor>(end);
    return o;
  }
};

inline flatbuffers::Offset<ChannelShuffleDescriptor> CreateChannelShuffleDescriptor(
    flatbuffers::FlatBufferBuilder &_fbb,
    uint32_t axis = 0,
    uint32_t numGroups = 0) {
  ChannelShuffleDescriptorBuilder builder_(_fbb);
  builder_.add_numGroups(numGroups);
  builder_.add_axis(axis);
  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 Convolution3dLayer FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
  typedef Convolution3dLayerBuilder 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::Convolution3dDescriptor *descriptor() const {
    return GetPointer<const armnnSerializer::Convolution3dDescriptor *>(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 Convolution3dLayerBuilder {
  typedef Convolution3dLayer Table;
  flatbuffers::FlatBufferBuilder &fbb_;
  flatbuffers::uoffset_t start_;
  void add_base(flatbuffers::Offset<armnnSerializer::LayerBase> base) {
    fbb_.AddOffset(Convolution3dLayer::VT_BASE, base);
  }
  void add_descriptor(flatbuffers::Offset<armnnSerializer::Convolution3dDescriptor> descriptor) {
    fbb_.AddOffset(Convolution3dLayer::VT_DESCRIPTOR, descriptor);
  }
  explicit Convolution3dLayerBuilder(flatbuffers::FlatBufferBuilder &_fbb)
        : fbb_(_fbb) {
    start_ = fbb_.StartTable();
  }
  Convolution3dLayerBuilder &operator=(const Convolution3dLayerBuilder &);
  flatbuffers::Offset<Convolution3dLayer> Finish() {
    const auto end = fbb_.EndTable(start_);
    auto o = flatbuffers::Offset<Convolution3dLayer>(end);
    return o;
  }
};

inline flatbuffers::Offset<Convolution3dLayer> CreateConvolution3dLayer(
    flatbuffers::FlatBufferBuilder &_fbb,
    flatbuffers::Offset<armnnSerializer::LayerBase> base = 0,
    flatbuffers::Offset<armnnSerializer::Convolution3dDescriptor> descriptor = 0) {
  Convolution3dLayerBuilder builder_(_fbb);
  builder_.add_descriptor(descriptor);
  builder_.add_base(base);
  return builder_.Finish();
}

struct Convolution3dDescriptor FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
  typedef Convolution3dDescriptorBuilder Builder;
  enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
    VT_PADLEFT = 4,
    VT_PADRIGHT = 6,
    VT_PADTOP = 8,
    VT_PADBOTTOM = 10,
    VT_PADFRONT = 12,
    VT_PADBACK = 14,
    VT_STRIDEX = 16,
    VT_STRIDEY = 18,
    VT_STRIDEZ = 20,
    VT_DILATIONX = 22,
    VT_DILATIONY = 24,
    VT_DILATIONZ = 26,
    VT_BIASENABLED = 28,
    VT_DATALAYOUT = 30
  };
  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 padFront() const {
    return GetField<uint32_t>(VT_PADFRONT, 0);
  }
  uint32_t padBack() const {
    return GetField<uint32_t>(VT_PADBACK, 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 strideZ() const {
    return GetField<uint32_t>(VT_STRIDEZ, 0);
  }
  uint32_t dilationX() const {
    return GetField<uint32_t>(VT_DILATIONX, 1);
  }
  uint32_t dilationY() const {
    return GetField<uint32_t>(VT_DILATIONY, 1);
  }
  uint32_t dilationZ() const {
    return GetField<uint32_t>(VT_DILATIONZ, 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, 2));
  }
  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_PADFRONT) &&
           VerifyField<uint32_t>(verifier, VT_PADBACK) &&
           VerifyField<uint32_t>(verifier, VT_STRIDEX) &&
           VerifyField<uint32_t>(verifier, VT_STRIDEY) &&
           VerifyField<uint32_t>(verifier, VT_STRIDEZ) &&
           VerifyField<uint32_t>(verifier, VT_DILATIONX) &&
           VerifyField<uint32_t>(verifier, VT_DILATIONY) &&
           VerifyField<uint32_t>(verifier, VT_DILATIONZ) &&
           VerifyField<uint8_t>(verifier, VT_BIASENABLED) &&
           VerifyField<int8_t>(verifier, VT_DATALAYOUT) &&
           verifier.EndTable();
  }
};

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

inline flatbuffers::Offset<Convolution3dDescriptor> CreateConvolution3dDescriptor(
    flatbuffers::FlatBufferBuilder &_fbb,
    uint32_t padLeft = 0,
    uint32_t padRight = 0,
    uint32_t padTop = 0,
    uint32_t padBottom = 0,
    uint32_t padFront = 0,
    uint32_t padBack = 0,
    uint32_t strideX = 0,
    uint32_t strideY = 0,
    uint32_t strideZ = 0,
    uint32_t dilationX = 1,
    uint32_t dilationY = 1,
    uint32_t dilationZ = 1,
    bool biasEnabled = false,
    armnnSerializer::DataLayout dataLayout = armnnSerializer::DataLayout_NDHWC) {
  Convolution3dDescriptorBuilder builder_(_fbb);
  builder_.add_dilationZ(dilationZ);
  builder_.add_dilationY(dilationY);
  builder_.add_dilationX(dilationX);
  builder_.add_strideZ(strideZ);
  builder_.add_strideY(strideY);
  builder_.add_strideX(strideX);
  builder_.add_padBack(padBack);
  builder_.add_padFront(padFront);
  builder_.add_padBottom(padBottom);
  builder_.add_padTop(padTop);
  builder_.add_padRight(padRight);
  builder_.add_padLeft(padLeft);
  builder_.add_dataLayout(dataLayout);
  builder_.add_biasEnabled(biasEnabled);
  return builder_.Finish();
}

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

struct GatherNdLayer FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
  typedef GatherNdLayerBuilder 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 GatherNdLayerBuilder {
  typedef GatherNdLayer Table;
  flatbuffers::FlatBufferBuilder &fbb_;
  flatbuffers::uoffset_t start_;
  void add_base(flatbuffers::Offset<armnnSerializer::LayerBase> base) {
    fbb_.AddOffset(GatherNdLayer::VT_BASE, base);
  }
  explicit GatherNdLayerBuilder(flatbuffers::FlatBufferBuilder &_fbb)
        : fbb_(_fbb) {
    start_ = fbb_.StartTable();
  }
  GatherNdLayerBuilder &operator=(const GatherNdLayerBuilder &);
  flatbuffers::Offset<GatherNdLayer> Finish() {
    const auto end = fbb_.EndTable(start_);
    auto o = flatbuffers::Offset<GatherNdLayer>(end);
    return o;
  }
};

inline flatbuffers::Offset<GatherNdLayer> CreateGatherNdLayer(
    flatbuffers::FlatBufferBuilder &_fbb,
    flatbuffers::Offset<armnnSerializer::LayerBase> base = 0) {
  GatherNdLayerBuilder builder_(_fbb);
  builder_.add_base(base);
  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 Pooling3dLayer FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
  typedef Pooling3dLayerBuilder 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::Pooling3dDescriptor *descriptor() const {
    return GetPointer<const armnnSerializer::Pooling3dDescriptor *>(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 Pooling3dLayerBuilder {
  typedef Pooling3dLayer Table;
  flatbuffers::FlatBufferBuilder &fbb_;
  flatbuffers::uoffset_t start_;
  void add_base(flatbuffers::Offset<armnnSerializer::LayerBase> base) {
    fbb_.AddOffset(Pooling3dLayer::VT_BASE, base);
  }
  void add_descriptor(flatbuffers::Offset<armnnSerializer::Pooling3dDescriptor> descriptor) {
    fbb_.AddOffset(Pooling3dLayer::VT_DESCRIPTOR, descriptor);
  }
  explicit Pooling3dLayerBuilder(flatbuffers::FlatBufferBuilder &_fbb)
        : fbb_(_fbb) {
    start_ = fbb_.StartTable();
  }
  Pooling3dLayerBuilder &operator=(const Pooling3dLayerBuilder &);
  flatbuffers::Offset<Pooling3dLayer> Finish() {
    const auto end = fbb_.EndTable(start_);
    auto o = flatbuffers::Offset<Pooling3dLayer>(end);
    return o;
  }
};

inline flatbuffers::Offset<Pooling3dLayer> CreatePooling3dLayer(
    flatbuffers::FlatBufferBuilder &_fbb,
    flatbuffers::Offset<armnnSerializer::LayerBase> base = 0,
    flatbuffers::Offset<armnnSerializer::Pooling3dDescriptor> descriptor = 0) {
  Pooling3dLayerBuilder 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 Pooling3dDescriptor FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
  typedef Pooling3dDescriptorBuilder Builder;
  enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
    VT_POOLTYPE = 4,
    VT_PADLEFT = 6,
    VT_PADRIGHT = 8,
    VT_PADTOP = 10,
    VT_PADBOTTOM = 12,
    VT_PADFRONT = 14,
    VT_PADBACK = 16,
    VT_POOLWIDTH = 18,
    VT_POOLHEIGHT = 20,
    VT_POOLDEPTH = 22,
    VT_STRIDEX = 24,
    VT_STRIDEY = 26,
    VT_STRIDEZ = 28,
    VT_OUTPUTSHAPEROUNDING = 30,
    VT_PADDINGMETHOD = 32,
    VT_DATALAYOUT = 34
  };
  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 padFront() const {
    return GetField<uint32_t>(VT_PADFRONT, 0);
  }
  uint32_t padBack() const {
    return GetField<uint32_t>(VT_PADBACK, 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 poolDepth() const {
    return GetField<uint32_t>(VT_POOLDEPTH, 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 strideZ() const {
    return GetField<uint32_t>(VT_STRIDEZ, 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_PADFRONT) &&
           VerifyField<uint32_t>(verifier, VT_PADBACK) &&
           VerifyField<uint32_t>(verifier, VT_POOLWIDTH) &&
           VerifyField<uint32_t>(verifier, VT_POOLHEIGHT) &&
           VerifyField<uint32_t>(verifier, VT_POOLDEPTH) &&
           VerifyField<uint32_t>(verifier, VT_STRIDEX) &&
           VerifyField<uint32_t>(verifier, VT_STRIDEY) &&
           VerifyField<uint32_t>(verifier, VT_STRIDEZ) &&
           VerifyField<int8_t>(verifier, VT_OUTPUTSHAPEROUNDING) &&
           VerifyField<int8_t>(verifier, VT_PADDINGMETHOD) &&
           VerifyField<int8_t>(verifier, VT_DATALAYOUT) &&
           verifier.EndTable();
  }
};

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

inline flatbuffers::Offset<Pooling3dDescriptor> CreatePooling3dDescriptor(
    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 padFront = 0,
    uint32_t padBack = 0,
    uint32_t poolWidth = 0,
    uint32_t poolHeight = 0,
    uint32_t poolDepth = 0,
    uint32_t strideX = 0,
    uint32_t strideY = 0,
    uint32_t strideZ = 0,
    armnnSerializer::OutputShapeRounding outputShapeRounding = armnnSerializer::OutputShapeRounding_Floor,
    armnnSerializer::PaddingMethod paddingMethod = armnnSerializer::PaddingMethod_IgnoreValue,
    armnnSerializer::DataLayout dataLayout = armnnSerializer::DataLayout_NHWC) {
  Pooling3dDescriptorBuilder builder_(_fbb);
  builder_.add_strideZ(strideZ);
  builder_.add_strideY(strideY);
  builder_.add_strideX(strideX);
  builder_.add_poolDepth(poolDepth);
  builder_.add_poolHeight(poolHeight);
  builder_.add_poolWidth(poolWidth);
  builder_.add_padBack(padBack);
  builder_.add_padFront(padFront);
  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,
    VT_AXIS = 6
  };
  float beta() const {
    return GetField<float>(VT_BETA, 0.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 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);
  }
  void add_axis(int32_t axis) {
    fbb_.AddElement<int32_t>(SoftmaxDescriptor::VT_AXIS, axis, -1);
  }
  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,
    int32_t axis = -1) {
  SoftmaxDescriptorBuilder builder_(_fbb);
  builder_.add_axis(axis);
  builder_.add_beta(beta);
  return builder_.Finish();
}

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

struct PadDescriptor FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
  typedef PadDescriptorBuilder Builder;
  enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
    VT_PADLIST = 4,
    VT_PADVALUE = 6,
    VT_PADDINGMODE = 8
  };
  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);
  }
  armnnSerializer::PaddingMode paddingMode() const {
    return static_cast<armnnSerializer::PaddingMode>(GetField<int8_t>(VT_PADDINGMODE, 0));
  }
  bool Verify(flatbuffers::Verifier &verifier) const {
    return VerifyTableStart(verifier) &&
           VerifyOffset(verifier, VT_PADLIST) &&
           verifier.VerifyVector(padList()) &&
           VerifyField<float>(verifier, VT_PADVALUE) &&
           VerifyField<int8_t>(verifier, VT_PADDINGMODE) &&
           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);
  }
  void add_paddingMode(armnnSerializer::PaddingMode paddingMode) {
    fbb_.AddElement<int8_t>(PadDescriptor::VT_PADDINGMODE, static_cast<int8_t>(paddingMode), 0);
  }
  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,
    armnnSerializer::PaddingMode paddingMode = armnnSerializer::PaddingMode_Constant) {
  PadDescriptorBuilder builder_(_fbb);
  builder_.add_padValue(padValue);
  builder_.add_padList(padList);
  builder_.add_paddingMode(paddingMode);
  return builder_.Finish();
}

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

/// @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 UnidirectionalSequenceLstmDescriptor FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
  typedef UnidirectionalSequenceLstmDescriptorBuilder 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,
    VT_TIMEMAJOR = 18
  };
  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 timeMajor() const {
    return GetField<uint8_t>(VT_TIMEMAJOR, 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) &&
           VerifyField<uint8_t>(verifier, VT_TIMEMAJOR) &&
           verifier.EndTable();
  }
};

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

inline flatbuffers::Offset<UnidirectionalSequenceLstmDescriptor> CreateUnidirectionalSequenceLstmDescriptor(
    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,
    bool timeMajor = false) {
  UnidirectionalSequenceLstmDescriptorBuilder builder_(_fbb);
  builder_.add_clippingThresProj(clippingThresProj);
  builder_.add_clippingThresCell(clippingThresCell);
  builder_.add_activationFunc(activationFunc);
  builder_.add_timeMajor(timeMajor);
  builder_.add_layerNormEnabled(layerNormEnabled);
  builder_.add_projectionEnabled(projectionEnabled);
  builder_.add_peepholeEnabled(peepholeEnabled);
  builder_.add_cifgEnabled(cifgEnabled);
  return builder_.Finish();
}

struct UnidirectionalSequenceLstmLayer FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
  typedef UnidirectionalSequenceLstmLayerBuilder 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::UnidirectionalSequenceLstmDescriptor *descriptor() const {
    return GetPointer<const armnnSerializer::UnidirectionalSequenceLstmDescriptor *>(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 UnidirectionalSequenceLstmLayerBuilder {
  typedef UnidirectionalSequenceLstmLayer Table;
  flatbuffers::FlatBufferBuilder &fbb_;
  flatbuffers::uoffset_t start_;
  void add_base(flatbuffers::Offset<armnnSerializer::LayerBase> base) {
    fbb_.AddOffset(UnidirectionalSequenceLstmLayer::VT_BASE, base);
  }
  void add_descriptor(flatbuffers::Offset<armnnSerializer::UnidirectionalSequenceLstmDescriptor> descriptor) {
    fbb_.AddOffset(UnidirectionalSequenceLstmLayer::VT_DESCRIPTOR, descriptor);
  }
  void add_inputParams(flatbuffers::Offset<armnnSerializer::LstmInputParams> inputParams) {
    fbb_.AddOffset(UnidirectionalSequenceLstmLayer::VT_INPUTPARAMS, inputParams);
  }
  explicit UnidirectionalSequenceLstmLayerBuilder(flatbuffers::FlatBufferBuilder &_fbb)
        : fbb_(_fbb) {
    start_ = fbb_.StartTable();
  }
  UnidirectionalSequenceLstmLayerBuilder &operator=(const UnidirectionalSequenceLstmLayerBuilder &);
  flatbuffers::Offset<UnidirectionalSequenceLstmLayer> Finish() {
    const auto end = fbb_.EndTable(start_);
    auto o = flatbuffers::Offset<UnidirectionalSequenceLstmLayer>(end);
    return o;
  }
};

inline flatbuffers::Offset<UnidirectionalSequenceLstmLayer> CreateUnidirectionalSequenceLstmLayer(
    flatbuffers::FlatBufferBuilder &_fbb,
    flatbuffers::Offset<armnnSerializer::LayerBase> base = 0,
    flatbuffers::Offset<armnnSerializer::UnidirectionalSequenceLstmDescriptor> descriptor = 0,
    flatbuffers::Offset<armnnSerializer::LstmInputParams> inputParams = 0) {
  UnidirectionalSequenceLstmLayerBuilder builder_(_fbb);
  builder_.add_inputParams(inputParams);
  builder_.add_descriptor(descriptor);
  builder_.add_base(base);
  return builder_.Finish();
}

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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