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

class MultiRegressLayer : public TensorOperate {
    public:
        MultiRegressLayer(int ifType, int iID, int iMaxSeqNum, DevicesBatchDisptach *iDevicesBatchDisptach, \
                          const char *iFunStr, int ifNormIn, int ifNormOut);
        virtual ~MultiRegressLayer();
        void ComputeAndCreateOutYInDTensorInfo();
        void InputTrainLabelData(float *inLabelData);
        int GetIfNormIn();
        int GetIfNormOut();
        void GetOutNumData(float *resultNum);
        void CompuateOutY(int devID, int seqNum);
        void CompuateOutD(int devID, int seqNum);
        void SaveLayerWeight(int n);
        void LoadLayerWeight();

        float GetThisBatchPerformance();
        void ComputerYMemRealease(int devID);
        void ComputerDMemRealease(int devID);
        void CreateParaAndInstance();
        TensorData *GetResultData(int devID, int seqNum);
        TensorData *GetLabelData(int devID, int seqNum);
        int inChannels, inHeight, inWidth;
        int outChannels, outHeight, outWidth;
 
    private:
        float ComputerD(int ifType, MyVoid *yData, MyVoid *lData, int len, int index);
        float ComputerD_FP32(float *yData, float *lData, int len, int index);
        float ComputerD_FP8_E4M3(fp8_e4m3 *yData, fp8_e4m3 *lData, int len, int index);
        float ComputerD_FP8_E5M2(fp8_e5m2 *yData, fp8_e5m2 *lData, int len, int index);
        float ComputerD_FP16(fp16 *yData, fp16 *lData, int len, int index);
        int GetPerformanceFunTypeByName(const char *strName);
        void SetChildLayerMomeryPointInitStatus();
        void RealeaseChildLayerMemory();
        void ComputerThisBatchPerformance(int devID, int seqNum);
        float ComputerThisBatchPerformanceFun(int ifType, MyVoid *yData, MyVoid *lData, int len);
        
        float GetRMSE(int ifType, MyVoid *y1, MyVoid *y2, int len);
        float GetMSE(int ifType, MyVoid *y1, MyVoid *y2, int len);
        float GetMAE(int ifType, MyVoid *y1, MyVoid *y2, int len);
        
        int mIfNormIn, mIfNormOut;
        TensorData *mLabelData;       // mLableData[batchNum][outChannels]
        TensorData *mResultData;      // mLableData[batchNum][outChannels]
        int mPerFun;
        float *mPerResult;
};

#endif
