#ifndef LCF_TRANSFORMER_DECODE_H_
#define LCF_TRANSFORMER_DECODE_H_
#include "tensorOperate.h"
#include "fusionLayer.h"
#include "layerNormLayer.h"
#include "fullConnectLayer.h"
#include "multiHeadAttentionLayer.h"

class TransformerDecodeLayer : public TensorOperate
{
    public:
        TransformerDecodeLayer();
        virtual ~TransformerDecodeLayer();
        void SetLayerConfig(int ifType, int iID, int iMaxSeqNum, DevicesBatchDisptach *iDevicesBatchDisptach, 
                            int iHVec, int KVNum, int inN, int headNum, float initGamma, float initBeta, \
                            float iLambda, float iAlpha, float lb, float ld, int ls);
        void ComputeAndCreateOutYInDTensorInfo();
        void CreateParaAndInstance();

        void ComputerYMemRealease(int devID);
        void ComputerDMemRealease(int devID);
        
        void CompuateOutY(int devID, int seqNum);
        void CompuateOutD(int devID, int seqNum);
        
        void UpdateWeightMain();
        int GetKVNum();
        
        void SetFilterMat(int seqNum, float *mat);
        void UpdateDSTD(float dStd);

    private:
        void RealeaseSubLayesInstance();
        void SetChildLayerMomeryPointInitStatus();
        void RealeaseChildLayerMemory();
        void SetInOutPoint();
        
        LayerNormLayer *mLayerNormLayerTop;
        FusionLayer *mFusionLayerTop;
        FCLayer *mFCLayer;
        LayerNormLayer *mLayerNormLayerMiddle;
        FusionLayer *mFusionLayerMiddle;
        MultiHeadAttentionLayer *mMultiHeadAttentionLayer;
        LayerNormLayer *mLayerNormLayerBottom;
        FusionLayer *mFusionLayerBottom;
        MultiHeadAttentionLayer *mMaskMultiHeadAttentionLayer;
        
        int mN;
        int mHidVecDim;                   // hidden layer dim equal out dim
        int mKVNum;
        int mHeadNum;
        float mGamma;
        float mBeta;
};

#endif
