//
// Copyright © 2017,2019-2023 Arm Ltd and Contributors. All rights reserved.
// SPDX-License-Identifier: MIT
//

namespace armnnSerializer;

file_identifier "ARMN";

file_extension "armnn";

enum ActivationFunction : byte {
    Sigmoid = 0,
    TanH = 1,
    Linear = 2,
    ReLu = 3,
    BoundedReLu = 4,
    SoftReLu = 5,
    LeakyReLu = 6,
    Abs = 7,
    Sqrt = 8,
    Square = 9,
    Elu = 10,
    HardSwish = 11
}

enum ArgMinMaxFunction : byte {
    Min = 0,
    Max = 1
}

enum DataType : byte {
    Float16 = 0,
    Float32 = 1,
    QuantisedAsymm8 = 2, // deprecated
    Signed32 = 3,
    Boolean = 4,
    QuantisedSymm16 = 5, // deprecated
    QAsymmU8 = 6,
    QSymmS16 = 7,
    QAsymmS8 = 8,
    QSymmS8 = 9,
    Signed64 = 10
}

enum DataLayout : byte {
    NHWC = 0,
    NCHW = 1,
    NDHWC = 2,
    NCDHW = 3
}

enum ReduceOperation: byte {
    Sum  = 0,
    Max  = 1,
    Mean = 2,
    Min  = 3,
    Prod  = 4
}

enum ResizeMethod: byte {
    NearestNeighbor = 0,
    Bilinear = 1,
}

table TensorInfo {
    dimensions:[uint];
    dataType:DataType;
    quantizationScale:float = 1.0; // @deprecated Use quantizationScales instead
    quantizationOffset:int = 0;
    quantizationScales:[float];
    quantizationDim:uint;
    dimensionality:uint = 1;
    dimensionSpecificity:[bool];
    isConstant:bool = false;
}

struct Connection {
    sourceLayerIndex:uint;
    outputSlotIndex:uint;
}

table ByteData {
    data:[byte];
}

table ShortData {
    data:[short];
}

table IntData {
    data:[int];
}

table LongData {
    data:[long];
}

union ConstTensorData { ByteData, ShortData, IntData, LongData }

table ConstTensor {
    info:TensorInfo;
    data:ConstTensorData;
}

table InputSlot {
    index:uint;
    connection:Connection;
    isOverridden:bool;
    overriddenTensorInfo:TensorInfo;
}

table OutputSlot {
    index:uint;
    tensorInfo:TensorInfo;
}

enum LayerType : uint {
    Addition = 0,
    Input = 1,
    Multiplication = 2,
    Output = 3,
    Pooling2d = 4,
    Reshape = 5,
    Softmax = 6,
    Convolution2d = 7,
    DepthwiseConvolution2d = 8,
    Activation = 9,
    Permute = 10,
    FullyConnected = 11,
    Constant = 12,
    SpaceToBatchNd = 13,
    BatchToSpaceNd = 14,
    Division = 15,
    Minimum = 16,
    Equal = 17,
    Maximum = 18,
    Normalization = 19,
    Pad = 20,
    Rsqrt = 21,
    Floor = 22,
    BatchNormalization = 23,
    Greater = 24,
    ResizeBilinear = 25,
    Subtraction = 26,
    StridedSlice = 27,
    Gather = 28,
    Mean = 29,
    Merger = 30,
    L2Normalization = 31,
    Splitter = 32,
    DetectionPostProcess = 33,
    Lstm = 34,
    Quantize = 35,
    Dequantize = 36,
    Merge = 37,
    Switch = 38,
    Concat = 39,
    SpaceToDepth = 40,
    Prelu = 41,
    TransposeConvolution2d = 42,
    Resize = 43,
    Stack = 44,
    QuantizedLstm = 45,
    Abs = 46,
    ArgMinMax = 47,
    Slice = 48,
    DepthToSpace = 49,
    InstanceNormalization = 50,
    LogSoftmax = 51,
    Comparison = 52,
    StandIn = 53,
    ElementwiseUnary = 54,
    Transpose = 55,
    QLstm = 56,
    Fill = 57,
    Rank = 58,
    LogicalBinary = 59,
    Reduce = 60,
    Cast = 61,
    Shape = 62,
    UnidirectionalSequenceLstm = 63,
    ChannelShuffle = 64,
    Convolution3d = 65,
    Pooling3d = 66,
    GatherNd = 67,
    BatchMatMul = 68,
    ElementwiseBinary = 69,
    ReverseV2 = 70,
    Tile = 71,
}

