diff options
Diffstat (limited to 'src/CuTNetLib/cuMisc.h')
-rw-r--r-- | src/CuTNetLib/cuMisc.h | 555 |
1 files changed, 555 insertions, 0 deletions
diff --git a/src/CuTNetLib/cuMisc.h b/src/CuTNetLib/cuMisc.h new file mode 100644 index 0000000..7319adf --- /dev/null +++ b/src/CuTNetLib/cuMisc.h @@ -0,0 +1,555 @@ +#ifndef _CUMISC_H_ +#define _CUMISC_H_ + +#include <vector> + +#include "cuComponent.h" +#include "cumatrix.h" + + +#include "Matrix.h" +#include "Vector.h" +#include "Error.h" + + +namespace TNet { + /** + * \brief A pipe for input and errorinput propagation(doesn't incurr copy) + * + * \ingroup CuNNMisc + */ + class CuPipe : public CuComponent + { + public: + CuPipe(size_t nInputs, size_t nOutputs, CuComponent* pPred) + : CuComponent(nInputs,nOutputs,pPred) + { } + + ~CuPipe() + { } + + ComponentType GetType() const + { return PIPE; } + + const char* GetName() const + { return "<pipe>"; } + + void ReadFromStream(std::istream& rIn) + { } + + void WriteToStream(std::ostream& rOut) + { } + + void Propagate() + { + if (NULL == mpInput) Error("mpInput is NULL"); + mOutput.Init(*mpInput); + } + void BackPropagate() + { + if (NULL == mpErrorInput) Error("mpErrorInput is NULL"); + mErrorOutput.Init(*mpErrorInput); + } + + protected: + + void PropagateFnc(const CuMatrix<BaseFloat>& X, CuMatrix<BaseFloat>& Y) + { Y.CopyFrom(X);} + + void BackpropagateFnc(const CuMatrix<BaseFloat>& X, CuMatrix<BaseFloat>& Y) + { Y.CopyFrom(X); } + + }; + + /** + * \brief A pipe for input propagation(doesn't incurr copy) and set any error to zero + * + * \ingroup CuNNMisc + * + * @todo have to be set to zero on every pass(setup a common zeroed space?!) + */ + class CuLearnStop : public CuComponent + { + public: + CuLearnStop(size_t nInputs, size_t nOutputs, CuComponent* pPred) + : CuComponent(nInputs,nOutputs,pPred) + { } + + ~CuLearnStop() + { } + + ComponentType GetType() const + { return LEARNSTOP; } + + const char* GetName() const + { return "<learnstop>"; } + + void ReadFromStream(std::istream& rIn) + { } + + void WriteToStream(std::ostream& rOut) + { } + + void Propagate() + { + if (NULL == mpInput) Error("mpInput is NULL"); + mOutput.Init(*mpInput); + } + + protected: + + void PropagateFnc(const CuMatrix<BaseFloat>& X, CuMatrix<BaseFloat>& Y) + { Y.CopyFrom(X);} + + void BackpropagateFnc(const CuMatrix<BaseFloat>& X, CuMatrix<BaseFloat>& Y) + { Y.SetZero(); } + + }; + + /** + * \brief Distribute the input to several output + * + * \ingroup CuNNMisc + * + */ + class CuDistrib : public CuComponent + { + public: + CuDistrib(size_t nInputs, size_t nOutputs, CuComponent* pPred) + : CuComponent(nInputs,nOutputs,pPred),size(0),ErrInputVec() + { + } + + ~CuDistrib() + { } + + ComponentType GetType() const + { return DISTRIB; } + + const char* GetName() const + { return "<distrib>"; } + + void ReadFromStream(std::istream& rIn) + { + rIn >> std::ws >> size; + ErrInputVec.clear(); + for (int i=0; i<size;++i) + ErrInputVec.push_back(NULL); + } + + void WriteToStream(std::ostream& rOut) + { + rOut<<size<<std::endl; + } + + void Propagate() + { + if (NULL == mpInput) Error("mpInput is NULL"); + mOutput.Init(*mpInput); + } + + int GetOutSect() + { + return size; + } + + CuMatrix<BaseFloat>& GetErrorInput(int pos=0) + { + if (pos>=0 && pos<size) + return *ErrInputVec[pos]; + return *ErrInputVec[0]; + } + + void SetErrorInput(CuMatrix<BaseFloat>& rErrorInput,int pos=0) + { + if (pos==0) + mpErrorInput=&rErrorInput; + if (pos>=0 && pos<size) + ErrInputVec[pos]=&rErrorInput; + } + + protected: + + void PropagateFnc(const CuMatrix<BaseFloat>& X, CuMatrix<BaseFloat>& Y) + { Y.CopyFrom(X);} + + void BackpropagateFnc(const CuMatrix<BaseFloat>& X, CuMatrix<BaseFloat>& Y) + { + Y.SetZero(); + for (int i=0;i<size;++i) + Y.AddScaled(1.0,*ErrInputVec[i],1.0); + } + + int size; + MatrixPtrVec ErrInputVec; + Vector<BaseFloat> Scale; + }; + + /** + * \brief Combining(Adding) several inputs together + * + * \ingroup CuNNMisc + * + */ + class CuCombine : public CuComponent + { + public: + CuCombine(size_t nInputs, size_t nOutputs, CuComponent* pPred) + : CuComponent(nInputs,nOutputs,pPred),size(0),InputVec() + { + } + + ~CuCombine() + { } + + ComponentType GetType() const + { return COMBINE; } + + const char* GetName() const + { return "<combine>"; } + + void ReadFromStream(std::istream& rIn) + { + rIn >> std::ws >> size; + InputVec.clear(); + for (int i=0; i<size;++i) + InputVec.push_back(NULL); + } + + void WriteToStream(std::ostream& rOut) + { + rOut<<size<<std::endl; + } + + void Backpropagate() + { + if (NULL == mpErrorInput) Error("mpErrorInput is NULL"); + mErrorOutput.Init(*mpErrorInput); + } + + int GetInSect() + { + return size; + } + + /// IO Data getters + CuMatrix<BaseFloat>& GetInput(int pos=0) + { + if (pos>=0 && pos<size) + return *InputVec[pos]; + return *InputVec[0]; + } + + /// Set input vector (bind with the preceding NetworkComponent) + void SetInput(CuMatrix<BaseFloat>& rInput,int pos=0) + { + if (pos==0) + mpInput=&rInput; + if (pos>=0 && pos<size) + InputVec[pos]=&rInput; + } + + protected: + + void PropagateFnc(const CuMatrix<BaseFloat>& X, CuMatrix<BaseFloat>& Y) + { + Y.SetZero(); + for (int i=0;i<size;++i) + Y.AddScaled(1.0,*InputVec[i],1.0); + } + + void BackpropagateFnc(const CuMatrix<BaseFloat>& X, CuMatrix<BaseFloat>& Y) + { + Y.CopyFrom(X); + } + + int size; + MatrixPtrVec InputVec; + }; + + /** + * \brief Divide the input matrix to several outputs + * + * \ingroup CuNNMisc + * + */ + class CuDivide : public CuComponent + { + public: + CuDivide(size_t nInputs, size_t nOutputs, CuComponent* pPred) + : CuComponent(nInputs,nOutputs,pPred),size(0) + { } + + ~CuDivide() + { } + + ComponentType GetType() const + { return DIVIDE; } + + const char* GetName() const + { return "<divide>"; } + + int GetOutSect() + { + return size; + } + + void ReadFromStream(std::istream& rIn) + { + int len; + for (int i=0; i<size;++i) + delete OutputVec[i]; + rIn >> std::ws >> size; + OutputVec.clear(); + for (int i=0; i<size;++i) + { + rIn>>len; + OutputVec.push_back(new CuMatrix<BaseFloat>()); + SectLen.push_back(len); + } + } + + void WriteToStream(std::ostream& rOut) + { + rOut<<size<<" "; + for (int i=0; i<size;++i) + rOut<<SectLen[i]<<" "; + rOut<<std::endl; + } + + void Propagate() + { + if (NULL == mpInput) Error("mpInput is NULL"); + int loc=0; + for (int i=0;i<size;++i) + { + OutputVec[i]->Init(*mpInput,loc,SectLen[i]); + loc+=SectLen[i]; + } + } + + protected: + + void PropagateFnc(const CuMatrix<BaseFloat>& X, CuMatrix<BaseFloat>& Y) + { Error("__func__ Nonsense"); } + + void BackpropagateFnc(const CuMatrix<BaseFloat>& X, CuMatrix<BaseFloat>& Y) + { + int loc=0; + for (int i=0;i<size;++i) + { + Y.CopyCols(SectLen[i], 0, X, loc); + loc+=SectLen[i]; + } + } + + int size; + MatrixPtrVec OutputVec; + MatrixPtrVec ErrorInputVec; + std::vector<int> SectLen; + + }; + + /** + * \brief Merge several input matrices to one single output + * + * \ingroup CuNNMisc + * + */ + class CuMerge : public CuComponent + { + public: + CuMerge(size_t nInputs, size_t nOutputs, CuComponent* pPred) + : CuComponent(nInputs,nOutputs,pPred) + { } + + ~CuMerge() + { } + + ComponentType GetType() const + { return MERGE; } + + const char* GetName() const + { return "<merge>"; } + + int GetInSect() + { + return size; + } + + void ReadFromStream(std::istream& rIn) + { + int len; + for (int i=0; i<size;++i) + delete ErrorOutputVec[i]; + rIn >> std::ws >> size; + ErrorOutputVec.clear(); + for (int i=0; i<size;++i) + { + rIn>>len; + ErrorOutputVec.push_back(new CuMatrix<BaseFloat>()); + SectLen.push_back(len); + } + } + + void WriteToStream(std::ostream& rOut) + { + rOut<<size<<" "; + for (int i=0; i<size;++i) + rOut<<SectLen[i]<<" "; + rOut<<std::endl; + } + + void Backpropagate() + { + if (NULL == mpErrorInput) Error("mpErrorInput is NULL"); + int loc=0; + for (int i=0;i<size;++i) + { + ErrorOutputVec[i]->Init(*mpErrorInput,loc,SectLen[i]); + loc+=SectLen[i]; + } + } + + protected: + + void PropagateFnc(const CuMatrix<BaseFloat>& X, CuMatrix<BaseFloat>& Y) + { + int loc=0; + for (int i=0;i<size;++i) + { + Y.CopyCols(SectLen[i], 0, X, loc); + loc+=SectLen[i]; + } + } + + void BackpropagateFnc(const CuMatrix<BaseFloat>& X, CuMatrix<BaseFloat>& Y) + { Error("__func__ Nonsense"); } + + int size; + + MatrixPtrVec InputVec; + MatrixPtrVec ErrorOutputVec; + std::vector<int> SectLen; + + }; + + /** + * \brief Reordering several inputs + * + * \ingroup CuNNMisc + * + */ + class CuReorder : public CuComponent + { + public: + CuReorder(size_t nInputs, size_t nOutputs, CuComponent* pPred) + : CuComponent(nInputs,nOutputs,pPred) + { } + + ~CuReorder() + { } + + ComponentType GetType() const + { return REORDER; } + + const char* GetName() const + { return "<reorder>"; } + + int GetInSect() + { + return size; + } + + int GetOutSect() + { + return size; + } + + void ReadFromStream(std::istream& rIn) + { + int pos; + for (int i=0; i<size;++i) + delete PipeVec[i]; + rIn >> std::ws >> size; + Order.clear(); + PipeVec.clear(); + for (int i=0; i<size;++i) + { + rIn>>pos; + Order.push_back(pos); + PipeVec.push_back(new CuPipe(0,0,NULL)); + } + } + + void WriteToStream(std::ostream& rOut) + { + rOut << size<< " "; + for (int i=0; i<size;++i) + rOut<<Order[i]<<" "; + rOut<<std::endl; + } + + void Propagate() + { + if (NULL == mpInput) Error("mpInput is NULL"); + for (int i=0; i<size;++i) + PipeVec[i]->Propagate(); + } + + void Backpropagate() + { + if (NULL == mpErrorInput) Error("mpErrorInput is NULL"); + for (int i=0; i<size;++i) + PipeVec[i]->Backpropagate(); + } + + /// IO Data getters + CuMatrix<BaseFloat>& GetInput(int pos=0) + { + return PipeVec[pos]->GetInput(); + } + CuMatrix<BaseFloat>& GetOutput(int pos=0) + { + return PipeVec[Order[pos]]->GetOutput(); + } + CuMatrix<BaseFloat>& GetErrorInput(int pos=0) + { + return PipeVec[Order[pos]]->GetErrorInput(); + } + CuMatrix<BaseFloat>& GetErrorOutput(int pos=0) + { + return PipeVec[pos]->GetErrorOutput(); + } + + /// Set input vector (bind with the preceding NetworkComponent) + void SetInput(CuMatrix<BaseFloat>& rInput,int pos=0) + { + PipeVec[pos]->SetInput(rInput); + } + /// Set error input vector (bind with the following NetworkComponent) + void SetErrorInput(CuMatrix<BaseFloat>& rErrorInput,int pos=0) + { + PipeVec[Order[pos]]->SetErrorInput(rErrorInput); + } + + protected: + + void PropagateFnc(const CuMatrix<BaseFloat>& X, CuMatrix<BaseFloat>& Y) + { Error("__func__ Nonsense"); } + + void BackpropagateFnc(const CuMatrix<BaseFloat>& X, CuMatrix<BaseFloat>& Y) + { Error("__func__ Nonsense"); } + + int size; + + std::vector<int> Order; + + std::vector< CuPipe* > PipeVec; + }; + +} //namespace + + + +#endif |