Renamed new meta model branch

git-svn-id: svn://scm.gforge.inria.fr/svnroot/paradiseo@609 331e1502-861f-0410-8da2-ba01fb791d7f
This commit is contained in:
legrand 2007-09-20 14:33:54 +00:00
commit a0f7039b27
413 changed files with 31937 additions and 0 deletions

View file

@ -0,0 +1,8 @@
######################################################################################
### 1) Where must cmake go now ?
######################################################################################
SUBDIRS(core rmc)
######################################################################################

View file

@ -0,0 +1,49 @@
######################################################################################
### 1) Include the sources
######################################################################################
INCLUDE_DIRECTORIES(${EO_SRC_DIR})
######################################################################################
######################################################################################
### 2) Define your target(s): just the peo library here
######################################################################################
SET(CORE_LIB_OUTPUT_PATH ${ParadisEO-PEO_BINARY_DIR}/lib)
SET(LIBRARY_OUTPUT_PATH ${CORE_LIB_OUTPUT_PATH})
SET (CORE_SOURCES peo_init.cpp
peo_fin.cpp
peo_run.cpp
peo_param.cpp
peo_debug.cpp
thread.cpp
reac_thread.cpp
service.cpp
runner.cpp
communicable.cpp
topology.cpp
ring_topo.cpp)
ADD_LIBRARY(peo STATIC ${CORE_SOURCES})
######################################################################################
######################################################################################
### 3) Optionnal: define your target(s)'s version: no effect for windows
######################################################################################
SET(CORE_VERSION "1.0.beta")
SET_TARGET_PROPERTIES(peo PROPERTIES VERSION "${CORE_VERSION}")
######################################################################################

View file

@ -0,0 +1,70 @@
// "comm.cpp"
// (c) OPAC Team, LIFL, August 2005
/*
Contact: paradiseo-help@lists.gforge.inria.fr
*/
#include <vector>
#include <map>
#include <cassert>
#include "communicable.h"
static std :: vector <Communicable *> key_to_comm (1); /* Vector of registered cooperators */
static std :: map <const Communicable *, unsigned> comm_to_key; /* Map of registered cooperators */
unsigned Communicable :: num_comm = 0;
Communicable :: Communicable () {
comm_to_key [this] = key = ++ num_comm;
key_to_comm.push_back (this);
sem_init (& sem_lock, 0, 1);
sem_init (& sem_stop, 0, 0);
}
Communicable :: ~ Communicable () {
}
COMM_ID Communicable :: getKey () {
return key;
}
Communicable * getCommunicable (COMM_ID __key) {
assert (__key < key_to_comm.size ());
return key_to_comm [__key];
}
COMM_ID getKey (const Communicable * __comm) {
return comm_to_key [__comm];
}
void Communicable :: lock () {
sem_wait (& sem_lock);
}
void Communicable :: unlock () {
sem_post (& sem_lock);
}
void Communicable :: stop () {
sem_wait (& sem_stop);
}
void Communicable :: resume () {
sem_post (& sem_stop);
}

View file

@ -0,0 +1,47 @@
// "communicable.h"
// (c) OPAC Team, LIFL, August 2005
/*
Contact: paradiseo-help@lists.gforge.inria.fr
*/
#ifndef __communicable_h
#define __communicable_h
#include <semaphore.h>
typedef unsigned COMM_ID;
class Communicable {
public :
Communicable ();
virtual ~ Communicable ();
COMM_ID getKey ();
void lock (); /* It suspends the current process if the semaphore is locked */
void unlock (); /* It unlocks the shared semaphore */
void stop (); /* It suspends the current process */
void resume (); /* It resumes ___________ */
protected :
COMM_ID key;
sem_t sem_lock;
sem_t sem_stop;
static unsigned num_comm;
};
extern Communicable * getCommunicable (COMM_ID __key);
//extern COMM_ID getKey (const Communicable * __comm);
#endif

View file

@ -0,0 +1,41 @@
// "cooperative.h"
// (c) OPAC Team, LIFL, August 2005
/*
Contact: paradiseo-help@lists.gforge.inria.fr
*/
#ifndef __cooperative_h
#define __cooperative_h
#include "communicable.h"
#include "runner.h"
typedef unsigned COOP_ID;
class Cooperative : public Communicable {
public :
Runner * getOwner ();
void setOwner (Runner & __runner);
virtual void pack () = 0;
virtual void unpack () = 0;
void send (Cooperative * __coop);
virtual void notifySending ();
private :
Runner * owner;
};
extern Cooperative * getCooperative (COOP_ID __key);
#endif

View file

@ -0,0 +1,32 @@
// "eoPop_comm.h"
// (c) OPAC Team, LIFL, August 2005
/*
Contact: paradiseo-help@lists.gforge.inria.fr
*/
#ifndef __eoPop_comm_h
#define __eoPop_comm_h
#include <eoPop.h>
#include "messaging.h"
template <class EOT> void pack (const eoPop <EOT> & __pop) {
pack ((unsigned) __pop.size ());
for (unsigned i = 0; i < __pop.size (); i ++)
pack (__pop [i]);
}
template <class EOT> void unpack (eoPop <EOT> & __pop) {
unsigned n;
unpack (n);
__pop.resize (n);
for (unsigned i = 0; i < n; i ++)
unpack (__pop [i]);
}
#endif

View file

@ -0,0 +1,38 @@
// "eoVector_comm.h"
// (c) OPAC Team, LIFL, August 2005
/*
Contact: paradiseo-help@lists.gforge.inria.fr
*/
#ifndef __eoVector_comm_h
#define __eoVector_comm_h
#include <eoVector.h>
#include "messaging.h"
template <class F, class T> void pack (const eoVector <F, T> & __v) {
pack (__v.fitness ()) ;
unsigned len = __v.size ();
pack (len);
for (unsigned i = 0 ; i < len; i ++)
pack (__v [i]);
}
template <class F, class T> void unpack (eoVector <F, T> & __v) {
F fit;
unpack (fit);
__v.fitness (fit);
unsigned len;
unpack (len);
__v.resize (len);
for (unsigned i = 0 ; i < len; i ++)
unpack (__v [i]);
}
#endif

View file

@ -0,0 +1,104 @@
// "messaging.h"
// (c) OPAC Team, LIFL, August 2005
/*
Contact: paradiseo-help@lists.gforge.inria.fr
*/
#ifndef __mess_h
#define __mess_h
#include <utility>
/* Char */
extern void pack (const char & __c);
/* Float */
extern void pack (const float & __f, int __nitem = 1);
/* Double */
extern void pack (const double & __d, int __nitem = 1);
/* Integer */
extern void pack (const int & __i, int __nitem = 1);
/* Unsigned int. */
extern void pack (const unsigned int & __ui, int __nitem = 1);
/* Short int. */
extern void pack (const short & __sh, int __nitem = 1);
/* Unsigned short */
extern void pack (const unsigned short & __ush, int __nitem = 1);
/* Long */
extern void pack (const long & __l, int __nitem = 1);
/* Unsigned long */
extern void pack (const unsigned long & __ul, int __nitem = 1);
/* String */
extern void pack (const char * __str);
/* Pointer */
template <class T> void pack (const T * __ptr) {
pack ((unsigned long) __ptr);
}
/* Pair */
template <class U, class V> void pack (const std :: pair <U, V> & __pair) {
pack (__pair.first);
pack (__pair.second);
}
//
/* Float */
extern void unpack (char & __c);
/* Float */
extern void unpack (float & __f, int __nitem = 1);
/* Double */
extern void unpack (double & __d, int __nitem = 1);
/* Integer */
extern void unpack (int & __i, int __nitem = 1);
/* Unsigned int. */
extern void unpack (unsigned int & __ui, int __nitem = 1);
/* Short int. */
extern void unpack (short & __sh, int __nitem = 1);
/* Unsigned short */
extern void unpack (unsigned short & __ush, int __nitem = 1);
/* Long */
extern void unpack (long & __l, int __nitem = 1);
/* Unsigned long */
extern void unpack (unsigned long & __ul, int __nitem = 1);
/* String */
extern void unpack (char * __str);
/* Pointer */
template <class T> void unpack (T * & __ptr) {
unsigned long p;
unpack (p);
__ptr = (T *) p;
}
/* Pair */
template <class U, class V> void unpack (std :: pair <U, V> & __pair) {
unpack (__pair.first);
unpack (__pair.second);
}
#endif

View file

@ -0,0 +1,77 @@
// "peo_debug.cpp"
// (c) OPAC Team, LIFL, August 2005
/*
Contact: paradiseo-help@lists.gforge.inria.fr
*/
#include "peo_debug.h"
#include <stdio.h>
#include <time.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <vector>
#include "peo_debug.h"
#define MAX_BUFF_SIZE 1000
#define DEBUG_PATH "./log/"
static bool debug = true;
static char host [MAX_BUFF_SIZE];
std :: vector <FILE *> files;
void setDebugMode (bool __dbg) {
debug = __dbg;
gethostname (host, MAX_BUFF_SIZE);
}
extern int getNodeRank ();
void initDebugging () {
mkdir (DEBUG_PATH, S_IRWXU);
// files.push_back (stdout);
char buff [MAX_BUFF_SIZE];
sprintf (buff, "%s/%d", DEBUG_PATH, getNodeRank ());
files.push_back (fopen (buff, "w"));
}
void endDebugging () {
for (unsigned i = 0; i < files.size (); i ++)
if (files [i] != stdout)
fclose (files [i]);
}
void printDebugMessage (const char * __mess) {
if (debug) {
char buff [MAX_BUFF_SIZE];
time_t t = time (0);
/* Date */
sprintf (buff, "[%s][%s: ", host, ctime (& t));
* strchr (buff, '\n') = ']';
for (unsigned i = 0; i < files.size (); i ++)
fprintf (files [i], buff);
/* Message */
sprintf (buff, "%s", __mess);
for (unsigned i = 0; i < files.size (); i ++) {
fputs (buff, files [i]);
fputs ("\n", files [i]);
fflush (files [i]);
}
}
}

View file

@ -0,0 +1,22 @@
// "peo_debug.h"
// (c) OPAC Team, LIFL, August 2005
/*
Contact: paradiseo-help@lists.gforge.inria.fr
*/
#ifndef __peo_debug_h
#define __peo_debug_h
extern void initDebugging ();
extern void endDebugging ();
extern void setDebugMode (bool __dbg = true); /* (Des)activating the Debugging mode */
extern void printDebugMessage (const char * __mess); /* Print a new message both on the
standard output and a target
text-file in a subdirectory) */
#endif

View file

@ -0,0 +1,24 @@
// "peo_finalize.cpp"
// (c) OPAC Team, LIFL, August 2005
/*
Contact: paradiseo-help@lists.gforge.inria.fr
*/
#include "peo_fin.h"
#include "peo_debug.h"
#include "runner.h"
#include "rmc.h"
void peo :: finalize () {
printDebugMessage ("waiting for the termination of all threads");
joinRunners ();
finalizeRMC ();
printDebugMessage ("this is the end");
endDebugging ();
}

View file

@ -0,0 +1,17 @@
// "peo_finalize.h"
// (c) OPAC Team, LIFL, August 2005
/*
Contact: paradiseo-help@lists.gforge.inria.fr
*/
#ifndef __peo_finalize_h
#define __peo_finalize_h
namespace peo {
extern void finalize ();
}
#endif

View file

@ -0,0 +1,37 @@
// "peo_init.cpp"
// (c) OPAC Team, LIFL, August 2005
/*
Contact: paradiseo-help@lists.gforge.inria.fr
*/
#include <stdio.h>
#include "peo_init.h"
#include "peo_param.h"
#include "peo_debug.h"
#include "rmc.h"
namespace peo {
int * argc;
char * * * argv;
void init (int & __argc, char * * & __argv) {
argc = & __argc;
argv = & __argv;
/* Initializing the the Resource Management and Communication */
initRMC (__argc, __argv);
/* Loading the common parameters */
loadParameters (__argc, __argv);
/* */
initDebugging ();
}
}

View file

@ -0,0 +1,21 @@
// "peo_init.h"
// (c) OPAC Team, LIFL, August 2005
/*
Contact: paradiseo-help@lists.gforge.inria.fr
*/
#ifndef __peo_init_h
#define __peo_init_h
namespace peo {
extern int * argc;
extern char * * * argv;
extern void init (int & __argc, char * * & __argv);
}
#endif

View file

@ -0,0 +1,25 @@
// "peo_param.cpp"
// (c) OPAC Team, LIFL, August 2005
/*
Contact: paradiseo-help@lists.gforge.inria.fr
*/
#include <utils/eoParser.h>
#include "peo_param.h"
#include "peo_debug.h"
void peo :: loadParameters (int & __argc, char * * & __argv) {
eoParser parser (__argc, __argv);
/* Debug */
eoValueParam <std :: string> debug_param ("false", "debug", "?");
parser.processParam (debug_param);
if (debug_param.value () == "true")
setDebugMode ();
}

View file

@ -0,0 +1,17 @@
// "peo_param.h"
// (c) OPAC Team, LIFL, August 2005
/*
Contact: paradiseo-help@lists.gforge.inria.fr
*/
#ifndef __peo_param_h
#define __peo_param_h
namespace peo {
extern void loadParameters (int & __argc, char * * & __argv);
}
#endif

View file

@ -0,0 +1,19 @@
// "peo_run.cpp"
// (c) OPAC Team, LIFL, August 2005
/*
Contact: paradiseo-help@lists.gforge.inria.fr
*/
#include "peo_init.h"
#include "peo_run.h"
#include "rmc.h"
#include "runner.h"
void peo :: run () {
startRunners ();
runRMC ();
}

View file

@ -0,0 +1,17 @@
// "peo_run.h"
// (c) OPAC Team, LIFL, August 2005
/*
Contact: paradiseo-help@lists.gforge.inria.fr
*/
#ifndef __peo_run_h
#define __peo_run_h
namespace peo {
extern void run ();
}
#endif

View file

@ -0,0 +1,36 @@
// "reac_thread.cpp"
// (c) OPAC Team, LIFL, August 2005
/*
Contact: paradiseo-help@lists.gforge.inria.fr
*/
#include "reac_thread.h"
static bool the_end = false;
static std :: vector <ReactiveThread *> reac_threads;
ReactiveThread :: ReactiveThread () {
reac_threads.push_back (this);
sem_init (& sem, 0, 0);
}
void ReactiveThread :: sleep () {
sem_wait (& sem);
}
void ReactiveThread :: wakeUp () {
sem_post (& sem);
}
void stopReactiveThreads () {
the_end = true;
for (unsigned i = 0; i < reac_threads.size (); i ++)
reac_threads [i] -> wakeUp ();
}

View file

@ -0,0 +1,35 @@
// "reac_thread.h"
// (c) OPAC Team, LIFL, August 2005
/*
Contact: paradiseo-help@lists.gforge.inria.fr
*/
#ifndef REAC_THREAD_H_
#define REAC_THREAD_H_
#include <semaphore.h>
#include "thread.h"
class ReactiveThread : public Thread {
public:
/* Ctor */
ReactiveThread ();
void sleep ();
void wakeUp ();
private:
sem_t sem;
};
extern void stopReactiveThreads ();
#endif /*THREAD_H_*/

View file

