25 #include <boost/date_time/posix_time/posix_time.hpp>
26 #include <boost/scoped_ptr.hpp>
27 #include <boost/shared_ptr.hpp>
28 #include <boost/thread/condition_variable.hpp>
29 #include <boost/thread/thread.hpp>
30 #include <boost/thread/locks.hpp>
31 #include <boost/thread/mutex.hpp>
37 #include "algorithm/base.h"
38 #include "base_island.h"
39 #include "exceptions.h"
40 #include "mpi_environment.h"
41 #include "mpi_island.h"
42 #include "migration/base_r_policy.h"
43 #include "migration/base_s_policy.h"
44 #include "population.h"
45 #include "problem/base.h"
50 boost::mutex mpi_island::m_proc_mutex;
51 boost::condition_variable mpi_island::m_proc_cond;
52 boost::mutex mpi_island::m_mpi_mutex;
53 std::list<mpi_island const *> mpi_island::m_queue;
54 boost::scoped_ptr<std::set<int> > mpi_island::m_available_processors;
97 const boost::shared_ptr<population> pop_copy(
new population(pop));
100 const int processor = acquire_processor();
105 boost::lock_guard<boost::mutex> lock(m_mpi_mutex);
108 bool successful =
false;
109 boost::shared_ptr<population> in;
116 boost::lock_guard<boost::mutex> lock(m_mpi_mutex);
122 boost::this_thread::sleep(boost::posix_time::milliseconds(10));
126 }
catch (
const boost::archive::archive_exception &e) {
127 std::cout <<
"MPI Recv Error during island evolution using " << algo.
get_name() <<
": " << e.what() << std::endl;
129 std::cout <<
"MPI Recv Error during island evolution using " << algo.
get_name() <<
", unknown exception caught. :(" << std::endl;
131 release_processor(processor);
148 void mpi_island::init_processors()
151 pagmo_assert(!m_proc_mutex.try_lock());
152 if (!m_available_processors) {
153 m_available_processors.reset(
new std::set<int>());
157 m_available_processors->insert(i);
162 int mpi_island::acquire_processor()
const
165 boost::unique_lock<boost::mutex> lock(m_proc_mutex);
167 if (m_available_processors->empty() || !m_queue.empty()) {
169 m_queue.push_back(
this);
170 while (*m_queue.begin() !=
this || m_available_processors->empty()) {
171 m_proc_cond.wait(lock);
177 pagmo_assert(!m_available_processors->empty());
178 const int retval = *m_available_processors->begin();
179 m_available_processors->erase(m_available_processors->begin());
183 void mpi_island::release_processor(
int n)
const
186 boost::lock_guard<boost::mutex> lock(m_proc_mutex);
189 pagmo_throw(std::runtime_error,
"invalid processor id: the value is either non-positive or exceeding the size of the MPI world");
191 if (m_available_processors->find(n) != m_available_processors->end()) {
192 pagmo_throw(std::runtime_error,
"trying to release a processor which was never acquired");
195 m_available_processors->insert(n);
197 m_proc_cond.notify_all();
boost::shared_ptr< base > base_ptr
Alias for shared pointer to base algorithm.
static bool is_multithread()
Thread-safety of the MPI implementation.
static void recv(T &retval, int source)
Receive MPI payload.
void perform_evolution(const algorithm::base &, population &) const
Method that implements the evolution of the population.
Base class for migration replacement policies.
Base class for migration selection policies.
mpi_island & operator=(const mpi_island &)
Assignment operator.
static bool iprobe(int)
Probe for message.
mpi_island(const mpi_island &)
Copy constructor.
static int get_size()
MPI world size.
virtual base_ptr clone() const =0
Clone method.
base_island & operator=(const base_island &)
Assignment operator.
virtual std::string get_name() const
Get algorithm's name.
std::string get_name() const
Return a string identifying the island's type.
boost::shared_ptr< base_island > base_island_ptr
Alias for the shared pointer to a pagmo::base_island.
base_island_ptr clone() const
Clone method.
static void send(const T &payload, int destination)
Send MPI payload.