// Base layer table to be used as part of other layers
table LayerBase {
    index:uint;
    layerName:string;
    layerType:LayerType;
    inputSlots:[InputSlot];
    outputSlots:[OutputSlot];
}

table BindableLayerBase {
    base:LayerBase;
    layerBindingId:int;
}

// Table for each layer defined below

/// @deprecated Use ElementwiseUnaryLayer instead
table AbsLayer {
    base:LayerBase;
}

table ActivationLayer {
    base:LayerBase;
    descriptor:ActivationDescriptor;
}

table ActivationDescriptor {
    activationFunction:ActivationFunction = Sigmoid;
    a:float;
    b:float;
}

table AdditionLayer {
    base:LayerBase;
}

table ArgMinMaxLayer {
    base:LayerBase;
    descriptor:ArgMinMaxDescriptor;
}

table ArgMinMaxDescriptor{
    argMinMaxFunction:ArgMinMaxFunction;
    axis:int;
}

table CastLayer {
    base:LayerBase;
}

table ChannelShuffleLayer {
    base:LayerBase;
    descriptor:ChannelShuffleDescriptor;
}

table ChannelShuffleDescriptor {
    axis:uint = 0;
    numGroups:uint = 0;
}

enum ComparisonOperation : byte {
    Equal = 0,
    Greater = 1,
    GreaterOrEqual = 2,
    Less = 3,
    LessOrEqual = 4,
    NotEqual = 5
}

table ComparisonDescriptor {
    operation:ComparisonOperation;
}

table ComparisonLayer {
    base:LayerBase;
    descriptor:ComparisonDescriptor;
}

table ConstantLayer {
    base:LayerBase;
    input:ConstTensor;
}

table Convolution2dLayer {
    base:LayerBase;
    descriptor:Convolution2dDescriptor;
    weights:ConstTensor;
    biases:ConstTensor;
}

table Convolution2dDescriptor {
    padLeft:uint;
    padRight:uint;
    padTop:uint;
    padBottom:uint;
    strideX:uint;
    strideY:uint;
    dilationX:uint = 1;
    dilationY:uint = 1;
    biasEnabled:bool = false;
    dataLayout:DataLayout = NCHW;
}

table Convolution3dLayer {
    base:LayerBase;
    descriptor:Convolution3dDescriptor;
}

table Convolution3dDescriptor {
    padLeft:uint;
    padRight:uint;
    padTop:uint;
    padBottom:uint;
    padFront:uint;
    padBack:uint;
    strideX:uint;
    strideY:uint;
    strideZ:uint;
    dilationX:uint = 1;
    dilationY:uint = 1;
    dilationZ:uint = 1;
    biasEnabled:bool = false;
    dataLayout:DataLayout = NDHWC;
}

table DepthToSpaceLayer {
    base:LayerBase;
    descriptor:DepthToSpaceDescriptor;
}

table DepthToSpaceDescriptor {
    blockSize:uint;
    dataLayout:DataLayout;
}

table DivisionLayer {
    base:LayerBase;
}

enum BinaryOperation : byte {
    Add     = 0,
    Div     = 1,
    Maximum = 2,
    Minimum = 3,
    Mul     = 4,
    Sub     = 5,
    SqDiff  = 6,
    Power   = 7
}

