[galib] Parallelize the genome evaluation?

Glenn Sugden headcrash at mac.com
Fri Sep 2 23:10:59 EDT 2011


On Sep 2, 2011, at 9:14 AM, galib-request at mit.edu wrote:

> Is it possible to parallelize the genome evaluation?

Here's an old posting of mine that I've updated with some better changes:

	I did this (a pthreaded version) without touching the GALib itself .. it was a tad bit hacky .. but I didn't want to touch the library in case there were updates later on (and I just don't have time to fold .diffs back in).

	Anyway, in a nutshell (this is copy, massaged, and pasted code, so YMMV):

	1) I get ahold of the GA's GAPopulation:

		GAPopulation *pop = const_cast<GAPopulation *>(&ga->population());

	2) I make a copy of the current population*:

		GAPopulation *newpop = pop->clone();

	3) This is optional, but a way to ensure that both populations carry the userData**...

		newpop->userData( ga->userData() );

	4) I install my (threaded) evaluator:

		newpop->evaluator( MyEvaluator );

	5) Now I install the new, modified population into my ga:

		ga->population(*newpop);

	6) Then in my Evaluator:

		extern void MyEvaluator( GAPopulation & p )

	7) I launch threads for each individual***:

		for ( int i = 0; i < p.size(); i++ )
			parameters->individual = &p.individual( i );
			int rc = pthread_create( &task_threads[i], &attr, thread_function, parameters );

	8) And in my thread / background function:

		static void *thread_function( void *parameters )

	9) I simply evaluate the individual:

		parameters->individual->evaluate();

	10) Then when all of the threads are complete (joined), I pull out the best genome from the population (just so I can display the progress so far):
		GARealGenome *best_genome = (GARealGenome*)&p.individual(0);
		double best_score = best_genome->score();
		for ( int i = 1; i < p.size(); i++ )
		        GARealGenome* genome = (GARealGenome*)&p.individual(i);
			if ( genome->score() > best_score )
				best_genome_index = i;
			        best_genome = genome;
			        best_score = genome->score();

	11) All of the other magic happens in the outer functionality (e.g. ga->step(), ga->statistics().bestIndividual(), etc.)


::Glenn Sugden


* NEW: For optimization purposes (I assume) the population alternates back and forth between the "old" population and the "new" population. This causes galib to clobber the evaluator
(**as well as userData for the members of the population!). The clone forces the generation of the "other" population so that the evaluator (and userData) are swapped correctly.

*** You may want to queue up your threads, and run n-cores at a time, if you have a large population size.



More information about the galib mailing list