//
//  MNN.fbs
//  MNN
//
//  Created by jiangxiaotang on 2019/1/4.
//  Copyright © 2018, Alibaba Group Holding Limited
//

include "CaffeOp.fbs";
include "TensorflowOp.fbs";
include "TFQuantizeOp.fbs";
include "GpuLibrary.fbs";
include "UserDefine.fbs";
include "SuperAcmeQuantizeOp.fbs";
namespace MNN;
attribute "priority";

enum OpType : int {
    AbsVal,
    QuantizedAdd,
    ArgMax,
    AsString,
    InstanceNorm,
    BatchToSpaceND,
    Bias,
    BinaryOp,
    Bnll,
    Cast,
    Concat,
    Const,
    Convolution,
    ConvolutionDepthwise,
    Crop,
    CropAndResize,
    Cubic,
    Deconvolution,
    DeconvolutionDepthwise,
    Dequantize,
    DetectionOutput,
    Dropout,
    Eltwise,
    ELU,
    Unique,
    Exp,
    ExpandDims,
    Fill,
    Flatten,
    FloorMod,
    Gather,
    GatherV2,
    Im2Seq,
    InnerProduct,
    Input,
    Interp,
    Log,
    LRN,
    LSTM,
    MatMul,
    MVN,
    NonMaxSuppression,
    NonMaxSuppressionV2,
    Normalize,
    Pack,
    Padding,
    Permute,
    Pooling,
    Power,
    PReLU,
    PriorBox,
    Proposal,
    QuantizedAvgPool,
    QuantizedBiasAdd,
    QuantizedConcat,
    QuantizedDepthwiseConv2D,
    QuantizedLogistic,
    QuantizedMatMul,
    QuantizedMaxPool,
    QuantizedRelu,
    QuantizedRelu6,
    QuantizedReshape,
    QuantizedSoftmax,
    QuantizeMaxMin,
    QuantizeV2,
    Range,
    Rank,
    ReduceJoin,
    Reduction,
    ReLU,
    ReLU6, // Use as Clip
    RequantizationRange,
    Requantize,
    Reshape,
    Resize,
    RNN,
    ROIPooling,
    Scale,
    Selu,
    Seq2Out,
    Shape,
    Sigmoid,
    Size,
    Slice,
    SliceTf,
    Softmax,
    SpaceToBatchND,
    SpatialProduct,
    Split,
    Segment,
    Squeeze,
    StridedSlice,
    StringJoin,
    StringSplit,
    StringToNumber,
    TanH,
    TfQuantizedConv2D,
    Threshold,
    Tile,
    TopKV2,
    Transpose,
    UnaryOp,
    Unpack,
    Where,

    Moments,
    RNNSequenceGRU,
    BatchMatMul,
    Unsqueeze,
    CosineSimilarity,
    DepthToSpace,
    SpaceToDepth,
    ReverseSequence,
    Pooling3D,
    Convolution3D,
    MatrixBandPart,
    GatherND,
    DetectionPostProcess,
    UnravelIndex,
    ScatterNd,
    OneHot,
    BroadcastTo,
    Dilation2D,
    Raster = 128,
    ConvertTensor = 129,
    ArgMin = 130,
    LinSpace = 131,
    RandomUniform = 132,
    // TensorArray Ops
    TensorArray = 133,
    TensorArraySize = 134,
    TensorArrayRead = 135,
    TensorArrayWrite = 136,
    TensorArrayGather = 137,
    TensorArrayScatter = 138,
    TensorArraySplit = 139,
    TensorArrayConcat = 140,
    LSTMBlockCell = 141,
    Reverse = 142,

    Plugin = 256, //The Type load from plugin
    //Training Op Start from 257
    Select = 257,
    ZerosLike,
    Broastcast,
    SetDiff1D,
    ReluGrad,
    Relu6Grad,
    PoolGrad,
    SoftmaxGrad,
    Conv2DBackPropFilter,
    TrainableParam,
    BatchNorm,