table ElementwiseBinaryDescriptor {
    operation:BinaryOperation;
}

table ElementwiseBinaryLayer {
    base:LayerBase;
    descriptor:ElementwiseBinaryDescriptor;
}

enum UnaryOperation : byte {
    Abs = 0,
    Rsqrt = 1,
    Sqrt = 2,
    Exp = 3,
    Neg = 4,
    LogicalNot = 5,
    Log = 6,
    Sin = 7,
    Ceil = 8
}

table ElementwiseUnaryDescriptor {
    operation:UnaryOperation;
}

table ElementwiseUnaryLayer {
    base:LayerBase;
    descriptor:ElementwiseUnaryDescriptor;
}

/// @deprecated Use ComparisonLayer instead
table EqualLayer {
    base:LayerBase;
}

table FillLayer {
    base:LayerBase;
    descriptor:FillDescriptor;
}

table FillDescriptor {
    value:float;
}

table FloorLayer{
    base:LayerBase;
}

table FullyConnectedLayer {
    base:LayerBase;
    descriptor:FullyConnectedDescriptor;
    weights:ConstTensor; // ConstTensors are now passed as inputs.
    biases:ConstTensor;
}

table FullyConnectedDescriptor {
    biasEnabled:bool = false;
    transposeWeightsMatrix:bool = false;
    constantWeights:bool = true;
}

table GatherLayer {
    base:LayerBase;
    descriptor:GatherDescriptor;
}

table GatherDescriptor {
    axis:int = 0;
}

table GatherNdLayer {
    base:LayerBase;
}

/// @deprecated Use ComparisonLayer instead
table GreaterLayer {
    base:LayerBase;
}

table InputLayer {
    base:BindableLayerBase;
}

table InstanceNormalizationLayer {
    base:LayerBase;
    descriptor:InstanceNormalizationDescriptor;
}

table InstanceNormalizationDescriptor {
    gamma:float;
    beta:float;
    eps:float;
    dataLayout:DataLayout;
}

table LogSoftmaxLayer {
    base:LayerBase;
    descriptor:LogSoftmaxDescriptor;
}

table LogSoftmaxDescriptor {
    beta:float = 1;
    axis:int = -1;
}

table L2NormalizationLayer {
    base:LayerBase;
    descriptor:L2NormalizationDescriptor;
}

table L2NormalizationDescriptor {
    dataLayout:DataLayout = NCHW;
    eps:float = 1e-12;
}

enum LogicalBinaryOperation : byte {
    LogicalAnd = 0,
    LogicalOr = 1
}

table LogicalBinaryDescriptor {
    operation:LogicalBinaryOperation;
}

table LogicalBinaryLayer {
    base:LayerBase;
    descriptor:LogicalBinaryDescriptor;
}

table MinimumLayer {
    base:LayerBase;
}

table MaximumLayer {
    base:LayerBase;
}

table MultiplicationLayer {
    base:LayerBase;
}

table Pooling2dLayer {
    base:LayerBase;
    descriptor:Pooling2dDescriptor;
}

table Pooling3dLayer {
    base:LayerBase;
    descriptor:Pooling3dDescriptor;
}

enum PoolingAlgorithm : byte {
    Max = 0,
    Average = 1,
    L2 = 2
}

enum OutputShapeRounding : byte {
    Floor = 0,
    Ceiling = 1
}

enum PaddingMethod : byte {
    IgnoreValue = 0,
    Exclude = 1
}

table Pooling2dDescriptor {
    poolType:PoolingAlgorithm;
    padLeft:uint;
    padRight:uint;
    padTop:uint;
    padBottom:uint;
    poolWidth:uint;
    poolHeight:uint;
    strideX:uint;
    strideY:uint;
    outputShapeRounding:OutputShapeRounding;
    paddingMethod:PaddingMethod;
    dataLayout:DataLayout;
}