@ -0,0 +1,25 @@
// "ring_topo.cpp"
// (c) OPAC Team, LIFL, September 2005
/*
Contact: paradiseo-help@lists.gforge.inria.fr
*/
#include "ring_topo.h"
void RingTopology :: setNeighbors (Cooperative * __mig,
std :: vector <Cooperative *> & __from,
std :: vector <Cooperative *> & __to) {
__from.clear () ;
__to.clear () ;
int len = mig.size () ;
for (int i = 0 ; i < len ; i ++)
if (mig [i] == __mig) {
__from.push_back (mig [(i - 1 + len) % len]) ;
__to.push_back (mig [(i + 1) % len]) ;
break;
}
}

View file

@ -0,0 +1,24 @@
// "ring_topo.h"
// (c) OPAC Team, LIFL, September 2005
/*
Contact: paradiseo-help@lists.gforge.inria.fr
*/
#ifndef __ring_topo_h
#define __ring_topo_h
#include "topology.h"
class RingTopology : public Topology {
public :
void setNeighbors (Cooperative * __mig,
std :: vector <Cooperative *> & __from,
std :: vector <Cooperative *> & __to);
};
#endif

View file

@ -0,0 +1,18 @@
// "rmc.h"
// (c) OPAC Team, LIFL, August 2005
/*
Contact: paradiseo-help@lists.gforge.inria.fr
*/
#ifndef __rmc_h
#define __rmc_h
extern void initRMC (int & __argc, char * * & __argv);
extern void runRMC (); /* Resource Management and Communication */
extern void finalizeRMC ();
#endif

View file

@ -0,0 +1,104 @@
// "runner.cpp"
// (c) OPAC Team, LIFL, August 2005
/*
Contact: paradiseo-help@lists.gforge.inria.fr
*/
#include <vector>
#include "runner.h"
#include "reac_thread.h"
#include "peo_debug.h"
#include "messaging.h"
static unsigned num_act = 0; /* Number of active runners */
static std :: vector <pthread_t *> ll_threads; /* Low-level runner threads */
static std :: vector <Runner *> the_runners;
static unsigned num_runners = 0;
Runner :: Runner () {
id = ++ num_runners;
the_runners.push_back (this);
sem_init (& sem_start, 0, 0);
num_act ++;
}
extern int getNodeRank ();
extern int getNumberOfNodes ();
void unpackTerminationOfRunner () {
RUNNER_ID id;
unpack (id);
num_act --;
printDebugMessage ("I'm noticed of the termination of a runner");
if (! num_act) {
printDebugMessage ("all the runners have terminated. Now stopping the reactive threads.");
stopReactiveThreads ();
}
}
bool atLeastOneActiveRunner () {
return num_act;
}
RUNNER_ID Runner :: getID () {
return id;
}
void Runner :: start () {
setActive ();
sem_post (& sem_start);
run ();
terminate ();
}
void Runner :: notifySendingTermination () {
/*
char b [1000];
sprintf (b, "Il reste encore %d !!!!!!!!!!!!", n);
printDebugMessage (b);
*/
printDebugMessage ("je suis informe que tout le monde a recu ma terminaison");
setPassive ();
}
void Runner :: waitStarting () {
sem_wait (& sem_start);
}
Runner * getRunner (RUNNER_ID __key) {
return dynamic_cast <Runner *> (getCommunicable (__key));
}
void startRunners () {
/* Runners */
for (unsigned i = 0; i < the_runners.size (); i ++)
if (the_runners [i] -> isLocal ()) {
addThread (the_runners [i], ll_threads);
the_runners [i] -> waitStarting ();
}
printDebugMessage ("launched the parallel runners");
}
void joinRunners () {
joinThreads (ll_threads);
}

View file

@ -0,0 +1,58 @@
// "runner.h"
// (c) OPAC Team, LIFL, August 2005
/*
Contact: paradiseo-help@lists.gforge.inria.fr
*/
#ifndef __runner_h
#define __runner_h
#include <eoFunctor.h>
#include "communicable.h"
#include "thread.h"
typedef unsigned RUNNER_ID;
class Runner : public Communicable, public Thread {
public :
Runner ();
void start ();
void waitStarting ();
bool isLocal ();
void terminate ();
virtual void run () = 0;
RUNNER_ID getID ();
void packTermination ();
void notifySendingTermination ();
private :
sem_t sem_start;
unsigned id;
};
extern bool atLeastOneActiveRunner ();
extern void unpackTerminationOfRunner ();
extern Runner * getRunner (RUNNER_ID __key);
extern void startRunners ();
extern void joinRunners ();
#endif

View file

@ -0,0 +1,58 @@
// "service.cpp"
// (c) OPAC Team, LIFL, August 2005
/*
Contact: paradiseo-help@lists.gforge.inria.fr
*/
#include "service.h"
void Service :: setOwner (Thread & __owner) {
owner = & __owner;
}
Thread * Service :: getOwner () {
return owner;
}
Service * getService (SERVICE_ID __key) {
return dynamic_cast <Service *> (getCommunicable (__key));
}
void Service :: notifySendingData () {
}
void Service :: notifySendingResourceRequest () {
num_sent_rr --;
if (! num_sent_rr)
notifySendingAllResourceRequests ();
}
void Service :: notifySendingAllResourceRequests () {
}
void Service :: packData () {
}
void Service :: unpackData () {
}
void Service :: execute () {
}
void Service :: packResult () {
}
void Service :: unpackResult () {
}

View file

@ -0,0 +1,50 @@
// "service.h"
// (c) OPAC Team, LIFL, August 2005
/*
Contact: paradiseo-help@lists.gforge.inria.fr
*/
#ifndef __service_h
#define __service_h
#include "communicable.h"
#include "thread.h"
typedef unsigned SERVICE_ID;
class Service : public Communicable {
public :
void setOwner (Thread & __owner);
Thread * getOwner ();
void requestResourceRequest (unsigned __how_many = 1);
void packResourceRequest ();
virtual void packData ();
virtual void unpackData ();
virtual void execute ();
virtual void packResult ();
virtual void unpackResult ();
virtual void notifySendingData ();
virtual void notifySendingResourceRequest ();
virtual void notifySendingAllResourceRequests ();
private :
Thread * owner; /* Owner thread (i.e. 'uses' that service) */
unsigned num_sent_rr; /* Number of RR not really sent (i.e. still in the sending queue)*/
};
extern Service * getService (SERVICE_ID __key);
#endif

View file

@ -0,0 +1,81 @@
// "thread.cpp"
// (c) OPAC Team, LIFL, August 2005
/*
Contact: paradiseo-help@lists.gforge.inria.fr
*/
#include <map>
#include "thread.h"
static std :: vector <Thread *> threads;
unsigned num_act = 0;
Thread :: Thread () {
threads.push_back (this);
act = false;
}
Thread :: ~ Thread () {
/* Nothing ! */
}
extern int getNodeRank ();
void Thread :: setActive () {
if (! act ) {
act = true;
num_act ++;
// if (getNodeRank () == 1)
// printf ("On passe a %d\n", num_act);
}
}
void Thread :: setPassive () {
if (act) {
act = false;
num_act --;
// if (getNodeRank () == 1)
// printf ("On passe a %d\n", num_act);
}
}
bool atLeastOneActiveThread () {
return num_act;
}
unsigned numberOfActiveThreads () {
return num_act;
}
static void * launch (void * __arg) {
Thread * thr = (Thread *) __arg;
thr -> start ();
return 0;
}
void addThread (Thread * __hl_thread, std :: vector <pthread_t *> & __ll_threads) {
pthread_t * ll_thr = new pthread_t;
__ll_threads.push_back (ll_thr);
pthread_create (ll_thr, 0, launch, __hl_thread);
}
void joinThreads (std :: vector <pthread_t *> & __threads) {
for (unsigned i = 0; i < __threads.size (); i ++)
pthread_join (* __threads [i], 0);
}

View file

@ -0,0 +1,48 @@
// "thread.h"
// (c) OPAC Team, LIFL, August 2005
/*
Contact: paradiseo-help@lists.gforge.inria.fr
*/
#ifndef THREAD_H_
#define THREAD_H_
#include <vector>
/* A high-level thread */
class Thread {
public:
/* Ctor */
Thread ();
/* Dtor */
virtual ~ Thread ();
/* Go ! */
virtual void start () = 0;
void setActive ();/* It means the current process is going to send messages soon */
void setPassive ();/* The current process is not going to perform send operations
(but it may receive messages) */
private :
bool act;
};
extern void addThread (Thread * __hl_thread, std :: vector <pthread_t *> & __ll_threads);
extern void joinThreads (std :: vector <pthread_t *> & __ll_threads);
extern bool atLeastOneActiveThread (); /* It returns 'true' iff at least one process is going
to send messages */
extern unsigned numberOfActiveThreads ();
#endif /*THREAD_H_*/

View file

@ -0,0 +1,20 @@
// "topo.cpp"
// (c) OPAC Team, LIFL, September 2005
/*
Contact: paradiseo-help@lists.gforge.inria.fr
*/
#include "topology.h"
Topology :: ~ Topology () {
/* Nothing ! */
}
void Topology :: add (Cooperative & __mig) {
mig.push_back (& __mig) ;
}

View file

@ -0,0 +1,33 @@
// "topology.h"
// (c) OPAC Team, LIFL, September 2005
/*
Contact: paradiseo-help@lists.gforge.inria.fr
*/
#ifndef __topology_h
#define __topology_h
#include <vector>
#include "cooperative.h"
class Topology {
public:
virtual ~Topology ();
void add (Cooperative & __mig);
virtual void setNeighbors (Cooperative * __mig,
std :: vector <Cooperative *> & __from,
std :: vector <Cooperative *> & __to) = 0;
protected:
std :: vector <Cooperative *> mig ;
};
#endif

View file

@ -0,0 +1,14 @@
// "paradiseo"
// (c) OPAC Team, LIFL, August 2005
/*
Contact: paradiseo-help@lists.gforge.inria.fr
*/
#ifndef __paradiseo_
#define __paradiseo_
#include "paradiseo.h"
#endif

View file

