//
// 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 Pooling2dDescriptor;
struct Pooling2dDescriptorBuilder;

struct QuantizeLayer;
struct QuantizeLayerBuilder;

struct SoftmaxLayer;
struct SoftmaxLayerBuilder;

struct SoftmaxDescriptor;
struct SoftmaxDescriptorBuilder;

struct DepthwiseConvolution2dLayer;
struct DepthwiseConvolution2dLayerBuilder;

struct DepthwiseConvolution2dDescriptor;
struct DepthwiseConvolution2dDescriptorBuilder;

struct OutputLayer;
struct OutputLayerBuilder;

struct ReshapeLayer;
struct ReshapeLayerBuilder;

struct ReshapeDescriptor;
struct ReshapeDescriptorBuilder;

struct PermuteLayer;
struct PermuteLayerBuilder;

struct PermuteDescriptor;
struct PermuteDescriptorBuilder;

struct ShapeLayer;
struct ShapeLayerBuilder;

struct SpaceToBatchNdLayer;
struct SpaceToBatchNdLayerBuilder;

struct SpaceToBatchNdDescriptor;
struct SpaceToBatchNdDescriptorBuilder;

struct SpaceToDepthLayer;
struct SpaceToDepthLayerBuilder;

struct SpaceToDepthDescriptor;
struct SpaceToDepthDescriptorBuilder;

struct SubtractionLayer;
struct SubtractionLayerBuilder;

struct BatchToSpaceNdLayer;
struct BatchToSpaceNdLayerBuilder;

struct BatchToSpaceNdDescriptor;
struct BatchToSpaceNdDescriptorBuilder;

struct NormalizationLayer;
struct NormalizationLayerBuilder;

struct NormalizationDescriptor;
struct NormalizationDescriptorBuilder;

struct MeanLayer;
struct MeanLayerBuilder;

struct MeanDescriptor;
struct MeanDescriptorBuilder;

struct PadLayer;
struct PadLayerBuilder;

struct PadDescriptor;
struct PadDescriptorBuilder;

struct RsqrtLayer;
struct RsqrtLayerBuilder;

struct BatchNormalizationLayer;
struct BatchNormalizationLayerBuilder;

struct BatchNormalizationDescriptor;
struct BatchNormalizationDescriptorBuilder;

struct ResizeBilinearLayer;
struct ResizeBilinearLayerBuilder;

struct ResizeBilinearDescriptor;
struct ResizeBilinearDescriptorBuilder;

struct SliceLayer;
struct SliceLayerBuilder;

struct SliceDescriptor;
struct SliceDescriptorBuilder;

struct StridedSliceLayer;
struct StridedSliceLayerBuilder;

struct StridedSliceDescriptor;
struct StridedSliceDescriptorBuilder;

struct ConcatLayer;
struct ConcatLayerBuilder;

struct MergerLayer;
struct MergerLayerBuilder;

struct UintVector;
struct UintVectorBuilder;

struct OriginsDescriptor;
struct OriginsDescriptorBuilder;

struct ViewsDescriptor;
struct ViewsDescriptorBuilder;

struct SplitterLayer;
struct SplitterLayerBuilder;

struct DetectionPostProcessLayer;
struct DetectionPostProcessLayerBuilder;

struct DetectionPostProcessDescriptor;
struct DetectionPostProcessDescriptorBuilder;

struct LstmInputParams;
struct LstmInputParamsBuilder;

struct LstmDescriptor;
struct LstmDescriptorBuilder;

struct LstmLayer;
struct LstmLayerBuilder;

struct QLstmInputParams;
struct QLstmInputParamsBuilder;

struct QLstmDescriptor;
struct QLstmDescriptorBuilder;

struct QLstmLayer;
struct QLstmLayerBuilder;

struct QuantizedLstmInputParams;
struct QuantizedLstmInputParamsBuilder;

struct QuantizedLstmLayer;
struct QuantizedLstmLayerBuilder;

struct DequantizeLayer;
struct DequantizeLayerBuilder;

struct MergeLayer;
struct MergeLayerBuilder;

struct SwitchLayer;
struct SwitchLayerBuilder;

struct PreluLayer;
struct PreluLayerBuilder;

struct TransposeConvolution2dLayer;
struct TransposeConvolution2dLayerBuilder;

struct TransposeConvolution2dDescriptor;
struct TransposeConvolution2dDescriptorBuilder;

struct TransposeLayer;
struct TransposeLayerBuilder;

struct TransposeDescriptor;
struct TransposeDescriptorBuilder;

struct ResizeLayer;
struct ResizeLayerBuilder;

struct ResizeDescriptor;
struct ResizeDescriptorBuilder;

struct StackLayer;
struct StackLayerBuilder;

struct StackDescriptor;
struct StackDescriptorBuilder;

struct StandInDescriptor;
struct StandInDescriptorBuilder;

struct StandInLayer;
struct StandInLayerBuilder;

struct RankLayer;
struct RankLayerBuilder;

struct ReduceLayer;
struct ReduceLayerBuilder;

struct ReduceDescriptor;
struct ReduceDescriptorBuilder;

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

struct SoftmaxDescriptor FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
  typedef SoftmaxDescriptorBuilder Builder;
  enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
    VT_BETA = 4,
    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;
  }
  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();
}

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