/* * Copyright (C) 2003-2004 * Slawomir Lisznianski * * Permission to use, copy, modify, distribute and sell this software * and its documentation for any purpose is hereby granted without fee, * provided that the above copyright notice appear in all copies and * that both that copyright notice and this permission notice appear * in supporting documentation. Slawomir Lisznianski makes no * representations about the suitability of this software for any * purpose. It is provided "as is" without express or implied warranty. * */ // June 18 2010 #ifndef RHA_MYTASKSYSTEM_HPP #define RHA_MYTASKSYSTEM_HPP #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include const int PLUS = 1; const int MINUS = 2; namespace mpi = boost::mpi; namespace Rha { template class TaskSystem { private: int destRank; int myTaskTag; int sourceRank; mpi::communicator world; class DelegateBase { public: virtual ~DelegateBase() { } virtual void Invoke(ARG arg) = 0; }; template class Delegate : public DelegateBase { public: typedef void (T::*Func)(ARG arg); private: Func m_func; T* m_object; public: Delegate(T* object, Func func) : m_object(object), m_func(func) { } virtual void Invoke(ARG arg) { ((*m_object).*(m_func))(arg); } }; typedef std::vector Delegates; Delegates m_delegates; public: typedef TaskSystem myTaskType; ~TaskSystem() { Clear(); } void Clear() { typename Delegates::iterator item = m_delegates.begin(); for (; item != m_delegates.end(); ++item) { delete *item; } m_delegates.clear(); } template void AddDelegate(T& object, typename Delegate::Func func) { DelegateBase* delegate = new Delegate(&object, func); m_delegates.push_back(delegate); } void Invoke(ARG arg) { typename Delegates::iterator item = m_delegates.begin(); for (; item != m_delegates.end(); ++item) { (*item)->Invoke(arg); } } }; } class TaskObject1 { public: void CallOne(const wchar_t* value) { std::wcout << L"CallOne(): " << value << std::endl; } void CallTwo(const wchar_t* value) { std::wcout << L"CallTwo(): " << value << std::endl; } }; class TaskObject2 { public: void CallThree(const wchar_t* value) { std::wcout << L"CallThree(): " << value << std::endl; } }; class TaskSleep { public: void setSleepTime(const int sTime){sleepTime = sTime ; }; int getSleepTime(){return sleepTime;}; void doSleep(){sleep(sleepTime);}; private: int sleepTime; protected: // provide serialization of this class, for MPI send/recv friend class boost::serialization::access; template void serialize(Archive& ar, const unsigned int version) { ar & sleepTime ; }; }; /* class TaskPackage { private: friend class boost::serialization::access; public: TaskPackage(){}; ~TaskPackage(){}; int taskType; int taskData; }; */ class TaskPackage { private: int rank_; int myRank; std::string node_; std::string os_; // operation int taskOperationType; // operands int operandA, operandB; int result; int endRun; int generation; int taskNum; int totalTaskNum; TaskSleep taskSleep; int sourceRank; int destRank; int taskTag; public: void setMyRank(int rank){myRank = rank;}; int getMyRank(){return myRank;}; void setTaskOperationType(int type){taskOperationType = type;}; int getTaskOperationType(){return taskOperationType;}; void setOperandA(int operand){operandA=operand;}; int getOperandA(){return operandA;}; void setOperandB(int operand){operandB=operand;}; int getOperandB(){return operandB;}; int getResult(){return result;}; void setResult(int myResult){result = myResult;}; void setEndRun(int endrun){endRun = endrun; std::cout << "endRun = " << endRun << std::endl;}; int getEndRun(){return endRun; }; void setMyGeneration(int gene){generation = gene ;}; int getMyGeneration(){return generation; }; void setTaskNum(int taskN){taskNum = taskN ;}; int getTaskNum(){return taskNum;}; int getTotalTaskNum(){return totalTaskNum;}; void setTotalTaskNum(int ttask){totalTaskNum = ttask;}; void setSleepTime(const int wtime){taskSleep.setSleepTime(wtime);}; const int getSleepTime(){return taskSleep.getSleepTime();}; void sleepNow(){taskSleep.doSleep();}; int getSourceRank(){return sourceRank;}; void setSourceRank(int ranki){sourceRank = ranki;}; int getDestRank(){return destRank;}; void setDestRank(int ranki){destRank = ranki;}; void setTaskTag(int iTag){taskTag = iTag;}; int getTaskTag(){return taskTag;}; /// Ctor, using mpi::communicator instance to get rank no. //hello_msg(const mpi::communicator& comm) { TaskPackage(const mpi::communicator& comm) { rank_ = comm.rank(); // get nodename and os from uname(2) struct utsname uname_; uname(&uname_); node_ = uname_.nodename; os_ = uname_.sysname; }; /// Default ctor, to use only just before serialization //hello_msg() TaskPackage() : rank_(-1), node_("unknown"), os_("unknown") { }; // print out the greeeting //friend std::ostream& operator<< (std::ostream& o, hello_msg const& msg) { friend std::ostream& operator<< (std::ostream& o, TaskPackage const& msg) { o << "Hello from MPI rank " << msg.rank_ << " running on host " << msg.node_ << " (" << msg.os_ <<")" << std::endl; }; protected: // provide serialization of this class, for MPI send/recv friend class boost::serialization::access; template void serialize(Archive& ar, const unsigned int version) { ar & rank_ & myRank & node_ & os_ & taskOperationType & operandA & operandB & result & endRun & generation & taskNum & totalTaskNum & taskSleep & sourceRank & destRank & taskTag; }; }; //BOOST_IS_MPI_DATATYPE (TaskPackage) #endif //int _tmain(int argc, _TCHAR* argv[]) /* int main(int argc, char* argv[]) { TaskSystem tasks; TaskObject1 obj1; TaskObject2 obj2; tasks.AddDelegate(obj1, &TaskObject1::CallOne); tasks.AddDelegate(obj1, &TaskObject1::CallTwo); tasks.AddDelegate(obj2, &TaskObject2::CallThree); tasks.Invoke(L"Hello, World!\n"); //tasks.Invoke("Hello, World!\n"); return 0; } */