    // Use for self defined grad
    ZeroGrad,

    Extra = 512,
    // quantization
    ConvInt8 = 513,
    Int8ToFloat = 514,
    DepthwiseConvInt8 = 515,
    PoolInt8 = 516,
    FloatToInt8 = 517,
    EltwiseInt8 = 518,
    DepthwiseDeconvInt8 = 519,

    // SuperAcme Start
    SelectIntSuperAcme = 590,
    ReductionIntSuperAcme = 591,
    ArgMaxIntSuperAcme = 592,
    SoftmaxIntSuperAcme = 593,
    MatMulIntSuperAcme = 594,
    ScaleIntSuperAcme = 595,
    BinaryInt8SuperAcme = 596,
    InterpIntSuperAcme = 597,
    PoolInt8SuperAcme = 598,
    EltwiseIntSuperAcme = 599,

    While = 600,
    If    = 601,
    LayerNorm = 603,
    GridSample = 604,
    Swish = 605,
    Mish = 606,
    LutUnary = 607,
    CvtColor = 608
}

table Plugin {
    type: string;
    attr: [Attribute];
}

table Extra {
    type: string;
    engine: string;
    info: [byte];
    attr:[Attribute];
}

table StringVec {
    data: [string];
}

table WhileParam {
    // The name of condition subgraph.
    cond_graph: string;

    // The name of body subgraph.
    body_graph: string;

    // Aliases the forigen inputs and subgraph inputs.
    // One forign input maybe correspond to multiple subgraph inputs.
    aliases_inputs: [StringVec];

    // Aliases the forigen outputs and subgraph outputs.
    aliases_outputs: [string];

    // Aliases body subgraph outputs and inputs.
    // One input should be updated by only one output.
    aliases_updates: [StringVec];
}

table IfParam {
    // The name of then subgraph.
    then_graph: string;

    // The name of else subgraph.
    else_graph: string;

    // Aliases the forigen inputs and subgraph inputs.
    // One forign input maybe correspond to multiple subgraph inputs.
    aliases_inputs: [StringVec];

    // Aliases the forigen outputs and subgraph outputs.
    // Each output should has two possible value from then branch and
    // else branch.
    aliases_outputs: [StringVec];
}

table RegionCommand {
    op: Op;
    steps:[int];
    size:[int];
    indexes:[int];
    view:[View];

    // How to treat output's old value for the region position
    // If fuse < 0, it means out_new = compute
    // -3 means output outside region should be set as zero
    // For backend memory layout is not linear:
    // -2 means output is totally invalid, we can rewrite output outside region
    // -1 means the output has valid value outside compute region, we can only rewrite the value in region

    // If fuse >= 0, use as a BinaryOpOperation op
    // For example, BinaryOpOperation_DIV means: out_new = out_old / compute
    fuse: int = -1;

    // If iterIndex == -1, use 0 -> loopNumber - 1
    // If iterIndex >= 0, for i in (inputTensor[loopIndexes])
    iterIndexes:[int];
}

table LoopParam {
    tensorNumber:int;
    outputIndexes:[int];
    inputIndexes:[int];
    midTensors:[TensorDescribe];
    // The loop can be parallel executed
    parallel:bool = true;
    // The number of loop (for i = 0; i<loopNumber; ++i)
    loopNumber:int;

    commands:[RegionCommand];
    is_binary:bool = false;
}

