1 /*
2  *  cWorld.h
3  *  Avida
4  *
5  *  Copyright 1999-2009 Michigan State University. All rights reserved.
6  *
7  *
8  *  This file is part of Avida.
9  *
10  *  Avida is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License
11  *  as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
12  *
13  *  Avida is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
14  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more details.
15  *
16  *  You should have received a copy of the GNU Lesser General Public License along with Avida.
17  *  If not, see <http://www.gnu.org/licenses/>.
18  *
19  */
20 
21 #ifndef cMultiProcessWorld_h
22 #define cMultiProcessWorld_h
23 
24 /* THIS HEADER REQUIRES BOOST */
25 #include <boost/mpi.hpp>
26 #include <boost/mpi/environment.hpp>
27 #include <boost/mpi/communicator.hpp>
28 #include <boost/timer.hpp>
29 #include <vector>
30 
31 #include "cWorld.h"
32 #include "cAvidaConfig.h"
33 #include "cStats.h"
34 
35 /*! Multi-process Avida world.
36 
37  This class enables multi-process Avida, which provides a mechanism for much larger
38  populations than are possible on a single machine.  This is made possible through
39  a single new technique, that of "cross-world migration," where an individual organism
40  is transferred to a different Avida world and injected into a random location in that
41  world's population.
42  */
43 class cMultiProcessWorld : public cWorld
44 	{
45 	private:
46 		cMultiProcessWorld(); // @not_implemented
47 		cMultiProcessWorld(const cMultiProcessWorld&); // @not_implemented
48 		cMultiProcessWorld& operator=(const cMultiProcessWorld&); // @not_implemented
49 
50 	protected:
51 		boost::mpi::environment& m_mpi_env; //!< MPI environment.
52 		boost::mpi::communicator& m_mpi_world; //!< World-wide MPI communicator.
53 		std::vector<boost::mpi::request> m_reqs; //!< Requests outstanding since the last ProcessPostUpdate.
54 		int m_universe_dim; //!< Dimension (x & y) of the universe (number of worlds along the side of a grid of worlds).
55 		int m_universe_x; //!< X coordinate of this world.
56 		int m_universe_y; //!< Y coordinate of this world.
57 		int m_universe_popsize; //!< Total size of the universe, delayed one update.
58 
59 		boost::timer m_update_timer; //!< Tracks the clock-time of updates.
60 		boost::timer m_post_update_timer; //!< Tracks the clock-time of post-update processing.
61 		boost::timer m_calc_update_timer; //!< Tracks the clock-time of calculating the update size.
62 		cStats::profiling_stats_t m_pf; //!< Buffers profiling stats until the post-update step.
63 
64 		//! Constructor (prefer Initialize).
65 		cMultiProcessWorld(cAvidaConfig* cfg, const cString& cwd, boost::mpi::environment& env, boost::mpi::communicator& worldcomm);
66 
67 	public:
68 		//! Create and initialize a cMultiProcessWorld.
69 		static cMultiProcessWorld* Initialize(cAvidaConfig* cfg, const cString& cwd, boost::mpi::environment& env, boost::mpi::communicator& worldcomm);
70 
71 		//! Destructor.
~cMultiProcessWorld()72 		virtual ~cMultiProcessWorld() { }
73 
74 		//! Migrate this organism to a different world.
75 		virtual void MigrateOrganism(cOrganism* org, const cPopulationCell& cell,
76 																 const cMerit& merit, int lineage);
77 
78 		//! Returns true if an organism should be migrated to a different world, false otherwise.
79 		virtual bool TestForMigration();
80 
81 		//! Returns true if the given cell is on the boundary of the world, false otherwise.
82 		virtual bool IsWorldBoundary(const cPopulationCell& cell);
83 
84 		//! Process post-update events.
85 		virtual void ProcessPostUpdate(cAvidaContext& ctx);
86 
87 		//! Returns true if this world allows early exits, e.g., when the population reaches 0.
88 		virtual bool AllowsEarlyExit() const;
89 
90 		//! Calculate the size (in virtual CPU cycles) of the current update.
91 		virtual int CalculateUpdateSize();
92 	};
93 
94 #endif
95