/*!
 *  \brief Read individuals from a given file to seed the evolution.
 *  \param inFileName File name to read seeds individual from.
 *  \param ioDeme Deme to initialize with seeds.
 *  \param ioContext Evolutionary context.
 *  \return Number of seeds read.
 *
 *  Seeds file format is quite simple: XML file with "Beagle" root tag, and then a
 *  "Seeds" tag with in it the individuals representation to read. Here is a
 *  seeds file example with one individual in it.
 *  \verbatim
    <?xml version="1.0" encoding="ISO-8859-1"?>
    <Beagle>
      <Seeds>
        <Individual>
          <Genotype type="bitstring">11111</Genotype>
        </Individual>
      </Seeds>
    </Beagle>
    \endverbatim
 *  If there is less individuals in the seed file than the population size, the
 *  remaining individuals are initialized as usual. If there is more individuals
 *  than needed, the last individuals of the seeds file are ignored. If more than one
 *  deme is used in the evolution, each deme will be seeded with the same seeds file.
 *
 */
unsigned int InitializationOp::readSeeds(std::string inFileName,
        Deme& ioDeme,
        Context& ioContext)
{
	Beagle_StackTraceBeginM();
#ifdef BEAGLE_HAVE_LIBZ
	igzstream lIFStream(inFileName.c_str());
#else // BEAGLE_HAVE_LIBZ
	std::ifstream lIFStream(inFileName.c_str());
#endif // BEAGLE_HAVE_LIBZ
	PACC::XML::Document lParser;
	try {
		lParser.parse(lIFStream, inFileName);
	} catch(IOException& inExcept) {
		std::ostringstream lOSS;
		lOSS << "The seeds file is invalid: " << inExcept.what();
		throw Beagle_IOExceptionMessageM(lOSS.str());
	}

	unsigned int lReadIndividuals=0;
	unsigned int lOldIndivIndex = ioContext.getIndividualIndex();
	Individual::Handle lOldIndivHandle = ioContext.getIndividualHandle();
	for(PACC::XML::ConstIterator lNode=lParser.getFirstRoot(); lNode; ++lNode) {
		if((lNode->getType()==PACC::XML::eData) && (lNode->getValue()=="Beagle")) {
			for(PACC::XML::ConstIterator lChild=lNode->getFirstChild(); lChild; ++lChild) {
				if((lChild->getType()==PACC::XML::eData) && (lChild->getValue()=="Seeds")) {
					for(PACC::XML::ConstIterator lChild2=lChild->getFirstChild(); lChild2; ++lChild2) {
						if((lChild2->getType()==PACC::XML::eData) && (lChild2->getValue()=="Individual")) {
							if(lReadIndividuals >= ioDeme.size()) break;
							Beagle_NonNullPointerAssertM(ioDeme[lReadIndividuals]);
							ioContext.setIndividualIndex(lReadIndividuals);
							ioContext.setIndividualHandle(ioDeme[lReadIndividuals]);
							Beagle_LogVerboseM(
							    ioContext.getSystem().getLogger(),
							    std::string("Reading the ")+uint2ordinal(lReadIndividuals+1)+
							    std::string(" individual from seeds file")
							);
							ioDeme[lReadIndividuals]->readWithContext(lChild2, ioContext);
							Beagle_LogDebugM(ioContext.getSystem().getLogger(), *ioDeme[lReadIndividuals]);
							++lReadIndividuals;
						}
					}
				}
			}
		}
	}
	ioContext.setIndividualHandle(lOldIndivHandle);
	ioContext.setIndividualIndex(lOldIndivIndex);
	return lReadIndividuals;
	Beagle_StackTraceEndM();
}
void Beagle::MPI::EvaluationOp::evaluatorOperate(Deme& ioDeme, Context& ioContext) {
	try {
		//char lMessage[4096];
		int lMessageSize;
		MPI_Status lStatus;
		int lSource;

		bool lDone = false;
		while(!lDone) {
			//Receive an individual to evaluate
			MPI_Recv(&lMessageSize, 1, MPI_INT, MPI_ANY_SOURCE, MPI_ANY_TAG, MPI_COMM_WORLD, &lStatus);
			lSource = lStatus.MPI_SOURCE;
			if(lStatus.MPI_TAG == eEvolutionEnd) {
				Beagle_LogDetailedM(
								   ioContext.getSystem().getLogger(),
								   "evaluation", "Beagle::MPIEvaluationOp",
								   std::string("End of evolution received from process ") + int2str(lSource)
								   );
				lDone = true;
			} else {
				char *lMessage = new char[lMessageSize];
				unsigned int lGeneration;
				MPI_Recv(lMessage, lMessageSize, MPI_CHAR, lSource, MPI_ANY_TAG, MPI_COMM_WORLD, &lStatus);
				MPI_Recv(&lGeneration, 1, MPI_INT, lSource, MPI_ANY_TAG, MPI_COMM_WORLD, &lStatus);
				ioContext.setGeneration(lGeneration);
				Beagle_LogTraceM(
								   ioContext.getSystem().getLogger(),
								   "evaluation", "Beagle::MPIEvaluationOp",
								   std::string("Evaluating individual send from process ") + int2str(lSource)
								   );
				
				//Parse the received individual
				std::istringstream lStreamIn(lMessage);

				PACC::XML::Document lXMLParser;
				lXMLParser.parse(lStreamIn);

				PACC::XML::ConstIterator lIndividualRootNode = lXMLParser.getFirstRoot(); 

				
				//Read the received individual
				ioContext.getDeme().resize(0);
				Individual::Handle lIndividual = castHandleT<Individual>(ioContext.getDeme().getTypeAlloc()->allocate());
				lIndividual->readWithContext(lIndividualRootNode,ioContext);
				ioContext.setIndividualHandle(lIndividual);
				ioContext.setIndividualIndex(0);
				
//				Beagle_LogDebugM(
//								 ioContext.getSystem().getLogger(),
//								 "evaluation", "Beagle::MPIEvaluationOp",
//								 std::string("Individual received: ") + lIndividual->serialize()
//								 );
				
				//Free message string
				delete [] lMessage;
				
				//Evaluated the fitness of the received individual
				Fitness::Handle lFitness = evaluate(*lIndividual, ioContext);
			
				//Send back the fitness
				std::ostringstream lStreamOut;
				PACC::XML::Streamer lXMLStream(lStreamOut);

				lFitness->write(lXMLStream);
				//std::cout << "Sending fitness of size " << lStreamOut.str().size()+1 << ":" << std::endl << lStreamOut.str() << std::endl;
				lMessageSize = lStreamOut.str().size()+1;
				
				Beagle_LogTraceM(
									ioContext.getSystem().getLogger(),
									"evaluation", "Beagle::MPIEvaluationOp",
									std::string("Sending back fitness")
									);
				
				MPI_Send(&lMessageSize, 1, MPI_INT, lSource, eMessageSize, MPI_COMM_WORLD);
				MPI_Send(const_cast<char*>(lStreamOut.str().data()), lMessageSize, MPI_CHAR, lSource, eFitness, MPI_COMM_WORLD);
			}
		}
	} catch(Exception& inException) {
		std::cerr << "Exception catched in evaluator:" << std::endl << std::flush;
		std::cerr << inException.what() << std::endl << std::flush;
		exit(1);
	}
	catch(std::exception& inException) {
		std::cerr << "Standard exception catched in evaluator:" << std::endl << std::flush;
		std::cerr << inException.what() << std::endl << std::flush;
		exit(1);
	}
}
Exemple #3
0
/*!
 *  \brief Send a receive a deme.
 *
 *  A deme here is more a sub-deme since it only has a portion of
 *  the total individuals of a deme.
 *  \throw Beagle_InternalExceptionM Bad application name received
 */
