int NonBlockingReceiveMessage(message* m, msg_type in_type) { int stat = pvm_nrecv(-1, in_type); if( stat ) { pvm_upkbyte((char*)m, sizeof(message), 1); } return stat; }
value Pvm_nrecv(value tid,value msgtag) { int res = pvm_nrecv(Int_val(tid),Int_val(msgtag)); if (res<0) TreatError(res); return(Val_int(res)); }
int nreceive_msg(int who, int what) { int r_bufid; PVM_FUNC(r_bufid, pvm_nrecv(who, what)); return(r_bufid); }
/*--------------------------------------------------------------------------- ** MBUSPING -- Ping the specified tid to see if it is still alive. ** A timeout given in milliseconds may be specified before declaring ** a process dead. */ int mbusPing (int tid, int timeout) { int len = 0, info, bufid; pvm_initsend (PvmDataDefault); pvm_pkint (&len, 1, 1); if (MB_DEBUG) fprintf (stderr, "mbPing: tid=%d timout=%d\n", tid, timeout); if ((info = pvm_send (tid, MB_PING)) < 0) { switch (info) { case PvmBadParam: fprintf (stderr, "Ping to %d fails, bad tid\n", tid); return (ERR); case PvmSysErr: fprintf (stderr, "Ping to %d fails, pvmd not responding\n", tid); return (ERR); case PvmNoBuf: fprintf (stderr, "Ping to %d fails, no active buffer\n", tid); return (ERR); } } /* Wait .... */ usleep ((unsigned int)timeout * 1000); /* Now get the ACK. A negative timeout means block until we get a reply. */ bufid = ((timeout < 0) ? pvm_recv (tid,MB_PING) : pvm_nrecv (tid,MB_PING)); return ( (bufid <= 0) ? ERR : OK ); }
// This population evaluator is the administrator for the parallelization. // It looks around to see when slaves are available to evaluate a genome. As // soon as a slave is available and a genome needs to be evaluated, this // routine sends it off. When a slave is finished, it posts a message to // say so and this routine gets the message and grabs the results from the // slave that posted the message. // An index of -1 means that the slave has no assignment. The first int in // the stream of stuff is always the ID of the slave (0-nslaves) that is // sending the information. After that it is either nothing (the slave just // reported that it is ready for another genome) or it is a float (the score // of the genome that was assigned to the slave). void PopulationEvaluator(GAPopulation& pop) { PVMDataPtr data = (PVMDataPtr)pop.userData(); int* index = new int [data->nreq]; int done = 0, outstanding = 0, next = 0; int bufid, status, bytes, msgtag, tid, who; while(!done) { // If we have a genome that needs to be evaluated and one of the slaves is // ready to evaluate it, send the genome to the slave. if(next < pop.size() && (bufid=pvm_nrecv(-1, MSG_READY)) != 0) { if(bufid > 0) { pvm_bufinfo(bufid, &bytes, &msgtag, &tid); status = SendGenomeData(pop.individual(next), tid); if(status >= 0) { if((who = id2idx(tid, *data)) >= 0) { index[who] = next; next++; outstanding++; } else { cerr << "PopEval: bogus tid mapping: " << tid << "\n"; } } else { cerr << "PopEval: error sending data to: " << tid; cerr << " error code is: " << status << "\n"; } } else { cerr << "PopEval: error from pvm_nrecv: " << bufid << "\n"; } } // If we have any genomes waiting for their evaluation and any slaves have // posted a message stating that they have a finished score ready for us, get // the score from the slave and stuff it into the appropriate genome. if(outstanding > 0 && (bufid=pvm_nrecv(-1, MSG_GENOME_SCORE)) != 0) { if(bufid > 0) { pvm_bufinfo(bufid, &bytes, &msgtag, &tid); if((who = id2idx(tid, *data)) >= 0) { if(index[who] >= 0) { status = RecvGenomeScore(pop.individual(index[who])); if(status >= 0) { index[who] = -1; outstanding--; } else { cerr << "PopEval: error receiving score from: " << tid; cerr << " error code is: " << status << "\n"; } } else { cerr << "PopEval: index conflict from tid " << tid << "\n"; } } else { cerr << "PopEval: bogus tid mapping: " << tid << "\n"; } } else { cerr << "PopEval: error from pvm_nrecv: " << bufid << "\n"; } } if(next == pop.size() && outstanding == 0) done = 1; if(next > pop.size()) { cerr << "bogus value for next: " << next; cerr << " popsize is: " << pop.size() << "\n"; } } delete [] index; }
// The population initializer invokes the genomes' initializers just like the // standard population initializer, but here we farm out the genomes to the // slaves before invoking the initialization. Farm out the genomes and give // the slaves the initialize command rather than the evaluate command. void PopulationInitializer(GAPopulation& pop) { PVMDataPtr data = (PVMDataPtr)pop.userData(); int* index = new int [data->nreq]; int done = 0, outstanding = 0, next = 0; int bufid, status, bytes, msgtag, tid, who; while(!done) { // If we have a genome that needs to be initialized and one of the slaves is // available, then ask the slave to configure a genome and send us back the // configured, initialized genome. if(next < pop.size() && (bufid=pvm_nrecv(-1, MSG_READY)) != 0) { if(bufid > 0) { status = pvm_bufinfo(bufid, &bytes, &msgtag, &tid); status = SendGenomeInitialize(pop.individual(next), tid); if(status >= 0) { if((who = id2idx(tid, *data)) >= 0) { index[who] = next; next++; outstanding++; } else { cerr << "PopInit: bogus tid mapping: " << tid << "\n"; } } else { cerr << "PopInit: error sending initialize command to: " << tid; cerr << " genome " << next << " will be inited by next slave\n"; cerr << " error code is: " << status << "\n"; } } else { cerr << "PopInit: error from pvm_nrecv: " << bufid << "\n"; } } // If we have requests for initialization outstanding and a slave has posted // a message stating that it will provide genome data, then get the data from // the slave and stuff it into the appropriate genome in the population. if(outstanding > 0 && (bufid=pvm_nrecv(-1, MSG_GENOME_DATA)) != 0) { if(bufid > 0) { status = pvm_bufinfo(bufid, &bytes, &msgtag, &tid); if((who = id2idx(tid, *data)) >= 0) { if(index[who] >= 0) { status = RecvGenomeData(pop.individual(index[who])); if(status >= 0) { index[who] = -1; outstanding--; } else { cerr << "PopInit: error receiving data from: " << tid; cerr << " error code is: " << status << "\n"; } } else { cerr << "PopInit: index conflict from tid " << tid << "\n"; } } else { cerr << "PopInit: bogus tid mapping: " << tid << "\n"; } } else { cerr << "PopInit: error from pvm_nrecv: " << bufid << "\n"; } } if(next == pop.size() && outstanding == 0) done = 1; if(next > pop.size()) { cerr << "bogus value for next: " << next; cerr << " popsize is: " << pop.size() << "\n"; } } delete [] index; }