git-svn-id: svn://scm.gforge.inria.fr/svnroot/paradiseo@810 331e1502-861f-0410-8da2-ba01fb791d7f
This commit is contained in:
parent
f0b21ecfae
commit
7526792805
49 changed files with 449 additions and 420 deletions
|
|
@ -51,6 +51,7 @@ static sem_t sem_comm_init;
|
|||
|
||||
static Communicator * the_thread;
|
||||
|
||||
|
||||
Communicator :: Communicator (int * __argc, char * * * __argv) {
|
||||
|
||||
the_thread = this;
|
||||
|
|
@ -69,23 +70,28 @@ void Communicator :: start () {
|
|||
|
||||
sendMessages ();
|
||||
|
||||
if (theEnd() || ! atLeastOneActiveRunner ())
|
||||
if (! atLeastOneActiveRunner () && ! atLeastOneActiveThread() && allResourcesFree ())
|
||||
break;
|
||||
|
||||
receiveMessages ();
|
||||
}
|
||||
|
||||
waitBuffers ();
|
||||
sem_destroy(& sem_comm_init);
|
||||
|
||||
printDebugMessage ("finalizing");
|
||||
|
||||
synchronizeNodes ();
|
||||
//synchronizeNodes ();
|
||||
}
|
||||
|
||||
void initCommunication () {
|
||||
|
||||
static bool initializedSemaphore = false;
|
||||
|
||||
if (initializedSemaphore) {
|
||||
sem_destroy(& sem_comm_init);
|
||||
}
|
||||
|
||||
sem_init (& sem_comm_init, 0, 0);
|
||||
initializedSemaphore = true;
|
||||
}
|
||||
|
||||
void waitNodeInitialization () {
|
||||
|
|
@ -97,6 +103,3 @@ void wakeUpCommunicator () {
|
|||
|
||||
the_thread -> wakeUp ();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -43,7 +43,7 @@
|
|||
class Communicator : public ReactiveThread {
|
||||
|
||||
public :
|
||||
|
||||
|
||||
/* Ctor */
|
||||
Communicator (int * __argc, char * * * __argv);
|
||||
|
||||
|
|
|
|||
|
|
@ -53,7 +53,7 @@ void Cooperative :: setOwner (Runner & __runner) {
|
|||
|
||||
void Cooperative :: send (Cooperative * __coop) {
|
||||
|
||||
:: send (this, getRankOfRunner (__coop -> getOwner () -> getDefinitionID ()), COOP_TAG);
|
||||
:: send (this, getRankOfRunner (__coop -> getOwner () -> getDefinitionID ()), COOP_TAG);
|
||||
// stop ();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -45,18 +45,26 @@
|
|||
|
||||
static char mpi_buf [MPI_BUF_SIZE];
|
||||
|
||||
static int pos_buf ;
|
||||
static int pos_buf;
|
||||
|
||||
static std :: vector <char *> act_buf; /* Active buffers */
|
||||
|
||||
static std :: vector <MPI_Request *> act_req; /* Active requests */
|
||||
|
||||
void initBuffers () {
|
||||
|
||||
pos_buf = 0;
|
||||
act_buf.clear ();
|
||||
act_req.clear ();
|
||||
}
|
||||
|
||||
void cleanBuffers () {
|
||||
|
||||
for (unsigned i = 0; i < act_req.size ();) {
|
||||
|
||||
MPI_Status stat ;
|
||||
int flag ;
|
||||
|
||||
MPI_Test (act_req [i], & flag, & stat) ;
|
||||
if (flag) {
|
||||
|
||||
|
|
@ -71,7 +79,7 @@ void cleanBuffers () {
|
|||
}
|
||||
else
|
||||
i ++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void waitBuffers () {
|
||||
|
|
@ -79,14 +87,14 @@ 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) {
|
||||
|
|
@ -111,17 +119,17 @@ void waitMessage () {
|
|||
}
|
||||
|
||||
void initMessage () {
|
||||
|
||||
|
||||
pos_buf = 0;
|
||||
}
|
||||
|
||||
void sendMessage (int __to, int __tag) {
|
||||
|
||||
cleanBuffers ();
|
||||
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 ());
|
||||
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) {
|
||||
|
|
@ -131,8 +139,8 @@ void sendMessageToAll (int __tag) {
|
|||
}
|
||||
|
||||
void receiveMessage (int __from, int __tag) {
|
||||
|
||||
MPI_Status stat;
|
||||
|
||||
MPI_Status stat;
|
||||
MPI_Request req;
|
||||
|
||||
MPI_Irecv (mpi_buf, MPI_BUF_SIZE, MPI_PACKED, __from, __tag, MPI_COMM_WORLD, & req);
|
||||
|
|
@ -200,7 +208,7 @@ void pack (const unsigned long & __ul, int __nitem) {
|
|||
|
||||
/* String */
|
||||
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);
|
||||
|
|
@ -267,4 +275,3 @@ void unpack (char * __str) {
|
|||
MPI_Unpack (mpi_buf, MPI_BUF_SIZE, & pos_buf, & len, 1, MPI_INT, MPI_COMM_WORLD);
|
||||
MPI_Unpack (mpi_buf, MPI_BUF_SIZE, & pos_buf, __str, len, MPI_CHAR, MPI_COMM_WORLD);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -47,6 +47,8 @@ extern void sendMessageToAll (int __tag);
|
|||
|
||||
extern void receiveMessage (int __from, int __tag);
|
||||
|
||||
extern void initBuffers ();
|
||||
|
||||
extern void cleanBuffers ();
|
||||
|
||||
extern void waitBuffers ();
|
||||
|
|
|
|||
|
|
@ -40,6 +40,8 @@
|
|||
#include <string>
|
||||
#include <cassert>
|
||||
|
||||
#include "mess.h"
|
||||
|
||||
|
||||
class MPIThreadedEnv {
|
||||
|
||||
|
|
@ -63,7 +65,7 @@ public:
|
|||
|
||||
private:
|
||||
|
||||
/* No instance of this class can be created outside its domain */
|
||||
/* No instance of this class can be created outside its domain! */
|
||||
MPIThreadedEnv ( int * __argc, char * * * __argv ) {
|
||||
|
||||
static bool MPIThreadedEnvInitialized = false;
|
||||
|
|
@ -72,6 +74,7 @@ private:
|
|||
if (! MPIThreadedEnvInitialized) {
|
||||
|
||||
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 */
|
||||
|
|
@ -92,6 +95,7 @@ static std :: map <std :: string, int> name_to_rk;
|
|||
|
||||
static std :: vector <std :: string> rk_to_name;
|
||||
|
||||
|
||||
int getNodeRank () {
|
||||
|
||||
return rk;
|
||||
|
|
@ -102,6 +106,11 @@ int getNumberOfNodes () {
|
|||
return sz;
|
||||
}
|
||||
|
||||
void collectiveCountOfRunners ( unsigned int* num_local_exec_runners, unsigned int* num_exec_runners ) {
|
||||
|
||||
MPI_Allreduce( num_local_exec_runners, num_exec_runners, 1, MPI_UNSIGNED, MPI_SUM, MPI_COMM_WORLD );
|
||||
}
|
||||
|
||||
int getRankFromName (const std :: string & __name) {
|
||||
|
||||
return atoi (__name.c_str ());
|
||||
|
|
@ -112,9 +121,8 @@ void initNode (int * __argc, char * * * __argv) {
|
|||
rk_to_name.clear ();
|
||||
name_to_rk.clear ();
|
||||
|
||||
|
||||
MPIThreadedEnv :: init ( __argc, __argv );
|
||||
|
||||
//synchronizeNodes();
|
||||
|
||||
MPI_Comm_rank (MPI_COMM_WORLD, & rk); /* Who ? */
|
||||
MPI_Comm_size (MPI_COMM_WORLD, & sz); /* How many ? */
|
||||
|
|
|
|||
|
|
@ -44,6 +44,8 @@ extern int getNodeRank (); /* It gives the rank of the calling process */
|
|||
|
||||
extern int getNumberOfNodes (); /* It gives the size of the environment (Total number of nodes) */
|
||||
|
||||
extern void collectiveCountOfRunners ( unsigned int* num_local_exec_runners, unsigned int* num_exec_runners );
|
||||
|
||||
extern int getRankFromName (const std :: string & __name); /* It gives the rank of the process
|
||||
expressed by its name */
|
||||
|
||||
|
|
|
|||
|
|
@ -130,7 +130,5 @@ void receiveMessages () {
|
|||
};
|
||||
}
|
||||
|
||||
} while ( ! atLeastOneActiveThread () && atLeastOneActiveRunner () /*&& ! allResourcesFree ()*/);
|
||||
|
||||
cleanBuffers ();
|
||||
} while ( ! atLeastOneActiveThread () && atLeastOneActiveRunner () /*&& ! allResourcesFree ()*/ );
|
||||
}
|
||||
|
|
|
|||
|
|
@ -45,6 +45,7 @@ static std :: vector <pthread_t *> ll_threads; /* Low level threads */
|
|||
static std :: vector <Worker *> worker_threads; /* Worker threads */
|
||||
static Communicator* communicator_thread = NULL; /* Communicator thread */
|
||||
|
||||
|
||||
void runRMC () {
|
||||
|
||||
/* Worker(s) ? */
|
||||
|
|
|
|||
|
|
@ -47,6 +47,8 @@ static std :: queue <SCHED_REQUEST> requests; /* Requests */
|
|||
|
||||
static unsigned initNumberOfRes = 0;
|
||||
|
||||
extern void wakeUpCommunicator();
|
||||
|
||||
void initScheduler () {
|
||||
|
||||
resources = std :: queue <SCHED_RESOURCE> ();
|
||||
|
|
@ -57,36 +59,39 @@ void initScheduler () {
|
|||
|
||||
const Node & node = the_schema [i];
|
||||
|
||||
if (node.rk_sched == my_node -> rk)
|
||||
if (node.rk_sched == my_node -> rk)
|
||||
for (unsigned j = 0; j < node.num_workers; j ++)
|
||||
resources.push (std :: pair <RANK_ID, WORKER_ID> (i, j + 1));
|
||||
}
|
||||
resources.push (std :: pair <RANK_ID, WORKER_ID> (i, j + 1));
|
||||
}
|
||||
initNumberOfRes = resources.size ();
|
||||
}
|
||||
|
||||
bool allResourcesFree () {
|
||||
|
||||
return resources.size () == initNumberOfRes;
|
||||
}
|
||||
|
||||
unsigned numResourcesFree () {
|
||||
return resources.size ();
|
||||
}
|
||||
|
||||
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.");
|
||||
printDebugMessage ("allocating a resource.");
|
||||
initMessage ();
|
||||
pack (req.second);
|
||||
pack (res);
|
||||
sendMessage (req.first, SCHED_RESULT_TAG);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void unpackResourceRequest () {
|
||||
|
|
@ -107,4 +112,5 @@ void unpackTaskDone () {
|
|||
if (resources.size () == initNumberOfRes)
|
||||
printDebugMessage ("all the resources are now free.");
|
||||
update ();
|
||||
wakeUpCommunicator();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -57,4 +57,6 @@ extern void unpackTaskDone ();
|
|||
|
||||
extern bool allResourcesFree ();
|
||||
|
||||
extern unsigned numResourcesFree ();
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -76,7 +76,7 @@ static void loadNode (int __rk_sched) {
|
|||
|
||||
/* TAG: <runner> | </node> */
|
||||
std :: string name = getNextNode ();
|
||||
assert (name == "runner" || name == "node");
|
||||
assert (name == "runner" || name == "node");
|
||||
if (name == "runner") {
|
||||
/* TAG: </node> */
|
||||
node.id_run.push_back (atoi (getNextNode ().c_str ()));
|
||||
|
|
@ -105,7 +105,7 @@ static void loadGroup () {
|
|||
|
||||
/* TAG: <node> | </group> */
|
||||
name = getNextNode ();
|
||||
assert (name == "node" || name == "group");
|
||||
assert (name == "node" || name == "group");
|
||||
if (name == "node")
|
||||
/* TAG: <node> */
|
||||
loadNode (rk_sched);
|
||||
|
|
@ -173,7 +173,7 @@ void loadSchema (const char * __filename) {
|
|||
printDebugMessage (mess);
|
||||
|
||||
if (isScheduleNode ())
|
||||
printDebugMessage ("I'am a scheduler");
|
||||
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]);
|
||||
|
|
|
|||
|
|
@ -47,7 +47,7 @@
|
|||
typedef int RANK_ID;
|
||||
|
||||
struct Node {
|
||||
|
||||
|
||||
RANK_ID rk; /* Rank */
|
||||
std :: string name; /* Host name */
|
||||
unsigned num_workers; /* Number of parallel workers */
|
||||
|
|
|
|||
|
|
@ -49,6 +49,7 @@
|
|||
|
||||
#define TO_ALL -1
|
||||
|
||||
|
||||
typedef struct {
|
||||
|
||||
Communicable * comm;
|
||||
|
|
@ -56,28 +57,28 @@ typedef struct {
|
|||
int tag;
|
||||
|
||||
} SEND_REQUEST;
|
||||
|
||||
|
||||
|
||||
static std :: queue <SEND_REQUEST> mess;
|
||||
|
||||
static sem_t sem_send;
|
||||
|
||||
static bool contextInitialized = false;
|
||||
|
||||
|
||||
void initSending () {
|
||||
|
||||
static bool initializedSem = false;
|
||||
static bool initializedSemaphore = false;
|
||||
|
||||
mess = std :: queue <SEND_REQUEST> ();
|
||||
|
||||
if (! initializedSem) {
|
||||
sem_init (& sem_send, 0, 1);
|
||||
initializedSem = true;
|
||||
}
|
||||
else {
|
||||
if (initializedSemaphore) {
|
||||
sem_destroy(& sem_send);
|
||||
sem_init (& sem_send, 0, 1);
|
||||
}
|
||||
|
||||
sem_init (& sem_send, 0, 1);
|
||||
initializedSemaphore = true;
|
||||
|
||||
contextInitialized = false;
|
||||
}
|
||||
|
||||
|
|
@ -103,13 +104,13 @@ extern void initializeContext ();
|
|||
|
||||
void sendMessages () {
|
||||
|
||||
sem_wait (& sem_send);
|
||||
|
||||
if (! contextInitialized) {
|
||||
contextInitialized = true;
|
||||
initializeContext();
|
||||
}
|
||||
|
||||
sem_wait (& sem_send);
|
||||
|
||||
while (! mess.empty ()) {
|
||||
|
||||
SEND_REQUEST req = mess.front ();
|
||||
|
|
@ -132,7 +133,7 @@ void sendMessages () {
|
|||
|
||||
case SCHED_REQUEST_TAG:
|
||||
dynamic_cast <Service *> (comm) -> packResourceRequest ();
|
||||
dynamic_cast <Service *> (comm) -> notifySendingResourceRequest ();
|
||||
dynamic_cast <Service *> (comm) -> notifySendingResourceRequest ();
|
||||
break;
|
||||
|
||||
case TASK_RESULT_TAG:
|
||||
|
|
@ -157,5 +158,5 @@ void sendMessages () {
|
|||
mess.pop ();
|
||||
}
|
||||
|
||||
sem_post (& sem_send);
|
||||
sem_post (& sem_send);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -48,6 +48,4 @@
|
|||
#define TASK_RESULT_TAG 19
|
||||
#define TASK_DONE_TAG 20
|
||||
|
||||
#define EXECUTION_CONTEXT_TAG 1000
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -46,26 +46,32 @@
|
|||
|
||||
static std :: vector <Worker *> key_to_worker (1); /* Vector of registered workers */
|
||||
|
||||
extern void wakeUpCommunicator ();
|
||||
|
||||
Worker * getWorker (WORKER_ID __key) {
|
||||
|
||||
return key_to_worker [__key];
|
||||
return key_to_worker [__key];
|
||||
}
|
||||
|
||||
Worker :: Worker () {
|
||||
|
||||
|
||||
recvAndCompleted = false;
|
||||
taskAssigned = 0;
|
||||
id = key_to_worker.size ();
|
||||
key_to_worker.push_back (this);
|
||||
|
||||
sem_init( &sem_task_done, 0, 0 );
|
||||
}
|
||||
|
||||
void Worker :: packResult () {
|
||||
|
||||
|
||||
pack (serv_id);
|
||||
serv -> packResult ();
|
||||
serv -> packResult ();
|
||||
}
|
||||
|
||||
void Worker :: unpackData () {
|
||||
|
||||
taskAssigned ++;
|
||||
printDebugMessage ("unpacking the ID. of the service.");
|
||||
unpack (serv_id);
|
||||
serv = getService (serv_id);
|
||||
|
|
@ -90,9 +96,10 @@ void Worker :: notifySendingResult () {
|
|||
|
||||
void Worker :: notifySendingTaskDone () {
|
||||
|
||||
sem_post(&sem_task_done);
|
||||
setPassive ();
|
||||
}
|
||||
|
||||
|
||||
void Worker :: setSource (int __rank) {
|
||||
|
||||
src = __rank;
|
||||
|
|
@ -102,22 +109,28 @@ void Worker :: start () {
|
|||
|
||||
while (true) {
|
||||
|
||||
sleep ();
|
||||
sleep ();
|
||||
|
||||
if (! atLeastOneActiveRunner ())
|
||||
if (! atLeastOneActiveRunner () && ! taskAssigned)
|
||||
break;
|
||||
|
||||
if (recvAndCompleted) {
|
||||
send (this, my_node -> rk_sched, TASK_DONE_TAG);
|
||||
recvAndCompleted = false;
|
||||
sem_wait(&sem_task_done);
|
||||
taskAssigned --;
|
||||
}
|
||||
else {
|
||||
|
||||
printDebugMessage ("executing the task.");
|
||||
serv -> execute ();
|
||||
send (this, src, TASK_RESULT_TAG);
|
||||
serv -> execute ();
|
||||
send (this, src, TASK_RESULT_TAG);
|
||||
}
|
||||
}
|
||||
|
||||
printDebugMessage ("Worker finished execution.");
|
||||
setPassive ();
|
||||
|
||||
wakeUpCommunicator();
|
||||
}
|
||||
|
||||
void initWorkersEnv () {
|
||||
|
|
|
|||
|
|
@ -46,7 +46,7 @@ typedef unsigned WORKER_ID;
|
|||
|
||||
class Worker : public Communicable, public ReactiveThread {
|
||||
|
||||
public :
|
||||
public :
|
||||
|
||||
Worker ();
|
||||
|
||||
|
|
@ -56,14 +56,14 @@ public :
|
|||
|
||||
void unpackData ();
|
||||
|
||||
void packTaskDone ();
|
||||
void packTaskDone ();
|
||||
|
||||
void notifySendingResult ();
|
||||
|
||||
void notifySendingTaskDone ();
|
||||
|
||||
|
||||
void setSource (int __rank);
|
||||
|
||||
|
||||
private :
|
||||
|
||||
WORKER_ID id;
|
||||
|
|
@ -72,6 +72,10 @@ private :
|
|||
int src;
|
||||
|
||||
bool recvAndCompleted;
|
||||
unsigned taskAssigned;
|
||||
|
||||
sem_t sem_task_done;
|
||||
sem_t sem_task_asgn;
|
||||
};
|
||||
|
||||
extern void initWorkersEnv ();
|
||||
|
|
|
|||
|
|
@ -41,11 +41,11 @@
|
|||
static xmlTextReaderPtr reader;
|
||||
|
||||
void openXMLDocument (const char * __filename) {
|
||||
|
||||
|
||||
reader = xmlNewTextReaderFilename (__filename);
|
||||
|
||||
|
||||
if (! reader) {
|
||||
|
||||
|
||||
fprintf (stderr, "unable to open '%s'.\n", __filename);
|
||||
exit (1);
|
||||
}
|
||||
|
|
@ -57,18 +57,18 @@ void closeXMLDocument () {
|
|||
}
|
||||
|
||||
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;
|
||||
|
|
@ -76,7 +76,7 @@ static bool isSep (const xmlChar * __text) {
|
|||
}
|
||||
|
||||
std :: string getNextNode () {
|
||||
|
||||
|
||||
xmlChar * name, * value;
|
||||
|
||||
do {
|
||||
|
|
@ -91,12 +91,11 @@ std :: string getNextNode () {
|
|||
str.assign ((char *) name);
|
||||
else
|
||||
str.assign ((char *) value);
|
||||
|
||||
|
||||
if (name)
|
||||
xmlFree (name);
|
||||
if (value)
|
||||
xmlFree (value);
|
||||
|
||||
|
||||
return str;
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue