# ifndef __EO_PARALLEL_APPLY_H__ # define __EO_PARALLEL_APPLY_H__ # include "eoMpi.h" # include # include namespace eo { namespace mpi { struct ParallelApplyAssignment { int index; int size; }; template class SendTaskParallelApply; template class HandleResponseParallelApply; template class ProcessTaskParallelApply; template class IsFinishedParallelApply; template class ParallelApply; template< class EOT > class BaseParallelApply { public: void owner(ParallelApply * job) { j = job; } protected: ParallelApply * j; }; template< typename EOT > class ParallelApply : public Job { friend class SendTaskParallelApply; friend class HandleResponseParallelApply; friend class ProcessTaskParallelApply; friend class IsFinishedParallelApply; public: ParallelApply( eoUF & _proc, std::vector& _pop, AssignmentAlgorithm & algo, int _masterRank, const JobStore& store, // long _maxTime = 0, int _packetSize = 1 ) : Job( algo, _masterRank, store ), // Job( algo, _masterRank, _maxTime ), func( _proc ), data( _pop ), packetSize( _packetSize ), index( 0 ), size( _pop.size() ) { if ( _packetSize <= 0 ) { throw std::runtime_error("Packet size should not be negative."); } tempArray = new EOT [ _packetSize ]; dynamic_cast< BaseParallelApply& >( sendTask ).owner( this ); dynamic_cast< BaseParallelApply& >( handleResponse ).owner( this ); dynamic_cast< BaseParallelApply& >( processTask ).owner( this ); dynamic_cast< BaseParallelApply& >( isFinished ).owner( this ); } ~ParallelApply() { delete [] tempArray; } protected: std::vector & data; eoUF & func; int index; int size; std::map< int /* worker rank */, ParallelApplyAssignment /* min indexes in vector */> assignedTasks; int packetSize; EOT* tempArray; // bmpi::communicator& comm; }; template< class EOT > class SendTaskParallelApply : public SendTaskFunction, public BaseParallelApply { public: using BaseParallelApply::j; // futureIndex, index, packetSize, size, comm, assignedTasks, data void operator()(int wrkRank) { int futureIndex; if( j->index + j->packetSize < j->size ) { futureIndex = j->index + j->packetSize; } else { futureIndex = j->size; } int sentSize = futureIndex - j->index ; j->comm.send( wrkRank, 1, sentSize ); eo::log << eo::progress << "Evaluating individual " << j->index << std::endl; j->assignedTasks[ wrkRank ].index = j->index; j->assignedTasks[ wrkRank ].size = sentSize; j->comm.send( wrkRank, 1, & ( (j->data)[ j->index ] ) , sentSize ); j->index = futureIndex; } }; template< class EOT > class HandleResponseParallelApply : public HandleResponseFunction, public BaseParallelApply { public: using BaseParallelApply::j; void operator()(int wrkRank) { j->comm.recv( wrkRank, 1, & (j->data[ j->assignedTasks[wrkRank].index ] ), j->assignedTasks[wrkRank].size ); } }; template< class EOT > class ProcessTaskParallelApply : public ProcessTaskFunction, public BaseParallelApply { public: using BaseParallelApply::j; void operator()() { int recvSize; j->comm.recv( j->masterRank, 1, recvSize ); j->comm.recv( j->masterRank, 1, j->tempArray, recvSize ); timerStat.start("worker_processes"); for( int i = 0; i < recvSize ; ++i ) { j->func( j->tempArray[ i ] ); } timerStat.stop("worker_processes"); j->comm.send( j->masterRank, 1, j->tempArray, recvSize ); } }; template< class EOT > class IsFinishedParallelApply : public IsFinishedFunction, public BaseParallelApply { public: using BaseParallelApply::j; bool operator()() { return j->index == j->size; } }; template< class EOT > struct ParallelApplyStore : public JobStore { ParallelApplyStore() { stpa = new SendTaskParallelApply; hrpa = new HandleResponseParallelApply; ptpa = new ProcessTaskParallelApply; ispa = new IsFinishedParallelApply; } ~ParallelApplyStore() { delete stpa; delete hrpa; delete ptpa; delete ispa; } SendTaskFunction& sendTask() const { return *stpa; } HandleResponseFunction& handleResponse() const { return *hrpa; } ProcessTaskFunction& processTask() const { return *ptpa; } IsFinishedFunction& isFinished() const { return *ispa; } protected: SendTaskParallelApply* stpa; HandleResponseParallelApply* hrpa; ProcessTaskParallelApply* ptpa; IsFinishedParallelApply* ispa; }; } } # endif // __EO_PARALLEL_APPLY_H__