git-svn-id: svn://scm.gforge.inria.fr/svnroot/paradiseo@810 331e1502-861f-0410-8da2-ba01fb791d7f

This commit is contained in:
atantar 2007-11-23 16:41:23 +00:00
commit 7526792805
49 changed files with 449 additions and 420 deletions

View file

@ -46,6 +46,7 @@ static std :: map <const Communicable *, unsigned> comm_to_key; /* Map of regist
unsigned Communicable :: num_comm = 0; unsigned Communicable :: num_comm = 0;
Communicable :: Communicable () { Communicable :: Communicable () {
comm_to_key [this] = key = ++ num_comm; comm_to_key [this] = key = ++ num_comm;
@ -70,7 +71,7 @@ Communicable * getCommunicable (COMM_ID __key) {
} }
COMM_ID getKey (const Communicable * __comm) { COMM_ID getKey (const Communicable * __comm) {
return comm_to_key [__comm]; return comm_to_key [__comm];
} }

View file

@ -47,10 +47,10 @@ class Communicable {
public : public :
Communicable (); Communicable ();
virtual ~ Communicable (); virtual ~ Communicable ();
COMM_ID getKey (); COMM_ID getKey ();
void lock (); /* It suspends the current process if the semaphore is locked */ void lock (); /* It suspends the current process if the semaphore is locked */
void unlock (); /* It unlocks the shared semaphore */ void unlock (); /* It unlocks the shared semaphore */
@ -67,7 +67,7 @@ protected :
COMM_ID key; COMM_ID key;
sem_t sem_lock; sem_t sem_lock;
sem_t sem_stop; sem_t sem_stop;
}; };
@ -75,6 +75,4 @@ extern void initCommunicableEnv ();
extern Communicable * getCommunicable (COMM_ID __key); extern Communicable * getCommunicable (COMM_ID __key);
//extern COMM_ID getKey (const Communicable * __comm);
#endif #endif

View file

@ -51,7 +51,7 @@ public :
void setOwner (Runner & __runner); void setOwner (Runner & __runner);
virtual void pack () = 0; virtual void pack () = 0;
virtual void unpack () = 0; virtual void unpack () = 0;
void send (Cooperative * __coop); void send (Cooperative * __coop);

View file

