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


#ifndef FLATBUFFERS_GENERATED_ARMNNSCHEMA_ARMNNSERIALIZER_H_
#define FLATBUFFERS_GENERATED_ARMNNSCHEMA_ARMNNSERIALIZER_H_

#include "flatbuffers/flatbuffers.h"

namespace armnnSerializer {

struct TensorInfo;
struct TensorInfoBuilder;

struct Connection;

struct ByteData;
struct ByteDataBuilder;

struct ShortData;
struct ShortDataBuilder;

struct IntData;
struct IntDataBuilder;

struct LongData;
struct LongDataBuilder;

struct ConstTensor;
struct ConstTensorBuilder;

struct InputSlot;
struct InputSlotBuilder;

struct OutputSlot;
struct OutputSlotBuilder;

struct LayerBase;
struct LayerBaseBuilder;

struct BindableLayerBase;
struct BindableLayerBaseBuilder;

struct AbsLayer;
struct AbsLayerBuilder;

struct ActivationLayer;
struct ActivationLayerBuilder;

struct ActivationDescriptor;
struct ActivationDescriptorBuilder;

struct AdditionLayer;
struct AdditionLayerBuilder;

struct ArgMinMaxLayer;
struct ArgMinMaxLayerBuilder;

struct ArgMinMaxDescriptor;
struct ArgMinMaxDescriptorBuilder;

struct CastLayer;
struct CastLayerBuilder;

struct 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 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_MIN = LayerType_Addition,
  LayerType_MAX = LayerType_Pooling3d
};

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

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

inline const char *EnumNameLayerType(LayerType e) {
  if (flatbuffers::IsOutRange(e, LayerType_Addition, LayerType_Pooling3d)) 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_MIN = Layer_NONE,
  Layer_MAX = Layer_Pooling3dLayer
};

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

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

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

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();
}

/// @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;
  }
  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();
}

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);
    }
    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_