@ -0,0 +1,285 @@
// "paradiseo.h"
// (c) OPAC Team, LIFL, August 2005
/*
Contact: paradiseo-help@lists.gforge.inria.fr
*/
#ifndef __paradiseo_h_
#define __paradiseo_h_
#include <eo>
#include <mo>
//! \mainpage The ParadisEO-PEO Framework
//!
//! \section intro Introduction
//!
//! ParadisEO is a white-box object-oriented framework dedicated to the reusable design
//! of parallel and distributed metaheuristics (PDM). ParadisEO provides a broad range of features including evolutionary
//! algorithms (EA), local searches (LS), the most common parallel and distributed models and hybridization
//! mechanisms, etc. This high content and utility encourages its use at European level. ParadisEO is based on a
//! clear conceptual separation of the solution methods from the problems they are intended to solve. This separation
//! confers to the user a maximum code and design reuse. Furthermore, the fine-grained nature of the classes
//! provided by the framework allow a higher flexibility compared to other frameworks. ParadisEO is one of the rare
//! frameworks that provide the most common parallel and distributed models. Their implementation is portable on
//! distributed-memory machines as well as on shared-memory multiprocessors, as it uses standard libraries such as
//! MPI, PVM and PThreads. The models can be exploited in a transparent way, one has just to instantiate their associated
//! provided classes. Their experimentation on the radio network design real-world application demonstrate their
//! efficiency.
//!
//! In practice, combinatorial optimization problems are often NP-hard, CPU time-consuming,
//! and evolve over time. Unlike exact methods, metaheuristics allow to tackle large-size problems
//! instances by delivering satisfactory solutions in a reasonable time. Metaheuristics are
//! general-purpose heuristics that split in two categories: evolutionary algorithms (EA) and local
//! search methods (LS). These two families have complementary characteristics: EA allow
//! a better exploration of the search space, while LS have the power to intensify the search in
//! promising regions. Their hybridization allows to deliver robust and better solutions
//!
//! Although serial metaheuristics have a polynomial temporal complexity, they remain
//! unsatisfactory for industrial problems. Parallel and distributed computing is a powerful way
//! to deal with the performance issue of these problems. Numerous parallel and distributed
//! metaheuristics (PDM) and their implementations have been proposed, and are available on
//! theWeb. They can be reused and adapted to his/her own problems. However, the user has to
//! deeply examine the code and rewrite its problem-specific sections. The task is tedious, errorprone,
//! takes along time and makes harder the produced code maintenance. A better way to
//! reuse the code of existing PDM is the reuse through libraries. These are often
//! more reliable as they are more tested and documented. They allow a better maintainability
//! and efficiency. However, libraries do not allow the reuse of design.
//!
//! \section parallel_metaheuristics Parallel and distributed metaheuristics
//!
//! \subsection parallel_distributed Parallel distributed evolutionary algorithms
//!
//! Evolutionary Algorithms (EA) are based on the iterative improvement of a
//! population of solutions. At each step, individuals are selected, paired and recombined in order
//! to generate new solutions that replace other ones, and so on. As the algorithm converges,
//! the population is mainly composed of individuals well adapted to the "environment", for
//! instance the problem. The main features that characterize EA are the way the population is
//! initialized, the selection strategy (deterministic/stochastic) by fostering "good" solutions,
//! the replacement strategy that discards individuals, and the continuation/stopping criterion
//! to decide whether the evolution should go on or not.
//!
//! Basically, three major parallel and distributed models for EA can been distinguished:
//! the island (a)synchronous cooperative model, the parallel evaluation of the
//! population, and the distributed evaluation of a single solution.
//! <ul>
//! <li> <i>Island (a)synchronous cooperative model</i>. Different EA are simultaneously deployed to
//! cooperate for computing better and robust solutions. They exchange in an asynchronous
//! way genetic stuff to diversify the search. The objective is to allow to delay the global
//! convergence, especially when theEAare heterogeneous regarding the variation operators.
//! The migration of individuals follows a policy defined by few parameters: the migration
//! decision criterion, the exchange topology, the number of emigrants, the emigrants selection
//! policy, and the replacement/integration policy.</li>
//!
//! <li> <i>Parallel evaluation of the population</i>. It is required as it is in general the most timeconsuming.
//! The parallel evaluation follows the centralized model. The farmer applies
//! the following operations: selection, transformation and replacement as they require a
//! global management of the population. At each generation, it distributes the set of new
//! solutions between differentworkers. These evaluate and return back the solutions and their
//! quality values. An efficient execution is often obtained particularly when the evaluation
//! of each solution is costly. The two main advantages of an asynchronous model over
//! the synchronous model are: (1) the fault tolerance of the asynchronous model; (2) the
//! robustness in case the fitness computation can take very different computation times (e.g.
//! for nonlinear numerical optimization). Whereas some time-out detection can be used to
//! address the former issue, the latter one can be partially overcome if the grain is set to very
//! small values, as individuals will be sent out for evaluations upon request of the workers.</li>
//!
//! <li> <i>Distributed evaluation of a single solution</i>. The quality of each solution is evaluated in
//! a parallel centralized way. That model is particularly interesting when the evaluation
//! function can be itself parallelized as it is CPU time-consuming and/or IO intensive. In
//! that case, the function can be viewed as an aggregation of a certain number of partial
//! functions. The partial functions could also be identical if for example the problem to deal
//! with is a data mining one. The evaluation is thus data parallel and the accesses to data
//! base are performed in parallel. Furthermore, a reduction operation is performed on the
//! results returned by the partial functions. As a summary, for this model the user has to
//! indicate a set of partial functions and an aggregation operator of these.</li>
//! </ul>
//!
//! \subsection parallel_ls Parallel distributed local searches
//!
//! \subsubsection local_searches Local searches
//!
//! All metaheuristics dedicated to the improvement of a single solution
//! are based on the concept of neighborhood. They start from a solution randomly generated or
//! obtained from another optimization algorithm, and update it, step by step, by replacing the
//! current solution by one of its neighboring candidates. Some criterion have been identified to
//! differentiate such searches: the heuristic internal memory, the choice of the initial solution,
//! the candidate solutions generator, and the selection strategy of candidate moves. Three main
//! algorithms of local search stand out: Hill Climbing (HC), Simulated
//! Annealing (SA) and Tabu Search (TS).
//!
//! \subsubsection parallel_local_searches Parallel local searches
//!
//! Two parallel distributed models are commonly used in the literature: the parallel distributed
//! exploration of neighboring candidate solutions model, and the multi-start model.
//! <ul>
//! <li><i>Parallel exploration of neighboring candidates</i>. It is a low-level Farmer-Worker model
//! that does not alter the behavior of the heuristic. A sequential search computes the same
//! results slower.At the beginning of each iteration, the farmer duplicates the current solution
//! between distributed nodes. Each one manages some candidates and the results are returned to the farmer.
//! The model is efficient if the evaluation of a each solution is time-consuming and/or there are a great
//! deal of candidate neighbors to evaluate. This is obviously not applicable to SA since only one candidate
//! is evaluated at each iteration. Likewise, the efficiency of the model for HC is not always guaranteed as
//! the number of neighboring solutions to process before finding one that improves the current objective function may
//! be highly variable.</li>
//!
//! <li> <i>Multi-start model</i>. It consists in simultaneously launching several local searches. They
//! may be heterogeneous, but no information is exchanged between them. The resultswould
//! be identical as if the algorithms were sequentially run.Very often deterministic algorithms
//! differ by the supplied initial solution and/or some other parameters. This trivial model is
//! convenient for low-speed networks of workstations.</li>
//! </ul>
//!
//! \section hybridization Hybridization
//!
//! Recently, hybrid metaheuristics have gained a considerable interest. For many
//! practical or academic optimization problems, the best found solutions are obtained by
//! hybrid algorithms. Combinations of different metaheuristics have provided very powerful
//! search methods. Two levels and two modes
//! of hybridization have been distinguished: Low and High levels, and Relay and Cooperative modes.
//! The low-level hybridization addresses the functional composition of a single optimization
//! method. A function of a given metaheuristic is replaced by another metaheuristic. On the
//! contrary, for high-level hybrid algorithms the different metaheuristics are self-containing,
//! meaning no direct relationship to their internal working is considered. On the other hand,
//! relay hybridization means a set of metaheuristics is applied in a pipeline way. The output
//! of a metaheuristic (except the last) is the input of the following one (except the first).
//! Conversely, co-evolutionist hybridization is a cooperative optimization model. Each metaheuristic
//! performs a search in a solution space, and exchange solutions with others.
//!
//! \section paradiseo_goals Paradiseo goals and architecture
//!
//! The "EO" part of ParadisEO means Evolving Objects. EO is a C++ LGPL open source
//! framework and includes a paradigm-free Evolutionary Computation library (EOlib)
//! dedicated to the flexible design of EA through evolving objects superseding the most common
//! dialects (Genetic Algorithms, Evolution Strategies, Evolutionary Programming and
//! Genetic Programming). Furthermore, EO integrates several services including visualization
//! facilities, on-line definition of parameters, application check-pointing, etc. ParadisEO is an
//! extended version of the EO framework. The extensions include local search methods, hybridization
//! mechanisms, parallelism and distribution mechanisms, and other features that
//! are not addressed in this paper such as multi-objective optimization and grid computing. In
//! the next sections, we present the motivations and goals of ParadisEO, its architecture and
//! some of its main implementation details and issues.
//!
//! \subsection motivation Motivations and goals
//!
//! A framework is normally intended to be exploited by as many users as possible. Therefore,
//! its exploitation could be successful only if some important user criteria are satisfied. The
//! following criteria are the major of them and constitute the main objectives of the ParadisEO
//! framework:
//!
//! <ul>
//! <li><i>Maximum design and code reuse</i>. The framework must provide for the user a whole
//! architecture design of his/her solution method. Moreover, the programmer may redo as
//! little code as possible. This objective requires a clear and maximal conceptual separation
//! between the solution methods and the problems to be solved, and thus a deep domain
//! analysis. The user might therefore develop only the minimal problem-specific code.</li>
//!
//! <li><i>Flexibility and adaptability</i>. It must be possible for the user to easily add new features/
//! metaheuristics or change existing ones without implicating other components. Furthermore,
//! as in practice existing problems evolve and new others arise these have to be
//! tackled by specializing/adapting the framework components.</li>
//!
//! <li><i>Utility</i>. The framework must allow the user to cover a broad range of metaheuristics,
//! problems, parallel distributed models, hybridization mechanisms, etc.</li>
//!
//! <li><i>Transparent and easy access to performance and robustness</i>. As the optimization applications
//! are often time-consuming the performance issue is crucial. Parallelism and
//! distribution are two important ways to achieve high performance execution. In order to
//! facilitate its use it is implemented so that the user can deploy his/her parallel algorithms in
//! a transparent manner. Moreover, the execution of the algorithms must be robust to guarantee
//! the reliability and the quality of the results. The hybridization mechanism allows
//! to obtain robust and better solutions.</li>
//!
//! <li><i>Portability</i>. In order to satisfy a large number of users the framework must support
//! different material architectures and their associated operating systems.</li>
//! </ul>
//!
//! \subsection architecture ParadisEO architecture
//!
//! The architecture of ParadisEO is multi-layer and modular allowing to achieve the objectives
//! quoted above. This allows particularly a high flexibility and adaptability, an
//! easier hybridization, and more code and design reuse. The architecture has three layers
//! identifying three major categories of classes: <i>Solvers</i>, <i>Runners</i> and <i>Helpers</i>.
//! <ul>
//! <li><i>Helpers</i>. Helpers are low-level classes that perform specific actions related to the evolution
//! or search process. They are split in two categories: <i>Evolutionary helpers (EH)</i>
//! and <i>Local search helpers (LSH)</i>. EH include mainly the transformation, selection and
//! replacement operations, the evaluation function and the stopping criterion. LSH can be
//! generic such as the neighborhood explorer class, or specific to the local search metaheuristic
//! like the tabu list manager class in the Tabu Search solution method. On the
//! other hand, there are some special helpers dedicated to the management of parallel and
//! distributed models 2 and 3, such as the communicators that embody the communication
//! services.
//!
//! Helpers cooperate between them and interact with the components of the upper layer
//! i.e. the runners. The runners invoke the helpers through function parameters. Indeed,
//! helpers have not their own data, but they work on the internal data of the runners.</li>
//!
//! <li><i>Runners</i>. The Runners layer contains a set of classes that implement the metaheuristics
//! themselves. They perform the run of the metaheuristics from the initial state or
//! population to the final one. One can distinguish the <i>Evolutionary runners (ER)</i> such as
//! genetic algorithms, evolution strategies, etc., and <i>Local search runners (LSR)</i> like tabu
//! search, simulated annealing and hill climbing. Runners invoke the helpers to perform
//! specific actions on their data. For instance, an ER may ask the fitness function evaluation
//! helper to evaluate its population. An LSR asks the movement helper to perform
//! a given movement on the current state. Furthermore, runners can be serial or parallel
//! distributed.</li>
//!
//! <li><i>Solvers</i>. Solvers are devoted to control the evolution process and/or the search. They
//! generate the initial state (solution or population) and define the strategy for combining
//! and sequencing different metaheuristics. Two types of solvers can be distinguished.
//! <i>Single metaheuristic solvers (SMS)</i> and <i>Multiple metaheuristics solvers (MMS)</i>. SMSs
//! are dedicated to the execution of only one metaheuristic.MMS are more complex as they
//! control and sequence several metaheuristics that can be heterogeneous. Solvers interact with
//! the user by getting the input data and delivering the output (best solution, statistics,
//! etc).</li>
//! </ul>
//!
//! According to the generality of their embedded features, the classes of the architecture split
//! in two major categories: <i>Provided classes</i> and <i>Required classes</i>. Provided classes embody
//! the factored out part of the metaheuristics. They are generic, implemented in the framework,
//! and ensure the control at run time. Required classes are those that must be supplied by the
//! user. They encapsulate the problem-specific aspects of the application. These classes are
//! fixed but not implemented in ParadisEO. The programmer has the burden to develop them
//! using the OO specialization mechanism.
//!
//! \section tutorials ParadisEO-PEO Tutorials
//!
//! The basisc of the ParadisEO framework philosophy are exposed in a few simple tutorials:
//! <ul>
//! <li>
//! <a href="lesson1/html/main.html" style="text-decoration:none;"> creating a simple ParadisEO evolutionary algorithm</a>;
//! </li>
//! </ul>
//! All the presented examples have as case study the traveling salesman problem (TSP). Different operators and auxiliary objects were designed,
//! standing as a <a href="lsnshared/html/index.html" target="new" style="text-decoration:none;">common shared source code base</a>. While not being
//! part of the ParadisEO-PEO framework, it may represent a startpoint for a better understanding of the presented tutorials.
#include "core/peo_init.h"
#include "core/peo_run.h"
#include "core/peo_fin.h"
#include "core/eoVector_comm.h"
#include "peoEA.h"
/* Parallel steps of the E.A. */
#include "peoSeqTransform.h"
#include "peoParaSGATransform.h"
#include "peoSeqPopEval.h"
#include "peoParaPopEval.h"
/* Cooperative island model */
#include "core/ring_topo.h"
#include "peoAsyncIslandMig.h"
#include "peoSyncIslandMig.h"
/* Synchronous multi-start model */
#include "peoSyncMultiStart.h"
#endif

View file

@ -0,0 +1,30 @@
// "peoAggEvalFunc.h"
// (c) OPAC Team, LIFL, August 2005
/*
Contact: paradiseo-help@lists.gforge.inria.fr
*/
#ifndef __peoAggEvalFunc_h
#define __peoAggEvalFunc_h
#include <eoFunctor.h>
//! Interface class for creating an aggregate evaluation function.
//! The peoAggEvalFunc class offers only the interface for creating aggregate evaluation functions - there
//! are no direct internal functions provided. The class inherits <b>public eoBF< EOT&, const typename EOT :: Fitness&, void ></b>
//! thus requiring, for the derived classes, the creation of a function having the following signature:
//!
//! <table style="border:none; border-spacing:0px;text-align:left; vertical-align:top; font-size:8pt;" border="0">
//! <tr><td>void operator()( EOT& __eot, const typename EOT :: Fitness& __partial_fittness ); &nbsp;</td> <td> &nbsp; </td></tr>
//! </table>
//!
//! The aggregation object is called in an iterative manner for each of the results obtained by applying partial evaluation functions.
template< class EOT > class peoAggEvalFunc : public eoBF< EOT&, const typename EOT :: Fitness&, void > {
};
#endif

View file

