#ifndef LCF_FULLCONNECT_H_
#define LCF_FULLCONNECT_H_
#include "tensorOperate.h"

class FCLayer : public TensorOperate
{
    public:
        FCLayer();
        FCLayer(int ifType, int iID, int iMaxSeqNum, DevicesBatchDisptach *iDevicesBatchDisptach, \
                int inOutputNum, float iLambda, float iAlpha, float lb, float ld, int ls);
        void SetLayerConfig(int ifType, int iID, int iMaxSeqNum, DevicesBatchDisptach *iDevicesBatchDisptach, \
                            int inOutputNum, float iLambda, float iAlpha, float lb, float ld, int ls);
        virtual ~FCLayer();
        void ComputeAndCreateOutYInDTensorInfo();
        void ComputerWeightUpdateGrad(int devID, MyVoid *inUpdateResultGrad, MyVoid *inD, MyVoid *tmpYInCMem, int seqNum);
        void SaveLayerWeight(int n);
        void LoadLayerWeight();
        void UpdateWeightEnter(int devID, MyVoid *inWGrad);
        void CompuateOutY(int devID, int seqNum);
        void CompuateOutD(int devID, int seqNum);
        void ComputerYMemRealease(int devID);
        void ComputerDMemRealease(int devID);
        void UpdateWeightMain();
        void CreateParaAndInstance();
        void CompGrad(int devID, int seqNum);

private:
        void SetChildLayerMomeryPointInitStatus();
        void RealeaseChildLayerMemory();
        void SetYDSaveInfo();

        int inputNum;                                               // number of yIn: inChannels * inHeight * inWidth;
        int outputNum;                                              // equal to outChannels; outHeight = 1, outWidth = 1
        TensorData *mWeight;                                        // mWeight[outputNum][inputNum]
        TensorData *mMomentumDw;                                    // Handle for momentumDw
        TensorData *mWeightGrad;                                    // wData update grad
};

#endif