@ -44,7 +44,14 @@
template <class F, class T> void pack (const eoVector <F, T> & __v) { template <class F, class T> void pack (const eoVector <F, T> & __v) {
pack (__v.fitness ()) ; if (__v.invalid()) {
pack((unsigned)0);
}
else {
pack((unsigned)1);
pack (__v.fitness ());
}
unsigned len = __v.size (); unsigned len = __v.size ();
pack (len); pack (len);
for (unsigned i = 0 ; i < len; i ++) for (unsigned i = 0 ; i < len; i ++)
@ -53,9 +60,16 @@ template <class F, class T> void pack (const eoVector <F, T> & __v) {
template <class F, class T> void unpack (eoVector <F, T> & __v) { template <class F, class T> void unpack (eoVector <F, T> & __v) {
F fit; unsigned valid; unpack(valid);
unpack (fit);
__v.fitness (fit); if (! valid) {
__v.invalidate();
}
else {
F fit;
unpack (fit);
__v.fitness (fit);
}
unsigned len; unsigned len;
unpack (len); unpack (len);

View file

@ -71,13 +71,13 @@ extern void pack (const char * __str);
/* Pointer */ /* Pointer */
template <class T> void pack (const T * __ptr) { template <class T> void pack (const T * __ptr) {
pack ((unsigned long) __ptr); pack ((unsigned long) __ptr);
} }
/* Pair */ /* Pair */
template <class U, class V> void pack (const std :: pair <U, V> & __pair) { template <class U, class V> void pack (const std :: pair <U, V> & __pair) {
pack (__pair.first); pack (__pair.first);
pack (__pair.second); pack (__pair.second);
} }
@ -116,7 +116,7 @@ extern void unpack (char * __str);
/* Pointer */ /* Pointer */
template <class T> void unpack (T * & __ptr) { template <class T> void unpack (T * & __ptr) {
unsigned long p; unsigned long p;
unpack (p); unpack (p);
__ptr = (T *) p; __ptr = (T *) p;
@ -124,10 +124,9 @@ template <class T> void unpack (T * & __ptr) {
/* Pair */ /* Pair */
template <class U, class V> void unpack (std :: pair <U, V> & __pair) { template <class U, class V> void unpack (std :: pair <U, V> & __pair) {
unpack (__pair.first); unpack (__pair.first);
unpack (__pair.second); unpack (__pair.second);
} }
#endif #endif

View file

@ -50,12 +50,14 @@
#define DEBUG_PATH "./log/" #define DEBUG_PATH "./log/"
static bool debug = true; static bool debug = true;
static char host [MAX_BUFF_SIZE]; static char host [MAX_BUFF_SIZE];
std :: vector <FILE *> files; std :: vector <FILE *> files;
void setDebugMode (bool __dbg) { void setDebugMode (bool __dbg) {
debug = __dbg; debug = __dbg;
@ -65,7 +67,7 @@ void setDebugMode (bool __dbg) {
extern int getNodeRank (); extern int getNodeRank ();
void initDebugging () { void initDebugging () {
mkdir (DEBUG_PATH, S_IRWXU); mkdir (DEBUG_PATH, S_IRWXU);
// files.push_back (stdout); // files.push_back (stdout);
char buff [MAX_BUFF_SIZE]; char buff [MAX_BUFF_SIZE];

View file

@ -44,7 +44,6 @@ void peo :: finalize () {
printDebugMessage ("waiting for the termination of all threads"); printDebugMessage ("waiting for the termination of all threads");
joinRunners (); joinRunners ();
finalizeRMC (); finalizeRMC ();
printDebugMessage ("this is the end"); printDebugMessage ("this is the end");

View file

@ -38,11 +38,14 @@
#include "peo_init.h" #include "peo_init.h"
#include "peo_param.h" #include "peo_param.h"
#include "peo_debug.h" #include "peo_debug.h"
#include "rmc.h" #include "rmc.h"
#include "runner.h"
extern void initCommunicableEnv (); extern void initCommunicableEnv ();
extern void initBuffers ();
extern void initThreadsEnv (); extern void initThreadsEnv ();
extern void initReactiveThreadsEnv (); extern void initReactiveThreadsEnv ();
@ -50,10 +53,14 @@ extern void initReactiveThreadsEnv ();
extern void initRunnersEnv (); extern void initRunnersEnv ();
extern void initWorkersEnv (); extern void initWorkersEnv ();
extern void initScheduler ();
static void initExecutionEnv() { static void initExecutionEnv() {
initCommunicableEnv (); initCommunicableEnv ();
initBuffers ();
initScheduler();
initThreadsEnv (); initThreadsEnv ();
initReactiveThreadsEnv (); initReactiveThreadsEnv ();
@ -62,27 +69,28 @@ static void initExecutionEnv() {
initWorkersEnv (); initWorkersEnv ();
} }
namespace peo { namespace peo {
int * argc; int * argc;
char * * * argv; char * * * argv;
void init (int & __argc, char * * & __argv) { void init (int & __argc, char * * & __argv) {
argc = & __argc; argc = & __argc;
argv = & __argv; argv = & __argv;
/* Initializing the execution environment */ /* Initializing the execution environment */
initExecutionEnv(); initExecutionEnv();
/* Initializing the the Resource Management and Communication */
initRMC (__argc, __argv);
/* Loading the common parameters */ /* Loading the common parameters */
loadParameters (__argc, __argv); loadParameters (__argc, __argv);
/* Initializing the the Resource Management and Communication */
initRMC ( *peo::argc, *peo::argv);
/* */ /* */
initDebugging (); initDebugging ();
} }

View file

@ -40,9 +40,9 @@
namespace peo { namespace peo {
extern int * argc; extern int * argc;
extern char * * * argv; extern char * * * argv;
extern void init (int & __argc, char * * & __argv); extern void init (int & __argc, char * * & __argv);
} }

View file

@ -40,7 +40,6 @@
#include "peo_debug.h" #include "peo_debug.h"
void peo :: loadParameters (int & __argc, char * * & __argv) { void peo :: loadParameters (int & __argc, char * * & __argv) {
eoParser parser (__argc, __argv); eoParser parser (__argc, __argv);

View file

@ -38,7 +38,7 @@
#define __peo_param_h #define __peo_param_h
namespace peo { namespace peo {
extern void loadParameters (int & __argc, char * * & __argv); extern void loadParameters (int & __argc, char * * & __argv);
} }

View file

@ -34,11 +34,11 @@
* *
*/ */
#include "peo_init.h"
#include "peo_run.h" #include "peo_run.h"
#include "rmc.h" #include "rmc.h"
#include "runner.h" #include "runner.h"
void peo :: run () { void peo :: run () {
startRunners (); startRunners ();

View file

@ -38,7 +38,7 @@
#define __peo_run_h #define __peo_run_h
namespace peo { namespace peo {
extern void run (); extern void run ();
} }

View file

@ -40,6 +40,7 @@ static bool the_end = false;
static std :: vector <ReactiveThread *> reac_threads; static std :: vector <ReactiveThread *> reac_threads;
ReactiveThread :: ReactiveThread () { ReactiveThread :: ReactiveThread () {
reac_threads.push_back (this); reac_threads.push_back (this);

View file

@ -43,14 +43,14 @@
class ReactiveThread : public Thread { class ReactiveThread : public Thread {
public: public:
/* Ctor */ /* Ctor */
ReactiveThread (); ReactiveThread ();
void sleep (); void sleep ();
void wakeUp (); void wakeUp ();
private: private:
@ -62,6 +62,4 @@ extern void initReactiveThreadsEnv ();
extern void stopReactiveThreads (); extern void stopReactiveThreads ();
extern bool theEnd ();
#endif /*REAC_THREAD_H_*/ #endif /*REAC_THREAD_H_*/

View file

@ -43,7 +43,7 @@ void RingTopology :: setNeighbors (Cooperative * __mig,
__to.clear () ; __to.clear () ;
int len = mig.size () ; int len = mig.size () ;
for (int i = 0 ; i < len ; i ++) for (int i = 0 ; i < len ; i ++)
if (mig [i] == __mig) { if (mig [i] == __mig) {
__from.push_back (mig [(i - 1 + len) % len]) ; __from.push_back (mig [(i - 1 + len) % len]) ;

View file

@ -40,9 +40,9 @@
#include "topology.h" #include "topology.h"
class RingTopology : public Topology { class RingTopology : public Topology {
public : public :
void setNeighbors (Cooperative * __mig, void setNeighbors (Cooperative * __mig,
std :: vector <Cooperative *> & __from, std :: vector <Cooperative *> & __from,
std :: vector <Cooperative *> & __to); std :: vector <Cooperative *> & __to);

View file

@ -95,50 +95,19 @@ Runner * getRunner (RUNNER_ID __key) {
return dynamic_cast <Runner *> (getCommunicable (__key)); return dynamic_cast <Runner *> (getCommunicable (__key));
} }
void packExecutionContext () {
num_local_exec_runners = 0;
for (unsigned i = 0; i < the_runners.size (); i ++)
if (the_runners [i] -> isAssignedLocally ()) num_local_exec_runners ++;
pack(num_local_exec_runners);
}
void unpackExecutionContext () {
unsigned num_remote_runners;
unpack(num_remote_runners);
num_exec_runners += num_remote_runners;
}
void initializeContext () { void initializeContext () {
initMessage (); num_local_exec_runners = 0;
packExecutionContext ();
sendMessageToAll (EXECUTION_CONTEXT_TAG);
int src, tag; // setting up the execution IDs & counting the number of local exec. runners
for (unsigned i = 0; i < getNumberOfNodes(); i ++) { for (unsigned i = 0; i < the_runners.size (); i ++) {
the_runners [i] -> setExecutionID ( my_node -> execution_id_run[ i ] );
cleanBuffers (); if (the_runners [i] -> isAssignedLocally ()) num_local_exec_runners ++;
waitMessage ();
probeMessage ( src, tag );
receiveMessage( src, tag );
initMessage ();
unpackExecutionContext ();
} }
cleanBuffers (); collectiveCountOfRunners( &num_local_exec_runners, &num_exec_runners );
// setting up the execution IDs // synchronizeNodes ();
for (unsigned i = 0; i < the_runners.size (); i ++)
the_runners [i] -> setExecutionID ( my_node -> execution_id_run[ i ] );
// synchronizing - all the nodes have to finish initializing
// the context before actually executing the runners
synchronizeNodes ();
for (unsigned i = 0; i < the_runners.size (); i ++) for (unsigned i = 0; i < the_runners.size (); i ++)
if (the_runners [i] -> isAssignedLocally ()) the_runners [i] -> notifyContextInitialized (); if (the_runners [i] -> isAssignedLocally ()) the_runners [i] -> notifyContextInitialized ();
@ -217,6 +186,7 @@ void unpackTerminationOfRunner () {
printDebugMessage ("All the runners have terminated - now stopping the reactive threads."); printDebugMessage ("All the runners have terminated - now stopping the reactive threads.");
stopReactiveThreads (); stopReactiveThreads ();
printDebugMessage ("Reactive threads stopped!");
} }
} }

View file

@ -40,7 +40,7 @@ void Service :: setOwner (Thread & __owner) {
owner = & __owner; owner = & __owner;
} }
Thread * Service :: getOwner () { Thread * Service :: getOwner () {
return owner; return owner;

View file

@ -48,7 +48,7 @@ class Service : public Communicable {
public : public :
void setOwner (Thread & __owner); void setOwner (Thread & __owner);
Thread * getOwner (); Thread * getOwner ();
void requestResourceRequest (unsigned __how_many = 1); void requestResourceRequest (unsigned __how_many = 1);
@ -58,7 +58,7 @@ public :
virtual void unpackData (); virtual void unpackData ();
virtual void execute (); virtual void execute ();
virtual void packResult (); virtual void packResult ();
virtual void unpackResult (); virtual void unpackResult ();

View file

@ -42,8 +42,9 @@ static std :: vector <Thread *> threads;
unsigned num_act = 0; unsigned num_act = 0;
Thread :: Thread () { Thread :: Thread () {
threads.push_back (this); threads.push_back (this);
act = false; act = false;
} }
@ -53,8 +54,6 @@ Thread :: ~ Thread () {
/* Nothing ! */ /* Nothing ! */
} }
extern int getNodeRank ();
void Thread :: setActive () { void Thread :: setActive () {
if (! act) { if (! act) {
@ -70,7 +69,7 @@ void Thread :: setPassive () {
act = false; act = false;
num_act --; num_act --;
} }
} }
void initThreadsEnv () { void initThreadsEnv () {

View file

@ -42,7 +42,7 @@
/* A high-level thread */ /* A high-level thread */
class Thread { class Thread {
public: public:
/* Ctor */ /* Ctor */
@ -50,7 +50,7 @@ public:
/* Dtor */ /* Dtor */
virtual ~ Thread (); virtual ~ Thread ();
/* Go ! */ /* Go ! */
virtual void start () = 0; virtual void start () = 0;
@ -59,7 +59,7 @@ public:
(but it may receive messages) */ (but it may receive messages) */
private : private :
bool act; bool act;
}; };

View file

@ -37,12 +37,11 @@
#include "topology.h" #include "topology.h"
Topology :: ~ Topology () { Topology :: ~ Topology () {
/* Nothing ! */ /* Nothing ! */
} }
void Topology :: add (Cooperative & __mig) { void Topology :: add (Cooperative & __mig) {
mig.push_back (& __mig) ;
}
mig.push_back (& __mig) ;
}

View file

@ -80,48 +80,48 @@
//! <tr><td>... &nbsp;</td> <td> &nbsp; </td></tr> //! <tr><td>... &nbsp;</td> <td> &nbsp; </td></tr>
//! </table> //! </table>
template < class EOT > class peoEA : public Runner template < class EOT > class peoEA : public Runner
{ {
public: public:
//! Constructor for the evolutionary algorithm object - several basic parameters have to be specified, //! Constructor for the evolutionary algorithm object - several basic parameters have to be specified,
//! allowing for different levels of parallelism. Depending on the requirements, a sequential or a parallel //! allowing for different levels of parallelism. Depending on the requirements, a sequential or a parallel
//! evaluation operator may be specified or, in the same manner, a sequential or a parallel transformation //! evaluation operator may be specified or, in the same manner, a sequential or a parallel transformation
//! operator may be given as parameter. Out of the box objects may be provided, from the EO package, for example, //! operator may be given as parameter. Out of the box objects may be provided, from the EO package, for example,
//! or custom defined ones may be specified, provided that they are derived from the correct base classes. //! or custom defined ones may be specified, provided that they are derived from the correct base classes.
//! //!
//! @param eoContinue< EOT >& __cont - continuation criterion specifying whether the algorithm should continue or not; //! @param eoContinue< EOT >& __cont - continuation criterion specifying whether the algorithm should continue or not;
//! @param peoPopEval< EOT >& __pop_eval - evaluation operator; it allows the specification of parallel evaluation operators, aggregate evaluation functions, etc.; //! @param peoPopEval< EOT >& __pop_eval - evaluation operator; it allows the specification of parallel evaluation operators, aggregate evaluation functions, etc.;
//! @param eoSelect< EOT >& __select - selection strategy to be applied for constructing a list of offspring individuals; //! @param eoSelect< EOT >& __select - selection strategy to be applied for constructing a list of offspring individuals;
//! @param peoTransform< EOT >& __trans - transformation operator, i.e. crossover and mutation; allows for sequential or parallel transform; //! @param peoTransform< EOT >& __trans - transformation operator, i.e. crossover and mutation; allows for sequential or parallel transform;
//! @param eoReplacement< EOT >& __replace - replacement strategy for integrating the offspring individuals in the initial population; //! @param eoReplacement< EOT >& __replace - replacement strategy for integrating the offspring individuals in the initial population;
peoEA( peoEA(
eoContinue< EOT >& __cont, eoContinue< EOT >& __cont,
peoPopEval< EOT >& __pop_eval, peoPopEval< EOT >& __pop_eval,
eoSelect< EOT >& __select, eoSelect< EOT >& __select,
peoTransform< EOT >& __trans, peoTransform< EOT >& __trans,
eoReplacement< EOT >& __replace eoReplacement< EOT >& __replace
); );
//! Evolutionary algorithm function - a side effect of the fact that the class is derived from the <b>Runner</b> class, //! Evolutionary algorithm function - a side effect of the fact that the class is derived from the <b>Runner</b> class,
//! thus requiring the existence of a <i>run</i> function, the algorithm being executed on a distinct thread. //! thus requiring the existence of a <i>run</i> function, the algorithm being executed on a distinct thread.
void run(); void run();
//! Function operator for specifying the population to be associated with the algorithm. //! Function operator for specifying the population to be associated with the algorithm.
//! //!
//! @param eoPop< EOT >& __pop - initial population of the algorithm, to be iteratively evolved; //! @param eoPop< EOT >& __pop - initial population of the algorithm, to be iteratively evolved;
void operator()( eoPop< EOT >& __pop ); void operator()( eoPop< EOT >& __pop );
private:
eoContinue< EOT >& cont; private:
peoPopEval< EOT >& pop_eval;
eoSelect< EOT >& select; eoContinue< EOT >& cont;
peoTransform< EOT >& trans; peoPopEval< EOT >& pop_eval;
eoReplacement< EOT >& replace; eoSelect< EOT >& select;
eoPop< EOT >* pop; peoTransform< EOT >& trans;
}; eoReplacement< EOT >& replace;
eoPop< EOT >* pop;
};
template < class EOT > peoEA< EOT > :: peoEA( template < class EOT > peoEA< EOT > :: peoEA(
@ -150,30 +150,29 @@ template< class EOT > void peoEA< EOT > :: operator ()( eoPop< EOT >& __pop )
template< class EOT > void peoEA< EOT > :: run() template< class EOT > void peoEA< EOT > :: run()
{ {
printDebugMessage( "performing the first evaluation of the population." ); printDebugMessage( "peoEA: performing the first evaluation of the population." );
pop_eval( *pop ); pop_eval( *pop );
do do
{ {
eoPop< EOT > off; eoPop< EOT > off;
printDebugMessage( "performing the selection step." ); printDebugMessage( "peoEA: performing the selection step." );
select( *pop, off ); select( *pop, off );
trans( off ); trans( off );
printDebugMessage( "performing the evaluation of the population." ); printDebugMessage( "peoEA: performing the evaluation of the population." );
pop_eval( off ); pop_eval( off );
printDebugMessage( "performing the replacement of the population." ); printDebugMessage( "peoEA: performing the replacement of the population." );
replace( *pop, off ); replace( *pop, off );
printDebugMessage( "deciding of the continuation." ); printDebugMessage( "peoEA: deciding of the continuation." );
} }
while ( cont( *pop ) ); while ( cont( *pop ) );
} }
#endif #endif

View file

@ -43,20 +43,20 @@ template< class EOT, class FitT = EOT::Fitness, class FunctionArg = const EOT& >
template< class EOT, class FitT = typename EOT::Fitness, class FunctionArg = const EOT& > template< class EOT, class FitT = typename EOT::Fitness, class FunctionArg = const EOT& >
#endif #endif
struct peoEvalFunc: public eoEvalFunc<EOT> struct peoEvalFunc: public eoEvalFunc<EOT>
{
peoEvalFunc( FitT (* _eval)( FunctionArg ) )
: eoEvalFunc<EOT>(), evalFunc( _eval )
{};
virtual void operator() ( EOT & _peo )
{ {
_peo.fitness((*evalFunc)( _peo ));
peoEvalFunc( FitT (* _eval)( FunctionArg ) ) };
: eoEvalFunc<EOT>(), evalFunc( _eval )
{};
virtual void operator() ( EOT & _peo )
{
_peo.fitness((*evalFunc)( _peo ));
};
private: private:
FitT (* evalFunc )( FunctionArg ); FitT (* evalFunc )( FunctionArg );
}; };
#endif #endif

View file

@ -45,13 +45,13 @@
//! The class is provided as a mean of declaring that no aggregation is required for the evaluation function - the fitness //! The class is provided as a mean of declaring that no aggregation is required for the evaluation function - the fitness
//! value is explicitly specified. //! value is explicitly specified.
template< class EOT > class peoNoAggEvalFunc : public peoAggEvalFunc< EOT > template< class EOT > class peoNoAggEvalFunc : public peoAggEvalFunc< EOT >
{ {
public : public :
//! Operator which sets as fitness the <b>__fit</b> value for the <b>__sol</b> individual //! Operator which sets as fitness the <b>__fit</b> value for the <b>__sol</b> individual
void operator()( EOT& __sol, const typename EOT :: Fitness& __fit ); void operator()( EOT& __sol, const typename EOT :: Fitness& __fit );
}; };
template< class EOT > void peoNoAggEvalFunc< EOT > :: operator()( EOT& __sol, const typename EOT :: Fitness& __fit ) template< class EOT > void peoNoAggEvalFunc< EOT > :: operator()( EOT& __sol, const typename EOT :: Fitness& __fit )

View file

@ -47,54 +47,54 @@ extern int getNodeRank();
template< class EOT > class peoParaSGATransform : public peoTransform< EOT > template< class EOT > class peoParaSGATransform : public peoTransform< EOT >
{ {
public: public:
using peoTransform< EOT > :: requestResourceRequest; using peoTransform< EOT > :: requestResourceRequest;
using peoTransform< EOT > :: resume; using peoTransform< EOT > :: resume;
using peoTransform< EOT > :: stop; using peoTransform< EOT > :: stop;
using peoTransform< EOT > :: getOwner; using peoTransform< EOT > :: getOwner;
peoParaSGATransform( peoParaSGATransform(
eoQuadOp< EOT >& __cross, eoQuadOp< EOT >& __cross,
double __cross_rate, double __cross_rate,
eoMonOp< EOT >& __mut, eoMonOp< EOT >& __mut,
double __mut_rate double __mut_rate
); );
void operator()( eoPop< EOT >& __pop ); void operator()( eoPop< EOT >& __pop );
void packData(); void packData();
void unpackData(); void unpackData();
void execute(); void execute();
void packResult(); void packResult();
void unpackResult(); void unpackResult();
void notifySendingData(); void notifySendingData();
void notifySendingAllResourceRequests(); void notifySendingAllResourceRequests();
private: private:
eoQuadOp< EOT >& cross; eoQuadOp< EOT >& cross;
double cross_rate; double cross_rate;
eoMonOp< EOT >& mut; eoMonOp< EOT >& mut;
double mut_rate; double mut_rate;
unsigned idx; unsigned idx;
eoPop< EOT >* pop; eoPop< EOT >* pop;
EOT father, mother; EOT father, mother;
unsigned num_term; unsigned num_term;
}; };
template< class EOT > peoParaSGATransform< EOT > :: peoParaSGATransform( template< class EOT > peoParaSGATransform< EOT > :: peoParaSGATransform(
@ -156,18 +156,18 @@ template< class EOT > void peoParaSGATransform< EOT > :: unpackResult()
// Can be used with an odd size // Can be used with an odd size
if ( num_term == 2*(pop->size()/2) ) if ( num_term == 2*(pop->size()/2) )
{ {
getOwner()->setActive(); getOwner()->setActive();
resume(); resume();
} }
} }
template< class EOT > void peoParaSGATransform< EOT > :: operator()( eoPop < EOT >& __pop ) template< class EOT > void peoParaSGATransform< EOT > :: operator()( eoPop < EOT >& __pop )
{ {
printDebugMessage( "performing the parallel transformation step." ); printDebugMessage( "peoParaSGATransform: performing the parallel transformation step." );
pop = &__pop; pop = &__pop;
idx = 0; idx = 0;
num_term = 0; num_term = 0;

View file

@ -67,7 +67,7 @@ class peoParallelAlgorithmWrapper : public Runner
~peoParallelAlgorithmWrapper() ~peoParallelAlgorithmWrapper()
{ {
delete algorithm; delete algorithm;
} }
@ -76,12 +76,12 @@ class peoParallelAlgorithmWrapper : public Runner
algorithm->operator()(); algorithm->operator()();
} }
private: private:
struct AbstractAlgorithm struct AbstractAlgorithm
{ {
// virtual destructor as we will be using inheritance and polymorphism // virtual destructor as we will be using inheritance and polymorphism
virtual ~AbstractAlgorithm() virtual ~AbstractAlgorithm()
{ } { }
@ -90,7 +90,7 @@ class peoParallelAlgorithmWrapper : public Runner
virtual void operator()() virtual void operator()()
{ } { }
}; };
template< typename AlgorithmType, typename AlgorithmDataType > struct Algorithm : public AbstractAlgorithm template< typename AlgorithmType, typename AlgorithmDataType > struct Algorithm : public AbstractAlgorithm
{ {
@ -117,7 +117,7 @@ class peoParallelAlgorithmWrapper : public Runner
{ {
algorithm(); algorithm();
} }
AlgorithmType& algorithm; AlgorithmType& algorithm;
}; };
@ -127,7 +127,7 @@ class peoParallelAlgorithmWrapper : public Runner
FunctionAlgorithm( AlgorithmReturnType (*externalAlgorithm)( AlgorithmDataType& ), AlgorithmDataType& externalData ) FunctionAlgorithm( AlgorithmReturnType (*externalAlgorithm)( AlgorithmDataType& ), AlgorithmDataType& externalData )
: algorithm( externalAlgorithm ), algorithmData( externalData ) : algorithm( externalAlgorithm ), algorithmData( externalData )
{} {}
virtual void operator()() virtual void operator()()
{ {
algorithm( algorithmData ); algorithm( algorithmData );
@ -136,22 +136,22 @@ class peoParallelAlgorithmWrapper : public Runner
AlgorithmReturnType (*algorithm)( AlgorithmDataType& ); AlgorithmReturnType (*algorithm)( AlgorithmDataType& );
AlgorithmDataType& algorithmData; AlgorithmDataType& algorithmData;
}; };
template< typename AlgorithmReturnType > struct FunctionAlgorithm< AlgorithmReturnType, void > : public AbstractAlgorithm template< typename AlgorithmReturnType > struct FunctionAlgorithm< AlgorithmReturnType, void > : public AbstractAlgorithm
{ {
FunctionAlgorithm( AlgorithmReturnType (*externalAlgorithm)() ) FunctionAlgorithm( AlgorithmReturnType (*externalAlgorithm)() )
: algorithm( externalAlgorithm ) : algorithm( externalAlgorithm )
{} {}
virtual void operator()() virtual void operator()()
{ {
algorithm(); algorithm();
} }
AlgorithmReturnType (*algorithm)(); AlgorithmReturnType (*algorithm)();
}; };
private: private:
AbstractAlgorithm* algorithm; AbstractAlgorithm* algorithm;

View file

@ -45,13 +45,12 @@
//! The derived classes may be used as wrappers for <b>EO</b>-derived evaluation functors. In order to have an example, //! The derived classes may be used as wrappers for <b>EO</b>-derived evaluation functors. In order to have an example,
//! please refer to the implementation of the <b>peoSeqPopEval</b> and <b>peoParaPopEval</b> classes. //! please refer to the implementation of the <b>peoSeqPopEval</b> and <b>peoParaPopEval</b> classes.
template< class EOT > class peoPopEval : public Service template< class EOT > class peoPopEval : public Service
{ {
public: public:
//! Interface function providing the signature for constructing an evaluation functor.
virtual void operator()( eoPop< EOT >& __pop ) = 0;
};
//! Interface function providing the signature for constructing an evaluation functor.
virtual void operator()( eoPop< EOT >& __pop ) = 0;
};
#endif #endif

View file

@ -144,68 +144,68 @@
//! the associated distinctly parametrized migration objects. The interconnecting element is the underlying topology, defined at step 1 //! the associated distinctly parametrized migration objects. The interconnecting element is the underlying topology, defined at step 1
//! (the same C++ migTopology object has to be passed as parameter for all the migration objects, in order to interconnect them). //! (the same C++ migTopology object has to be passed as parameter for all the migration objects, in order to interconnect them).
template< class EOT > class peoSyncIslandMig : public Cooperative, public eoUpdater template< class EOT > class peoSyncIslandMig : public Cooperative, public eoUpdater
{ {
public: public:
//! Constructor for the peoSyncIslandMig class; the characteristics of the migration model are defined //! Constructor for the peoSyncIslandMig class; the characteristics of the migration model are defined
//! through the specified parameters - out of the box objects provided in EO, etc., or custom, derived objects may be passed as parameters. //! through the specified parameters - out of the box objects provided in EO, etc., or custom, derived objects may be passed as parameters.
//! //!
//! @param unsigned __frequency - frequency of the migrations - the migrations occur periodically; //! @param unsigned __frequency - frequency of the migrations - the migrations occur periodically;
//! @param eoSelect< EOT >& __select - selection strategy to be applied for constructing a list of emigrant individuals out of the source population; //! @param eoSelect< EOT >& __select - selection strategy to be applied for constructing a list of emigrant individuals out of the source population;
//! @param eoReplacement< EOT >& __replace - replacement strategy used for integrating the immigrant individuals in the destination population; //! @param eoReplacement< EOT >& __replace - replacement strategy used for integrating the immigrant individuals in the destination population;
//! @param Topology& __topology - topological model to be followed when performing migrations; //! @param Topology& __topology - topological model to be followed when performing migrations;
//! @param eoPop< EOT >& __source - source population from which the emigrant individuals are selected; //! @param eoPop< EOT >& __source - source population from which the emigrant individuals are selected;
//! @param eoPop< EOT >& __destination - destination population in which the immigrant population are integrated. //! @param eoPop< EOT >& __destination - destination population in which the immigrant population are integrated.
peoSyncIslandMig( peoSyncIslandMig(
unsigned __frequency, unsigned __frequency,
eoSelect< EOT >& __select, eoSelect< EOT >& __select,
eoReplacement< EOT >& __replace, eoReplacement< EOT >& __replace,
Topology& __topology, Topology& __topology,
eoPop< EOT >& __source, eoPop< EOT >& __source,
eoPop< EOT >& __destination eoPop< EOT >& __destination
); );
//! Function operator to be called as checkpoint for performing the migration step. The emigrant individuals are selected //! Function operator to be called as checkpoint for performing the migration step. The emigrant individuals are selected
//! from the source population and sent to the next island (defined by the topology object) while the immigrant //! from the source population and sent to the next island (defined by the topology object) while the immigrant
//! individuals are integrated in the destination population. There is no need to explicitly call the function - the //! individuals are integrated in the destination population. There is no need to explicitly call the function - the
//! wrapper checkpoint object (please refer to the above example) will perform the call when required. //! wrapper checkpoint object (please refer to the above example) will perform the call when required.
void operator()(); void operator()();
//! Auxiliary function dealing with sending the emigrant individuals. There is no need to explicitly call the function. //! Auxiliary function dealing with sending the emigrant individuals. There is no need to explicitly call the function.
void pack(); void pack();
//! Auxiliary function dealing with receiving immigrant individuals. There is no need to explicitly call the function. //! Auxiliary function dealing with receiving immigrant individuals. There is no need to explicitly call the function.
void unpack(); void unpack();
//! Auxiliary function dealing with migration notifications. There is no need to explicitly call the function. //! Auxiliary function dealing with migration notifications. There is no need to explicitly call the function.
void notifySending(); void notifySending();
private: private:
void emigrate(); void emigrate();
void immigrate(); void immigrate();
private: private:
eoPeriodicContinue< EOT > cont; eoPeriodicContinue< EOT > cont;
eoSelect< EOT >& select; // selection strategy eoSelect< EOT >& select; // selection strategy
eoReplacement< EOT >& replace; // replacement strategy eoReplacement< EOT >& replace; // replacement strategy
Topology& topology; // neighboring topology Topology& topology; // neighboring topology
// source and target populations // source and target populations
eoPop< EOT >& source; eoPop< EOT >& source;
eoPop< EOT >& destination; eoPop< EOT >& destination;
// immigrants & emigrants in the queue // immigrants & emigrants in the queue
std :: queue< eoPop< EOT > > imm; std :: queue< eoPop< EOT > > imm;
std :: queue< eoPop< EOT > > em; std :: queue< eoPop< EOT > > em;
std :: queue< Cooperative* > coop_em; std :: queue< Cooperative* > coop_em;
sem_t sync; sem_t sync;
}; };
template< class EOT > peoSyncIslandMig< EOT > :: peoSyncIslandMig( template< class EOT > peoSyncIslandMig< EOT > :: peoSyncIslandMig(
@ -261,15 +261,15 @@ template< class EOT > void peoSyncIslandMig< EOT > :: emigrate()
topology.setNeighbors( this, in, out ); topology.setNeighbors( this, in, out );
for ( unsigned i = 0; i < out.size(); i ++ ) for ( unsigned i = 0; i < out.size(); i ++ )
{ {
eoPop< EOT > mig; eoPop< EOT > mig;
select( source, mig ); select( source, mig );
em.push( mig ); em.push( mig );
coop_em.push( out[ i ] ); coop_em.push( out[ i ] );
send( out[ i ] ); send( out[ i ] );
printDebugMessage( "sending some emigrants." ); printDebugMessage( "peoSyncIslandMig: sending some emigrants." );
} }
} }
@ -282,7 +282,7 @@ template< class EOT > void peoSyncIslandMig< EOT > :: immigrate()
assert( imm.size() ); assert( imm.size() );
replace( destination, imm.front() ) ; replace( destination, imm.front() ) ;
imm.pop(); imm.pop();
printDebugMessage( "receiving some immigrants." ); printDebugMessage( "peoSyncIslandMig: receiving some immigrants." );
} }
unlock(); unlock();
} }
@ -292,19 +292,19 @@ template< class EOT > void peoSyncIslandMig< EOT > :: operator()()
{ {
if ( !cont( source ) ) if ( !cont( source ) )
{ {
// sending emigrants // sending emigrants
emigrate(); emigrate();
stop(); stop();
// synchronizing // synchronizing
sem_wait( &sync ); sem_wait( &sync );
getOwner()->setActive(); getOwner()->setActive();
// receiving immigrants // receiving immigrants
immigrate(); immigrate();
} }
} }
@ -315,13 +315,13 @@ template< class EOT > void peoSyncIslandMig< EOT > :: notifySending()
{ {
if ( imm.empty() ) if ( imm.empty() )
{ {
printDebugMessage( "entering pasive mode\n" ); printDebugMessage( "peoSyncIslandMig: entering pasive mode\n" );
getOwner()->setPassive(); getOwner()->setPassive();
} }
} }
unlock(); unlock();
resume(); resume();
} }

View file

@ -62,74 +62,74 @@ extern int getNodeRank();
//! thus allowing for simple hybridization schemes which combine the evolutionary approach with a local search approach, //! thus allowing for simple hybridization schemes which combine the evolutionary approach with a local search approach,
//! for example, executed at the end of each generation. //! for example, executed at the end of each generation.
template< class EOT > class peoSyncMultiStart : public Service, public eoUpdater template< class EOT > class peoSyncMultiStart : public Service, public eoUpdater
{ {
public: public:
//! Constructor function - several simple parameters are required for defining the characteristics of the multi-start model. //! Constructor function - several simple parameters are required for defining the characteristics of the multi-start model.
//! //!
//! @param eoContinue< EOT >& __cont - defined for including further functionality - no semantics associated at this time; //! @param eoContinue< EOT >& __cont - defined for including further functionality - no semantics associated at this time;
//! @param eoSelect< EOT >& __select - selection strategy for obtaining a subset of the initial population on which to apply the specified algorithm; //! @param eoSelect< EOT >& __select - selection strategy for obtaining a subset of the initial population on which to apply the specified algorithm;
//! @param eoReplacement< EOT >& __replace - replacement strategy for integrating the resulting individuals in the initial population; //! @param eoReplacement< EOT >& __replace - replacement strategy for integrating the resulting individuals in the initial population;
//! @param moAlgo< EOT >& __ls - algorithm to be applied on each of the selected individuals - a <b>moAlgo< EOT ></b>-derived object must be specified; //! @param moAlgo< EOT >& __ls - algorithm to be applied on each of the selected individuals - a <b>moAlgo< EOT ></b>-derived object must be specified;
//! @param eoPop< EOT >& __pop - the initial population from which the individuals are selected for applying the specified algorithm. //! @param eoPop< EOT >& __pop - the initial population from which the individuals are selected for applying the specified algorithm.
peoSyncMultiStart( peoSyncMultiStart(
eoContinue< EOT >& __cont, eoContinue< EOT >& __cont,
eoSelect< EOT >& __select, eoSelect< EOT >& __select,
eoReplacement< EOT >& __replace, eoReplacement< EOT >& __replace,
moAlgo< EOT >& __ls, moAlgo< EOT >& __ls,
eoPop< EOT >& __pop eoPop< EOT >& __pop
); );
//! Operator which synchronously executes the specified algorithm on the individuals selected from the initial population. //! Operator which synchronously executes the specified algorithm on the individuals selected from the initial population.
//! There is no need to explicitly call the operator - automatically called as checkpoint operator. //! There is no need to explicitly call the operator - automatically called as checkpoint operator.
void operator()(); void operator()();
//! Auxiliary function for transferring data between the process requesting the synchronous execution of the specified //! Auxiliary function for transferring data between the process requesting the synchronous execution of the specified
//! algorithm and the process which actually executes the algorithm. There is no need to explicitly call the function. //! algorithm and the process which actually executes the algorithm. There is no need to explicitly call the function.
void packData(); void packData();
//! Auxiliary function for transferring data between the process requesting the synchronous execution of the specified //! Auxiliary function for transferring data between the process requesting the synchronous execution of the specified
//! algorithm and the process which actually executes the algorithm. There is no need to explicitly call the function. //! algorithm and the process which actually executes the algorithm. There is no need to explicitly call the function.
void unpackData(); void unpackData();
//! Auxiliary function for actually executing the specified algorithm on one assigned individual. There is no need to //! Auxiliary function for actually executing the specified algorithm on one assigned individual. There is no need to
//! explicitly call the function. //! explicitly call the function.
void execute(); void execute();
//! Auxiliary function for transferring data between the process requesting the synchronous execution of the specified //! Auxiliary function for transferring data between the process requesting the synchronous execution of the specified
//! algorithm and the process which actually executes the algorithm. There is no need to explicitly call the function. //! algorithm and the process which actually executes the algorithm. There is no need to explicitly call the function.
void packResult(); void packResult();
//! Auxiliary function for transferring data between the process requesting the synchronous execution of the specified //! Auxiliary function for transferring data between the process requesting the synchronous execution of the specified
//! algorithm and the process which actually executes the algorithm. There is no need to explicitly call the function. //! algorithm and the process which actually executes the algorithm. There is no need to explicitly call the function.
void unpackResult(); void unpackResult();
//! Auxiliary function for notifications between the process requesting the synchronous multi-start execution //! Auxiliary function for notifications between the process requesting the synchronous multi-start execution
//! and the processes that performs the actual execution phase. There is no need to explicitly call the function. //! and the processes that performs the actual execution phase. There is no need to explicitly call the function.
void notifySendingData(); void notifySendingData();
//! Auxiliary function for notifications between the process requesting the synchronous multi-start execution //! Auxiliary function for notifications between the process requesting the synchronous multi-start execution
//! and the processes that performs the actual execution phase. There is no need to explicitly call the function. //! and the processes that performs the actual execution phase. There is no need to explicitly call the function.
void notifySendingAllResourceRequests(); void notifySendingAllResourceRequests();
private: private:
eoContinue< EOT >& cont; eoContinue< EOT >& cont;
eoSelect< EOT >& select; eoSelect< EOT >& select;
eoReplacement< EOT >& replace; eoReplacement< EOT >& replace;
moAlgo< EOT >& ls; moAlgo< EOT >& ls;
eoPop< EOT >& pop; eoPop< EOT >& pop;
eoPop< EOT > sel; eoPop< EOT > sel;
eoPop< EOT > impr_sel; eoPop< EOT > impr_sel;
EOT sol; EOT sol;
unsigned idx; unsigned idx;
unsigned num_term; unsigned num_term;
}; };
template< class EOT > peoSyncMultiStart< EOT > :: peoSyncMultiStart( template< class EOT > peoSyncMultiStart< EOT > :: peoSyncMultiStart(
@ -180,14 +180,14 @@ template< class EOT > void peoSyncMultiStart< EOT > :: unpackResult()
num_term++; num_term++;
if ( num_term == sel.size() ) if ( num_term == sel.size() )
{ {
getOwner()->setActive(); getOwner()->setActive();
replace( pop, impr_sel ); replace( pop, impr_sel );
printDebugMessage( "replacing the improved individuals in the population." ); printDebugMessage( "replacing the improved individuals in the population." );
resume(); resume();
} }
} }

View file

@ -51,6 +51,7 @@ static sem_t sem_comm_init;
static Communicator * the_thread; static Communicator * the_thread;
Communicator :: Communicator (int * __argc, char * * * __argv) { Communicator :: Communicator (int * __argc, char * * * __argv) {
the_thread = this; the_thread = this;
@ -69,23 +70,28 @@ void Communicator :: start () {
sendMessages (); sendMessages ();
if (theEnd() || ! atLeastOneActiveRunner ()) if (! atLeastOneActiveRunner () && ! atLeastOneActiveThread() && allResourcesFree ())
break; break;
receiveMessages (); receiveMessages ();
} }
waitBuffers (); waitBuffers ();
sem_destroy(& sem_comm_init);
printDebugMessage ("finalizing"); printDebugMessage ("finalizing");
synchronizeNodes (); //synchronizeNodes ();
} }
void initCommunication () { void initCommunication () {
static bool initializedSemaphore = false;
if (initializedSemaphore) {
sem_destroy(& sem_comm_init);
}
sem_init (& sem_comm_init, 0, 0); sem_init (& sem_comm_init, 0, 0);
initializedSemaphore = true;
} }
void waitNodeInitialization () { void waitNodeInitialization () {
@ -97,6 +103,3 @@ void wakeUpCommunicator () {
the_thread -> wakeUp (); the_thread -> wakeUp ();
} }

View file

@ -43,7 +43,7 @@
class Communicator : public ReactiveThread { class Communicator : public ReactiveThread {
public : public :
/* Ctor */ /* Ctor */
Communicator (int * __argc, char * * * __argv); Communicator (int * __argc, char * * * __argv);

View file

@ -53,7 +53,7 @@ void Cooperative :: setOwner (Runner & __runner) {
void Cooperative :: send (Cooperative * __coop) { void Cooperative :: send (Cooperative * __coop) {
:: send (this, getRankOfRunner (__coop -> getOwner () -> getDefinitionID ()), COOP_TAG); :: send (this, getRankOfRunner (__coop -> getOwner () -> getDefinitionID ()), COOP_TAG);
// stop (); // stop ();
} }

View file

@ -45,18 +45,26 @@
static char mpi_buf [MPI_BUF_SIZE]; static char mpi_buf [MPI_BUF_SIZE];
static int pos_buf ; static int pos_buf;
static std :: vector <char *> act_buf; /* Active buffers */ static std :: vector <char *> act_buf; /* Active buffers */
static std :: vector <MPI_Request *> act_req; /* Active requests */ static std :: vector <MPI_Request *> act_req; /* Active requests */
void initBuffers () {
pos_buf = 0;
act_buf.clear ();
act_req.clear ();
}
void cleanBuffers () { void cleanBuffers () {
for (unsigned i = 0; i < act_req.size ();) { for (unsigned i = 0; i < act_req.size ();) {
MPI_Status stat ; MPI_Status stat ;
int flag ; int flag ;
MPI_Test (act_req [i], & flag, & stat) ; MPI_Test (act_req [i], & flag, & stat) ;
if (flag) { if (flag) {
@ -71,7 +79,7 @@ void cleanBuffers () {
} }
else else
i ++; i ++;
} }
} }
void waitBuffers () { void waitBuffers () {
@ -79,14 +87,14 @@ void waitBuffers () {
printDebugMessage ("waiting the termination of the asynchronous operations to complete"); printDebugMessage ("waiting the termination of the asynchronous operations to complete");
for (unsigned i = 0; i < act_req.size (); i ++) { for (unsigned i = 0; i < act_req.size (); i ++) {
MPI_Status stat ; MPI_Status stat ;
MPI_Wait (act_req [i], & stat) ; MPI_Wait (act_req [i], & stat) ;
delete[] act_buf [i] ; delete[] act_buf [i] ;
delete act_req [i] ; delete act_req [i] ;
} }
} }
bool probeMessage (int & __src, int & __tag) { bool probeMessage (int & __src, int & __tag) {
@ -111,17 +119,17 @@ void waitMessage () {
} }
void initMessage () { void initMessage () {
pos_buf = 0; pos_buf = 0;
} }
void sendMessage (int __to, int __tag) { void sendMessage (int __to, int __tag) {
cleanBuffers (); cleanBuffers ();
act_buf.push_back (new char [pos_buf]); act_buf.push_back (new char [pos_buf]);
act_req.push_back (new MPI_Request); act_req.push_back (new MPI_Request);
memcpy (act_buf.back (), mpi_buf, pos_buf); memcpy (act_buf.back (), mpi_buf, pos_buf);
MPI_Isend (act_buf.back (), pos_buf, MPI_PACKED, __to, __tag, MPI_COMM_WORLD, act_req.back ()); MPI_Isend (act_buf.back (), pos_buf, MPI_PACKED, __to, __tag, MPI_COMM_WORLD, act_req.back ());
} }
void sendMessageToAll (int __tag) { void sendMessageToAll (int __tag) {
@ -131,8 +139,8 @@ void sendMessageToAll (int __tag) {
} }
void receiveMessage (int __from, int __tag) { void receiveMessage (int __from, int __tag) {
MPI_Status stat; MPI_Status stat;
MPI_Request req; MPI_Request req;
MPI_Irecv (mpi_buf, MPI_BUF_SIZE, MPI_PACKED, __from, __tag, MPI_COMM_WORLD, & req); MPI_Irecv (mpi_buf, MPI_BUF_SIZE, MPI_PACKED, __from, __tag, MPI_COMM_WORLD, & req);
@ -200,7 +208,7 @@ void pack (const unsigned long & __ul, int __nitem) {
/* String */ /* String */
void pack (const char * __str) { void pack (const char * __str) {
int len = strlen (__str) + 1; int len = strlen (__str) + 1;
MPI_Pack (& len, 1, MPI_INT, mpi_buf, MPI_BUF_SIZE, & pos_buf, MPI_COMM_WORLD); MPI_Pack (& len, 1, MPI_INT, mpi_buf, MPI_BUF_SIZE, & pos_buf, MPI_COMM_WORLD);
MPI_Pack ((void *) __str, len, MPI_CHAR, mpi_buf, MPI_BUF_SIZE, & pos_buf, MPI_COMM_WORLD); MPI_Pack ((void *) __str, len, MPI_CHAR, mpi_buf, MPI_BUF_SIZE, & pos_buf, MPI_COMM_WORLD);
@ -267,4 +275,3 @@ void unpack (char * __str) {
MPI_Unpack (mpi_buf, MPI_BUF_SIZE, & pos_buf, & len, 1, MPI_INT, MPI_COMM_WORLD); MPI_Unpack (mpi_buf, MPI_BUF_SIZE, & pos_buf, & len, 1, MPI_INT, MPI_COMM_WORLD);
MPI_Unpack (mpi_buf, MPI_BUF_SIZE, & pos_buf, __str, len, MPI_CHAR, MPI_COMM_WORLD); MPI_Unpack (mpi_buf, MPI_BUF_SIZE, & pos_buf, __str, len, MPI_CHAR, MPI_COMM_WORLD);
} }

View file

@ -47,6 +47,8 @@ extern void sendMessageToAll (int __tag);
extern void receiveMessage (int __from, int __tag); extern void receiveMessage (int __from, int __tag);
extern void initBuffers ();
extern void cleanBuffers (); extern void cleanBuffers ();
extern void waitBuffers (); extern void waitBuffers ();

View file

@ -40,6 +40,8 @@
#include <string> #include <string>
#include <cassert> #include <cassert>
#include "mess.h"
class MPIThreadedEnv { class MPIThreadedEnv {
@ -63,7 +65,7 @@ public:
private: private:
/* No instance of this class can be created outside its domain */ /* No instance of this class can be created outside its domain! */
MPIThreadedEnv ( int * __argc, char * * * __argv ) { MPIThreadedEnv ( int * __argc, char * * * __argv ) {
static bool MPIThreadedEnvInitialized = false; static bool MPIThreadedEnvInitialized = false;
@ -72,6 +74,7 @@ private:
if (! MPIThreadedEnvInitialized) { if (! MPIThreadedEnvInitialized) {
MPI_Init_thread (__argc, __argv, MPI_THREAD_FUNNELED, & provided); MPI_Init_thread (__argc, __argv, MPI_THREAD_FUNNELED, & provided);
assert (provided == MPI_THREAD_FUNNELED); /* The MPI implementation must be multi-threaded. assert (provided == MPI_THREAD_FUNNELED); /* The MPI implementation must be multi-threaded.
Yet, only one thread performs the comm. Yet, only one thread performs the comm.
operations */ operations */
@ -92,6 +95,7 @@ static std :: map <std :: string, int> name_to_rk;
static std :: vector <std :: string> rk_to_name; static std :: vector <std :: string> rk_to_name;
int getNodeRank () { int getNodeRank () {
return rk; return rk;
@ -102,6 +106,11 @@ int getNumberOfNodes () {
return sz; return sz;
} }
void collectiveCountOfRunners ( unsigned int* num_local_exec_runners, unsigned int* num_exec_runners ) {
MPI_Allreduce( num_local_exec_runners, num_exec_runners, 1, MPI_UNSIGNED, MPI_SUM, MPI_COMM_WORLD );
}
int getRankFromName (const std :: string & __name) { int getRankFromName (const std :: string & __name) {
return atoi (__name.c_str ()); return atoi (__name.c_str ());
@ -112,9 +121,8 @@ void initNode (int * __argc, char * * * __argv) {
rk_to_name.clear (); rk_to_name.clear ();
name_to_rk.clear (); name_to_rk.clear ();
MPIThreadedEnv :: init ( __argc, __argv ); MPIThreadedEnv :: init ( __argc, __argv );
//synchronizeNodes();
MPI_Comm_rank (MPI_COMM_WORLD, & rk); /* Who ? */ MPI_Comm_rank (MPI_COMM_WORLD, & rk); /* Who ? */
MPI_Comm_size (MPI_COMM_WORLD, & sz); /* How many ? */ MPI_Comm_size (MPI_COMM_WORLD, & sz); /* How many ? */

View file

@ -44,6 +44,8 @@ extern int getNodeRank (); /* It gives the rank of the calling process */
extern int getNumberOfNodes (); /* It gives the size of the environment (Total number of nodes) */ extern int getNumberOfNodes (); /* It gives the size of the environment (Total number of nodes) */
extern void collectiveCountOfRunners ( unsigned int* num_local_exec_runners, unsigned int* num_exec_runners );
extern int getRankFromName (const std :: string & __name); /* It gives the rank of the process extern int getRankFromName (const std :: string & __name); /* It gives the rank of the process
expressed by its name */ expressed by its name */

View file

@ -130,7 +130,5 @@ void receiveMessages () {
}; };
} }
} while ( ! atLeastOneActiveThread () && atLeastOneActiveRunner () /*&& ! allResourcesFree ()*/); } while ( ! atLeastOneActiveThread () && atLeastOneActiveRunner () /*&& ! allResourcesFree ()*/ );
cleanBuffers ();
} }

View file

@ -45,6 +45,7 @@ static std :: vector <pthread_t *> ll_threads; /* Low level threads */
static std :: vector <Worker *> worker_threads; /* Worker threads */ static std :: vector <Worker *> worker_threads; /* Worker threads */
static Communicator* communicator_thread = NULL; /* Communicator thread */ static Communicator* communicator_thread = NULL; /* Communicator thread */
void runRMC () { void runRMC () {
/* Worker(s) ? */ /* Worker(s) ? */

View file

@ -47,6 +47,8 @@ static std :: queue <SCHED_REQUEST> requests; /* Requests */
static unsigned initNumberOfRes = 0; static unsigned initNumberOfRes = 0;
extern void wakeUpCommunicator();
void initScheduler () { void initScheduler () {
resources = std :: queue <SCHED_RESOURCE> (); resources = std :: queue <SCHED_RESOURCE> ();
@ -57,36 +59,39 @@ void initScheduler () {
const Node & node = the_schema [i]; const Node & node = the_schema [i];
if (node.rk_sched == my_node -> rk) if (node.rk_sched == my_node -> rk)
for (unsigned j = 0; j < node.num_workers; j ++) for (unsigned j = 0; j < node.num_workers; j ++)
resources.push (std :: pair <RANK_ID, WORKER_ID> (i, j + 1)); resources.push (std :: pair <RANK_ID, WORKER_ID> (i, j + 1));
} }
initNumberOfRes = resources.size (); initNumberOfRes = resources.size ();
} }
bool allResourcesFree () { bool allResourcesFree () {
return resources.size () == initNumberOfRes; return resources.size () == initNumberOfRes;
} }
unsigned numResourcesFree () {
return resources.size ();
}
static void update () { static void update () {
unsigned num_alloc = std :: min (resources.size (), requests.size ()); unsigned num_alloc = std :: min (resources.size (), requests.size ());
for (unsigned i = 0; i < num_alloc; i ++) { for (unsigned i = 0; i < num_alloc; i ++) {
SCHED_REQUEST req = requests.front (); SCHED_REQUEST req = requests.front ();
requests.pop (); requests.pop ();
SCHED_RESOURCE res = resources.front (); SCHED_RESOURCE res = resources.front ();
resources.pop (); resources.pop ();
printDebugMessage ("allocating a resource."); printDebugMessage ("allocating a resource.");
initMessage (); initMessage ();
pack (req.second); pack (req.second);
pack (res); pack (res);
sendMessage (req.first, SCHED_RESULT_TAG); sendMessage (req.first, SCHED_RESULT_TAG);
} }
} }
void unpackResourceRequest () { void unpackResourceRequest () {
@ -107,4 +112,5 @@ void unpackTaskDone () {
if (resources.size () == initNumberOfRes) if (resources.size () == initNumberOfRes)
printDebugMessage ("all the resources are now free."); printDebugMessage ("all the resources are now free.");
update (); update ();
wakeUpCommunicator();
} }

View file

@ -57,4 +57,6 @@ extern void unpackTaskDone ();
extern bool allResourcesFree (); extern bool allResourcesFree ();
extern unsigned numResourcesFree ();
#endif #endif

View file

@ -76,7 +76,7 @@ static void loadNode (int __rk_sched) {
/* TAG: <runner> | </node> */ /* TAG: <runner> | </node> */
std :: string name = getNextNode (); std :: string name = getNextNode ();
assert (name == "runner" || name == "node"); assert (name == "runner" || name == "node");
if (name == "runner") { if (name == "runner") {
/* TAG: </node> */ /* TAG: </node> */
node.id_run.push_back (atoi (getNextNode ().c_str ())); node.id_run.push_back (atoi (getNextNode ().c_str ()));
@ -105,7 +105,7 @@ static void loadGroup () {
/* TAG: <node> | </group> */ /* TAG: <node> | </group> */
name = getNextNode (); name = getNextNode ();
assert (name == "node" || name == "group"); assert (name == "node" || name == "group");
if (name == "node") if (name == "node")
/* TAG: <node> */ /* TAG: <node> */
loadNode (rk_sched); loadNode (rk_sched);
@ -173,7 +173,7 @@ void loadSchema (const char * __filename) {
printDebugMessage (mess); printDebugMessage (mess);
if (isScheduleNode ()) if (isScheduleNode ())
printDebugMessage ("I'am a scheduler"); printDebugMessage ("I'am a scheduler");
for (unsigned i = 0; i < my_node -> id_run.size (); i ++) { for (unsigned i = 0; i < my_node -> id_run.size (); i ++) {
sprintf (mess, "I manage the runner %d", my_node -> id_run [i]); sprintf (mess, "I manage the runner %d", my_node -> id_run [i]);

View file

@ -47,7 +47,7 @@
typedef int RANK_ID; typedef int RANK_ID;
struct Node { struct Node {
RANK_ID rk; /* Rank */ RANK_ID rk; /* Rank */
std :: string name; /* Host name */ std :: string name; /* Host name */
unsigned num_workers; /* Number of parallel workers */ unsigned num_workers; /* Number of parallel workers */

View file

@ -49,6 +49,7 @@
#define TO_ALL -1 #define TO_ALL -1
typedef struct { typedef struct {
Communicable * comm; Communicable * comm;
@ -56,28 +57,28 @@ typedef struct {
int tag; int tag;
} SEND_REQUEST; } SEND_REQUEST;
static std :: queue <SEND_REQUEST> mess; static std :: queue <SEND_REQUEST> mess;
static sem_t sem_send; static sem_t sem_send;
static bool contextInitialized = false; static bool contextInitialized = false;
void initSending () { void initSending () {
static bool initializedSem = false; static bool initializedSemaphore = false;
mess = std :: queue <SEND_REQUEST> (); mess = std :: queue <SEND_REQUEST> ();
if (! initializedSem) { if (initializedSemaphore) {
sem_init (& sem_send, 0, 1);
initializedSem = true;
}
else {
sem_destroy(& sem_send); sem_destroy(& sem_send);
sem_init (& sem_send, 0, 1);
} }
sem_init (& sem_send, 0, 1);
initializedSemaphore = true;
contextInitialized = false; contextInitialized = false;
} }
@ -103,13 +104,13 @@ extern void initializeContext ();
void sendMessages () { void sendMessages () {
sem_wait (& sem_send);
if (! contextInitialized) { if (! contextInitialized) {
contextInitialized = true; contextInitialized = true;
initializeContext(); initializeContext();
} }
sem_wait (& sem_send);
while (! mess.empty ()) { while (! mess.empty ()) {
SEND_REQUEST req = mess.front (); SEND_REQUEST req = mess.front ();
@ -132,7 +133,7 @@ void sendMessages () {
case SCHED_REQUEST_TAG: case SCHED_REQUEST_TAG:
dynamic_cast <Service *> (comm) -> packResourceRequest (); dynamic_cast <Service *> (comm) -> packResourceRequest ();
dynamic_cast <Service *> (comm) -> notifySendingResourceRequest (); dynamic_cast <Service *> (comm) -> notifySendingResourceRequest ();
break; break;
case TASK_RESULT_TAG: case TASK_RESULT_TAG:
@ -157,5 +158,5 @@ void sendMessages () {
mess.pop (); mess.pop ();
} }
sem_post (& sem_send); sem_post (& sem_send);
} }

View file

@ -48,6 +48,4 @@
#define TASK_RESULT_TAG 19 #define TASK_RESULT_TAG 19
#define TASK_DONE_TAG 20 #define TASK_DONE_TAG 20
#define EXECUTION_CONTEXT_TAG 1000
#endif #endif

View file

@ -46,26 +46,32 @@
static std :: vector <Worker *> key_to_worker (1); /* Vector of registered workers */ static std :: vector <Worker *> key_to_worker (1); /* Vector of registered workers */
extern void wakeUpCommunicator ();
Worker * getWorker (WORKER_ID __key) { Worker * getWorker (WORKER_ID __key) {
return key_to_worker [__key]; return key_to_worker [__key];
} }
Worker :: Worker () { Worker :: Worker () {
recvAndCompleted = false; recvAndCompleted = false;
taskAssigned = 0;
id = key_to_worker.size (); id = key_to_worker.size ();
key_to_worker.push_back (this); key_to_worker.push_back (this);
sem_init( &sem_task_done, 0, 0 );
} }
void Worker :: packResult () { void Worker :: packResult () {
pack (serv_id); pack (serv_id);
serv -> packResult (); serv -> packResult ();
} }
void Worker :: unpackData () { void Worker :: unpackData () {
taskAssigned ++;
printDebugMessage ("unpacking the ID. of the service."); printDebugMessage ("unpacking the ID. of the service.");
unpack (serv_id); unpack (serv_id);
serv = getService (serv_id); serv = getService (serv_id);
@ -90,9 +96,10 @@ void Worker :: notifySendingResult () {
void Worker :: notifySendingTaskDone () { void Worker :: notifySendingTaskDone () {
sem_post(&sem_task_done);
setPassive (); setPassive ();
} }
void Worker :: setSource (int __rank) { void Worker :: setSource (int __rank) {
src = __rank; src = __rank;
@ -102,22 +109,28 @@ void Worker :: start () {
while (true) { while (true) {
sleep (); sleep ();
if (! atLeastOneActiveRunner ()) if (! atLeastOneActiveRunner () && ! taskAssigned)
break; break;
if (recvAndCompleted) { if (recvAndCompleted) {
send (this, my_node -> rk_sched, TASK_DONE_TAG); send (this, my_node -> rk_sched, TASK_DONE_TAG);
recvAndCompleted = false; recvAndCompleted = false;
sem_wait(&sem_task_done);
taskAssigned --;
} }
else { else {
printDebugMessage ("executing the task."); serv -> execute ();
serv -> execute (); send (this, src, TASK_RESULT_TAG);
send (this, src, TASK_RESULT_TAG);
} }
} }
printDebugMessage ("Worker finished execution.");
setPassive ();
wakeUpCommunicator();
} }
void initWorkersEnv () { void initWorkersEnv () {

View file

@ -46,7 +46,7 @@ typedef unsigned WORKER_ID;
class Worker : public Communicable, public ReactiveThread { class Worker : public Communicable, public ReactiveThread {
public : public :
Worker (); Worker ();
@ -56,14 +56,14 @@ public :
void unpackData (); void unpackData ();
void packTaskDone (); void packTaskDone ();
void notifySendingResult (); void notifySendingResult ();
void notifySendingTaskDone (); void notifySendingTaskDone ();
void setSource (int __rank); void setSource (int __rank);
private : private :
WORKER_ID id; WORKER_ID id;
@ -72,6 +72,10 @@ private :
int src; int src;
bool recvAndCompleted; bool recvAndCompleted;
unsigned taskAssigned;
sem_t sem_task_done;
sem_t sem_task_asgn;
}; };
extern void initWorkersEnv (); extern void initWorkersEnv ();

View file

@ -41,11 +41,11 @@
static xmlTextReaderPtr reader; static xmlTextReaderPtr reader;
void openXMLDocument (const char * __filename) { void openXMLDocument (const char * __filename) {
reader = xmlNewTextReaderFilename (__filename); reader = xmlNewTextReaderFilename (__filename);
if (! reader) { if (! reader) {
fprintf (stderr, "unable to open '%s'.\n", __filename); fprintf (stderr, "unable to open '%s'.\n", __filename);
exit (1); exit (1);
} }
@ -57,18 +57,18 @@ void closeXMLDocument () {
} }
std :: string getAttributeValue (const std :: string & __attr) { std :: string getAttributeValue (const std :: string & __attr) {
xmlChar * value = xmlTextReaderGetAttribute (reader, (const xmlChar *) __attr.c_str ()); xmlChar * value = xmlTextReaderGetAttribute (reader, (const xmlChar *) __attr.c_str ());
std :: string str ((const char *) value); std :: string str ((const char *) value);
xmlFree (value); xmlFree (value);
return str; return str;
} }
static bool isSep (const xmlChar * __text) { static bool isSep (const xmlChar * __text) {
for (unsigned i = 0; i < strlen ((char *) __text); i ++) for (unsigned i = 0; i < strlen ((char *) __text); i ++)
if (__text [i] != ' ' && __text [i] != '\t' && __text [i] != '\n') if (__text [i] != ' ' && __text [i] != '\t' && __text [i] != '\n')
return false; return false;
@ -76,7 +76,7 @@ static bool isSep (const xmlChar * __text) {
} }
std :: string getNextNode () { std :: string getNextNode () {
xmlChar * name, * value; xmlChar * name, * value;
do { do {
@ -91,12 +91,11 @@ std :: string getNextNode () {
str.assign ((char *) name); str.assign ((char *) name);
else else
str.assign ((char *) value); str.assign ((char *) value);
if (name) if (name)
xmlFree (name); xmlFree (name);
if (value) if (value)
xmlFree (value); xmlFree (value);
return str; return str;
} }