@ -0,0 +1,258 @@
// "peoAsyncIslandMig.h"
// (c) OPAC Team, LIFL, August 2005
/*
Contact: paradiseo-help@lists.gforge.inria.fr
*/
#ifndef __peoAsyncIslandMig_h
#define __peoAsyncIslandMig_h
#include <queue>
#include <utils/eoUpdater.h>
#include <eoContinue.h>
#include <eoSelect.h>
#include <eoReplacement.h>
#include <eoPop.h>
#include "core/topology.h"
#include "core/cooperative.h"
#include "core/eoPop_comm.h"
#include "core/peo_debug.h"
//! Class providing the basis for the asynchronous island migration model.
//! The peoAsyncIslandMig class offers the elementary basis for implementating an
//! asynchronous island migration model - requires the specification of several basic
//! parameters, i.e. continuation criterion, selection and replacement strategies,
//! a topological model and the source and destination population for the migrating individuals.
//! As opposed to the synchronous migration model, in the asynchronous migration approach, there is
//! no synchronization step between islands after performing the emigration phase.
//!
//! The migration operator is called at the end of each generation of an evolutionary algorithms
//! as a checkpoint object - the following code exposes the structure of a classic evolutionary algorithm:
//!
//! <table style="border:none; border-spacing:0px;text-align:left; vertical-align:top; font-size:8pt;" border="0">
//! <tr><td><b>do</b> { &nbsp;</td> <td> &nbsp; </td></tr>
//! <tr><td>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; select( population, offsprings ); &nbsp;</td> <td>// select the offsprings from the current population</td></tr>
//! <tr><td>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; transform( offsprings ); &nbsp;</td> <td>// crossover and mutation operators are applied on the selected offsprings</td></tr>
//! <tr><td>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; evaluate( offsprings ); &nbsp;</td> <td>// evaluation step of the resulting offsprings</td></tr>
//! <tr><td>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; replace( population, offsprings ); &nbsp;</td> <td>// replace the individuals in the current population whith individuals from the offspring population, according to a specified replacement strategy</td></tr>
//! <tr><td>} <b>while</b> ( eaCheckpointContinue( population ) ); &nbsp;</td> <td>// checkpoint operators are applied on the current population, including the migration operator, if any specified </td></tr>
//! </table>
//!
//! Constructing an asynchronous island migration model requires having defined (1) a topological migration model,
//! (2) the control parameters of the migration process, (3) a checkpoint object associated with an evolutionary algorithm,
//! and (4) an owner object must be set. The owner object must be derived from the <b>Runner</b> class (for example
//! a peoEA object represents a possible owner).
//! A simple example is offered bellow:
//!
//! <ol>
//! <li> topological model to be followed when performing migrations: <br/>
//! <br/>
//! <table style="border:none; border-spacing:0px;text-align:left; vertical-align:top; font-size:8pt;" border="0">
//! <tr><td>RingTopology migTopology; &nbsp;</td> <td>// a simple ring topological model - each island communicates with two other islands</td></tr>
//! </table>
//! </li>
//!
//! <li> the continuation criterion, selection and replacement strategy etc. are defined: <br/>
//! <br/>
//! <table style="border:none; border-spacing:0px; font-size:8pt;" border="0">
//! <tr><td>eoPop< EOT > population( POP_SIZE, popInitializer ); &nbsp;</td> <td>// population of individuals to be used for the evolutionary algorithm</td></tr>
//! <tr><td> &nbsp; </td> <td> &nbsp; </td></tr>
//! <tr><td>eoPeriodicContinue< EOT > migCont( MIG_FREQ ); &nbsp;</td> <td>// migrations occur periodically at MIG_FREQ iterations</td></tr>
//! <tr><td>eoRandomSelect< EOT > migSelectStrategy; &nbsp;</td> <td>// selection strategy - in this case a random selection is applied</td></tr>
//! <tr><td>eoSelectNumber< EOT > migSelect( migSelectStrategy, MIG_SIZE ); &nbsp;</td> <td>// number of individuals to be selected using the specified strategy</td></tr>
//! <tr><td>eoPlusReplacement< EOT > migReplace; &nbsp;</td> <td>// immigration strategy - the worse individuals in the destination population are replaced by the immigrant individuals</td></tr>
//! <tr><td> &nbsp; </td> <td> &nbsp; </td></tr>
//! <tr><td>peoAsyncIslandMig< EOT > asyncMigration(
//! <br/> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; migCont, migSelect, migReplace, migTopology,
//! <br/> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; population, population
//! <br/> ); &nbsp; </td>
//! <td>// asynchronous migration object - the emigrant individuals are selected from the same from population in which the immigrant individuals are being integrated </td></tr>
//! </table>
//! </li>
//!
//! <li> creation of a checkpoint object as part of the definition of an evolutionary algoritm (details of th EA not given as being out of scope): <br/>
//! <br/>
//! <table style="border:none; border-spacing:0px;text-align:left; vertical-align:top; font-size:8pt;" border="0">
//! <tr><td>... &nbsp;</td> <td> &nbsp; </td></tr>
//! <tr><td>eoGenContinue< EOT > eaCont( NUM_GEN ); &nbsp;</td> <td>// the evolutionary algorithm will stop after NUM_GEN generations</td></tr>
//! <tr><td>eoCheckPoint< EOT > eaCheckpointContinue( eaCont ); &nbsp;</td> <td>// number of individuals to be selected using the specified strategy</td></tr>
//! <tr><td>... &nbsp;</td> <td> &nbsp; </td></tr>
//! <tr><td>eaCheckpointContinue.add( asyncMigration ); &nbsp;</td> <td>// adding the migration operator as checkpoint element</td></tr>
//! <tr><td>... &nbsp;</td> <td> &nbsp; </td></tr>
//! </table>
//! </li>
//!
//! <li> definition of an owner evolutionary algorithm (an object inheriting the <b>Runner</b> class): <br/>
//! <br/>
//! <table style="border:none; border-spacing:0px;text-align:left; vertical-align:top; font-size:8pt;" border="0">
//! <tr><td>peoEA< EOT > eaAlg( eaCheckpointContinue, eaPopEval, eaSelect, eaTransform, eaReplace); &nbsp;</td> <td>// evolutionary algorithm having as checkpoint the eaCheckpointContinue object defined above </td></tr>
//! <tr><td>asyncMigration.setOwner( eaAlg ); &nbsp;</td> <td>// setting the evolutionary algorithm as owner of the migration object </td></tr>
//! <tr><td>eaAlg( population ); &nbsp;</td> <td>// applying the evolutionary algorithm on a given population </td></tr>
//! </table>
//! </li>
//! </ol>
//!
//! The source and the destination population for the migration object were specified as being the same, in step no. 2,
//! as we are usually interested in selecting the emigrants and integrating the immigrant individuals from and in, respectively, one unique
//! population, iteratively evolved by an evolutionary algorithm. There is no restriction in having two distinct populations
//! as source and destination for the emigrant and immigrant individuals respectively.
//!
//! The above steps only create an asynchronous migration object associated to an evolutionary algorithm. The creation of several
//! islands requires the reiteration of the steps 2 through 4 for creating distinct algorithms, with distinct populations and
//! 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).
template< class EOT > class peoAsyncIslandMig : public Cooperative, public eoUpdater {
public:
//! Constructor for the peoAsyncIslandMig 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.
//!
//! @param eoContinue< EOT >& __cont - continuation criterion specifying whether the migration is performed or not;
//! @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 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 >& __destination - destination population in which the immigrant population are integrated.
peoAsyncIslandMig(
eoContinue< EOT >& __cont,
eoSelect< EOT >& __select,
eoReplacement< EOT >& __replace,
Topology& __topology,
eoPop< EOT >& __source,
eoPop< EOT >& __destination
);
//! 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
//! 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.
void operator()();
//! Auxiliary function dealing with sending the emigrant individuals. There is no need to explicitly call the function.
void pack();
//! Auxiliary function dealing with receiving immigrant individuals. There is no need to explicitly call the function.
void unpack();
private:
void emigrate();
void immigrate();
private:
eoContinue< EOT >& cont; // continuator
eoSelect< EOT >& select; // the selection strategy
eoReplacement< EOT >& replace; // the replacement strategy
Topology& topology; // the neighboring topology
// source and destination populations
eoPop< EOT >& source;
eoPop< EOT >& destination;
// immigrants & emigrants in the queue
std :: queue< eoPop< EOT > > imm;
std :: queue< eoPop< EOT > > em;
std :: queue< Cooperative* > coop_em;
};
template< class EOT > peoAsyncIslandMig< EOT > :: peoAsyncIslandMig(
eoContinue< EOT >& __cont,
eoSelect< EOT >& __select,
eoReplacement< EOT >& __replace,
Topology& __topology,
eoPop< EOT >& __source,
eoPop< EOT >& __destination
) : cont( __cont ), select( __select ), replace( __replace ), topology( __topology ), source( __source ), destination( __destination )
{
__topology.add( *this );
}
template< class EOT > void peoAsyncIslandMig< EOT > :: pack()
{
lock(); {
:: pack( coop_em.front()->getKey() );
:: pack( em.front() );
coop_em.pop();
em.pop();
}
unlock();
}
template< class EOT > void peoAsyncIslandMig< EOT > :: unpack()
{
lock(); {
eoPop< EOT > mig;
:: unpack( mig );
imm.push( mig );
}
unlock();
}
template< class EOT > void peoAsyncIslandMig< EOT > :: emigrate()
{
std :: vector< Cooperative* >in, out;
topology.setNeighbors( this, in, out );
for ( unsigned i = 0; i < out.size(); i++ ) {
eoPop< EOT > mig;
select( source, mig );
em.push( mig );
coop_em.push( out[i] );
send( out[i] );
printDebugMessage( "sending some emigrants." );
}
}
template< class EOT > void peoAsyncIslandMig< EOT > :: immigrate()
{
lock(); {
while ( !imm.empty() ) {
replace( destination, imm.front() );
imm.pop();
printDebugMessage( "receiving some immigrants." );
}
}
unlock();
}
template< class EOT > void peoAsyncIslandMig< EOT > :: operator()() {
if ( !cont( source ) ) {
emigrate(); // sending emigrants
immigrate(); // receiving immigrants
}
}
#endif

View file

@ -0,0 +1,145 @@
// "peoEA.h"
// (c) OPAC Team, LIFL, August 2005
/*
Contact: paradiseo-help@lists.gforge.inria.fr
*/
#ifndef __peoEA_h
#define __peoEA_h
#include <eoContinue.h>
#include <eoEvalFunc.h>
#include <eoSelect.h>
#include <eoPopEvalFunc.h>
#include <eoReplacement.h>
#include "peoPopEval.h"
#include "peoTransform.h"
#include "core/runner.h"
#include "core/peo_debug.h"
//! Class providing an elementary ParadisEO evolutionary algorithm.
//! The peoEA class offers an elementary evolutionary algorithm implementation. In addition, as compared
//! with the algorithms provided by the EO framework, the peoEA class has the underlying necessary structure
//! for including, for example, parallel evaluation and parallel transformation operators, migration operators
//! etc. Although there is no restriction on using the algorithms provided by the EO framework, the drawback resides
//! in the fact that the EO implementation is exclusively sequential and, in consequence, no parallelism is provided.
//! A simple example for constructing a peoEA object:
//!
//! <table style="border:none; border-spacing:0px;text-align:left; vertical-align:top; font-size:8pt;" border="0">
//! <tr><td>... &nbsp;</td> <td> &nbsp; </td></tr>
//! <tr><td>eoPop< EOT > population( POP_SIZE, popInitializer ); &nbsp;</td> <td>// creation of a population with POP_SIZE individuals - the popInitializer is a functor to be called for each individual</td></tr>
//! <tr><td> &nbsp; </td> <td> &nbsp; </td></tr>
//! <tr><td>eoGenContinue< EOT > eaCont( NUM_GEN ); &nbsp;</td> <td>// number of generations for the evolutionary algorithm</td></tr>
//! <tr><td>eoCheckPoint< EOT > eaCheckpointContinue( eaCont ); &nbsp;</td> <td>// checkpoint incorporating the continuation criterion - startpoint for adding other checkpoint objects</td></tr>
//! <tr><td> &nbsp; </td> <td> &nbsp; </td></tr>
//! <tr><td>peoSeqPopEval< EOT > eaPopEval( evalFunction ); &nbsp;</td> <td>// sequential evaluation functor wrapper - evalFunction represents the actual evaluation functor </td></tr>
//! <tr><td> &nbsp; </td> <td> &nbsp; </td></tr>
//! <tr><td>eoRankingSelect< EOT > selectionStrategy; &nbsp;</td> <td>// selection strategy for creating the offspring population - a simple ranking selection in this case </td></tr>
//! <tr><td>eoSelectNumber< EOT > eaSelect( selectionStrategy, POP_SIZE ); &nbsp;</td> <td>// the number of individuals to be selected for creating the offspring population </td></tr>
//! <tr><td>eoRankingSelect< EOT > selectionStrategy; &nbsp;</td> <td>// selection strategy for creating the offspring population - a simple ranking selection in this case </td></tr>
//! <tr><td> &nbsp; </td> <td> &nbsp; </td></tr>
//! <tr><td>eoSGATransform< EOT > transform( crossover, CROSS_RATE, mutation, MUT_RATE ); &nbsp;</td> <td>// transformation operator - crossover and mutation operators with their associated probabilities </td></tr>
//! <tr><td>peoSeqTransform< EOT > eaTransform( transform ); &nbsp;</td> <td>// ParadisEO specific sequential operator - a parallel version may be specified in the same manner </td></tr>
//! <tr><td> &nbsp; </td> <td> &nbsp; </td></tr>
//! <tr><td>eoPlusReplacement< EOT > eaReplace; &nbsp;</td> <td>// replacement strategy - for integrating the offspring resulting individuals in the initial population </td></tr>
//! <tr><td> &nbsp; </td> <td> &nbsp; </td></tr>
//! <tr><td>peoEA< EOT > eaAlg( eaCheckpointContinue, eaPopEval, eaSelect, eaTransform, eaReplace ); &nbsp;</td> <td>// ParadisEO evolutionary algorithm integrating the above defined objects </td></tr>
//! <tr><td>eaAlg( population ); &nbsp;</td> <td>// specifying the initial population for the algorithm </td></tr>
//! <tr><td>... &nbsp;</td> <td> &nbsp; </td></tr>
//! </table>
template < class EOT > class peoEA : public Runner {
public:
//! 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
//! 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,
//! 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 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 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;
peoEA(
eoContinue< EOT >& __cont,
peoPopEval< EOT >& __pop_eval,
eoSelect< EOT >& __select,
peoTransform< EOT >& __trans,
eoReplacement< EOT >& __replace
);
//! 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.
void run();
//! 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;
void operator()( eoPop< EOT >& __pop );
private:
eoContinue< EOT >& cont;
peoPopEval< EOT >& pop_eval;
eoSelect< EOT >& select;
peoTransform< EOT >& trans;
eoReplacement< EOT >& replace;
eoPop< EOT >* pop;
};
template < class EOT > peoEA< EOT > :: peoEA(
eoContinue< EOT >& __cont,
peoPopEval< EOT >& __pop_eval,
eoSelect< EOT >& __select,
peoTransform< EOT >& __trans,
eoReplacement< EOT >& __replace
) : cont( __cont ), pop_eval( __pop_eval ), select( __select ), trans( __trans ), replace( __replace )
{
trans.setOwner( *this );
pop_eval.setOwner( *this );
}
template< class EOT > void peoEA< EOT > :: operator ()( eoPop< EOT >& __pop ) {
pop = &__pop;
}
template< class EOT > void peoEA< EOT > :: run() {
printDebugMessage( "performing the first evaluation of the population." );
pop_eval( *pop );
do {
eoPop< EOT > off;
printDebugMessage( "performing the selection step." );
select( *pop, off );
trans( off );
printDebugMessage( "performing the evaluation of the population." );
pop_eval( off );
printDebugMessage( "performing the replacement of the population." );
replace( *pop, off );
printDebugMessage( "deciding of the continuation." );
} while ( cont( *pop ) );
}
#endif

View file

@ -0,0 +1,34 @@
// "peoNoAggEvalFunc.h"
// (c) OPAC Team, LIFL, August 2005
/*
Contact: paradiseo-help@lists.gforge.inria.fr
*/
#ifndef __peoNoAggEvalFunc_h
#define __peoNoAggEvalFunc_h
#include "peoAggEvalFunc.h"
//! Class providing a simple interface for associating a fitness value to a specified individual.
//! The peoNoAggEvalFunc class does nothing more than an association between a fitness value and a specified individual.
//! The class is provided as a mean of declaring that no aggregation is required for the evaluation function - the fitness
//! value is explicitly specified.
template< class EOT > class peoNoAggEvalFunc : public peoAggEvalFunc< EOT > {
public :
//! 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 );
};
template< class EOT > void peoNoAggEvalFunc< EOT > :: operator()( EOT& __sol, const typename EOT :: Fitness& __fit ) {
__sol.fitness( __fit );
}
#endif

View file