union OpParameter {
    QuantizedAdd,
    ArgMax,
    AsString,
    Axis,
    BatchNorm,
    BinaryOp,
    Blob,
    CastParam,
    Convolution2D,
    Crop,
    CropAndResize,
    Dequantize,
    DetectionOutput,
    Eltwise,
    ExpandDims,
    Fill,
    Flatten,
    Gather,
    GatherV2,
    InnerProduct,
    Input,
    Interp,
    LRN,
    LSTM,
    MatMul,
    NonMaxSuppressionV2,
    Normalize,
    PackParam,
    Permute,
    Plugin,
    Pool,
    PRelu,
    PriorBox,
    Proposal,
    QuantizedAvgPool,
    QuantizedBiasAdd,
    QuantizedConcat,
    QuantizedLogistic,
    QuantizedMatMul,
    QuantizedMaxPool,
    QuantizedRelu,
    QuantizedRelu6,
    QuantizedReshape,
    QuantizedSoftmax,
    QuantizeMaxMin,
    QuantizeV2,
    Range,
    Rank,
    ReduceJoin,
    ReductionParam,
    Relu,
    Relu6,
    RequantizationRange,
    Requantize,
    Reshape,
    Resize,
    RoiPooling,
    Scale,
    Selu,
    Size,
    Slice,
    SliceTf,
    SpaceBatch,
    SqueezeParam,
    StridedSliceParam,
    TensorConvertInfo,
    TfQuantizedConv2D,
    TopKV2,
    Transpose,
    UnaryOp,
    MomentsParam,
    RNNParam,
    BatchMatMulParam,
    QuantizedFloatParam,
    DepthSpaceParam, // DepthToSpace and SpaceToDepth using the same parameter
    EltwiseInt8,
    ReverseSequenceParam,
    Extra,
    Pool3D,
    Convolution3D,
    ELU,
    DetectionPostProcessParam,
    OneHotParam,
    PadParam,
    WhileParam,
    IfParam,
    RandomUniform,
    LayerNorm,
    TensorArray,
    LSTMBlockCell,
    GridSample,
    LoopParam,
    

    // SuperAcme Start
    // EltwiseAddSuperAcmeQuantizedParam,
    Conv2dSuperAcmeQuantizedParam,
    Sigmoid,
    Swish,
    Mish,
    LutUnary,
    SoftmaxIntSuperAcme,
    SelectIntSuperAcme,
    CvtColorParam,
}

table Op {
    inputIndexes: [int];
    main: OpParameter;
    name: string;
    outputIndexes: [int];
    type: OpType;
    defaultDimentionFormat : MNN_DATA_FORMAT = NHWC;
}

table View {
    offset:int;
    stride:[int];
}

table Region {
    src:View;
    dst:View;
    size:[int];
    origin:int;
}

table TensorDescribe {
    blob: Blob;
    index: int;
    name: string;
    regions:[Region];
    quantInfo:TensorQuantInfo;
}

enum ForwardType : byte {
    CPU = 0,
    METAL,
    OPENCL,
    OPENGLES,
    VULKAN,
}
enum Usage : byte {
    INFERENCE = 0,
    TRAIN = 1,
    INFERENCE_STATIC = 2
}

table SubGraphProto {
    // Subgraph unique name.
    name: string;

    // The ids of input tensors.
    inputs: [int];

    // The ids of output tensors.
    outputs: [int];

    // All tensor names.
    // The id of each tensor is the index in the vector names.
    tensors: [string];

    // Nodes of the subgraph.
    nodes: [Op];

    // Tensor describe info
    extraTensorDescribe:[TensorDescribe];
}

table TensorQuantInfo {
    scale:float;
    zero:float = 0;
    min:float = -128;
    max:float = 127;
    type:DataType;
    realtype:DataType = DT_INT8;
    isdequant:bool = false;
}

table Net {
    bizCode: string;
    extraTensorDescribe: [TensorDescribe];
    gpulibrary: GpuLibrary;
    oplists: [Op];
    outputName: [string];
    preferForwardType: ForwardType = CPU;
    sourceType: NetSource = CAFFE;
    tensorName: [string];
    tensorNumber: int = 0;
    usage:Usage = INFERENCE;  // used to more compatibility in future

    // Subgraphs of the Net.
    subgraphs: [SubGraphProto];
    mnn_uuid: string;
}

root_type Net;
