/*! * \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)"); }
/*! * \brief Calculate the statistics of the current deme/generation. * \param ioDeme Actual deme of the evolution. * \param ioContext Context of the evolution. */ void StatsCalculateOp::operate(Deme& ioDeme, Context& ioContext) { Beagle_StackTraceBeginM(); Beagle_LogTraceM( ioContext.getSystem().getLogger(), "stats", "Beagle::StatsCalculateOp", string("Calculating stats for the ")+ uint2ordinal(ioContext.getDemeIndex()+1)+" deme" ); if(ioContext.getGeneration() != mGenerationCalculated) { mGenerationCalculated = ioContext.getGeneration(); mNbDemesCalculated = 0; } if(ioDeme.getStats() == NULL) { const Factory& lFactory = ioContext.getSystem().getFactory(); Stats::Alloc::Handle lStatsAlloc = castHandleT<Stats::Alloc>(lFactory.getConceptAllocator("Stats")); Stats::Handle lStats = castHandleT<Stats>(lStatsAlloc->allocate()); ioDeme.addMember(lStats); } if(ioDeme.getStats()->isValid() == false) { calculateStatsDeme(*ioDeme.getStats(), ioDeme, ioContext); ioDeme.getStats()->setValid(); } Beagle_LogObjectM( ioContext.getSystem().getLogger(), Logger::eStats, "stats", "Beagle::StatsCalculateOp", *ioDeme.getStats() ); if(++mNbDemesCalculated == mPopSize->size()) { Beagle_LogTraceM( ioContext.getSystem().getLogger(), "stats", "Beagle::StatsCalculateOp", "Calculating stats for the vivarium" ); if(ioContext.getVivarium().getStats() == NULL) { const Factory& lFactory = ioContext.getSystem().getFactory(); Stats::Alloc::Handle lStatsAlloc = castHandleT<Stats::Alloc>(lFactory.getConceptAllocator("Stats")); Stats::Handle lStats = castHandleT<Stats>(lStatsAlloc->allocate()); ioContext.getVivarium().addMember(lStats); } calculateStatsVivarium(*ioContext.getVivarium().getStats(), ioContext.getVivarium(), ioContext); ioContext.getVivarium().getStats()->setValid(); Beagle_LogObjectM( ioContext.getSystem().getLogger(), Logger::eStats, "stats", "Beagle::StatsCalculateOp", *ioContext.getVivarium().getStats() ); } Beagle_StackTraceEndM("void StatsCalculateOp::operate(Deme& ioDeme, Context& ioContext)"); }