@ -0,0 +1,225 @@
// "peoParaPopEval.h"
// (c) OPAC Team, LIFL, August 2005
/*
Contact: paradiseo-help@lists.gforge.inria.fr
*/
#ifndef __peoParaPopEval_h
#define __peoParaPopEval_h
#include <queue>
#include <eoEvalFunc.h>
#include "core/messaging.h"
#include "core/peo_debug.h"
#include "peoAggEvalFunc.h"
#include "peoNoAggEvalFunc.h"
//! Parallel evaluation functor wrapper.
//! The peoParaPopEval represents a wrapper for creating a functor capable of applying in parallel
//! an EO-derived evaluation functor. The class offers the possibility of chosing between a single-function evaluation
//! and an aggregate evaluation function, including several sub-evalution functions.
template< class EOT > class peoParaPopEval : public peoPopEval< EOT > {
public:
using peoPopEval< EOT > :: requestResourceRequest;
using peoPopEval< EOT > :: resume;
using peoPopEval< EOT > :: stop;
using peoPopEval< EOT > :: getOwner;
//! Constructor function - an EO-derived evaluation functor has to be specified; an internal reference
//! is set towards the specified evaluation functor.
//!
//! @param eoEvalFunc< EOT >& __eval_func - EO-derived evaluation functor to be applied in parallel on each individual of a specified population
peoParaPopEval( eoEvalFunc< EOT >& __eval_func );
//! Constructor function - a vector of EO-derived evaluation functors has to be specified as well as an aggregation function.
//!
//! @param const std :: vector< eoEvalFunc < EOT >* >& __funcs - vector of EO-derived partial evaluation functors;
//! @param peoAggEvalFunc< EOT >& __merge_eval - aggregation functor for creating a fitness value out of the partial fitness values.
peoParaPopEval( const std :: vector< eoEvalFunc < EOT >* >& __funcs, peoAggEvalFunc< EOT >& __merge_eval );
//! Operator for applying the evaluation functor (direct or aggregate) for each individual of the specified population.
//!
//! @param eoPop< EOT >& __pop - population to be evaluated by applying the evaluation functor specified in the constructor.
void operator()( eoPop< EOT >& __pop );
//! Auxiliary function for transferring data between the process requesting an evaluation operation and the process that
//! performs the actual evaluation phase. There is no need to explicitly call the function.
void packData();
//! Auxiliary function for transferring data between the process requesting an evaluation operation and the process that
//! performs the actual evaluation phase. There is no need to explicitly call the function.
void unpackData();
//! Auxiliary function - it calls the specified evaluation functor(s). There is no need to explicitly call the function.
void execute();
//! Auxiliary function for transferring data between the process requesting an evaluation operation and the process that
//! performs the actual evaluation phase. There is no need to explicitly call the function.
void packResult();
//! Auxiliary function for transferring data between the process requesting an evaluation operation and the process that
//! performs the actual evaluation phase. There is no need to explicitly call the function.
void unpackResult();
//! Auxiliary function for notifications between the process requesting an evaluation operation and the processes that
//! performs the actual evaluation phase. There is no need to explicitly call the function.
void notifySendingData();
//! Auxiliary function for notifications between the process requesting an evaluation operation and the processes that
//! performs the actual evaluation phase. There is no need to explicitly call the function.
void notifySendingAllResourceRequests();
private:
const std :: vector< eoEvalFunc < EOT >* >& funcs;
std :: vector< eoEvalFunc < EOT >* > one_func;
peoAggEvalFunc< EOT >& merge_eval;
peoNoAggEvalFunc< EOT > no_merge_eval;
std :: queue< EOT* >tasks;
std :: map< EOT*, std :: pair< unsigned, unsigned > > progression;
unsigned num_func;
EOT sol;
EOT *ad_sol;
unsigned total;
};
template< class EOT > peoParaPopEval< EOT > :: peoParaPopEval( eoEvalFunc< EOT >& __eval_func ) :
funcs( one_func ), merge_eval( no_merge_eval )
{
one_func.push_back( &__eval_func );
}
template< class EOT > peoParaPopEval< EOT > :: peoParaPopEval(
const std :: vector< eoEvalFunc< EOT >* >& __funcs,
peoAggEvalFunc< EOT >& __merge_eval
) : funcs( __funcs ), merge_eval( __merge_eval )
{
}
template< class EOT > void peoParaPopEval< EOT >::operator()( eoPop< EOT >& __pop ) {
for ( unsigned i = 0; i < __pop.size(); i++ ) {
__pop[ i ].fitness( typename EOT :: Fitness() );
progression[ &__pop[ i ] ].first = funcs.size() - 1;
progression[ &__pop[ i ] ].second = funcs.size();
for ( unsigned j = 0; j < funcs.size(); j++ ) {
/* Queuing the 'invalid' solution and its associated owner */
tasks.push( &__pop[ i ] );
}
}
total = funcs.size() * __pop.size();
requestResourceRequest( funcs.size() * __pop.size() );
stop();
}
template< class EOT > void peoParaPopEval< EOT > :: packData() {
// printDebugMessage ("debut pakc data");
pack( progression[ tasks.front() ].first-- );
/* Packing the contents :-) of the solution */
pack( *tasks.front() );
/* Packing the addresses of both the solution and the owner */
pack( tasks.front() );
tasks.pop( );
}
template< class EOT > void peoParaPopEval< EOT > :: unpackData() {
unpack( num_func );
/* Unpacking the solution */
unpack( sol );
/* Unpacking the @ of that one */
unpack( ad_sol );
}
template< class EOT > void peoParaPopEval< EOT > :: execute() {
/* Computing the fitness of the solution */
funcs[ num_func ]->operator()( sol );
}
template< class EOT > void peoParaPopEval< EOT > :: packResult() {
/* Packing the fitness of the solution */
pack( sol.fitness() );
/* Packing the @ of the individual */
pack( ad_sol );
}
template< class EOT > void peoParaPopEval< EOT > :: unpackResult() {
typename EOT :: Fitness fit;
/* Unpacking the computed fitness */
unpack( fit );
/* Unpacking the @ of the associated individual */
unpack( ad_sol );
/* Associating the fitness the local solution */
merge_eval( *ad_sol, fit );
progression[ ad_sol ].second--;
/* Notifying the container of the termination of the evaluation */
if ( !progression[ ad_sol ].second ) {
progression.erase( ad_sol );
}
total--;
if ( !total ) {
getOwner()->setActive();
resume();
}
}
template< class EOT > void peoParaPopEval< EOT > :: notifySendingData() {
}
template< class EOT > void peoParaPopEval< EOT > :: notifySendingAllResourceRequests() {
getOwner()->setPassive();
}
#endif

View file

@ -0,0 +1,155 @@
// "peoParaSGATransform.h"
//(c) OPAC Team, LIFL, August 2005
/*
Contact: paradiseo-help@lists.gforge.inria.fr
*/
#ifndef __peoParaSGATransform_h
#define __peoParaSGATransform_h
#include "peoTransform.h"
#include "core/thread.h"
#include "core/messaging.h"
#include "core/peo_debug.h"
extern int getNodeRank();
template< class EOT > class peoParaSGATransform : public peoTransform< EOT > {
public:
using peoTransform< EOT > :: requestResourceRequest;
using peoTransform< EOT > :: resume;
using peoTransform< EOT > :: stop;
using peoTransform< EOT > :: getOwner;
peoParaSGATransform(
eoQuadOp< EOT >& __cross,
double __cross_rate,
eoMonOp< EOT >& __mut,
double __mut_rate
);
void operator()( eoPop< EOT >& __pop );
void packData();
void unpackData();
void execute();
void packResult();
void unpackResult();
void notifySendingData();
void notifySendingAllResourceRequests();
private:
eoQuadOp< EOT >& cross;
double cross_rate;
eoMonOp< EOT >& mut;
double mut_rate;
unsigned idx;
eoPop< EOT >* pop;
EOT father, mother;
unsigned num_term;
};
template< class EOT > peoParaSGATransform< EOT > :: peoParaSGATransform(
eoQuadOp< EOT >& __cross,
double __cross_rate,
eoMonOp < EOT >& __mut,
double __mut_rate
) : cross( __cross ), cross_rate( __cross_rate ), mut( __mut ), mut_rate( __mut_rate )
{
}
template< class EOT > void peoParaSGATransform< EOT > :: packData() {
pack( idx );
:: pack( pop->operator[]( idx++ ) );
:: pack( pop->operator[]( idx++ ) );
}
template< class EOT > void peoParaSGATransform< EOT > :: unpackData() {
unpack( idx );
:: unpack( father );
:: unpack( mother );
}
template< class EOT > void peoParaSGATransform< EOT > :: execute() {
if( rng.uniform() < cross_rate ) cross( mother, father );
if( rng.uniform() < mut_rate ) mut( mother );
if( rng.uniform() < mut_rate ) mut( father );
}
template< class EOT > void peoParaSGATransform< EOT > :: packResult() {
pack( idx );
:: pack( father );
:: pack( mother );
}
template< class EOT > void peoParaSGATransform< EOT > :: unpackResult() {
unsigned sidx;
unpack( sidx );
:: unpack( pop->operator[]( sidx++ ) );
:: unpack( pop->operator[]( sidx ) );
num_term += 2;
if( num_term == pop->size() ) {
getOwner()->setActive();
resume();
}
}
template< class EOT > void peoParaSGATransform< EOT > :: operator()( eoPop < EOT >& __pop ) {
printDebugMessage( "performing the parallel transformation step." );
pop = &__pop;
idx = 0;
num_term = 0;
requestResourceRequest( __pop.size() / 2 );
stop();
}
template< class EOT > void peoParaSGATransform< EOT > :: notifySendingData() {
}
template< class EOT > void peoParaSGATransform< EOT > :: notifySendingAllResourceRequests() {
getOwner()->setPassive();
}
#endif

View file

@ -0,0 +1,28 @@
// "peoPopEval.h"
// (c) OPAC Team, LIFL, August 2005
/*
Contact: paradiseo-help@lists.gforge.inria.fr
*/
#ifndef __peoPopEval_h
#define __peoPopEval_h
#include "core/service.h"
//! Interface for ParadisEO specific evaluation functors.
//! The <b>peoPopEval</b> class provides the interface for constructing ParadisEO specific evaluation functors.
//! 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.
template< class EOT > class peoPopEval : public Service {
public:
//! Interface function providing the signature for constructing an evaluation functor.
virtual void operator()( eoPop< EOT >& __pop ) = 0;
};
#endif

View file

@ -0,0 +1,53 @@
// "peoSeqPopEval.h"
// (c) OPAC Team, LIFL, August 2005
/*
Contact: paradiseo-help@lists.gforge.inria.fr
*/
#ifndef __peoSeqPopEval_h
#define __peoSeqPopEval_h
#include <eoEvalFunc.h>
#include "peoPopEval.h"
//! Sequential evaluation functor wrapper.
//! The peoSeqPopEval class acts only as a ParadisEO specific sequential evaluation functor - a wrapper for incorporating
//! an <b>eoEvalFunc< EOT ></b>-derived class as evaluation functor. The specified EO evaluation object is applyied in an
//! iterative manner to each individual of a specified population.
template< class EOT > class peoSeqPopEval : public peoPopEval< EOT > {
public:
//! Constructor function - it only sets an internal reference to point to the specified evaluation object.
//!
//! @param eoEvalFunc< EOT >& __eval - evaluation object to be applied for each individual of a specified population
peoSeqPopEval( eoEvalFunc< EOT >& __eval );
//! Operator for evaluating all the individuals of a given population - in a sequential iterative manner.
//!
//! @param eoPop< EOT >& __pop - population to be evaluated.
void operator()( eoPop< EOT >& __pop );
private:
eoEvalFunc< EOT >& eval;
};
template< class EOT > peoSeqPopEval< EOT > :: peoSeqPopEval( eoEvalFunc< EOT >& __eval ) : eval( __eval ) {
}
template< class EOT > void peoSeqPopEval< EOT > :: operator()( eoPop< EOT >& __pop ) {
for ( unsigned i = 0; i < __pop.size(); i++ )
eval( __pop[i] );
}
#endif

View file

@ -0,0 +1,66 @@
// "peoSeqTransform.h"
// (c) OPAC Team, LIFL, August 2005
/*
Contact: paradiseo-help@lists.gforge.inria.fr
*/
#ifndef __peoSeqTransform_h
#define __peoSeqTransform_h
#include "peoTransform.h"
//! ParadisEO specific wrapper class offering the possibility of using EO derived transform operators.
//! The peoSeqTransform represent a wrapper for offering the possibility of using EO derived transform operators
//! along with the ParadisEO evolutionary algorithms. A minimal set of interface functions is also provided for creating the
//! link with the parallel architecture of the ParadisEO framework.
template< class EOT > class peoSeqTransform : public peoTransform< EOT > {
public:
//! Constructor function - sets an internal reference towards the specified EO-derived transform object.
//!
//! @param eoTransform< EOT >& __trans - EO-derived transform object including crossover and mutation operators.
peoSeqTransform( eoTransform< EOT >& __trans );
//! Operator for applying the specified transform operators on each individual of the given population.
//!
//! @param eoPop< EOT >& __pop - population to be transformed by applying the crossover and mutation operators.
void operator()( eoPop< EOT >& __pop );
//! Interface function for providing a link with the parallel architecture of the ParadisEO framework.
virtual void packData() { }
//! Interface function for providing a link with the parallel architecture of the ParadisEO framework.
virtual void unpackData() { }
//! Interface function for providing a link with the parallel architecture of the ParadisEO framework.
virtual void execute() { }
//! Interface function for providing a link with the parallel architecture of the ParadisEO framework.
virtual void packResult() { }
//! Interface function for providing a link with the parallel architecture of the ParadisEO framework.
virtual void unpackResult() { }
private:
eoTransform< EOT >& trans;
};
template< class EOT > peoSeqTransform< EOT > :: peoSeqTransform( eoTransform< EOT >& __trans ) : trans( __trans ) {
}
template< class EOT > void peoSeqTransform< EOT > :: operator()( eoPop< EOT >& __pop ) {
trans( __pop );
}
#endif

View file

