Example #1
0
/* i would prefer that the thread initialization code happen in MPIMain(), but
 * it needs Population pop, which is declared here */
int MasterMaster(MasterGamlConfig& conf, HKYData& data)	{
	Parameters params;
	params.SetParams(conf, data);
	LogParams(params);

	int nprocs;
	MPI_Comm_size(MPI_COMM_WORLD, &nprocs);

	bool poo=true;
//	while(poo);
		
	Tree::alpha = params.gammaShapeBrlen;
	Tree::meanBrlenMuts = params.meanBrlenMuts;

	Population pop;
//	debug_mpi("about to setup");
	pop.Setup(params, &conf, nprocs, 0);
	g_sw=&pop.stopwatch;
//	debug_mpi("setup");
	g_gen = &pop.gen;

	pop.CalcAverageFitness();

	// start the thread
	pthread_t thread;
	thread_arg_t targ;
	pthread_mutex_init(&lock_pm, NULL);
	pthread_mutex_init(&lock_pop, NULL);
	pthread_cond_init(&cond_pm, NULL);
	g_quit_time = false;
	g_processing_message = false;
	targ.conf = &const_cast<MasterGamlConfig&>(conf);
	targ.pop = &pop;
	targ.nprocs = nprocs;
	
	pthread_create(&thread, NULL, thread_func2, (void*)&targ);
	
	cout << "Master running..." << endl;

	pop.gen=0;
	while (!g_quit_time){
		pthread_mutex_lock(&lock_pop);
			pop.keepTrack();
			pop.OutputFate();
			if (pop.gen % conf.logevery == 0) pop.OutputLog();
			++pop.gen;
			pop.NextGeneration();
			if(pop.gen % pop.params->saveEvery == 0) pop.CreateTreeFile( pop.params->treefname );
			if(pop.gen % pop.adap->intervalLength == 0){
				if(pop.enforceTermConditions == true
					&& pop.gen-pop.lastTopoImprove > pop.lastTopoImproveThresh 
					&& pop.adap->improveOverStoredIntervals < pop.improveOverStoredIntervalsThresh
					&& pop.adap->branchOptPrecision == pop.adap->minOptPrecision){
			//		&& pop.paraMan->updateThresh == pop.paraMan->minUpdateThresh){
					cout << "Reached termination condition!\nlast topological improvement at gen " << pop.lastTopoImprove << endl;
					cout << "Improvement over last " << pop.adap->intervalsToStore*pop.adap->intervalLength << " gen = " << pop.adap->improveOverStoredIntervals << endl;
					g_quit_time=true;
					break;
					}
				pop.CheckSubtrees();
				//6-20-05 Changing this to deterministically reduce the replace thresh
				//every subtreeInterval generations.  Tying the reduction of this to 
				//how often the master recieved new bests from the remotes had odd properties,
				//and didn't scale well with differing numbers of processors.
				//and it's not clear what a better automated approach would be
				//pop.CheckRemoteReplaceThresh();
				if(pop.gen % pop.paraMan->subtreeInterval == 0) pop.paraMan->ReduceUpdateThresh();
#ifdef INCLUDE_PERTURBATION
				pop.CheckPerturbParallel();
#endif
				}
		pthread_mutex_unlock(&lock_pop);
		pthread_mutex_lock(&lock_pm);
			while (g_processing_message)
				pthread_cond_wait(&cond_pm, &lock_pm);
		pthread_mutex_unlock(&lock_pm);
		}
	pop.FinalOptimization();
	pthread_join(thread, NULL);
	return 0;
}
Example #2
0
int RemoteSubtreeWorker(Population& pop, const GeneralGamlConfig& conf){
	int *which, size, rank, tag;
	char *tree_strings, *buf;
	double score, *models;
	bool perturb;
	
	which=new int[5];
	
	MPI_Comm_rank(MPI_COMM_WORLD, &rank);
		
	pop.CalcAverageFitness();

	int lastSend=g_sw->SplitTime();	

	cout << "Remote number " << rank << " running..." << endl;

	for (pop.gen = 1; pop.gen < conf.stopgen;){

		pop.keepTrack();
		pop.OutputFate();
		if (pop.gen % conf.logevery == 0)
			pop.OutputLog();
		++pop.gen;
		pop.NextGeneration();

		if(g_sw->SplitTime() - lastSend > conf.sendInterval){
			debug_mpi("SYNCH COMM (node 0)");
			//send our best individual to the master
			RemoteSendBestTree(pop);		
			lastSend=g_sw->SplitTime();
			if(pop.params->stoptime - g_sw->SplitTime() < 0){
				debug_mpi("time limit of %d seconds reached...", pop.params->stoptime);
				break;
				}
			}
		//Check for a new tree from the master
		bool firstmessage=true;
		bool gotmessage=false;
		int subtreeNode;
		while(RecvMPIMessage(&tree_strings, &size, 0, &tag, false)==true){
			//check for a quit message
			if(tag == TAG_QUIT) {
				debug_mpi("\trecv: quit message");
				delete [] which;
				debug_mpi("quitting");
				return 0;	
				}
			//
			bool gotNewIndiv=false;
			int recievedDefNumber;
			debug_mpi("SYNCH COMM (node 0)");
			gotmessage=true;
			assert(tag == TAG_TREE_STRINGS || tag==TAG_PERTURB);
			if(firstmessage==false) debug_mpi("\tfound a newer message...");
			if(tag != TAG_PERTURB){
				gotNewIndiv=true;
				RecvMPIMessage(&buf, &size, 0, &tag, true);
				assert(tag == TAG_MODEL);
				models=(double*) buf;
			
				debug_mpi("\tgot new ind" );
				RecvMPIMessage(&buf, &size, 0, &tag, true);
		
	//		if(tag != TAG_PERTURB){
				perturb=false;
				assert(tag == TAG_SUBTREE_DEFINE);
				subtreeNode=atoi(buf);
				if(subtreeNode!=0){
					delete []buf;
					RecvMPIMessage(&buf, &size, 0, &tag, true);
					assert(tag == TAG_SUBTREE_ITERATION);
					recievedDefNumber=atoi(buf);
					debug_mpi("\tworking on subtree def %d, node %d", recievedDefNumber, subtreeNode);
					}
				else recievedDefNumber=0;
				}
			else{
				pop.pertMan->pertType=atoi(tree_strings);
				perturb=true;
				}	
			
			//if the current best and the new tree are either both accurate for the same subtree def or both
			//inaccurate for subtrees, just replace the worst individual, rather than the
			// whole pop, that way if the tree is old and worse that what the remote
			// already has it won't matter
			if(gotNewIndiv){
				*which=(int)pop.cumfit[0][0];
				debug_mpi("\treplacing indiv %d", *which);
				pop.ReplaceSpecifiedIndividuals(1, which, tree_strings, models);
				if(recievedDefNumber!=pop.subtreeDefNumber || (pop.subtreeNode!=0 && subtreeNode!=0)){
					pop.AssignSubtree(subtreeNode, *which);
					pop.CalcAverageFitness();
					debug_mpi("\tfilling pop with clones of %d", *which);
					pop.SetNewBestIndiv(*which);
					pop.FillPopWithClonesOfBest();
					pop.subtreeDefNumber=recievedDefNumber;
					}

				delete [] models;
				delete [] buf;
				}
#ifdef INCLUDE_PERTURBATION
			if(perturb==true){
				pop.CalcAverageFitness();
				if(pop.pertMan->pertType==1){
					debug_mpi("peforming NNI perturbation...");
					int toReplace=(pop.bestIndiv == 0 ? 1 : 0);
					pop.AppendTreeToTreeLog(-1, pop.bestIndiv);
					pop.NNIPerturbation(pop.bestIndiv, toReplace);
					pop.SetNewBestIndiv(toReplace);
					pop.FillPopWithClonesOfBest();
					pop.AppendTreeToTreeLog(-1, pop.bestIndiv);
					}
				else if(pop.pertMan->pertType==2){
					debug_mpi("peforming SPR perturbation...");
					int toReplace=(pop.bestIndiv == 0 ? 1 : 0);
					pop.AppendTreeToTreeLog(-1, pop.bestIndiv);
					pop.SPRPerturbation(pop.bestIndiv, toReplace);
					pop.SetNewBestIndiv(toReplace);
					pop.FillPopWithClonesOfBest();
					pop.AppendTreeToTreeLog(-1, pop.bestIndiv);
					}
				else assert(0);
				}				
#endif

			delete [] tree_strings;
			tag=0;
			firstmessage=false;
			}
		if(gotmessage==true){
//			if(pop.subtreeNode != subtreeNode) pop.AssignSubtree(subtreeNode);
			pop.CalcAverageFitness();
			debug_mpi("\tbest score= %f", pop.indiv[*which].Fitness());
			//DEBUG
			//pop.AppendTreeToTreeLog(rank, -1, *which);
			}
		}

	SendMPIMessage(NULL, 0, 0, TAG_QUIT);
	debug_mpi("\tsent: quit message");
	delete [] which;
	debug_mpi("quitting");
	return 0;
	}