table Pooling3dDescriptor {
    poolType:PoolingAlgorithm;
    padLeft:uint;
    padRight:uint;
    padTop:uint;
    padBottom:uint;
    padFront:uint;
    padBack:uint;
    poolWidth:uint;
    poolHeight:uint;
    poolDepth:uint;
    strideX:uint;
    strideY:uint;
    strideZ:uint;
    outputShapeRounding:OutputShapeRounding;
    paddingMethod:PaddingMethod;
    dataLayout:DataLayout;
}

table QuantizeLayer {
    base:LayerBase;
}

table SoftmaxLayer {
    base:LayerBase;
    descriptor:SoftmaxDescriptor;
}

table SoftmaxDescriptor {
    beta:float;
    axis:int = -1;
}

table DepthwiseConvolution2dLayer {
    base:LayerBase;
    descriptor:DepthwiseConvolution2dDescriptor;
    weights:ConstTensor;
    biases:ConstTensor;
}

table DepthwiseConvolution2dDescriptor {
    padLeft:uint;
    padRight:uint;
    padTop:uint;
    padBottom:uint;
    strideX:uint;
    strideY:uint;
    dilationX:uint = 1;
    dilationY:uint = 1;
    biasEnabled:bool = false;
    dataLayout:DataLayout = NCHW;
}

table OutputLayer {
    base:BindableLayerBase;
}

table ReshapeLayer {
    base:LayerBase;
    descriptor:ReshapeDescriptor;
}

table ReshapeDescriptor {
    targetShape:[uint];
}

table PermuteLayer {
    base:LayerBase;
    descriptor:PermuteDescriptor;
}

table PermuteDescriptor {
    dimMappings:[uint];
}

table ShapeLayer {
    base:LayerBase;
}

table SpaceToBatchNdLayer {
    base:LayerBase;
    descriptor:SpaceToBatchNdDescriptor;
}

table SpaceToBatchNdDescriptor {
    blockShape:[uint];
    padList:[uint];
    dataLayout:DataLayout;
}

table SpaceToDepthLayer {
    base:LayerBase;
    descriptor:SpaceToDepthDescriptor;
}

table SpaceToDepthDescriptor {
    blockSize:uint;
    dataLayout:DataLayout;
}

table SubtractionLayer {
    base:LayerBase;
}

table BatchToSpaceNdLayer {
    base:LayerBase;
    descriptor:BatchToSpaceNdDescriptor;
}

table BatchToSpaceNdDescriptor {
    blockShape:[uint];
    crops:[uint];
    dataLayout:DataLayout;
}

enum NormalizationAlgorithmChannel : byte {
    Across = 0,
    Within = 1
}

enum NormalizationAlgorithmMethod : byte {
    LocalBrightness = 0,
    LocalContrast = 1
}

table NormalizationLayer {
    base:LayerBase;
    descriptor:NormalizationDescriptor;
}

table NormalizationDescriptor {
    normChannelType:NormalizationAlgorithmChannel = Across;
    normMethodType:NormalizationAlgorithmMethod = LocalBrightness;
    normSize:uint;
    alpha:float;
    beta:float;
    k:float;
    dataLayout:DataLayout = NCHW;
}

table MeanLayer {
    base:LayerBase;
    descriptor:MeanDescriptor;
}

table MeanDescriptor {
    axis:[uint];
    keepDims:bool = false;
}

table PadLayer {
    base:LayerBase;
    descriptor:PadDescriptor;
}

enum PaddingMode : byte {
    Constant  = 0,
    Reflect   = 1,
    Symmetric = 2
}

table PadDescriptor {
    padList:[uint];
    padValue:float = 0;
    paddingMode:PaddingMode = Constant;
}

/// @deprecated Use ElementwiseUnaryLayer instead
table RsqrtLayer {
    base:LayerBase;
}

table BatchNormalizationLayer {
    base:LayerBase;
    descriptor:BatchNormalizationDescriptor;
    mean:ConstTensor;
    variance:ConstTensor;
    beta:ConstTensor;
    gamma:ConstTensor;
}