@ -0,0 +1,286 @@
// "peoSyncIslandMig.h"
// (c) OPAC Team, LIFL, August 2005
/*
Contact: paradiseo-help@lists.gforge.inria.fr
*/
#ifndef __peoSyncIslandMig_h
#define __peoSyncIslandMig_h
#include <queue>
#include <cassert>
#include <eoPeriodicContinue.h>
#include <utils/eoUpdater.h>
#include <eoContinue.h>
#include <eoSelect.h>
#include <eoReplacement.h>
#include <eoPop.h>
#include "core/topology.h"
#include "core/thread.h"
#include "core/eoPop_comm.h"
#include "core/peo_debug.h"
//! Class providing the basis for the synchronous island migration model.
//! The peoSyncIslandMig class offers the elementary basis for implementating a
//! synchronous island migration model - requires the specification of several basic
//! parameters, i.e. frequency of the migrations, selection and replacement strategies,
//! a topological model and the source and destination population for the migrating individuals.
//! The main difference as opposed to the asynchronous migration model is the synchronization step
//! performed after selecting and sending the emigrant individuals.
//!
//! The migration operator is called at the end of each generation of an evolutionary algorithms
//! as a checkpoint object - the following code exposes the structure of a classic evolutionary algorithm:
//!
//! <table style="border:none; border-spacing:0px;text-align:left; vertical-align:top; font-size:8pt;" border="0">
//! <tr><td><b>do</b> { &nbsp;</td> <td> &nbsp; </td></tr>
//! <tr><td>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; select( population, offsprings ); &nbsp;</td> <td>// select the offsprings from the current population</td></tr>
//! <tr><td>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; transform( offsprings ); &nbsp;</td> <td>// crossover and mutation operators are applied on the selected offsprings</td></tr>
//! <tr><td>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; evaluate( offsprings ); &nbsp;</td> <td>// evaluation step of the resulting offspring</td></tr>
//! <tr><td>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; replace( population, offsprings ); &nbsp;</td> <td>// replace the individuals in the current population whith individuals from the offspring population, according to a specified replacement strategy</td></tr>
//! <tr><td>} <b>while</b> ( eaCheckpointContinue( population ) ); &nbsp;</td> <td>// checkpoint operators are applied on the current population, including the migration operator, if any specified </td></tr>
//! </table>
//!
//! Constructing a synchronous island migration model requires having defined (1) a topological migration model,
//! (2) the control parameters of the migration process, (3) a checkpoint object associated with an evolutionary algorithm,
//! and (4) an owner object must be set. The owner object must be derived from the <b>Runner</b> class (for example
//! a peoEA object represents a possible owner).
//! A simple example is offered bellow:
//!
//! <ol>
//! <li> topological model to be followed when performing migrations: <br/>
//! <br/>
//! <table style="border:none; border-spacing:0px;text-align:left; vertical-align:top; font-size:8pt;" border="0">
//! <tr><td>RingTopology migTopology; &nbsp;</td> <td>// a simple ring topological model - each island communicates with two other islands</td></tr>
//! </table>
//! </li>
//!
//! <li> the continuation criterion, selection and replacement strategy etc. are defined: <br/>
//! <br/>
//! <table style="border:none; border-spacing:0px; font-size:8pt;" border="0">
//! <tr><td>eoPop< EOT > population( POP_SIZE, popInitializer ); &nbsp;</td> <td>// population of individuals to be used for the evolutionary algorithm</td></tr>
//! <tr><td> &nbsp; </td> <td> &nbsp; </td></tr>
//! <tr><td>eoRandomSelect< EOT > migSelectStrategy; &nbsp;</td> <td>// selection strategy - in this case a random selection is applied</td></tr>
//! <tr><td>eoSelectNumber< EOT > migSelect( migSelectStrategy, MIG_SIZE ); &nbsp;</td> <td>// number of individuals to be selected using the specified strategy</td></tr>
//! <tr><td>eoPlusReplacement< EOT > migReplace; &nbsp;</td> <td>// immigration strategy - the worse individuals in the destination population are replaced by the immigrant individuals</td></tr>
//! <tr><td> &nbsp; </td> <td> &nbsp; </td></tr>
//! <tr><td>peoSyncIslandMig< EOT > syncMigration(
//! <br/> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; MIG_FREQ, migSelect, migReplace, migTopology,
//! <br/> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; population, population
//! <br/> ); &nbsp; </td>
//! <td>// synchronous migration object - the emigrant individuals are selected from the same from population in which the immigrant individuals are being integrated </td></tr>
//! </table>
//! </li>
//!
//! <li> creation of a checkpoint object as part of the definition of an evolutionary algoritm (details of th EA not given as being out of scope): <br/>
//! <br/>
//! <table style="border:none; border-spacing:0px;text-align:left; vertical-align:top; font-size:8pt;" border="0">
//! <tr><td>... &nbsp;</td> <td> &nbsp; </td></tr>
//! <tr><td>eoGenContinue< EOT > eaCont( NUM_GEN ); &nbsp;</td> <td>// the evolutionary algorithm will stop after NUM_GEN generations</td></tr>
//! <tr><td>eoCheckPoint< EOT > eaCheckpointContinue( eaCont ); &nbsp;</td> <td>// number of individuals to be selected using the specified strategy</td></tr>
//! <tr><td>... &nbsp;</td> <td> &nbsp; </td></tr>
//! <tr><td>eaCheckpointContinue.add( syncMigration ); &nbsp;</td> <td>// adding the migration operator as checkpoint element</td></tr>
//! <tr><td>... &nbsp;</td> <td> &nbsp; </td></tr>
//! </table>
//! </li>
//!
//! <li> definition of an owner evolutionary algorithm (an object inheriting the <b>Runner</b> class): <br/>
//! <br/>
//! <table style="border:none; border-spacing:0px;text-align:left; vertical-align:top; font-size:8pt;" border="0">
//! <tr><td>peoEA< EOT > eaAlg( eaCheckpointContinue, eaPopEval, eaSelect, eaTransform, eaReplace); &nbsp;</td> <td>// evolutionary algorithm having as checkpoint the eaCheckpointContinue object defined above </td></tr>
//! <tr><td>syncMigration.setOwner( eaAlg ); &nbsp;</td> <td>// setting the evolutionary algorithm as owner of the migration object </td></tr>
//! <tr><td>eaAlg( population ); &nbsp;</td> <td>// applying the evolutionary algorithm on a given population </td></tr>
//! </table>
//! </li>
//! </ol>
//!
//! The source and the destination population for the migration object were specified as being the same, in step no. 2,
//! as we are usually interested in selecting the emigrants and integrating the immigrant individuals from and in, respectively, one unique
//! population, iteratively evolved by an evolutionary algorithm. There is no restriction in having two distinct populations
//! as source and destination for the emigrant and immigrant individuals respectively.
//!
//! The above steps only create a synchronous migration object associated to an evolutionary algorithm. The creation of several
//! islands requires the reiteration of the steps 2 through 4 for creating distinct algorithms, with distinct populations and
//! 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).
template< class EOT > class peoSyncIslandMig : public Cooperative, public eoUpdater {
public:
//! 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.
//!
//! @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 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 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.
peoSyncIslandMig(
unsigned __frequency,
eoSelect< EOT >& __select,
eoReplacement< EOT >& __replace,
Topology& __topology,
eoPop< EOT >& __source,
eoPop< EOT >& __destination
);
//! 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
//! 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.
void operator()();
//! Auxiliary function dealing with sending the emigrant individuals. There is no need to explicitly call the function.
void pack();
//! Auxiliary function dealing with receiving immigrant individuals. There is no need to explicitly call the function.
void unpack();
//! Auxiliary function dealing with migration notifications. There is no need to explicitly call the function.
void notifySending();
private:
void emigrate();
void immigrate();
private:
eoPeriodicContinue< EOT > cont;
eoSelect< EOT >& select; // selection strategy
eoReplacement< EOT >& replace; // replacement strategy
Topology& topology; // neighboring topology
// source and target populations
eoPop< EOT >& source;
eoPop< EOT >& destination;
// immigrants & emigrants in the queue
std :: queue< eoPop< EOT > > imm;
std :: queue< eoPop< EOT > > em;
std :: queue< Cooperative* > coop_em;
sem_t sync;
};
template< class EOT > peoSyncIslandMig< EOT > :: peoSyncIslandMig(
unsigned __frequency,
eoSelect< EOT >& __select,
eoReplacement< EOT >& __replace,
Topology& __topology,
eoPop< EOT >& __source,
eoPop< EOT >& __destination
) : cont( __frequency ), select( __select ), replace( __replace ), topology( __topology ), source( __source ), destination( __destination )
{
__topology.add( *this );
sem_init( &sync, 0, 0 );
}
template< class EOT > void peoSyncIslandMig< EOT > :: pack() {
lock(); {
:: pack( coop_em.front()->getKey() );
:: pack( em.front() );
coop_em.pop();
em.pop();
}
unlock();
}
template< class EOT > void peoSyncIslandMig< EOT > :: unpack() {
lock(); {
eoPop< EOT > mig;
:: unpack( mig );
imm.push( mig );
}
unlock();
sem_post( &sync );
}
template< class EOT > void peoSyncIslandMig< EOT > :: emigrate() {
std :: vector< Cooperative* > in, out;
topology.setNeighbors( this, in, out );
for ( unsigned i = 0; i < out.size(); i ++ ) {
eoPop< EOT > mig;
select( source, mig );
em.push( mig );
coop_em.push( out[ i ] );
send( out[ i ] );
printDebugMessage( "sending some emigrants." );
}
}
template< class EOT > void peoSyncIslandMig< EOT > :: immigrate() {
lock(); {
assert( imm.size() );
replace( destination, imm.front() ) ;
imm.pop();
printDebugMessage( "receiving some immigrants." );
}
unlock();
}
template< class EOT > void peoSyncIslandMig< EOT > :: operator()() {
if ( !cont( source ) ) {
// sending emigrants
emigrate();
stop();
// synchronizing
sem_wait( &sync );
getOwner()->setActive();
// receiving immigrants
immigrate();
}
}
template< class EOT > void peoSyncIslandMig< EOT > :: notifySending() {
lock(); {
if ( imm.empty() ) {
printDebugMessage( "entering pasive mode\n" );
getOwner()->setPassive();
}
}
unlock();
resume();
}
#endif

View file

@ -0,0 +1,183 @@
// "peoSyncMultiStart.h"
// (c) OPAC Team, LIFL, August 2005
/*
Contact: paradiseo-help@lists.gforge.inria.fr
*/
#ifndef __peoSyncMultiStart_h
#define __peoSyncMultiStart_h
#include <utils/eoUpdater.h>
#include <moAlgo.h>
#include <eoSelect.h>
#include <eoReplacement.h>
#include <eoContinue.h>
#include "core/service.h"
#include "core/messaging.h"
#include "core/peo_debug.h"
extern int getNodeRank();
//! Class providing the basis for the synchronous multi-start model.
//! The peoSyncMultiStart class provides the basis for implementing the synchronous multi-start model,
//! for launching several solution-based algorithms in parallel on a specified initial population. As a simple
//! example, several hill climbing algorithms may be synchronously launched on the specified population, each
//! algorithm acting upon one individual only, the final result being integrated back in the population. A
//! peoSyncMultiStart object can be specified as checkpoint object for a classic ParadisEO evolutionary algorithm
//! 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.
template< class EOT > class peoSyncMultiStart : public Service, public eoUpdater {
public:
//! 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 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 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.
peoSyncMultiStart(
eoContinue< EOT >& __cont,
eoSelect< EOT >& __select,
eoReplacement< EOT >& __replace,
moAlgo< EOT >& __ls,
eoPop< EOT >& __pop
);
//! 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.
void operator()();
//! 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.
void packData();
//! 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.
void unpackData();
//! Auxiliary function for actually executing the specified algorithm on one assigned individual. There is no need to
//! explicitly call the function.
void execute();
//! 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.
void packResult();
//! 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.
void unpackResult();
//! 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.
void notifySendingData();
//! 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.
void notifySendingAllResourceRequests();
private:
eoContinue< EOT >& cont;
eoSelect< EOT >& select;
eoReplacement< EOT >& replace;
moAlgo< EOT >& ls;
eoPop< EOT >& pop;
eoPop< EOT > sel;
eoPop< EOT > impr_sel;
EOT sol;
unsigned idx;
unsigned num_term;
};
template< class EOT > peoSyncMultiStart< EOT > :: peoSyncMultiStart(
eoContinue < EOT >& __cont,
eoSelect< EOT >& __select,
eoReplacement< EOT >& __replace,
moAlgo < EOT >& __ls,
eoPop< EOT >& __pop
) : cont( __cont ), select( __select ), replace( __replace ), ls( __ls ), pop( __pop )
{
}
template< class EOT > void peoSyncMultiStart< EOT > :: packData() {
:: pack( sel[ idx++ ] );
}
template< class EOT > void peoSyncMultiStart< EOT > :: unpackData() {
unpack( sol );
}
template< class EOT > void peoSyncMultiStart< EOT > :: execute() {
ls( sol );
}
template< class EOT > void peoSyncMultiStart< EOT > :: packResult() {
pack( sol );
}
template< class EOT > void peoSyncMultiStart< EOT > :: unpackResult() {
unpack( sol );
impr_sel.push_back( sol );
num_term++;
if ( num_term == sel.size() ) {
getOwner()->setActive();
replace( pop, impr_sel );
printDebugMessage( "replacing the improved individuals in the population." );
resume();
}
}
template< class EOT > void peoSyncMultiStart< EOT > :: operator()() {
printDebugMessage( "performing the parallel multi-start hybridization." );
select( pop, sel );
impr_sel.clear();
idx = num_term = 0;
requestResourceRequest( sel.size() );
stop();
}
template< class EOT > void peoSyncMultiStart< EOT > :: notifySendingData() {
}
template< class EOT > void peoSyncMultiStart< EOT > :: notifySendingAllResourceRequests() {
getOwner()->setPassive();
}
#endif

View file

@ -0,0 +1,25 @@
// "peoTransform.h"
// (c) OPAC Team, LIFL, August 2005
/*
Contact: paradiseo-help@lists.gforge.inria.fr
*/
#ifndef __peoTransform_h
#define __peoTransform_h
#include <eoTransform.h>
#include "core/service.h"
//! Interface class for constructing more complex transformation operators.
//! The peoTransform class acts only as an interface for creating transform operators - for an example
//! please refer to the <b>peoSeqTransform</b> and the <b>peoParaSGATransform</b> classes.
template< class EOT > class peoTransform : public Service, public eoTransform< EOT > {
};
#endif

View file

@ -0,0 +1,9 @@
######################################################################################
### 1) Where must cmake go now ?
######################################################################################
SUBDIRS(mpi)
######################################################################################

View file

@ -0,0 +1,60 @@
######################################################################################
### 0) Set the compiler
######################################################################################
SET (CMAKE_CXX_COMPILER mpicxx)
######################################################################################
######################################################################################
### 1) Include the sources
######################################################################################
INCLUDE_DIRECTORIES(${EO_SRC_DIR})
INCLUDE_DIRECTORIES(${XML2_CFLAGS_WITH_WHITESPACE})
######################################################################################
######################################################################################
### 2) Define your target(s): just the core library here
######################################################################################
SET(RMC_MPI_LIB_OUTPUT_PATH ${ParadisEO-PEO_BINARY_DIR}/lib)
SET(LIBRARY_OUTPUT_PATH ${RMC_MPI_LIB_OUTPUT_PATH})
SET (RMC_MPI_SOURCES node.cpp
param.cpp
comm.cpp
coop.cpp
mess.cpp
rmc.cpp
scheduler.cpp
worker.cpp
send.cpp
recv.cpp
xml_parser.cpp
schema.cpp
runner.cpp
service.cpp)
ADD_LIBRARY(rmc_mpi STATIC ${RMC_MPI_SOURCES})
ADD_DEPENDENCIES(rmc_mpi peo)
######################################################################################
######################################################################################
### 3) Optionnal: define your lib version:
######################################################################################
SET(RMC_MPI_VERSION "1.0.beta")
SET_TARGET_PROPERTIES(rmc_mpi PROPERTIES VERSION "${RMC_MPI_VERSION}")
######################################################################################

View file

@ -0,0 +1,67 @@
// "comm.cpp"
// (c) OPAC Team, LIFL, August 2005
/*
Contact: paradiseo-help@lists.gforge.inria.fr
*/
#include <mpi.h>
#include "comm.h"
#include "mess.h"
#include "node.h"
#include "param.h"
#include "../../core/peo_debug.h"
#include "../../core/runner.h"
#include "send.h"
#include "recv.h"
#include "scheduler.h"
static sem_t sem_comm_init;
static Communicator * the_thread;
Communicator :: Communicator (int * __argc, char * * * __argv) {
the_thread = this;
initNode (__argc, __argv);
loadRMCParameters (* __argc, * __argv);
sem_post (& sem_comm_init);
}
void Communicator :: start () {
while (true) {
/* Zzz Zzz Zzz :-))) */
sleep ();
sendMessages ();
if (! atLeastOneActiveRunner ())
break;
receiveMessages ();
}
waitBuffers ();
printDebugMessage ("finalizing");
MPI_Finalize ();
}
void initCommunication () {
sem_init (& sem_comm_init, 0, 0);
}
void waitNodeInitialization () {
sem_wait (& sem_comm_init);
}
void wakeUpCommunicator () {
the_thread -> wakeUp ();
}

View file

@ -0,0 +1,31 @@
// "comm.h"
// (c) OPAC Team, LIFL, August 2005
/*
Contact: paradiseo-help@lists.gforge.inria.fr
*/
#ifndef __comm_mpi_h
#define __comm_mpi_h
#include "../../core/communicable.h"
#include "../../core/reac_thread.h"
class Communicator : public ReactiveThread {
public :
/* Ctor */
Communicator (int * __argc, char * * * __argv);
void start ();
};
extern void initCommunication ();
extern void waitNodeInitialization ();
extern void wakeUpCommunicator ();
#endif

View file

@ -0,0 +1,42 @@
// "coop.cpp"
// (c) OPAC Team, LIFL, August 2005
/*
Contact: paradiseo-help@lists.gforge.inria.fr
*/
#include "../../core/cooperative.h"
#include "send.h"
#include "tags.h"
#include "schema.h"
#include "mess.h"
#include "../../core/peo_debug.h"
Runner * Cooperative :: getOwner () {
return owner;
}
void Cooperative :: setOwner (Runner & __runner) {
owner = & __runner;
}
void Cooperative :: send (Cooperative * __coop) {
:: send (this, getRankOfRunner (__coop -> getOwner () -> getID ()), COOP_TAG);
// stop ();
}
Cooperative * getCooperative (COOP_ID __key) {
return dynamic_cast <Cooperative *> (getCommunicable (__key));
}
void Cooperative :: notifySending () {
//getOwner -> setPassive ();
// resume ();
// printDebugMessage (b);
}

