void DoMasterAMR(char *buf, int size, int who, int tag, thread_arg_t *targ) { MasterGamlConfig *conf = targ->conf; Population *pop = targ->pop; int count, start_shield, which; char *tree_strings, *model_buf; double *models, score; assert(tag == TAG_SCORE); memcpy(&score, buf, sizeof(double)); //delete [] buf; // print some messages debug_mpi("SYNCHRONOUS COMM (%d, AMR, %f)", who, pop->bestFitness); debug_mpi("\trecv: score %f", score); if (score > pop->bestFitness) { SendMPIMessage(NULL, 0, who, TAG_TREE_STRINGS_REQUEST); debug_mpi("\tsent: TAG_TREE_STRINGS_REQUEST"); RecvMPIMessage(&buf, &size, who, &tag, true); assert(tag == TAG_TREE_STRINGS); tree_strings = buf; debug_mpi("\trecv: %d tree strings", CountTreeStrings(tree_strings)); RecvMPIMessage(&buf, &size, who, &tag, true); assert(tag == TAG_MODEL); models=(double*)buf; which = pop->total_size-1; pop->ReplaceSpecifiedIndividuals(1, &which, tree_strings, models); pop->CalcAverageFitness(); debug_mpi("score sent: %f, score calced: %f", score, pop->IndivFitness(which)); //assert(abs(score - pop->IndivFitness(which))<.00001); } else { which = (int)pop->cumfit[pop->total_size-1][0]; pop->GetSpecifiedTreeStrings(&tree_strings, 1, &which); int model_size=pop->GetSpecifiedModels(&models, 1, &which); SendMPIMessage(tree_strings, strlen2(tree_strings)+2, who, TAG_TREE_STRINGS); debug_mpi("\tsent: %d tree strings", CountTreeStrings(tree_strings)); model_buf = (char*)models; SendMPIMessage(model_buf, sizeof(double)*model_size, who, TAG_MODEL); debug_mpi("\tsent: %d models", 1); } delete [] tree_strings; delete [] models; }
void RemoteSendBestTree(Population& pop){ int *which=new int; char *tree_strings; double *models; pop.GetNBestIndivIndices(&which, 1); pop.GetSpecifiedTreeStrings(&tree_strings, 1, which); int size=strlen2(tree_strings)+2; // debug_mpi("about to send treestrings..."); SendMPIMessage(tree_strings, size, 0, TAG_TREE_STRINGS); debug_mpi("\tsent ind %d, lnL %f", *which, pop.indiv[*which].Fitness()); // debug_mpi("about to send modelstrings..."); int model_size=pop.GetSpecifiedModels(&models, 1, which); SendMPIMessage((char*) models, sizeof(double)*model_size, 0, TAG_MODEL); // debug_mpi("about to send subdef..."); char std[5]; sprintf(std, "%d", pop.subtreeDefNumber); SendMPIMessage(std, strlen(std)+2, 0, TAG_SUBTREE_ITERATION); if(pop.subtreeDefNumber!=0){ char stn[10]; sprintf(stn, "%d", pop.subtreeNode); SendMPIMessage(stn, strlen(stn)+2, 0, TAG_SUBTREE_DEFINE); debug_mpi("\tvalid for subtree def %d, node %d", pop.subtreeDefNumber, pop.subtreeNode); } else debug_mpi("\tno defined subtree"); //finally, send the score double score = pop.indiv[*which].Fitness(); SendMPIMessage((char*)&score, sizeof(double), 0, TAG_SCORE); delete which; delete [] tree_strings; delete [] models; }
int DoMasterSW(char *buf, int size, int who, int tag, thread_arg_t *targ) { MasterGamlConfig *conf = targ->conf; Population *pop = targ->pop; int count, start_shield, *which = new int;//[conf->gc.numshields]; char *tree_strings, *model_buf; char *out_tree_strings; char *defbuf, *subbuf; double *out_models; double *models; int remoteSubtreeDef, remoteSubtreeNode; ParallelManager *paraMan=(pop->paraMan); //first get the tree and model from the remote and include it in //the master population. If there are multiple messages, chuck //earlier ones and just get the most recent bool firstmessage=true; do{ debug_mpi("Remote %d", who); assert(tag == TAG_TREE_STRINGS || tag == TAG_QUIT); if(tag==TAG_QUIT) return 1; tree_strings = buf; count = CountTreeStrings(tree_strings); // debug_mpi("about to get model strings..."); RecvMPIMessage(&buf, &size, who, &tag, true); assert(tag == TAG_MODEL); models=(double*)buf; // debug_mpi("about to get subdef strings..."); //determine what the remote was doing when it sent this tree RecvMPIMessage(&defbuf, &size, who, &tag, true); assert(tag==TAG_SUBTREE_ITERATION); remoteSubtreeDef=atoi(defbuf); if(remoteSubtreeDef>0){ RecvMPIMessage(&subbuf, &size, who, &tag, true); assert(tag==TAG_SUBTREE_DEFINE); remoteSubtreeNode=atoi(subbuf); if(remoteSubtreeDef==paraMan->subtreeDefNumber) paraMan->localSubtreeAssign[who]=remoteSubtreeNode; else paraMan->localSubtreeAssign[who]=0; delete []subbuf; } //DJZ 5-18-05 else { paraMan->localSubtreeAssign[who]=0; remoteSubtreeNode=0; } double score; char *scoreBuf; RecvMPIMessage(&scoreBuf, &size, who, &tag, true); assert(tag==TAG_SCORE); memcpy(&score, scoreBuf, sizeof(double)); // debug_mpi("recieved score of %f", score); delete []scoreBuf; if(firstmessage==false) debug_mpi("\tfound another tree from remote %d", who); *which = start_shield = pop->params->nindivs + (who-1); pop->ReplaceSpecifiedIndividuals(count, which, tree_strings, models); pop->indiv[*which].SetFitness(score); if(firstmessage==false) delete []tree_strings; delete [](char*)models; delete []defbuf; firstmessage=false; }while(RecvMPIMessage(&buf, &size, who, &tag, false)==true); bool subtreesCurrent = ((remoteSubtreeDef == paraMan->subtreeDefNumber) && remoteSubtreeDef > 0); if(paraMan->subtreeModeActive==false || subtreesCurrent==false){ pop->indiv[*which].accurateSubtrees=false; pop->newindiv[*which].accurateSubtrees=false; } else { pop->indiv[*which].accurateSubtrees=true; pop->newindiv[*which].accurateSubtrees=true; } // debug_mpi("about to CalcFitness..."); double prevBestScore=pop->BestFitness(); // pop->indiv[*which].CalcFitness(0); pop->indiv[*which].treeStruct->calcs=calcCount; pop->CalcAverageFitness(); //reclaim clas if the new tree has essentially no chance of reproducing if(((pop->indiv[*which].Fitness() - pop->indiv[pop->bestIndiv].Fitness()) < (-11.5/pop->params->selectionIntensity))){ // debug_mpi("about to reclaim..."); pop->indiv[*which].treeStruct->ReclaimUniqueClas(); } //Now, take a look at what we got from the remote and decide what to do double inscore=pop->indiv[*which].Fitness(); double scorediff=prevBestScore - inscore; debug_mpi("\tnew ind - def %d - node %d - lnL: %f", remoteSubtreeDef, remoteSubtreeNode, inscore); if(scorediff < 0) debug_mpi("\tPrev Best=%f, diff=%f (new best)", prevBestScore, scorediff); else debug_mpi("\tPrev Best=%f, diff=%f", prevBestScore, scorediff); // debug_mpi("\tbest=%d, bestAc=%d, bestlnL=%f, bestAcclnL=%f", pop->bestIndiv, pop->bestAccurateIndiv, pop->BestFitness(), pop->indiv[pop->bestAccurateIndiv].Fitness()); bool recalcSubtrees=false; if(scorediff < -0.01){ pop->LogNewBestFromRemote(-scorediff, *which); } int subtreeNum; bool send=false; //there are really 8 possible cases here //1. Subtree mode active, got accurate tree, score good -> do nothing //2. score bad -> send best accurate tree //3. inaccurate tree, score good -> recalc subtrees, send? //4. score bad -> send best accurate tree //5. Subtree mode inactive, got accurate tree, score good -> send best tree //6. score bad -> send best tree //7. inaccurate tree, score good -> do nothing //8. score bad -> send best tree //so, 2 "do nothings" 3 "send best", 2 "send best accurate" and 1 "subtree recalc" //if subtree mode isn't active, send the remote our best tree if the //tree we got from it is worse by some amount, or if it is still working //on a subtree double updateThresh=paraMan->updateThresh; //DEBUG // if(paraMan->subtreeModeActive==false && (paraMan->needToSend[who]==true || ((scorediff > nonSubThresh && paraMan->beforeFirstSubtree==false) || (scorediff > startThresh && paraMan->beforeFirstSubtree==true) || remoteSubtreeDef>0))){ if(paraMan->subtreeModeActive==false){ if((paraMan->perturbModeActive==false && (scorediff > updateThresh || remoteSubtreeDef>0))/* || (paraMan->needToSend[who]==true)*/){ debug_mpi("\tupdate thresh = %f, send indiv", updateThresh); //cases 5, 6 and 8 *which = (int)pop->cumfit[pop->total_size-1][0]; subtreeNum=0; send=true; } else debug_mpi("\tupdate thresh = %f", updateThresh); } else if(paraMan->subtreeModeActive==true){ //cases 1-4 if((scorediff > updateThresh) || (subtreesCurrent==false)/* || paraMan->perturb==true*/){ //cases 2 and 4. send the best accurate tree *which=pop->bestAccurateIndiv; if(paraMan->remoteSubtreeAssign[who] != 0) subtreeNum=paraMan->remoteSubtreeAssign[who]; else subtreeNum=paraMan->ChooseSubtree(); debug_mpi("\tsend best accurate ind, %f (best=%f)", pop->indiv[*which].Fitness(), pop->bestFitness); // debug_mpi("\tperturb=%d, bestFit=%f, indFit=%f", paraMan->perturb, pop->bestFitness, pop->indiv[*which].Fitness()); send=true; } else if(recalcSubtrees==true && subtreesCurrent==false){ //case 3 //if the new inaccurate tree that came in is better than what we have, //recalcuate the subtrees, and send the same tree back, but with a //subtree asignment pop->StartSubtreeMode(); debug_mpi("Recalculating subtrees"); subtreeNum=paraMan->ChooseSubtree(); send=true; } } if(paraMan->needToSend[who]){ char pertbuf[5]; int perttype = (pop->pertMan->pertType > 0 ? pop->pertMan->pertType : (int)(rnd.uniform() * 2 + 1)); sprintf(pertbuf, "%d", perttype); SendMPIMessage(pertbuf, strlen(pertbuf)+2, who, TAG_PERTURB); debug_mpi("sending pertub message to %d, type %d", who, perttype); paraMan->needToSend[who]=false; } if(send==true){ pop->GetSpecifiedTreeStrings(&out_tree_strings, 1, which); assert(*out_tree_strings == '('); int model_size=pop->GetSpecifiedModels(&out_models, 1, which); SendMPIMessage(out_tree_strings, strlen2(out_tree_strings)+2, who, TAG_TREE_STRINGS); SendMPIMessage((char*)out_models, sizeof(double)*model_size, who, TAG_MODEL); /* if(paraMan->needToSend[who]){ char pertbuf[5]; int perttype = (pop->pertMan->pertType > 0 ? pop->pertMan->pertType : (rnd.uniform() * 2 + 1)); sprintf(pertbuf, "%d", subtreeNum); SendMPIMessage(NULL, 0, who, TAG_PERTURB); debug_mpi("sending pertub message to %d, type %d", who, perttype); paraMan->needToSend[who]=false; } */ // else{ char stn[5]; sprintf(stn, "%d", subtreeNum); SendMPIMessage(stn, strlen(stn)+2, who, TAG_SUBTREE_DEFINE); debug_mpi("\tsent ind %d, lnL %f", *which, pop->indiv[*which].Fitness()); if(subtreeNum > 0){ //if this node was already assigned a subtree, be sure to subtract the old one from the assigned array sprintf(stn, "%d", paraMan->subtreeDefNumber); debug_mpi("\tsubdef %d, node %d", paraMan->subtreeDefNumber, subtreeNum); SendMPIMessage(stn, strlen(stn)+2, who, TAG_SUBTREE_ITERATION); } // } paraMan->remoteSubtreeAssign[who]=subtreeNum; delete []out_models; delete []out_tree_strings; } #ifndef NDEBUG if(paraMan->subtreeModeActive && paraMan->subtreeDefNumber==remoteSubtreeDef){ //DEBUG //if we think that this remote gave us a tree with accurate subtrees, check paraMan->CheckSubtreeAccuracy(pop->indiv[which[0]].treeStruct); } #endif //the tree_strings that were passed in will be deleted back //where the initial call to RecvMPIMessage was made delete [] which; pop->CalcAverageFitness(); return 0; }