MCPcopy Create free account
hub / github.com/devosoft/avida / ProcessPostUpdate

Method ProcessPostUpdate

avida-core/source/main/cMultiProcessWorld.cc:274–356  ·  view source on GitHub ↗

! Process post-update events. This method is called after each update of the local population completes. Here we check to see if this world has received any migrants from other worlds, and if so, we inject them into the local population. Note that this is an unconditional injection -- that is, migrants are "pushed" to this world. Migrants are injected according to BIRTH_METHOD. \todo

Source from the content-addressed store, hash-verified

272 second mode that relaxes consistency in favor of speed.
273 */
274void cMultiProcessWorld::ProcessPostUpdate(cAvidaContext& ctx) {
275 namespace mpi = boost::mpi;
276 using namespace boost;
277
278 // restart the timer for this method, and get the elapsed time for the past update:
279 m_pf[UPDATE] = m_update_timer.elapsed();
280 m_post_update_timer.restart();
281
282 // wait until we're sure that this process has sent all its messages:
283 mpi::wait_all(m_reqs.begin(), m_reqs.end());
284 m_reqs.clear();
285
286 // at this point, we know that *this* process has sent everything. but, we don't
287 // know if it's *received* everything. so, we're going to put in a synchronization
288 // barrier, which means that every process must reach the barrier before any are allowed
289 // to proceed. since we just finished waiting for all communication to complete,
290 // this means that all messages must have been received, too.
291 m_mpi_world.barrier();
292
293 // now, receive all the messages, but store them in order by source and tag:
294 typedef std::map<int,migration_message> rx_tag_t;
295 typedef std::map<int,rx_tag_t> rx_src_t;
296 rx_src_t recvd;
297 optional<mpi::status> s = m_mpi_world.iprobe(mpi::any_source,mpi::any_tag);
298 while(s.is_initialized()) {
299 migration_message msg;
300 m_mpi_world.recv(s->source(), s->tag(), msg);
301 recvd[s->source()][s->tag()] = msg;
302 // any others?
303 s = m_mpi_world.iprobe(mpi::any_source,mpi::any_tag);
304 }
305
306 // iterate over received messages in-order, injecting genomes into our population:
307 for(rx_src_t::iterator i=recvd.begin(); i!=recvd.end(); ++i) {
308 for(rx_tag_t::iterator j=i->second.begin(); j!=i->second.end(); ++j) {
309 //std::cerr << "********** INJECTING *********** " << i->first << " " << j->first << std::endl;
310 // ok, add this migrant to the current population
311 migration_message& migrant = j->second;
312 int target_cell=-1;
313
314 switch(GetConfig().BIRTH_METHOD.Get()) {
315 case POSITION_OFFSPRING_RANDOM: { // spatial
316 // invert the orginating cell
317 migrant._x = GetConfig().WORLD_X.Get() - migrant._x - 1;
318 migrant._y = GetConfig().WORLD_Y.Get() - migrant._y - 1;
319 target_cell = GetConfig().WORLD_Y.Get() * migrant._y + migrant._x;
320 break;
321 }
322 case POSITION_OFFSPRING_FULL_SOUP_RANDOM: { // mass action
323 target_cell = GetRandom().GetInt(GetPopulation().GetSize());
324 break;
325 }
326 default: {
327 GetDriver().RaiseFatalException(-1, "Avida-MP only supports BIRTH_METHODS 0 (POSITION_OFFSPRING_RANDOM) and 4 (POSITION_OFFSPRING_FULL_SOUP_RANDOM).");
328 }
329 }
330
331 GetPopulation().InjectGenome(target_cell,

Callers

nothing calls this directly

Calls 12

GetIntMethod · 0.80
InjectGenomeMethod · 0.80
unpackMethod · 0.80
IncomingMigrantMethod · 0.80
ProfilingDataMethod · 0.80
GenomeClass · 0.70
cStringClass · 0.70
GetMethod · 0.45
GetSizeMethod · 0.45
RaiseFatalExceptionMethod · 0.45
GetOrganismMethod · 0.45
GetCellMethod · 0.45

Tested by

no test coverage detected