View file

@ -0,0 +1,237 @@
// "mess.cpp"
// (c) OPAC Team, LIFL, August 2005
/*
Contact: paradiseo-help@lists.gforge.inria.fr
*/
#include <mpi.h>
#include <vector>
#include "mess.h"
#include "../../core/peo_debug.h"
#include "node.h"
#define MPI_BUF_SIZE 1024*64
static char mpi_buf [MPI_BUF_SIZE];
static int pos_buf ;
static std :: vector <char *> act_buf; /* Active buffers */
static std :: vector <MPI_Request *> act_req; /* Active requests */
void cleanBuffers () {
for (unsigned i = 0; i < act_req.size ();) {
MPI_Status stat ;
int flag ;
MPI_Test (act_req [i], & flag, & stat) ;
if (flag) {
delete act_buf [i] ;
delete act_req [i] ;
act_buf [i] = act_buf.back () ;
act_buf.pop_back () ;
act_req [i] = act_req.back () ;
act_req.pop_back () ;
}
else
i ++;
}
}
void waitBuffers () {
printDebugMessage ("waiting the termination of the asynchronous operations to complete");
for (unsigned i = 0; i < act_req.size (); i ++) {
MPI_Status stat ;
MPI_Wait (act_req [i], & stat) ;
delete act_buf [i] ;
delete act_req [i] ;
}
}
bool probeMessage (int & __src, int & __tag) {
int flag;
MPI_Status stat;
MPI_Iprobe (MPI_ANY_SOURCE, MPI_ANY_TAG, MPI_COMM_WORLD, & flag, & stat);
__src = stat.MPI_SOURCE;
__tag = stat.MPI_TAG;
return flag;
}
void waitMessage () {
MPI_Status stat;
MPI_Probe (MPI_ANY_SOURCE, MPI_ANY_TAG, MPI_COMM_WORLD, & stat);
}
void initMessage () {
pos_buf = 0;
}
void sendMessage (int __to, int __tag) {
cleanBuffers ();
act_buf.push_back (new char [pos_buf]);
act_req.push_back (new MPI_Request);
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 ());
}
void sendMessageToAll (int __tag) {
for (int i = 0; i < getNumberOfNodes (); i ++)
sendMessage (i, __tag);
}
void receiveMessage (int __from, int __tag) {
MPI_Status stat;
MPI_Request req;
MPI_Irecv (mpi_buf, MPI_BUF_SIZE, MPI_PACKED, __from, __tag, MPI_COMM_WORLD, & req) ;
MPI_Wait (& req, & stat) ;
}
/* Char */
void pack (const char & __c) {
MPI_Pack ((void *) & __c, 1, MPI_CHAR, mpi_buf, MPI_BUF_SIZE, & pos_buf, MPI_COMM_WORLD);
}
/* Float */
void pack (const float & __f, int __nitem) {
MPI_Pack ((void *) & __f, __nitem, MPI_FLOAT, mpi_buf, MPI_BUF_SIZE, & pos_buf, MPI_COMM_WORLD);
}
/* Double */
void pack (const double & __d, int __nitem) {
MPI_Pack ((void *) & __d, __nitem, MPI_DOUBLE, mpi_buf, MPI_BUF_SIZE, & pos_buf, MPI_COMM_WORLD);
}
/* Integer */
void pack (const int & __i, int __nitem) {
MPI_Pack ((void *) & __i, __nitem, MPI_INT, mpi_buf, MPI_BUF_SIZE, & pos_buf, MPI_COMM_WORLD);
}
/* Unsigned int. */
void pack (const unsigned int & __ui, int __nitem) {
MPI_Pack ((void *) & __ui, __nitem, MPI_UNSIGNED, mpi_buf, MPI_BUF_SIZE, & pos_buf, MPI_COMM_WORLD);
}
/* Short int. */
void pack (const short & __sh, int __nitem) {
MPI_Pack ((void *) & __sh, __nitem, MPI_SHORT, mpi_buf, MPI_BUF_SIZE, & pos_buf, MPI_COMM_WORLD);
}
/* Unsigned short */
void pack (const unsigned short & __ush, int __nitem) {
MPI_Pack ((void *) & __ush, __nitem, MPI_UNSIGNED_SHORT, mpi_buf, MPI_BUF_SIZE, & pos_buf, MPI_COMM_WORLD);
}
/* Long */
void pack (const long & __l, int __nitem) {
MPI_Pack ((void *) & __l, __nitem, MPI_LONG, mpi_buf, MPI_BUF_SIZE, & pos_buf, MPI_COMM_WORLD);
}
/* Unsigned long */
void pack (const unsigned long & __ul, int __nitem) {
MPI_Pack ((void *) & __ul, __nitem, MPI_UNSIGNED_LONG, mpi_buf, MPI_BUF_SIZE, & pos_buf, MPI_COMM_WORLD);
}
/* String */
void pack (const char * __str) {
int len = strlen (__str) + 1;
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);
}
/* Char */
void unpack (char & __c) {
MPI_Unpack (mpi_buf, MPI_BUF_SIZE, & pos_buf, & __c, 1, MPI_CHAR, MPI_COMM_WORLD);
}
/* Float */
void unpack (float & __f, int __nitem) {
MPI_Unpack (mpi_buf, MPI_BUF_SIZE, & pos_buf, & __f, __nitem, MPI_FLOAT, MPI_COMM_WORLD);
}
/* Double */
void unpack (double & __d, int __nitem) {
MPI_Unpack (mpi_buf, MPI_BUF_SIZE, & pos_buf, & __d, __nitem, MPI_DOUBLE, MPI_COMM_WORLD);
}
/* Integer */
void unpack (int & __i, int __nitem) {
MPI_Unpack (mpi_buf, MPI_BUF_SIZE, & pos_buf, & __i, __nitem, MPI_INT, MPI_COMM_WORLD);
}
/* Unsigned int. */
void unpack (unsigned int & __ui, int __nitem) {
MPI_Unpack (mpi_buf, MPI_BUF_SIZE, & pos_buf, & __ui, __nitem, MPI_UNSIGNED, MPI_COMM_WORLD);
}
/* Short int. */
void unpack (short & __sh, int __nitem) {
MPI_Unpack (mpi_buf, MPI_BUF_SIZE, & pos_buf, & __sh, __nitem, MPI_SHORT, MPI_COMM_WORLD);
}
/* Unsigned short */
void unpack (unsigned short & __ush, int __nitem) {
MPI_Unpack (mpi_buf, MPI_BUF_SIZE, & pos_buf, & __ush, __nitem, MPI_UNSIGNED_SHORT, MPI_COMM_WORLD);
}
/* Long */
void unpack (long & __l, int __nitem) {
MPI_Unpack (mpi_buf, MPI_BUF_SIZE, & pos_buf, & __l, __nitem, MPI_LONG, MPI_COMM_WORLD);
}
/* Unsigned long */
void unpack (unsigned long & __ul, int __nitem) {
MPI_Unpack (mpi_buf, MPI_BUF_SIZE, & pos_buf, & __ul, __nitem, MPI_UNSIGNED_LONG, MPI_COMM_WORLD);
}
/* String */
void unpack (char * __str) {
int len;
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);
}

View file

@ -0,0 +1,31 @@
// "mess.h"
// (c) OPAC Team, LIFL, August 2005
/*
Contact: paradiseo-help@lists.gforge.inria.fr
*/
#ifndef __mess_rmc_h
#define __mess_rmc_h
#include "../../core/messaging.h"
extern void initMessage ();
extern void sendMessage (int __to, int __tag);
extern void sendMessageToAll (int __tag);
extern void receiveMessage (int __from, int __tag);
extern void cleanBuffers ();
extern void waitBuffers ();
extern bool probeMessage (int & __src, int & __tag);
extern void waitMessage ();
#endif

View file

@ -0,0 +1,58 @@
// "node.cpp"
// (c) OPAC Team, LIFL, August 2005
/*
Contact: paradiseo-help@lists.gforge.inria.fr
*/
#include <mpi.h>
#include <vector>
#include <map>
#include <string>
#include <cassert>
static int rk, sz; /* Rank & size */
static std :: map <std :: string, int> name_to_rk;
static std :: vector <std :: string> rk_to_name;
int getNodeRank () {
return rk;
}
int getNumberOfNodes () {
return sz;
}
int getRankFromName (const std :: string & __name) {
return atoi (__name.c_str ());
}
void initNode (int * __argc, char * * * __argv) {
int provided;
MPI_Init_thread (__argc, __argv, MPI_THREAD_FUNNELED, & provided);
assert (provided == MPI_THREAD_FUNNELED); /* The MPI implementation must be multi-threaded.
Yet, only one thread performs the comm.
operations */
MPI_Comm_rank (MPI_COMM_WORLD, & rk); /* Who ? */
MPI_Comm_size (MPI_COMM_WORLD, & sz); /* How many ? */
char names [sz] [MPI_MAX_PROCESSOR_NAME];
int len;
/* Processor names */
MPI_Get_processor_name (names [0], & len); /* Me */
MPI_Allgather (names, MPI_MAX_PROCESSOR_NAME, MPI_CHAR, names, MPI_MAX_PROCESSOR_NAME, MPI_CHAR, MPI_COMM_WORLD); /* Broadcast */
for (int i = 0; i < sz; i ++) {
rk_to_name.push_back (names [i]);
name_to_rk [names [i]] = i;
}
}

View file

@ -0,0 +1,24 @@
// "node.h"
// (c) OPAC Team, LIFL, August 2005
/*
Contact: paradiseo-help@lists.gforge.inria.fr
*/
#ifndef __node_h
#define __node_h
#include <string>
#include <cassert>
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 getRankFromName (const std :: string & __name); /* It gives the rank of the process
expressed by its name */
extern void initNode (int * __argc, char * * * __argv);
#endif

View file

@ -0,0 +1,21 @@
// "param.cpp"
// (c) OPAC Team, LIFL, August 2005
/*
Contact: paradiseo-help@lists.gforge.inria.fr
*/
#include <utils/eoParser.h>
#include "schema.h"
void loadRMCParameters (int & __argc, char * * & __argv) {
eoParser parser (__argc, __argv);
/* Schema */
eoValueParam <std :: string> schema_param ("schema.xml", "schema", "?");
parser.processParam (schema_param);
loadSchema (schema_param.value ().c_str ());
}

View file

@ -0,0 +1,14 @@
// "param.h"
// (c) OPAC Team, LIFL, August 2005
/*
Contact: paradiseo-help@lists.gforge.inria.fr
*/
#ifndef __rmc_param_h
#define __rmc_param_h
extern void loadRMCParameters (int & __argc, char * * & __argv);
#endif

View file

@ -0,0 +1,112 @@
// "recv.cpp"
// (c) OPAC Team, LIFL, August 2005
/*
Contact: paradiseo-help@lists.gforge.inria.fr
*/
#include "comm.h"
#include "tags.h"
#include "worker.h"
#include "scheduler.h"
#include "mess.h"
#include "node.h"
#include "../../core/runner.h"
#include "../../core/cooperative.h"
#include "../../core/peo_debug.h"
void receiveMessages () {
cleanBuffers ();
do {
if (! atLeastOneActiveThread ()) {
// printDebugMessage ("debut wait");
waitMessage ();
//printDebugMessage ("fin wait");
}
int src, tag;
while (probeMessage (src, tag)) {
receiveMessage (src, tag);
initMessage ();
/*
char b [1000];
sprintf (b, "traitement recv %d\n", tag);
printDebugMessage (b);
*/
switch (tag) {
case RUNNER_STOP_TAG:
unpackTerminationOfRunner ();
wakeUpCommunicator ();
break;
case COOP_TAG:
// printDebugMessage ("reception de message de cooperation");
COOP_ID coop_id;
unpack (coop_id);
getCooperative (coop_id) -> unpack ();
break;
case SCHED_REQUEST_TAG:
unpackResourceRequest ();
break;
case SCHED_RESULT_TAG:
{
/* Unpacking the resource */
SERVICE_ID serv_id;
unpack (serv_id);
Service * serv = getService (serv_id);
int dest;
unpack (dest);
WORKER_ID worker_id;
unpack (worker_id);
/* Going back ... */
initMessage ();
pack (worker_id);
pack (serv_id);
serv -> packData ();
serv -> notifySendingData ();
sendMessage (dest, TASK_DATA_TAG);
break;
}
case TASK_DATA_TAG:
{
WORKER_ID worker_id;
unpack (worker_id);
Worker * worker = getWorker (worker_id);
worker -> setSource (src);
worker -> unpackData ();
worker -> wakeUp ();
break;
}
case TASK_RESULT_TAG:
{
SERVICE_ID serv_id;
unpack (serv_id);
Service * serv = getService (serv_id);
serv -> unpackResult ();
break;
}
case TASK_DONE_TAG:
unpackTaskDone ();
break;
default:
;
};
}
} while (! atLeastOneActiveThread () && atLeastOneActiveRunner () /*&& ! allResourcesFree ()*/);
}

View file

@ -0,0 +1,14 @@
// "recv.h"
// (c) OPAC Team, LIFL, August 2005
/*
Contact: paradiseo-help@lists.gforge.inria.fr
*/
#ifndef __recv_h
#define __recv_h
extern void receiveMessages ();
#endif

View file

@ -0,0 +1,47 @@
// "rmc.cpp"
// (c) OPAC Team, LIFL, August 2005
/*
Contact: paradiseo-help@lists.gforge.inria.fr
*/
#include "send.h"
#include "worker.h"
#include "schema.h"
#include "comm.h"
#include "scheduler.h"
#include "../../core/peo_debug.h"
static std :: vector <pthread_t *> ll_threads; /* Low level threads */
void runRMC () {
/* Worker(s) ? */
for (unsigned i = 0; i < my_node -> num_workers; i ++)
addThread (new Worker, ll_threads);
wakeUpCommunicator ();
}
void initRMC (int & __argc, char * * & __argv) {
/* Communication */
initCommunication ();
addThread (new Communicator (& __argc, & __argv), ll_threads);
waitNodeInitialization ();
initSending ();
/* Scheduler */
if (isScheduleNode ())
initScheduler ();
///
}
void finalizeRMC () {
printDebugMessage ("before join threads RMC");
joinThreads (ll_threads);
printDebugMessage ("after join threads RMC");
}

View file

@ -0,0 +1,33 @@
// "runner.cpp"
// (c) OPAC Team, LIFL, August 2005
/*
Contact: paradiseo-help@lists.gforge.inria.fr
*/
#include "../../core/messaging.h"
#include "../../core/runner.h"
#include "node.h"
#include "send.h"
#include "tags.h"
#include "schema.h"
bool Runner :: isLocal () {
for (unsigned i = 0; i < my_node -> id_run.size (); i ++)
if (my_node -> id_run [i] == id)
return true;
return false;
}
void Runner :: packTermination () {
pack (id);
}
void Runner :: terminate () {
sendToAll (this, RUNNER_STOP_TAG);
}