table BatchNormalizationDescriptor {
    eps:float;
    dataLayout:DataLayout;
}

/// @deprecated Use ResizeLayer instead
table ResizeBilinearLayer {
    base:LayerBase;
    descriptor:ResizeBilinearDescriptor;
}

table ResizeBilinearDescriptor {
    targetWidth:uint;
    targetHeight:uint;
    dataLayout:DataLayout;
    alignCorners:bool;
    halfPixelCenters:bool;
}

table SliceLayer {
    base:LayerBase;
    descriptor:SliceDescriptor;
}

table SliceDescriptor {
    begin:[uint];
    size:[uint];
}

table StridedSliceLayer {
    base:LayerBase;
    descriptor:StridedSliceDescriptor;
}

table StridedSliceDescriptor {
    begin:[int];
    end:[int];
    stride:[int];
    beginMask:int;
    endMask:int;
    shrinkAxisMask:int;
    ellipsisMask:int;
    newAxisMask:int;
    dataLayout:DataLayout;
}

table ConcatLayer {
    base:LayerBase;
    descriptor:OriginsDescriptor;
}

/// @deprecated Use ConcatLayer instead
table MergerLayer {
    base:LayerBase;
    descriptor:OriginsDescriptor;
}

table UintVector {
   data:[uint];
}

table OriginsDescriptor {
   concatAxis:uint;
   numViews:uint;
   numDimensions:uint;
   viewOrigins:[UintVector];
}

table ViewsDescriptor {
   origins:OriginsDescriptor;
   viewSizes:[UintVector];
   hasAxis:bool;
   axis:int;
}

table SplitterLayer {
   base:LayerBase;
   descriptor:ViewsDescriptor;
}

table DetectionPostProcessLayer {
    base:LayerBase;
    descriptor:DetectionPostProcessDescriptor;
    anchors:ConstTensor;
}

table DetectionPostProcessDescriptor {
    maxDetections:uint;
    maxClassesPerDetection:uint;
    detectionsPerClass:uint;
    nmsScoreThreshold:float;
    nmsIouThreshold:float;
    numClasses:uint;
    useRegularNms:bool;
    scaleX:float;
    scaleY:float;
    scaleW:float;
    scaleH:float;
}

table LstmInputParams {
    inputToForgetWeights:ConstTensor;
    inputToCellWeights:ConstTensor;
    inputToOutputWeights:ConstTensor;
    recurrentToForgetWeights:ConstTensor;
    recurrentToCellWeights:ConstTensor;
    recurrentToOutputWeights:ConstTensor;
    forgetGateBias:ConstTensor;
    cellBias:ConstTensor;
    outputGateBias:ConstTensor;

    inputToInputWeights:ConstTensor;
    recurrentToInputWeights:ConstTensor;
    cellToInputWeights:ConstTensor;
    inputGateBias:ConstTensor;

    projectionWeights:ConstTensor;
    projectionBias:ConstTensor;

    cellToForgetWeights:ConstTensor;
    cellToOutputWeights:ConstTensor;

    inputLayerNormWeights:ConstTensor;
    forgetLayerNormWeights:ConstTensor;
    cellLayerNormWeights:ConstTensor;
    outputLayerNormWeights:ConstTensor;
}

table LstmDescriptor {
    activationFunc:uint;
    clippingThresCell:float;
    clippingThresProj:float;
    cifgEnabled:bool = true;
    peepholeEnabled:bool = false;
    projectionEnabled:bool = false;
    layerNormEnabled:bool = false;
}

table LstmLayer {
    base:LayerBase;
    descriptor:LstmDescriptor;
    inputParams:LstmInputParams;
}

