#ifndef LCF_SEQ2SEQ_H_
#define LCF_SEQ2SEQ_H_
#include "tensorOperate.h"
#include "gruLayer.h"
#include "rnnLayer.h"
#include "attentionLayer.h"
#include "fusionLayer.h"
#include "cbaGroupLayer.h"
#include "tensorToLayer.h"
#include "formatToLayer.h"

#define MYRNN RNNLayer
class Seq2SeqLayer : public TensorOperate
{
    public:
        Seq2SeqLayer();
        virtual ~Seq2SeqLayer();
        void SetLayerConfig(int ifType, int iID, int iMaxSeqNum, DevicesBatchDisptach *iDevicesBatchDisptach, int iHNum, \
                            int iHDim, int iInDim, float iLambda, float iAlpha, float lb, float ld, int ls, int ifAtten);
        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 ForwardBeforeAction(int devID);
        void BackwardAfterAction(int devID);
        
        void ResetDecodeResultToSOS();
        void UpdateWeightMain();
        
        void CreateNetStruct();
        void SetInOutPoint();
        
        void SaveLayerWeight(int n);
        void LoadLayerWeight();
        
        AttentionLayer *GetAttentionLayer(int devID);
   
    private:
        void RealeaseSubLayesInstance();
                  
        MYRNN *mEncodeGruLayer, *mDecodeGruLayer;
        
        int mMaxSeqlen;                   // Max In Seqlen
        int mInVecDim;                    // input vector dim
        int mHidVecDim;                   // hidden layer dim equal out dim
        int mHiddenNum;
                
        int inChannels, inHeight, inWidth;
        int outChannels, outHeight, outWidth;
        
        int mIfAttention;
        FormatToLayer *mAttentionLayerPrepare;
        AttentionLayer **mAttentionLayer;
        FusionLayer *mFusionLayer;
        int mDecodeInVector;
        FBAGroupLayer *mResultFBALayer;
        
        void CreateEncodeSOSTensorData();
        TensorData *mSOSAttention;
};

#endif