void Master::EvalClient::sendAndReceiveDeme()
{
	Beagle_StackTraceBeginM();

	Beagle::String::Handle lAppName=
	    castHandleT<Beagle::String>(mContext->getSystem().getRegister().getEntry("db.app.name"));

	const Factory& lFactory = mContext->getSystem().getFactory();
	Individual::Alloc::Handle lIndividualAlloc =
		castHandleT<Individual::Alloc>(lFactory.getConceptAllocator("Individual"));

	std::ostringstream lOSS;
	lOSS << setprecision(10);

	if(mDemeStored) {
		double lTimeEval = mTimeStart.getValue()/(double)mDeme->size();
		std::ostringstream lOSSTime;
		lOSSTime << lTimeEval;

		PACC::XML::Streamer lStreamer(lOSS, 0);
		lStreamer.openTag("SG");
		lStreamer.insertAttribute("id", Beagle::uint2str(mDemeID));
		lStreamer.insertAttribute("app", lAppName->getWrappedValue());
		lStreamer.insertAttribute("gen", Beagle::uint2str(mGeneration));
		lStreamer.insertAttribute("tf", lOSSTime.str());

		// Send evaluated scores
		for(unsigned int i=0; i<mDeme->size(); ++i) {
			lStreamer.openTag("J"); //Job
			lStreamer.insertAttribute("id", Beagle::uint2str(mIndivID[i])); //job id
			lStreamer.openTag("Sc"); //Score
			lStreamer.insertAttribute("eval", "no"); //evaluation
			(*mDeme)[i]->getFitness()->write(lStreamer, false);
			lStreamer.closeTag();
			lStreamer.closeTag();
		}

		lStreamer.closeTag();
	}

	std::string lDemeSerialized = lOSS.str();

	DAGS::SubGroup lSubGroupDAGS;
	std::vector< std::pair<std::string,DAGS::Job> > lJobs;
	std::vector<std::string> lDontParseVector;
	lDontParseVector.push_back("Dt");  //Data
	lDontParseVector.push_back("Sc");  //Score
	lDontParseVector.push_back("Env"); //Environment
	doNotParseXMLTags(lDontParseVector);

	mDemeStored = false;
	while(true) {
		int lErrorNbr = getJobs(lDemeSerialized, lSubGroupDAGS, lJobs, lAppName->getWrappedValue());
		if(lErrorNbr == DAGS::Client::NoError) break;
		if(lErrorNbr < -17) logError(getErrorMessage());
		lDemeSerialized = std::string("");
		PACC::Threading::Thread::sleep(1);
	}

	mTimeStart.reset();

	std::string lObtAppName = lSubGroupDAGS.getAppName();
	if(lObtAppName != lAppName->getWrappedValue()) {
		std::string lMessage = "Bad application name received (desired: '";
		lMessage += lAppName->getWrappedValue();
		lMessage += "', obtained: '";
		lMessage += lObtAppName;
		lMessage += "').";
		throw Beagle_InternalExceptionM(lMessage);
	}

	mDemeID = (unsigned int)(lSubGroupDAGS.getGroupId());
	mGeneration = (unsigned int)lSubGroupDAGS.getGeneration();

	if(mEnvManager != NULL) {
		std::string lEnvironment = lSubGroupDAGS.getEnvironment();
		std::istringstream lEnvIS(lEnvironment);
		PACC::XML::Document lParserEnv;
		lParserEnv.parse(lEnvIS, "environmnent");
		PACC::XML::Iterator lEnvNode(lParserEnv.getFirstRoot());
		if(lEnvNode) {
			mEnvManager->readEnvironment(lEnvNode, *mDeme, *mContext);
		}
	}

	// Get jobs individual
	mIndivID.clear();
	const unsigned int lOldDemeSize = mDeme->size();
	mDeme->resize(lJobs.size());
	for(unsigned int i=lOldDemeSize; i<lJobs.size(); ++i) {
		(*mDeme)[i] = castHandleT<Individual>(lIndividualAlloc->allocate());
	}
	
	for(unsigned int i=0; i<mDeme->size(); ++i) {
		mIndivID.push_back(lJobs[i].second.getId());
		std::ostringstream lOSS;
		lOSS << "<Individual>" << lJobs[i].second.getData() << "</Individual>";
		std::istringstream lGenoIS(lOSS.str());
		PACC::XML::Document lParser;
		lParser.parse(lGenoIS);
		PACC::XML::Iterator lRootNode(lParser.getFirstRoot());
		(*mDeme)[i]->readWithContext(lRootNode, *mContext);
		(*mDeme)[i]->setFitness(NULL);
	}

	mDemeStored = true;

	Beagle_StackTraceEndM();
}
void Beagle::MPI::EvaluationOp::distributeDemeEvaluation(Deme& ioDeme, Context& ioContext) {
	try{
		std::vector<int> lProcess(mProcessSize, -1);
		lProcess[0] = -2; //Master should not be pick
		int lCurrentIndividual = 0;
		std::ostringstream lStreamOut;

		PACC::XML::Streamer lXMLStream(lStreamOut);

		//char lSizeMessage[256];
		int lMessageSize;
		MPI_Status lStatus;
		
		int lFlag;
		unsigned int lSource = 1;
		unsigned int lProcessIdx = 0;
		unsigned int lRecvIndividualIdx = 0;

		unsigned int lNbReceived = 0;		
		unsigned int lNbSent = 0;
		bool lAllSent = false;
		
		while( (lNbReceived < lNbSent) || !lAllSent ) {
			if(!lAllSent) {
				lProcessIdx = find(lProcess, -1, 0, lProcess.size());
				if( lProcessIdx != lProcess.size() ) {
					if((ioDeme[lCurrentIndividual]->getFitness() == NULL) ||
					   (ioDeme[lCurrentIndividual]->getFitness()->isValid() == false)) {
						
						//There is a process idle
						Beagle_LogVerboseM(   
										   ioContext.getSystem().getLogger(),
										   "evaluation", "Beagle::MPIEvaluationOp",
										   std::string("Evaluating the fitness of the ")+uint2ordinal(lCurrentIndividual+1)+
										   " individual"
										   );
						
						ioContext.setIndividualIndex(lCurrentIndividual);
						ioContext.setIndividualHandle(ioDeme[lCurrentIndividual]);
						
						//Send the individual to be evaluated
						Beagle_LogTraceM(
										   ioContext.getSystem().getLogger(),
										   "evaluation", "Beagle::MPIEvaluationOp",
										   std::string("Sending the ") + uint2ordinal(lCurrentIndividual+1) + std::string(" individual to ")+
										   uint2ordinal(lProcessIdx) + std::string(" evaluator")
										   );
						
						lStreamOut.str("");
						ioDeme[lCurrentIndividual]->write(lXMLStream);
						lMessageSize = lStreamOut.str().size()+1;
						MPI_Send(&lMessageSize, 1, MPI_INT, lProcessIdx, eMessageSize, MPI_COMM_WORLD);
						MPI_Send(const_cast<char*>(lStreamOut.str().data()), lMessageSize, MPI_CHAR, lProcessIdx, eIndividual, MPI_COMM_WORLD);
						//std::cout << "Sending individual : " << lStreamOut.str().data() << std::endl;
						unsigned int lGeneration = ioContext.getGeneration();
						MPI_Send(&lGeneration, 1, MPI_INT, lProcessIdx, eIndividual, MPI_COMM_WORLD);
						lProcess[lProcessIdx] = lCurrentIndividual;	
						++lNbSent;
					}
					++lCurrentIndividual;
					if(lCurrentIndividual >= ioDeme.size()) {
						lAllSent = true;
					}
				}
			}
			
			//Look if any cruncher sent a fitness back
			MPI_Iprobe(MPI_ANY_SOURCE, MPI_ANY_TAG, MPI_COMM_WORLD, &lFlag, &lStatus);
			if (lFlag) {
				//Receive the evaluated fitness
				lSource = lStatus.MPI_SOURCE;
				MPI_Recv(&lMessageSize, 1, MPI_INT, lSource, eMessageSize, MPI_COMM_WORLD, &lStatus);
				char *lMessage = new char[lMessageSize];
				MPI_Recv(lMessage, lMessageSize, MPI_CHAR, lSource, eFitness, MPI_COMM_WORLD, &lStatus);
				lRecvIndividualIdx = lProcess[lSource];
				lProcess[lSource] = -1;
				++lNbReceived;
				
				Beagle_LogTraceM(
								   ioContext.getSystem().getLogger(),
								   "evaluation", "Beagle::MPIEvaluationOp",
								   std::string("Receiving the fitness of the ") + uint2ordinal(lRecvIndividualIdx+1) + 
								   std::string(" individual from ")+uint2ordinal(lSource) + std::string(" evaluator")
								   );
				
				//Read the received fitness
				std::istringstream lStreamIn(lMessage);
				PACC::XML::Document lXMLParser;

				lXMLParser.parse(lStreamIn);
				
				Fitness::Handle lFitness = castHandleT<Fitness>(ioDeme[lRecvIndividualIdx]->getFitnessAlloc()->allocate());
				PACC::XML::ConstIterator lFitnessRootNode = lXMLParser.getFirstRoot(); 

				lFitness->read(lFitnessRootNode);
				
				//Free message space
				delete [] lMessage;
				
				//Assign the fitness
				ioDeme[lRecvIndividualIdx]->setFitness(lFitness);
				ioDeme[lRecvIndividualIdx]->getFitness()->setValid();
				
				//Update stats
				ioContext.setProcessedDeme(ioContext.getProcessedDeme()+1);
				ioContext.setTotalProcessedDeme(ioContext.getTotalProcessedDeme()+1);
				ioContext.setProcessedVivarium(ioContext.getProcessedVivarium()+1);
				ioContext.setTotalProcessedVivarium(ioContext.getTotalProcessedVivarium()+1);  
				
				Beagle_LogDebugM(
								 ioContext.getSystem().getLogger(),
								 "evaluation", "Beagle::MPIEvaluationOp",
								 std::string("Received fitness of individual: ")+
								 ioDeme[lRecvIndividualIdx]->serialize()
								 );
				
				Beagle_LogDebugM(
								   ioContext.getSystem().getLogger(),
								   "evaluation", "Beagle::MPIEvaluationOp",
								   std::string("The individual\'s fitness is: ")+
								   ioDeme[lRecvIndividualIdx]->getFitness()->serialize()
								   );
			}
		}
	} catch(Exception& inException) {
		std::cerr << "Exception catched in evolver:" << std::endl << std::flush;
		std::cerr << inException.what() << std::endl << std::flush;
		exit(1);
	}
	catch(std::exception& inException) {
		std::cerr << "Standard exception catched in evolver:" << std::endl << std::flush;
		std::cerr << inException.what() << std::endl << std::flush;
		exit(1);
	}
}