table QLstmInputParams {
    // Mandatory
    inputToForgetWeights:ConstTensor;
    inputToCellWeights:ConstTensor;
    inputToOutputWeights:ConstTensor;

    recurrentToForgetWeights:ConstTensor;
    recurrentToCellWeights:ConstTensor;
    recurrentToOutputWeights:ConstTensor;

    forgetGateBias:ConstTensor;
    cellBias:ConstTensor;
    outputGateBias:ConstTensor;

    // CIFG
    inputToInputWeights:ConstTensor;
    recurrentToInputWeights:ConstTensor;
    inputGateBias:ConstTensor;

    // Projection
    projectionWeights:ConstTensor;
    projectionBias:ConstTensor;

    // Peephole
    cellToInputWeights:ConstTensor;
    cellToForgetWeights:ConstTensor;
    cellToOutputWeights:ConstTensor;

    // Layer norm
    inputLayerNormWeights:ConstTensor;
    forgetLayerNormWeights:ConstTensor;
    cellLayerNormWeights:ConstTensor;
    outputLayerNormWeights:ConstTensor;
}

table QLstmDescriptor {
    cifgEnabled:bool       = true;
    peepholeEnabled:bool   = false;
    projectionEnabled:bool = false;
    layerNormEnabled:bool  = false;

    cellClip:float;
    projectionClip:float;

    inputIntermediateScale:float;
    forgetIntermediateScale:float;
    cellIntermediateScale:float;
    outputIntermediateScale:float;

    hiddenStateZeroPoint:int;
    hiddenStateScale:float;
}

table QLstmLayer {
    base:LayerBase;
    descriptor:QLstmDescriptor;
    inputParams:QLstmInputParams;
}

table QuantizedLstmInputParams {
    inputToInputWeights:ConstTensor;
    inputToForgetWeights:ConstTensor;
    inputToCellWeights:ConstTensor;
    inputToOutputWeights:ConstTensor;

    recurrentToInputWeights:ConstTensor;
    recurrentToForgetWeights:ConstTensor;
    recurrentToCellWeights:ConstTensor;
    recurrentToOutputWeights:ConstTensor;

    inputGateBias:ConstTensor;
    forgetGateBias:ConstTensor;
    cellBias:ConstTensor;
    outputGateBias:ConstTensor;
}

table QuantizedLstmLayer {
    base:LayerBase;
    inputParams:QuantizedLstmInputParams;
}

table DequantizeLayer {
    base:LayerBase;
}

table MergeLayer {
    base:LayerBase;
}

table SwitchLayer {
    base:LayerBase;
}

table PreluLayer {
    base:LayerBase;
}

table TransposeConvolution2dLayer {
    base:LayerBase;
    descriptor:TransposeConvolution2dDescriptor;
    weights:ConstTensor;
    biases:ConstTensor;
}

table TransposeConvolution2dDescriptor {
    padLeft:uint;
    padRight:uint;
    padTop:uint;
    padBottom:uint;
    strideX:uint;
    strideY:uint;
    biasEnabled:bool = false;
    dataLayout:DataLayout = NCHW;
}

table TransposeLayer {
    base:LayerBase;
    descriptor:TransposeDescriptor;
}

table TransposeDescriptor {
    dimMappings:[uint];
}

table ResizeLayer {
    base:LayerBase;
    descriptor:ResizeDescriptor;
}

table ResizeDescriptor {
    targetHeight:uint;
    targetWidth:uint;
    method:ResizeMethod = NearestNeighbor;
    dataLayout:DataLayout;
    alignCorners:bool;
    halfPixelCenters:bool;
}

table ReverseV2Layer {
    base:LayerBase;
}

table StackLayer {
    base:LayerBase;
    descriptor:StackDescriptor;
}

table StackDescriptor {
    axis:uint;
    numInputs:uint;
    inputShape:[uint];
}

table StandInDescriptor {
    numInputs:uint;
    numOutputs:uint;
}

table StandInLayer {
    base:LayerBase;
    descriptor:StandInDescriptor;
}

