/*! * \brief Send the individuals that were modified during the current generation. * \param ioDeme Current deme to execute the operator. * \param ioContext Current context to execute the operator. * \todo Check if this operator can be used with migration operator. * This operator can only be used in a context where the size of the * population remains constant for all generations. */ void HPC::SendProcessedToSupervisorOp::operate(Deme& ioDeme, Context& ioContext) { Beagle_StackTraceBeginM(); ProcessingBuffer::Handle lBuffer = castHandleT<ProcessingBuffer>(ioDeme.getMember("ProcessingBuffer")); Beagle_NonNullPointerAssertM(lBuffer); std::ostringstream lOutStream; PACC::XML::Streamer lStreamer(lOutStream); lStreamer.openTag("Population"); for(unsigned int i = 0; i < lBuffer->size(); ++i) (*lBuffer)[i]->write(lStreamer,false); lStreamer.closeTag(); mComm->send(uint2str(ioContext.getProcessedDeme()), "NbrProcessed", "Parent"); mComm->send(lBuffer->getIndex().serialize(), "ProcessedIndex", "Parent"); mComm->send(lOutStream.str(), "Processed", "Parent"); Beagle_LogDetailedM( ioContext.getSystem().getLogger(), "send", "Beagle::HPC::SendProcessedToSupervisorOp", std::string("Evolver send deme to his supervisor") ); Beagle_StackTraceEndM("void HPC::SendProcessedToSupervisorOp::operate(Deme& ioDeme, Context& ioContext)"); }
/*! * \brief Receive the fitness of an individuals group from evaluator node. * \param ioDeme Deme to update by the receive fitness. * \param ioContext Current context of the evolution. */ void HPC::RecvFitnessFromEvaluatorOp::operate(Deme& ioDeme, Context& ioContext) { Beagle_StackTraceBeginM(); ProcessingBuffer::Handle lBuffer = castHandleT<ProcessingBuffer>(ioDeme.getMember("ProcessingBuffer")); Beagle_NonNullPointerAssertM(lBuffer); Individual::Handle lOldIndividualHandle = ioContext.getIndividualHandle(); unsigned int lOldIndividualIndex = ioContext.getIndividualIndex(); prepareStats(ioDeme,ioContext); unsigned int lNbEvaluators = mComm->getNbrOfRelation("Child"); unsigned int lNbIndividualInt = lBuffer->size() / lNbEvaluators; unsigned int lNbIndividualFrac = lBuffer->size() % lNbEvaluators; unsigned int lNbIndividualTotal = 0; for(int i = 0; i < lNbEvaluators; ++i ){ int lNbIndividual = lNbIndividualInt; if(i < lNbIndividualFrac) ++lNbIndividual; std::string lFitnessString; mComm->receive(lFitnessString, "Fitness", "Child", i); Beagle_LogDetailedM( ioContext.getSystem().getLogger(), "receive", "Beagle::HPC::RecvFitnessFromEvaluatorOp", std::string("Evolver receive fitness from his ")+uint2ordinal(i+1)+ std::string(" evaluator") + std::string(" of ") + uint2str(lNbEvaluators) ); std::istringstream lInStream(lFitnessString); PACC::XML::Document lDocument(lInStream); const Factory& lFactory = ioContext.getSystem().getFactory(); Fitness::Alloc::Handle lFitnessAlloc = castHandleT<Fitness::Alloc>(lFactory.getConceptAllocator("Fitness")); for(PACC::XML::ConstIterator lIter = lDocument.getFirstRoot()->getFirstChild(); lIter; ++lIter){ ioContext.setIndividualIndex(lNbIndividualTotal); ioContext.setIndividualHandle(ioDeme[lNbIndividualTotal]); if((*lBuffer)[lNbIndividualTotal]->getFitness() == 0) (*lBuffer)[lNbIndividualTotal]->setFitness( castHandleT<Fitness>(lFitnessAlloc->allocate()) ); (*lBuffer)[lNbIndividualTotal]->getFitness()->read(lIter); ++lNbIndividualTotal; updateStats(1,ioContext); } } Beagle_LogDetailedM( ioContext.getSystem().getLogger(), "receive", "Beagle::HPC::RecvFitnessFromEvaluatorOp", std::string("Evolver receive all its fitness.") ); ioContext.setIndividualIndex(lOldIndividualIndex); ioContext.setIndividualHandle(lOldIndividualHandle); Beagle_StackTraceEndM("void RecvFitnessFromEvaluatorOp::operate(Deme& ioDeme, Context& ioContext)"); }
/*! * \brief Distribute groups of individuals to evaluators nodes childs. * \param ioDeme Current deme to execute the operator. * \param ioContext Current context to execute the operator. * This function distributed individuals to the evolver's evaluators. * * It first checks if the deme has a \ref ProcessingBuffer. The buffer * is used to memorize which individuals had invalid fitness, since the * function only distributes individuals that were modified during the * current generation. Once the buffer is filled, the individuals are * distributed to evaluator. * The number of individuals an evaluato will received is based on this * formula : * \f[ NbIndividuals = \left\{ \begin{array}{lr} \frac{BufferSize}{NbEvaluators} + 1, & EvaluatorRank > BufferSize \pmod{NbEvaluators} \\ \frac{BufferSize}{NbEvaluators}, & else \end{array} \right. \f] * * The function write the individuals in a streamer. The streamer opening * tag is <Population> so the evaluator can directly read the string at * its reception as a deme. * * The string are sent using a non-blocking send function, so the function * doesn't have to wait for the transaction to be completed before starting * to build another packet of individuals. The function ends when all * packets have been sent. */ void HPC::DistributeDemeToEvaluatorsOp::operate(Deme& ioDeme, Context& ioContext) { Beagle_StackTraceBeginM(); unsigned int lNbEvaluators = mComm->getNbrOfRelation("Child"); ProcessingBuffer::Handle lBuffer = castHandleT<ProcessingBuffer>(ioDeme.getMember("ProcessingBuffer")); if(lBuffer==0){ lBuffer = new ProcessingBuffer; ioDeme.addMember(lBuffer); } lBuffer->clear(); for(unsigned int i = 0; i < ioDeme.size(); ++i){ if((ioDeme[i]->getFitness() == 0) || (ioDeme[i]->getFitness()->isValid() == false)){ lBuffer->push_back(ioDeme[i], i); } } unsigned int lNbIndividualInt = lBuffer->size() / lNbEvaluators; unsigned int lNbIndividualFrac = lBuffer->size() % lNbEvaluators; unsigned int lNbIndividualTotal = 0; unsigned int lNbIndividual = 0; std::vector<std::string> lStreams(lNbEvaluators); MPICommunication::Request::Bag lRequests(lNbEvaluators); for(unsigned int i = 0; i < lNbEvaluators; ++i){ lNbIndividual = lNbIndividualInt; if(i < lNbIndividualFrac) lNbIndividual++; std::ostringstream lOutStream; PACC::XML::Streamer lStreamer(lOutStream); lStreamer.openTag("Population"); for(int j = 0; j < lNbIndividual; ++j){ (*lBuffer)[j+lNbIndividualTotal]->write(lStreamer, false); } lStreamer.closeTag(); lStreams[i] = lOutStream.str(); lRequests[i] = new MPICommunication::Request; mComm->sendNonBlocking(lStreams[i], lRequests[i], "Individuals", "Child", i); lNbIndividualTotal += lNbIndividual; Beagle_LogDetailedM( ioContext.getSystem().getLogger(), "distribute", "Beagle::HPC::DistributeDemeToEvaluatorsOp", std::string("Evolver send fractionnal Deme to his ")+uint2ordinal(i+1)+ " evaluator" ); } mComm->waitAll(lRequests); Beagle_StackTraceEndM("DistributeDemeToEvaluatorsOp::operate(Deme& ioDeme, Context& ioContext)"); }