#ifndef LCF_TRANSFORMER_H_
#define LCF_TRANSFORMER_H_
#include "tensorOperate.h"
#include "transformerEncodeLayer.h"
#include "transformerDecodeLayer.h"

class TransformerLayer : public TensorOperate
{
    public:
        TransformerLayer();
        virtual ~TransformerLayer();
        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, int resultDim);
        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);
        
        void InputTrainLabelData(int devID, float *inLabelData);
                
    private:
        void RealeaseSubLayesInstance();
        void SetChildLayerMomeryPointInitStatus();
        void RealeaseChildLayerMemory();
        void SetInOutPoint();
        TensorData *GetLabelData(int devID, int seqNum);
        void CreateLabelData();
        void CreateEncodeSOSTensorData();
        MemoryHandle *GetTransOutputEmbedding(int devID, int seqNum);
        
        TransformerEncodeLayer *mTransformerEncodeLayer;
        TransformerDecodeLayer *mTransformerDecodeLayer;
        
        int mN;
        int mHidVecDim;                   // hidden layer dim equal out dim
        int mKVNum;
        int mHeadNum;
        float mGamma;
        float mBeta;
        int mResultDim;
        TensorData *mLabelData;
        TensorData *mSOSAttention;
};

#endif