table RankLayer {
    base:LayerBase;
}

table ReduceLayer {
    base:LayerBase;
    descriptor:ReduceDescriptor;
}

table ReduceDescriptor {
    keepDims:bool = false;
    axis:[uint];
    reduceOperation:ReduceOperation = Sum;
}

table UnidirectionalSequenceLstmDescriptor {
    activationFunc:uint;
    clippingThresCell:float;
    clippingThresProj:float;
    cifgEnabled:bool = true;
    peepholeEnabled:bool = false;
    projectionEnabled:bool = false;
    layerNormEnabled:bool = false;
    timeMajor:bool = false;
}

table UnidirectionalSequenceLstmLayer {
    base:LayerBase;
    descriptor:UnidirectionalSequenceLstmDescriptor;
    inputParams:LstmInputParams;
}

table BatchMatMulDescriptor {
    transposeX:bool = false;
    transposeY:bool = false;
    adjointX:bool = false;
    adjointY:bool = false;
    dataLayoutX:DataLayout = NCHW;
    dataLayoutY:DataLayout = NCHW;
}

table BatchMatMulLayer {
    base:LayerBase;
    descriptor:BatchMatMulDescriptor;
}

table TileDescriptor {
   m_Multiples:[uint];
}

table TileLayer {
    base:LayerBase;
    descriptor:TileDescriptor;
}

union Layer {
    ActivationLayer,
    AdditionLayer,
    BatchToSpaceNdLayer,
    BatchNormalizationLayer,
    ConstantLayer,
    Convolution2dLayer,
    DepthwiseConvolution2dLayer,
    FullyConnectedLayer,
    InputLayer,
    MultiplicationLayer,
    OutputLayer,
    PermuteLayer,
    Pooling2dLayer,
    ReshapeLayer,
    SoftmaxLayer,
    SpaceToBatchNdLayer,
    DivisionLayer,
    MinimumLayer,
    EqualLayer,
    MaximumLayer,
    NormalizationLayer,
    PadLayer,
    RsqrtLayer,
    FloorLayer,
    GreaterLayer,
    ResizeBilinearLayer,
    SubtractionLayer,
    StridedSliceLayer,
    GatherLayer,
    MeanLayer,
    MergerLayer,
    L2NormalizationLayer,
    SplitterLayer,
    DetectionPostProcessLayer,
    LstmLayer,
    QuantizedLstmLayer,
    QuantizeLayer,
    DequantizeLayer,
    MergeLayer,
    SwitchLayer,
    ConcatLayer,
    SpaceToDepthLayer,
    PreluLayer,
    TransposeConvolution2dLayer,
    ResizeLayer,
    StackLayer,
    AbsLayer,
    ArgMinMaxLayer,
    SliceLayer,
    DepthToSpaceLayer,
    InstanceNormalizationLayer,
    LogSoftmaxLayer,
    ComparisonLayer,
    StandInLayer,
    ElementwiseUnaryLayer,
    TransposeLayer,
    QLstmLayer,
    FillLayer,
    RankLayer,
    LogicalBinaryLayer,
    ReduceLayer,
    CastLayer,
    ShapeLayer,
    UnidirectionalSequenceLstmLayer,
    ChannelShuffleLayer,
    Convolution3dLayer,
    Pooling3dLayer,
    GatherNdLayer,
    BatchMatMulLayer,
    ElementwiseBinaryLayer,
    ReverseV2Layer,
    TileLayer,
}

table AnyLayer {
    layer:Layer;
}

table FeatureCompatibilityVersions {
  bindingIdsScheme:uint = 0;
  weightsLayoutScheme:uint = 0;
  constantTensorsAsInputs:uint = 0;
}

// Root type for serialized data is the graph of the network
table SerializedGraph {
    layers:[AnyLayer];
    inputIds:[int];
    outputIds:[int];
    featureVersions:FeatureCompatibilityVersions;
}

root_type SerializedGraph;