View file

@ -0,0 +1,78 @@
// "sched_thread.cpp"
// (c) OPAC Team, LIFL, August 2005
/*
Contact: paradiseo-help@lists.gforge.inria.fr
*/
#include <queue>
#include "scheduler.h"
#include "tags.h"
#include "mess.h"
#include "../../core/peo_debug.h"
static std :: queue <SCHED_RESOURCE> resources; /* Free resources */
static std :: queue <SCHED_REQUEST> requests; /* Requests */
static unsigned initNumberOfRes = 0;
void initScheduler () {
for (unsigned i = 0; i < the_schema.size (); i ++) {
const Node & node = the_schema [i];
if (node.rk_sched == my_node -> rk)
for (unsigned j = 0; j < node.num_workers; j ++)
resources.push (std :: pair <RANK_ID, WORKER_ID> (i, j + 1));
}
initNumberOfRes = resources.size ();
}
bool allResourcesFree () {
return resources.size () == initNumberOfRes;
}
static void update () {
unsigned num_alloc = std :: min (resources.size (), requests.size ());
for (unsigned i = 0; i < num_alloc; i ++) {
SCHED_REQUEST req = requests.front ();
requests.pop ();
SCHED_RESOURCE res = resources.front ();
resources.pop ();
printDebugMessage ("allocating a resource.");
initMessage ();
pack (req.second);
pack (res);
sendMessage (req.first, SCHED_RESULT_TAG);
}
}
void unpackResourceRequest () {
printDebugMessage ("queuing a resource request.");
SCHED_REQUEST req;
unpack (req);
requests.push (req);
update ();
}
void unpackTaskDone () {
printDebugMessage ("I'm notified a worker is now idle.");
SCHED_RESOURCE res;
unpack (res);
resources.push (res);
if (resources.size () == initNumberOfRes)
printDebugMessage ("all the resources are now free.");
update ();
}

View file

@ -0,0 +1,32 @@
// "scheduler.h"
// (c) OPAC Team, LIFL, August 2005
/*
Contact: paradiseo-help@lists.gforge.inria.fr
*/
#ifndef __scheduler_h
#define __scheduler_h
#include <utility>
#include "schema.h"
#include "worker.h"
typedef std :: pair <RANK_ID, WORKER_ID> SCHED_RESOURCE;
typedef std :: pair <RANK_ID, SERVICE_ID> SCHED_REQUEST;
/* Initializing the list of available workers */
extern void initScheduler ();
/* Processing a resource request from a service */
extern void unpackResourceRequest ();
/* Being known a worker is now idle :-) */
extern void unpackTaskDone ();
extern bool allResourcesFree ();
#endif

View file

@ -0,0 +1,135 @@
// "schema.cpp"
// (c) OPAC Team, LIFL, August 2005
/*
Contact: paradiseo-help@lists.gforge.inria.fr
*/
#include <iostream>
#include <assert.h>
#include "schema.h"
#include "xml_parser.h"
#include "comm.h"
#include "node.h"
#include "../../core/peo_debug.h"
std :: vector <Node> the_schema;
Node * my_node;
RANK_ID getRankOfRunner (RUNNER_ID __key) {
for (unsigned i = 0; i < the_schema.size (); i ++)
for (unsigned j = 0; j < the_schema [i].id_run.size (); j ++)
if (the_schema [i].id_run [j] == __key)
return the_schema [i].rk;
assert (false);
return 0;
}
static void loadNode (int __rk_sched) {
Node node;
node.rk_sched = __rk_sched;
/* ATT: name*/
node.rk = getRankFromName (getAttributeValue ("name"));
/* ATT: num_workers */
node.num_workers = atoi (getAttributeValue ("num_workers").c_str ());
while (true) {
/* TAG: <runner> | </node> */
std :: string name = getNextNode ();
assert (name == "runner" || name == "node");
if (name == "runner") {
/* TAG: </node> */
node.id_run.push_back (atoi (getNextNode ().c_str ()));
/* TAG: </runner> */
assert (getNextNode () == "runner");
}
else {
/* TAG: </node> */
the_schema.push_back (node);
break;
}
}
}
static void loadGroup () {
std :: string name;
/* ATT: scheduler*/
int rk_sched = getRankFromName (getAttributeValue ("scheduler"));
while (true) {
/* TAG: <node> | </group> */
name = getNextNode ();
assert (name == "node" || name == "group");
if (name == "node")
/* TAG: <node> */
loadNode (rk_sched);
else
/* TAG: </group> */
break;
}
}
bool isScheduleNode () {
return my_node -> rk == my_node -> rk_sched;
}
void loadSchema (const char * __filename) {
openXMLDocument (__filename);
std :: string name;
/* TAG: <schema> */
name = getNextNode ();
assert (name == "schema");
while (true) {
/* TAG: <group> | </schema> */
name = getNextNode ();
assert (name == "group" || name == "schema");
if (name == "group")
/* TAG: <group> */
loadGroup ();
else
/* TAG: </schema> */
break;
}
/* Looking for my node */
for (unsigned i = 0; i < the_schema.size (); i ++)
if (the_schema [i].rk == getNodeRank ())
my_node = & (the_schema [i]);
/* About me */
char mess [1000];
sprintf (mess, "my rank is %d", my_node -> rk);
printDebugMessage (mess);
if (isScheduleNode ())
printDebugMessage ("I'am a scheduler");
for (unsigned i = 0; i < my_node -> id_run.size (); i ++) {
sprintf (mess, "I manage the runner %d", my_node -> id_run [i]);
printDebugMessage (mess);
}
if (my_node -> num_workers) {
sprintf (mess, "I manage %d worker(s)", my_node -> num_workers);
printDebugMessage (mess);
}
closeXMLDocument ();
}

View file

@ -0,0 +1,39 @@
// "schema.h"
// (c) OPAC Team, LIFL, August 2005
/*
Contact: paradiseo-help@lists.gforge.inria.fr
*/
#ifndef __schema_h
#define __schema_h
#include <string>
#include <vector>
#include <cassert>
#include "../../core/runner.h"
typedef int RANK_ID;
struct Node {
RANK_ID rk; /* Rank */
std :: string name; /* Host name */
unsigned num_workers; /* Number of parallel workers */
int rk_sched; /* rank of the scheduler */
std :: vector <RUNNER_ID> id_run; /* List of runners */
};
extern std :: vector <Node> the_schema;
extern Node * my_node;
extern void loadSchema (const char * __filename);
extern RANK_ID getRankOfRunner (RUNNER_ID __key);
extern bool isScheduleNode ();
#endif

View file

@ -0,0 +1,116 @@
// "send.cpp"
// (c) OPAC Team, LIFL, August 2005
/*
Contact: paradiseo-help@lists.gforge.inria.fr
*/
#include <mpi.h>
#include <semaphore.h>
#include <queue>
#include "tags.h"
#include "comm.h"
#include "worker.h"
#include "scheduler.h"
#include "mess.h"
#include "node.h"
#include "../../core/cooperative.h"
#include "../../core/peo_debug.h"
#define TO_ALL -1
typedef struct {
Communicable * comm;
int to;
int tag;
} SEND_REQUEST;
static std :: queue <SEND_REQUEST> mess;
static sem_t sem_send;
void initSending () {
sem_init (& sem_send, 0, 1);
}
void send (Communicable * __comm, int __to, int __tag) {
SEND_REQUEST req;
req.comm = __comm;
req.to = __to;
req.tag = __tag;
sem_wait (& sem_send);
mess.push (req);
sem_post (& sem_send);
wakeUpCommunicator ();
}
void sendToAll (Communicable * __comm, int __tag) {
send (__comm, TO_ALL, __tag);
}
void sendMessages () {
sem_wait (& sem_send);
while (! mess.empty ()) {
SEND_REQUEST req = mess.front ();
/*
char b [1000];
sprintf (b, "traitement send %d\n", req.tag);
printDebugMessage (b);
*/
Communicable * comm = req.comm;
initMessage ();
switch (req.tag) {
case RUNNER_STOP_TAG:
dynamic_cast <Runner *> (comm) -> packTermination ();
dynamic_cast <Runner *> (comm) -> notifySendingTermination ();
break;
case COOP_TAG:
dynamic_cast <Cooperative *> (comm) -> pack ();
dynamic_cast <Cooperative *> (comm) -> notifySending ();
break;
case SCHED_REQUEST_TAG:
dynamic_cast <Service *> (comm) -> packResourceRequest ();
dynamic_cast <Service *> (comm) -> notifySendingResourceRequest ();
break;
case TASK_RESULT_TAG:
dynamic_cast <Worker *> (comm) -> packResult ();
dynamic_cast <Worker *> (comm) -> notifySendingResult ();
break;
case TASK_DONE_TAG:
dynamic_cast <Worker *> (comm) -> packTaskDone ();
dynamic_cast <Worker *> (comm) -> notifySendingTaskDone ();
break;
default :
break;
};
if (req.to == TO_ALL)
sendMessageToAll (req.tag);
else
sendMessage (req.to, req.tag);
mess.pop ();
}
sem_post (& sem_send);
}

View file

@ -0,0 +1,22 @@
// "send.h"
// (c) OPAC Team, LIFL, August 2005
/*
Contact: paradiseo-help@lists.gforge.inria.fr
*/
#ifndef __send_h
#define __send_h
#include "../../core/communicable.h"
extern void initSending ();
extern void send (Communicable * __comm, int __to, int __tag);
extern void sendToAll (Communicable * __comm, int __tag);
extern void sendMessages ();
#endif

View file

@ -0,0 +1,30 @@
// "service.h"
// (c) OPAC Team, LIFL, August 2005
/*
Contact: paradiseo-help@lists.gforge.inria.fr
*/
#include "../../core/service.h"
#include "../../core/messaging.h"
#include "node.h"
#include "tags.h"
#include "send.h"
#include "scheduler.h"
void Service :: requestResourceRequest (unsigned __how_many) {
num_sent_rr = __how_many;
for (unsigned i = 0; i < __how_many; i ++)
send (this, my_node -> rk_sched, SCHED_REQUEST_TAG);
}
void Service :: packResourceRequest () {
SCHED_REQUEST req;
req.first = getNodeRank ();
req.second = getKey ();
// printf ("demande de ressource pour %d\n", req.second);
:: pack (req);
}

View file

@ -0,0 +1,24 @@
// "tags.h"
// (c) OPAC Team, LIFL, August 2005
/*
Contact: paradiseo-help@lists.gforge.inria.fr
*/
#ifndef __tags_h
#define __tags_h
#define RUNNER_STOP_TAG 13
#define COOP_TAG 14
#define SCHED_REQUEST_TAG 16
#define SCHED_RESULT_TAG 17
#define TASK_DATA_TAG 18
#define TASK_RESULT_TAG 19
#define TASK_DONE_TAG 20
#endif

View file

@ -0,0 +1,93 @@
// "worker.cpp"
// (c) OPAC Team, LIFL, August 2005
/*
Contact: paradiseo-help@lists.gforge.inria.fr
*/
#include <vector>
#include "tags.h"
#include "send.h"
#include "node.h"
#include "schema.h"
#include "worker.h"
#include "mess.h"
#include "../../core/peo_debug.h"
static std :: vector <Worker *> key_to_worker (1); /* Vector of registered workers */
Worker * getWorker (WORKER_ID __key) {
return key_to_worker [__key];
}
Worker :: Worker () {
toto = false;
id = key_to_worker.size ();
key_to_worker.push_back (this);
}
void Worker :: packResult () {
pack (serv_id);
serv -> packResult ();
}
void Worker :: unpackData () {
printDebugMessage ("unpacking the ID. of the service.");
unpack (serv_id);
serv = getService (serv_id);
printDebugMessage ("found the service.");
serv -> unpackData ();
printDebugMessage ("unpacking the data.");
setActive ();
}
void Worker :: packTaskDone () {
pack (getNodeRank ());
pack (id);
}
void Worker :: notifySendingResult () {
/* Notifying the scheduler of the termination */
toto = true;
wakeUp ();
}
void Worker :: notifySendingTaskDone () {
setPassive ();
}
void Worker :: setSource (int __rank) {
src = __rank;
}
void Worker :: start () {
while (true) {
sleep ();
if (! atLeastOneActiveRunner ())
break;
if (toto) {
send (this, my_node -> rk_sched, TASK_DONE_TAG);
toto = false;
}
else {
printDebugMessage ("executing the task.");
serv -> execute ();
send (this, src, TASK_RESULT_TAG);
}
}
}

View file

@ -0,0 +1,50 @@
// "worker.h"
// (c) OPAC Team, LIFL, August 2005
/*
Contact: paradiseo-help@lists.gforge.inria.fr
*/
#ifndef __worker_h
#define __worker_h
#include "../../core/communicable.h"
#include "../../core/reac_thread.h"
#include "../../core/service.h"
typedef unsigned WORKER_ID;
class Worker : public Communicable, public ReactiveThread {
public :
Worker ();
void start ();
void packResult ();
void unpackData ();
void packTaskDone ();
void notifySendingResult ();
void notifySendingTaskDone ();
void setSource (int __rank);
private :
WORKER_ID id;
SERVICE_ID serv_id;
Service * serv;
int src;
bool toto;
};
extern Worker * getWorker (WORKER_ID __key);
#endif

View file

@ -0,0 +1,75 @@
// "xml_parser.h"
// (c) OPAC Team, LIFL, August 2005
/*
Contact: paradiseo-help@lists.gforge.inria.fr
*/
#include <libxml/xmlreader.h>
#include "xml_parser.h"
static xmlTextReaderPtr reader;
void openXMLDocument (const char * __filename) {
reader = xmlNewTextReaderFilename (__filename);
if (! reader) {
fprintf (stderr, "unable to open '%s'.\n", __filename);
exit (1);
}
}
void closeXMLDocument () {
xmlFreeTextReader (reader);
}
std :: string getAttributeValue (const std :: string & __attr) {
xmlChar * value = xmlTextReaderGetAttribute (reader, (const xmlChar *) __attr.c_str ());
std :: string str ((const char *) value);
xmlFree (value);
return str;
}
static bool isSep (const xmlChar * __text) {
for (unsigned i = 0; i < strlen ((char *) __text); i ++)
if (__text [i] != ' ' && __text [i] != '\t' && __text [i] != '\n')
return false;
return true;
}
std :: string getNextNode () {
xmlChar * name, * value;
do {
xmlTextReaderRead (reader);
name = xmlTextReaderName (reader);
value = xmlTextReaderValue (reader);
// printf ("value = %s\n", value);
} while (! strcmp ((char *) name, "#text") && isSep (value));
std :: string str;
if (strcmp ((char *) name, "#text"))
str.assign ((char *) name);
else
str.assign ((char *) value);
if (name)
xmlFree (name);
if (value)
xmlFree (value);
return str;
}

View file

@ -0,0 +1,22 @@
// "xml_parser.h"
// (c) OPAC Team, LIFL, August 2005
/*
Contact: paradiseo-help@lists.gforge.inria.fr
*/
#ifndef __xml_parser_h
#define __xml_parser_h
#include <string>
extern void openXMLDocument (const char * __filename);
extern void closeXMLDocument ();
extern std :: string getAttributeValue (const std :: string & __attr);
extern std :: string getNextNode ();
#endif