Example #1
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;
	}