]> AND Private Git Repository - equilibrage.git/commitdiff
Logo AND Algorithmique Numérique Distribuée

Private GIT Repository
Initial commit.
authorArnaud Giersch <arnaud.giersch@iut-bm.univ-fcomte.fr>
Wed, 26 May 2010 14:05:31 +0000 (16:05 +0200)
committerArnaud Giersch <arnaud.giersch@iut-bm.univ-fcomte.fr>
Wed, 26 May 2010 14:05:31 +0000 (16:05 +0200)
simulation/Makefile [new file with mode: 0644]
simulation/aleat.cpp [new file with mode: 0644]
simulation/construitTableau.cpp [new file with mode: 0644]
simulation/equil6.cpp [new file with mode: 0644]
simulation/fin.sh [new file with mode: 0755]
simulation/generePlat.cpp [new file with mode: 0644]
simulation/lanceExpes.sh [new file with mode: 0755]

diff --git a/simulation/Makefile b/simulation/Makefile
new file mode 100644 (file)
index 0000000..1a07b96
--- /dev/null
@@ -0,0 +1,18 @@
+INCS = -I$(SIMGRID_LOC)/include
+LIBS = -L$(SIMGRID_LOC)/lib -lsimgrid
+FLAGSSG = -DHAVE_CONFIG_H -finline-functions -ffast-math -funroll-loops -fno-strict-aliasing -g -O2 
+FLAGS = -g -O2 
+
+all: equil6 generePlat construitTableau aleat
+
+%: %.cpp
+       $(CXX) $< -o $@ $(FLAGSSG) $(INCS) $(LIBS)
+
+generePlat: generePlat.cpp
+       $(CXX) $< -o $@ $(FLAGS)
+
+construitTableau: construitTableau.cpp
+       $(CXX) $< -o $@ $(FLAGS)
+
+clean:
+       rm -rf *.dSYM *~ generePlat equil6 aleat
diff --git a/simulation/aleat.cpp b/simulation/aleat.cpp
new file mode 100644 (file)
index 0000000..78b79cb
--- /dev/null
@@ -0,0 +1,36 @@
+#include <iostream>
+#include <stdlib.h>
+#include <sys/time.h>
+
+using namespace std;
+
+int main(int argc, char **argv)
+{
+  int graine;
+  int i, nb;
+
+  graine=time(NULL);
+  for(i=0;i<argc;++i){
+    if(argv[i][0]=='-'){
+      switch(argv[i][1]){
+      case 'g':
+        i++;
+        graine = atoi(argv[i]);
+        break;
+      case 'n':
+        i++;
+        nb = atoi(argv[i]);
+        break;
+      }
+    }
+  }
+
+  srand(graine);
+
+  cout << nb << endl;
+  for(i = 0; i < nb; ++i){
+    cout << rand() << " ";
+  }
+
+  cout << endl;
+}
diff --git a/simulation/construitTableau.cpp b/simulation/construitTableau.cpp
new file mode 100644 (file)
index 0000000..cc7ec1e
--- /dev/null
@@ -0,0 +1,186 @@
+#include <iostream>
+#include <fstream>
+#include <string>
+
+using namespace std;
+
+#define COMPLET 0
+
+bool lireFichier(string nom, double tab[][6], int nb);
+
+int main(int argc, char **argv)
+{
+  double tab[16][6]; // tableau des résultats en Latex
+  int i, lig, col;
+  string nom, base;
+
+  for(i=1; i<argc; i++){
+    if(argv[i][0] == '-'){
+      switch(argv[i][1]){
+      case 'f':
+        i++;
+        base = string(argv[i]);
+        break;
+      }
+    }
+  }
+
+  for(lig=0; lig<16; ++lig){
+    for(col=0; col<6; ++col){
+      tab[lig][col] = 0;
+    }
+  }
+
+  nom = string("expe_10/") + base;
+  if(!lireFichier(nom, tab, 10)){
+    cout << "Erreur d'ouverture du fichier d'entrées " << nom << endl;
+  }
+
+  nom = string("expe_50/") + base;
+  if(!lireFichier(nom, tab, 50)){
+    cout << "Erreur d'ouverture du fichier d'entrées " << nom << endl;
+  }
+
+#if COMPLET
+  for(lig=0; lig<16; ++lig){
+    if(lig == 0)
+      cout << "\\multirow{8}{7em}{Homogeneous processors} & ";
+    else
+      if(lig == 8)
+        cout << "\\multirow{8}{7em}{Heterogeneous processors} & ";
+      else
+        cout << " & ";
+    if(lig%8 == 0)
+      cout << "\\multirow{4}{7em}{Constant links} & ";
+    else
+      if(lig%4 == 0)
+        cout << "\\multirow{4}{7em}{Intermittent links} & ";
+      else
+        cout << " & ";
+    if(lig%4 == 0)
+      cout << "\\multirow{2}{7em}{All tasks on one node} & ";
+    else
+      if(lig%2 == 0)
+        cout << "\\multirow{2}{7em}{Homogeneous distribution} & ";
+      else
+        cout << " & ";
+
+    for(col=0; col<5; ++col){
+      cout << tab[lig][col] << " & ";
+    }
+    cout << tab[lig][col] << " \\\\" << endl;
+  }
+#else
+  for(lig=0; lig<8; lig+=2){
+
+    if(lig%4 == 0){
+      cout << "\\hline" << endl;
+    }else{
+      if(lig%2 == 0){
+        cout << "\\cline{2-6}" << endl;
+      }
+    }
+    if(lig == 0)
+      cout << "\\multirow{4}{7em}{Constant links} & ";
+    else
+      if(lig == 4)
+        cout << "\\multirow{4}{7em}{Intermittent links} & ";
+      else
+        cout << " & ";
+    if(lig%4 == 0){
+      cout << "\\multirow{2}{6em}{All tasks on one node} & ";
+    }else{
+      if(lig%2 == 0){
+        cout << "\\multirow{2}{6em}{Homogeneous distribution} & ";
+      }else
+        cout << " & ";
+    }
+
+    cout << tab[lig + 1][1] << " & ";
+    cout << tab[lig + 1][4] << " & ";
+    cout << tab[8 + lig + 1][1] << " & ";
+    cout << tab[8 + lig + 1][4] << " \\\\" << endl;
+
+    cout << " & & \\emph{" << tab[lig + 1][2] << "} & ";
+    cout << "     \\emph{" << tab[lig + 1][5] << "} & ";
+    cout << "     \\emph{" << tab[8 + lig + 1][2] << "} & ";
+    cout << "     \\emph{" << tab[8 + lig + 1][5] << "} \\\\" << endl;
+
+  }
+#endif
+}
+
+bool lireFichier(string nom, double tab[][6], int nb)
+{
+  ifstream fic;
+  bool ret = true;
+  int lig, col;
+  bool fini = false;
+  string mot;
+
+  cout << "Lecture données " << nom << " avec " << nb << " procs " << endl;
+
+  fic.open(nom.c_str());
+  if(fic.good()){
+    lig = 0;
+    if(nb == 10){
+      col = 0;
+    }else{
+      col = 3;
+    }
+    fic >> mot;
+    while(fic.good() && !fini){
+      if(mot == "Temps"){
+        fic >> mot;
+        if(mot == "de"){
+          fic >> mot; // "calcul"
+          fic >> mot; // ":"
+          fic >> tab[lig][col];
+          //          cout << lig << " " << col << " : " << tab[lig][col] << endl;
+        }else{
+          if(mot == "optimal"){
+            fic >> mot; // ":"
+            fic >> tab[lig][col + 1];
+            //            cout << lig << " " << col + 1 << " : " << tab[lig][col+1] << endl;
+          }else{
+            if(mot == "initial"){
+              fic >> mot; // ":"
+              fic >> tab[lig][col + 2];
+              //              cout << lig << " " << col + 2 << " : " << tab[lig][col+2] << endl;
+            }
+          }
+        }
+      }else{
+        if(mot == "Surcoût"){
+          fic >> mot; 
+          if(mot == "T"){
+            fic >> mot; // ":"
+            fic >> tab[lig + 1][col + 1];
+            //            cout << lig + 1 << " " << col + 1 << " : " << tab[lig+1][col+1] << endl;
+          }
+        }else{
+          if(mot == "Gain"){
+            fic >> mot;
+            if(mot == "réel"){
+              fic >> mot; // ":"
+              fic >> tab[lig + 1][col + 2];
+              //              cout << lig + 1 << " " << col + 2 << " : " << tab[lig+1][col+2] << endl;
+            }
+          }else{
+            if(mot == "time:"){
+              lig += 2;
+              if(lig >= 16){
+                fini = true;
+              }
+            }
+          }
+        }
+      }
+      fic >> mot;
+    }
+    fic.close();
+  }else{
+    ret = false;
+  }
+  return ret;
+}
diff --git a/simulation/equil6.cpp b/simulation/equil6.cpp
new file mode 100644 (file)
index 0000000..6a41bd8
--- /dev/null
@@ -0,0 +1,1206 @@
+#include <iostream>
+#include <list>
+#include <vector>
+#include <string>
+#include <fstream>
+#include <sstream>
+#include <stdlib.h>
+#include <sys/time.h>
+#include <cmath>
+#include "msg/msg.h" 
+#include "xbt/sysdep.h" 
+#include "xbt/log.h"
+#include "xbt/asserts.h"
+
+using namespace std;
+
+typedef enum {Unique,Unite,AM,Local,Local2} Type_T; // types de politiques de transfert de charge
+
+double ALPHA=0.125;           // poids de la dernière mesure d'intervalle d'attente d'équilibrage
+double BETA=0.125;            // poids de la dernière mesure d'intervalle d'attente d'envois/réceptions
+int SEUIL_ENVOI=1;            // nombre d'intervalles d'attente avant envoi d'infos
+double INTER=0.0;             // intervalle de temps pour les tests d'équilibrages
+double SLEEP=0.0;             // temps de mise en attente des processus
+double octetsTache=24.0;      // en octets (3 doubles)
+double flopsTache=500.0;      // en flops (500 opérations)
+int minNBT=1000,maxNBT=10000; // intervalle du nombre de tâches sur chaque proc
+int nbTerms=0;                // nombre de procs ayant terminé leurs calculs
+int nbTI=0,nbTT=0;            // nombres de tâches initiales et traitées
+double tGDMin=1e100,tGFMax=0; // temps globaux de début et fin
+int numUnique=-1;             // numéro du processeur reçevant la charge en cas de charge unique
+vector<int> nbTaches;         // tableau des nombres de tâches par proc
+double somVit=0;              // somme des vitesses des procs du système
+double maxTC;                 // temps de calcul max sur répartition initiale
+double tempsOpt;              // temps optimal de calcul des tâches sur le système
+int **nbIters=NULL,nbIt;      // tableau des nombres d'itérations nécessaires pour la CV (simulée)
+                              // et nb total itérations
+int minIt=1,maxIt=1;          // bornes de l'intervalle du nombre d'itérations par tâche 
+bool mutexTE,mutexTNE,mutexTR; // mutex pour la manipulation des listes de tâches
+vector<int> iterCumulees;     // itérations locales cumulées par proc
+unsigned int variante=0;      // indique les variantes éventuelles de l'algo d'équilibrage
+int nbArretEnvs=0;            // nombre de procs ayant arrêté leur processus d'envois des infos/equs
+int nbArretRecs=0;            // nombre de procs ayant arrêté leur processus de réception des infos/equs
+Type_T polit=AM;              /* type de politique de transfert de charge :
+                                 Unique : transfert vers le moins chargé des voisins
+                                 Unite  : transfert d'une unité de charge à chaque voisin moins chargé
+                                 AM     : transfert selon règles données dans thèse AM
+                                 Local  : répartition équilibrée sur voisins ayant moins de charge que
+                                          la moyenne de la source et des destinataires
+                               */
+vector<int> valsAleat;        // liste explicite de valeurs aléatoires (cross-plateforme)
+
+typedef enum {BASE=0,LL=1,CU=2,IL=4,IV=8,AB=16} Variante; 
+/*
+  BASE = algo initial avec limite stricte de la charge locale restante sur l'émetteur
+  LL   = léger dépassement de la limite de charge locale autorisé
+  CU   = charge initiale unique sur un proc
+  IL   = itérations liées (identiques entre les tâches)
+  IV   = itérations réalisées sur tout le vecteur local
+  AB   = processus d'apprentissage AdaBoost
+*/                                                       
+
+typedef vector<m_task_t> LTaches;
+typedef vector<m_host_t> LHotes;
+typedef struct {
+  double temps;
+  int nbT;
+} Charge;
+typedef struct {
+  Charge charge;
+  bool fini;
+  bool *connectes;
+  LHotes *voisins;
+  Charge *voCharges;
+  int icl;
+  double inter,*sleep;
+} Infos;
+typedef struct {
+  int pid;
+  Charge charge;
+  string nom;
+} Mess;
+typedef struct {
+  int nbT;
+  m_task_t *tab;
+} MessEqu;
+typedef struct {
+  string src;
+  int *dest,*icl;
+  LTaches *taches;
+  LTaches *recup;
+  LHotes *voisins;
+  bool fini;
+  double *sleep;
+} Equ;
+
+XBT_LOG_NEW_DEFAULT_CATEGORY(msg_test,"Messages specific to equil");
+
+int envInfos(int argc, char *argv[]);
+int recInfos(int argc, char *argv[]);
+int envEqu(int argc, char *argv[]);
+int recEqu(int argc, char *argv[]);
+int calculs(int argc, char *argv[]);
+double ordoOpt(m_host_t *listeHotes);
+bool lireListe(char *nom, vector<int> &valsAleat);
+int myRand();
+
+MSG_error_t test_all(const char *platform_file, const char *application_file);
+
+typedef enum {PORT_DON,PORT_EQU,MAX_CHANNEL} channel_t;
+
+// Fonction d'envoi des messages
+int envInfos(int argc, char *argv[])
+{
+  int pid;
+  m_task_t *enve = NULL;
+  m_process_t moi;
+  int i,j;
+  MSG_error_t err;
+  string nomHote;
+  Infos *denv=NULL;
+  stringstream sstr;
+  bool fini=false;
+  Charge chargePrec={-1.0,-1};
+  Mess *mess;
+  int compteur;
+
+  // Récupération de son processus
+  moi=MSG_process_self();
+
+  // Récupération nom machine
+  nomHote=string(MSG_host_get_name(MSG_host_self()));
+
+  // Récupération données
+  denv=(Infos *)MSG_process_get_data(moi);
+  denv->charge.temps=denv->icl*flopsTache/MSG_get_host_speed(MSG_host_self());
+
+  // Création tableau des messages d'envois
+  enve=new m_task_t[denv->voisins->size()];
+
+  // Affichage PID
+  pid=MSG_process_self_PID();
+  sstr.clear();
+  sstr << "Processus d'envoi des infos sur " << nomHote.c_str();
+  INFO1("\t* %s",sstr.str().c_str());
+  mess=new Mess;
+  mess->pid=pid;
+  mess->nom=nomHote;
+  compteur=0;
+
+  while(!fini){
+    if(compteur==SEUIL_ENVOI || chargePrec.temps!=denv->charge.temps || chargePrec.nbT!=denv->charge.nbT){
+      chargePrec=denv->charge;
+      // Envois bloquants des infos de charge
+      sstr.clear();
+      sstr.str("");
+      sstr << "Charge de " << mess->nom << " (" << pid << ")";
+      mess->charge=denv->charge;
+      for(i=0;i<denv->voisins->size();++i){
+        enve[i]=MSG_task_create(sstr.str().c_str(),0.0,(double)sizeof(Mess),(void *)mess);
+        err=MSG_task_put(enve[i],(*(denv->voisins))[i],PORT_DON);
+        if(err!=MSG_OK){
+          INFO2("\t* Pb à l'envoi des infos depuis %s vers %s",nomHote.c_str(),MSG_host_get_name((*(denv->voisins))[i]));
+          /*
+            switch(err){
+            case MSG_FATAL:
+            INFO1("\t* message mal initialisé sur %s",nomHote.c_str());
+            break;
+            case MSG_HOST_FAILURE:
+            INFO1("\t* hôte destination non joignable depuis %s",nomHote.c_str());
+            break;
+            case MSG_TRANSFER_FAILURE:
+            INFO1("\t* Erreur de transmission depuis %s",nomHote.c_str());
+            break;
+            }
+          */
+          MSG_task_destroy(enve[i]);
+        }else{
+          INFO1("\t* Envoi OK des infos depuis %s",nomHote.c_str());
+        }
+      }
+      sstr << " " << chargePrec.temps << " (" << chargePrec.nbT << ")";
+      INFO1("\t* %s",sstr.str().c_str());
+      compteur=0;
+    }else{
+      compteur++;
+    }
+    MSG_process_sleep(*(denv->sleep));
+    fini=denv->fini;
+  }
+  nbArretEnvs++;
+  INFO1("\t* Arrêt processus d'envois des infos sur %s",nomHote.c_str());
+
+  // Libérations mémoire
+  delete mess;
+  delete[] enve;
+}
+
+// Fonction de réception des messages
+int recInfos(int argc, char *argv[])
+{
+  Infos *drec;
+  m_process_t moi;
+  m_task_t recu=NULL;
+  string nomHote;
+  bool fini=false;
+  Mess *mess=NULL;
+  MSG_error_t err;
+  int i,pid;
+  stringstream sstr;
+  double tDeb,tFin;
+
+  // Récupération de son processus
+  moi=MSG_process_self();
+  nomHote=string(MSG_host_get_name(MSG_host_self()));
+
+  // Récupération données
+  drec=(Infos *)MSG_process_get_data(moi);
+
+  // Affichage infos
+  sstr.clear();
+  sstr << "Processus de réception des infos sur " << nomHote.c_str();
+  INFO1("\t\t# %s",sstr.str().c_str());
+
+  // Boucle de réception
+  tDeb=MSG_get_clock();
+  while(!fini){
+    pid=MSG_task_probe_from(PORT_DON);
+    if(pid>=0){
+      err=MSG_task_get(&recu,PORT_DON);
+      if(err!=MSG_OK){
+        INFO1("\t\t# Pb à la réception des infos sur %s",nomHote.c_str());
+      }else{
+        mess=(Mess *)MSG_task_get_data(recu);
+        drec->charge=mess->charge;
+        for(i=0;i<drec->voisins->size() && mess->nom!=MSG_host_get_name((*(drec->voisins))[i]);++i);
+        if(i<drec->voisins->size()){
+          drec->voCharges[i]=mess->charge;
+          drec->connectes[i]=true;
+        }
+        sstr.clear();
+        sstr.str("");
+        sstr << nomHote.c_str() << " a reçu l'info de charge " << drec->charge.temps << " (" << drec->charge.nbT << ") de " << mess->nom;
+        INFO1("\t\t# %s",sstr.str().c_str());
+        MSG_task_destroy(recu);
+        recu=NULL;
+      }
+    }else{
+      MSG_process_sleep(*(drec->sleep));
+    }
+    fini=drec->fini;
+    tFin=MSG_get_clock();
+    if(!fini && fabs(tFin-tDeb)>=drec->inter){
+      // réinitialisation de l'intervalle de temps
+      for(i=0;i<drec->voisins->size();++i){
+        drec->connectes[i]=false;
+      }
+      tDeb=tFin;
+    }
+  }
+  nbArretRecs++;
+  INFO1("\t\t# Arrêt processus de réceptions des infos sur %s",nomHote.c_str());
+}
+
+// Fonction d'envoi des données d'équilibrage
+int envEqu(int argc, char *argv[])
+{
+  string nomHote;
+  Equ *eenv=NULL;
+  bool fini=false;
+  MSG_error_t err=MSG_OK;
+  m_task_t tache=NULL;
+  int i,j;
+  MessEqu *mess=NULL;
+
+  // Récupération nom machine
+  nomHote=string(MSG_host_get_name(MSG_host_self()));
+  
+  // Récupération données
+  eenv=(Equ *)MSG_process_get_data(MSG_process_self());
+
+  // Allocation du tableau des messages
+  mess=new MessEqu[(*(eenv->voisins)).size()];
+
+  // Affichage infos
+  INFO1("\t\t\t§ Processus d'envoi des équilibrages sur %s",nomHote.c_str());
+
+  // Boucle des envois
+  while(!fini){
+    for(i=0;i<(eenv->voisins)->size();++i){
+      if(eenv->dest[i]>0){
+        mess[i].nbT=eenv->dest[i];
+        mess[i].tab=new m_task_t[mess[i].nbT];
+        mutexTE=true;
+        for(j=0;j<mess[i].nbT;++j){
+          mess[i].tab[j]=(eenv->taches)->back();
+          *(eenv->icl)-=*((int *)MSG_task_get_data((eenv->taches)->back()));
+          (eenv->taches)->pop_back();
+        }
+        mutexTE=false;
+        tache=MSG_task_create("lot tâches",0.0,mess[i].nbT*octetsTache,(void *)(mess+i));
+        err=MSG_task_put(tache,(*(eenv->voisins))[i],PORT_EQU);
+        if(err!=MSG_OK){
+          INFO2("\t\t\t§ Pb à l'envoi d'équilibrage depuis %s vers %s",nomHote.c_str(),MSG_host_get_name((*(eenv->voisins))[i]));
+          mutexTNE=true;
+          for(j=0;j<mess[i].nbT;++j){
+            (eenv->recup)->push_back(mess[i].tab[j]);
+            *(eenv->icl)+=*((int *)MSG_task_get_data((eenv->recup)->back()));
+          }
+          mutexTNE=false;
+          delete[] mess[i].tab;
+        }else{
+          INFO3("\t\t\t§ Envoi OK de %d tâche(s) depuis %s vers %s",mess[i].nbT,nomHote.c_str(),MSG_host_get_name((*(eenv->voisins))[i]));
+          // (*(eenv->taches)).erase((*(eenv->taches)).end()-mess[i].nbT,(*(eenv->taches)).end());
+        }
+        eenv->dest[i]=0;
+      }
+    }
+    MSG_process_sleep(*(eenv->sleep));
+    fini=eenv->fini;
+  }
+  nbArretEnvs++;
+  INFO1("\t\t\t§ Arrêt processus d'envoi des équilibrages sur %s",nomHote.c_str());
+
+  // Libérations mémoire
+  delete[] mess;
+}
+
+// Fonction de réception des données d'équilibrage
+int recEqu(int argc, char *argv[])
+{
+  string nomHote,lt;
+  Equ *erec=NULL;
+  bool fini=false;
+  MSG_error_t err;
+  m_task_t tache=NULL;
+  m_host_t hsrc;
+  int i,pid;
+  MessEqu *mess;
+
+  // Récupération nom machine
+  nomHote=string(MSG_host_get_name(MSG_host_self()));
+  
+  // Récupération données
+  erec=(Equ *)MSG_process_get_data(MSG_process_self());
+
+  // Affichage infos
+  INFO1("\t\t\t\t@ Processus de réception des équilibrages sur %s",nomHote.c_str());
+
+  // Boucle de réception
+  while(!fini){
+    pid=MSG_task_probe_from(PORT_EQU);
+    if(pid>=0){
+      err=MSG_task_get(&tache,PORT_EQU);
+      if(err!=MSG_OK){
+        INFO1("\t\t\t\t@ Pb à la réception d'un équilibrage sur %s",nomHote.c_str());
+      }else{
+        lt.clear();
+        mess=(MessEqu *)MSG_task_get_data(tache);
+        mutexTR=true;
+        lt=string(MSG_task_get_name(mess->tab[0]))+" oo "+string(MSG_task_get_name(mess->tab[mess->nbT-1]));
+        for(i=0;i<mess->nbT;++i){
+          (erec->taches)->push_back(mess->tab[i]);
+          *(erec->icl)+=*((int *)MSG_task_get_data((erec->taches)->back()));
+          // lt+=string(MSG_task_get_name(mess->tab[i]))+" ";
+        }
+        mutexTR=false;
+        delete[] mess->tab;
+        hsrc=MSG_task_get_source(tache);
+        for(i=0;i<erec->voisins->size() && hsrc!=(*(erec->voisins))[i];++i);
+        if(i<erec->voisins->size()){
+          erec->src=MSG_host_get_name((*(erec->voisins))[i]);
+        }
+        INFO3("\t\t\t\t@ %s a reçu %d tâche(s) de %s",nomHote.c_str(),mess->nbT,erec->src.c_str());
+        INFO2("\t\t\t\t@ %s %s",nomHote.c_str(),lt.c_str());
+        tache=NULL;
+      }
+    }
+    MSG_process_sleep(*(erec->sleep));
+    fini=erec->fini;
+  }
+  nbArretRecs++;
+  INFO1("\t\t\t\t@ Arrêt processus de réceptions des équilibrage sur %s",nomHote.c_str());
+}
+
+// Fonction d'équilibrage
+int calculs(int argc, char *argv[]) // Les paramètres sont : 0 = processus, 1,... = voisins
+{
+  m_host_t monHote=NULL,*listeHotes=NULL; 
+  m_task_t mess=NULL,tvect=NULL;
+  LTaches listeT,listeTE,listeTR,listeTNE;
+  LHotes voisins;
+  int i,j;
+  MSG_error_t err;
+  int num;
+  string nomHote,nomTache,tmp;
+  stringstream sstr;
+  double tDeb,tFin;
+  m_process_t envi,reci,enve,rece;
+  Infos *denv,*drec;
+  Equ *eenv,*erec;
+  bool fini=false,fam=false,limite;
+  int indLim;
+  int indVM;
+  double diffMax;
+  int dtmp;
+  int nbTachesTraitees=0,nbCon;
+  double tCycD,tCycF,intervalle,*_sleep;
+  double tGlobalDeb, tGlobalFin,tempsCalc;
+  vector<Charge> diffs; 
+  vector<int> indTries,tmpDest;
+  int tacheCrte,sommeTE;
+
+  // Récupération du nom de la machine courante
+  monHote = MSG_host_self();
+  nomHote=string(MSG_host_get_name(monHote));
+  // Récupération de la liste des machines
+  listeHotes=MSG_get_host_table();
+  // Récupération de la position de la machine courante dans la liste
+  for(num=0;num<MSG_get_host_number() && nomHote!=MSG_host_get_name(listeHotes[num]);++num);
+  num++;
+  // Récupération des voisins de la machine courante
+  for(i=0;i<MSG_get_host_number();++i){
+    tmp=string(MSG_host_get_name(listeHotes[i]));
+    for(j=1;j<argc && tmp!=argv[j];++j);
+    if(j<argc){
+      voisins.push_back(listeHotes[i]);
+    }
+  }
+  num--; // numérotation des procs à partir de 0
+  diffs.resize(voisins.size());
+
+  // Affichage infos
+  if(monHote==NULL){
+    INFO0("Unknown host... Stopping Now! ");
+    abort();
+  }else{
+    INFO3("Je suis %s et j'ai %d éléments / %d",nomHote.c_str(),nbTaches[num],nbTI);
+  }
+  sstr.str("");
+  for(i=0;i<voisins.size();++i){
+    sstr << MSG_host_get_name(voisins[i]) << " ";
+  }
+  INFO1("Mes voisins sont : %s",sstr.str().c_str());
+
+  // Allocation des infos de charge
+  _sleep=new double;
+  *_sleep=INTER;
+  denv=new Infos;
+  denv->fini=false;
+  denv->charge.temps=0;
+  denv->charge.nbT=nbTaches[num];
+  denv->voisins=&voisins;
+  denv->voCharges=NULL;
+  denv->icl=iterCumulees[num];
+  denv->inter=INTER;
+  denv->sleep=_sleep;
+  drec=new Infos;
+  drec->fini=false;
+  drec->connectes=new bool[voisins.size()];
+  for(i=0;i<voisins.size();++i){
+    drec->connectes[i]=false;
+  }
+  drec->voisins=&voisins;
+  drec->voCharges=new Charge[voisins.size()];
+  for(i=0;i<voisins.size();++i){
+    drec->voCharges[i].temps=1e100;
+    drec->voCharges[i].nbT=1<<30;
+  }
+  drec->inter=INTER;
+  drec->sleep=_sleep;
+
+  // Crée processus d'envois/réceptions des infos
+  envi=MSG_process_create("envInfos",&envInfos,(void *)denv,monHote);
+  reci=MSG_process_create("recInfos",&recInfos,(void *)drec,monHote);
+
+  // Allocation des messages d'équilibrage
+  eenv=new Equ;
+  eenv->src=nomHote;
+  eenv->dest=new int[voisins.size()];
+  for(i=0;i<voisins.size();++i){
+    eenv->dest[i]=0;
+  }
+  eenv->icl=&iterCumulees[num];
+  eenv->taches=&listeTE;
+  eenv->recup=&listeTNE;
+  eenv->voisins=&voisins;
+  eenv->fini=false;
+  eenv->sleep=_sleep;
+  erec=new Equ;
+  erec->icl=&iterCumulees[num];
+  erec->taches=&listeTR;
+  erec->voisins=&voisins;
+  erec->fini=false;
+  erec->sleep=_sleep;
+
+  mutexTE=mutexTNE=mutexTR=false;
+  tmpDest.resize(voisins.size(),0);
+
+  // Crée processus d'envois/réceptions des équilibrages
+  enve=MSG_process_create("envEqu",&envEqu,(void *)eenv,monHote);
+  rece=MSG_process_create("recEqu",&recEqu,(void *)erec,monHote);
+
+  // Création des tâches
+  nbCon=0;
+  for(i=0;i<num;++i){
+    nbCon+=nbTaches[i];
+  }
+  for(i=0;i<nbTaches[num];++i){
+    sstr.clear();
+    sstr.str("");
+    sstr << "T_" << i << "_" << num+1;
+    sstr >> nomTache;
+    listeT.push_back(MSG_task_create(nomTache.c_str(),flopsTache,octetsTache,(void *) nbIters[nbCon+i]));
+  }
+
+  // Exécution des itérations
+  tGlobalDeb=tCycD=MSG_get_clock();
+  tacheCrte=0;
+  while(!fini){
+
+    // Récupération des tâches non correctement envoyées précédemment
+    while(!mutexTNE && listeTNE.size()>0){
+      listeT.push_back(listeTNE.back());
+      listeTNE.pop_back();
+    }
+
+    // Récupération des tâches reçues d'un équilibrage
+    while(!mutexTR && listeTR.size()>0){
+      listeT.push_back(listeTR.back());
+      listeTR.pop_back();
+    }
+    
+    // Calculs des tâches  
+    if(listeT.size()>0){
+      // Mise à jour de l'état de terminaison globale si nécessaire
+      if(fam){
+        fam=false;
+        nbTerms--;
+        INFO1("%s reprends des calculs...",nomHote.c_str());
+      }
+
+      // Calcul seulement si tâche courante valide
+      if(tacheCrte>=listeT.size()){
+        tacheCrte=0;
+      }
+
+      // Affichage
+      if(!(variante & IV)){
+        INFO2("Nb tâches : %d\tTâche courante : %d",listeT.size(),tacheCrte);
+#if 0
+        nomTache.clear();
+        for(i=0;i<listeT.size();++i){
+          nomTache+=string(MSG_task_get_name(listeT[i]))+" ";
+        }
+        INFO2("!! %s %s",nomHote.c_str(),nomTache.c_str());
+#endif
+        INFO3("Exécution tâche %s (%d) sur proc %s",MSG_task_get_name(listeT[tacheCrte]),(*((int *) MSG_task_get_data(listeT[tacheCrte]))),nomHote.c_str()); 
+      }else{
+        INFO2("Exécution des %d tâches locales sur proc %s",listeT.size(),nomHote.c_str()); 
+        /*
+          nomTache.clear();
+          for(i=0;i<listeT.size();++i){
+          nomTache+=string(MSG_task_get_name(listeT[i]))+" (";
+          sstr.clear();
+          sstr.str("");
+          sstr << *((int *) MSG_task_get_data(listeT[i]));
+          nomTache+=sstr.str()+") ";
+          }
+          INFO2("!! %s %s",nomHote.c_str(),nomTache.c_str());
+        */
+      }
+
+      // Calculs 
+      tDeb=MSG_get_clock();
+      if(variante & IV){
+        // Exécution des tâches du vecteur
+        tvect=MSG_task_create("Itération vecteur",flopsTache*listeT.size(),octetsTache*listeT.size(),NULL);
+        if(MSG_task_execute(tvect)!=MSG_OK){
+          INFO0("Pb d'exécution de l'itération sur le vecteur");
+        }
+        MSG_task_destroy(tvect);
+        tvect=NULL;
+
+        tFin=MSG_get_clock();
+        nbTachesTraitees+=listeT.size();
+        // Calcul charge restante et envoi
+        iterCumulees[num]-=listeT.size(); // Suppression des itérations que l'on vient de faire
+        denv->charge.temps=(tFin-tDeb)*iterCumulees[num];
+          
+        // Décompte et suppression éventuelle de la tâche effectuée
+        for(tacheCrte=0;tacheCrte<listeT.size();){
+          (*((int *) MSG_task_get_data(listeT[tacheCrte])))--;
+          if(*((int *) MSG_task_get_data(listeT[tacheCrte]))==0){
+            delete ((int *) MSG_task_get_data(listeT[tacheCrte]));
+            MSG_task_destroy(listeT[tacheCrte]); // Vérifier si la destruction désalloue les data !!!
+            listeT.erase(listeT.begin()+tacheCrte);
+            INFO1("CONVERGENCE DE TACHE %d",tacheCrte);
+          }else{
+            tacheCrte++;
+          }
+        }
+
+        // Mise à jour nombre de tâches locales
+        denv->charge.nbT=listeT.size();
+      }else{
+
+        // Exécution tâche courante
+        if(MSG_task_execute(listeT[tacheCrte])!=MSG_OK){
+          INFO1("Pb d'exécution de la tâche %d",tacheCrte);
+        }
+        tFin=MSG_get_clock();
+        nbTachesTraitees++;
+        
+        // Décompte et suppression éventuelle de la tâche effectuée
+        (*((int *) MSG_task_get_data(listeT[tacheCrte])))--;
+        if(*((int *) MSG_task_get_data(listeT[tacheCrte]))==0){
+          delete ((int *) MSG_task_get_data(listeT[tacheCrte]));
+          MSG_task_destroy(listeT[tacheCrte]); // Vérifier si la destruction désalloue les data !!!
+          listeT.erase(listeT.begin()+tacheCrte);
+          INFO1("CONVERGENCE DE TACHE %d",tacheCrte);
+        }else{
+          tacheCrte++;
+        }
+        
+        // Calcul charge restante et envoi
+        iterCumulees[num]--; // Suppression de l'itération que l'on vient de faire
+        denv->charge.temps=(tFin-tDeb)*iterCumulees[num];
+        denv->charge.nbT=listeT.size();
+      }
+    
+    }else{
+      if(listeTNE.size()==0 && listeTR.size()==0){
+        if(!fam){
+          fam=true;
+          nbTerms++;
+        }
+        if(nbTerms<MSG_get_host_number()){
+          INFO2("%s en attente de calculs... (%f)",nomHote.c_str(),*_sleep);
+          MSG_process_sleep(*_sleep);
+        }
+      }
+    }
+
+    // Décision équilibrage à intervalle régulier (temps discret)
+    tCycF=MSG_get_clock();
+    intervalle=fabs(tCycF-tCycD);
+    INFO4("-----------\t\t%f %f -> %f / %f",tCycD,tCycF,intervalle,drec->inter);
+    if(intervalle>=drec->inter){
+
+      // Affichage charges
+      sstr.clear();
+      sstr.str("");
+      nbCon=0;
+      sstr << nomHote << " : " << denv->charge.temps << " (" << denv->charge.nbT << ")\t";
+      for(i=0;i<voisins.size();++i){
+        sstr << drec->voCharges[i].temps << " (" << drec->voCharges[i].nbT << ") [";
+        if(drec->connectes[i]){ sstr << "X"; nbCon++; }else sstr << " ";
+        sstr << "] ";
+      }
+      INFO1("%s",sstr.str().c_str());
+    
+      // Décision
+      if(listeT.size()>1){ // règles d'équilibrage
+        double somme=denv->charge.temps;
+        int nbTermes=1;
+
+        // Construction du tableau décroissant des diffs de charges
+        for(i=0;i<voisins.size();++i){
+          if(drec->connectes[i] 
+             && eenv->dest[i]==0 // envoi de charge en cours pour le voisin i
+             && (!(variante & LL) || denv->charge.nbT>drec->voCharges[i].nbT)
+             && (denv->charge.temps-drec->voCharges[i].temps)*MSG_get_host_speed(monHote)>flopsTache){
+            diffs[i].temps=denv->charge.temps-drec->voCharges[i].temps;
+            diffs[i].nbT=denv->charge.nbT-drec->voCharges[i].nbT;
+            if(indTries.size()==0){
+              indTries.push_back(i);
+            }else{
+              for(j=0;j<indTries.size() && diffs[i].temps<diffs[indTries[j]].temps;++j);
+              indTries.insert(indTries.begin()+j,i);
+            }
+            somme+=drec->voCharges[i].temps;
+            nbTermes++;
+          }else{
+            diffs[i].temps=0;
+            diffs[i].nbT=0;
+          }
+        }
+        if(nbTermes>0 && polit==Local){
+          somme/=nbTermes;
+
+          // difficile de voir l'intérêt de la boucle sur topologies à degré <=2 !
+          bool fin=false;
+          do{
+            int nbTs=1;
+            double moyC=denv->charge.temps;
+            for(i=0;i<indTries.size() && drec->voCharges[indTries[i]].temps<somme;++i){
+              moyC+=drec->voCharges[indTries[i]].temps;
+              nbTs++;
+            }
+            if(i<indTries.size()){
+              indTries.resize(i);
+            }else{
+              fin=true;
+            }
+            nbTermes=nbTs;
+            somme=moyC/nbTermes;
+          }while(!fin);
+
+        }
+
+        INFO2("Temps = %lf\tTermes = %d",somme,nbTermes);
+
+        for(i=0;i<indTries.size();++i){
+          INFO5("Diff %s : %lf %d %e %e",MSG_host_get_name(voisins[indTries[i]]),diffs[indTries[i]].temps,diffs[indTries[i]].nbT,denv->charge.temps,drec->voCharges[indTries[i]].temps);
+        }
+
+        // Initialisation de la répartition des envois de charges
+        dtmp=0;
+        limite=false;
+        indLim=indTries.size();
+        sommeTE=0;
+
+        // Boucle de calcul de la répartition
+        for(i=0;i<indTries.size() && !limite;++i){
+          switch(polit){
+          case Unique:
+            dtmp+=(tmpDest[indTries[i]]=(int)rint(diffs[indTries[i]].nbT/2.0));
+            break;
+          case Unite:
+            dtmp+=(tmpDest[indTries[i]]=1);
+            break;
+          case AM:
+            dtmp+=(tmpDest[indTries[i]]=(int)rint(diffs[indTries[i]].nbT/(voisins.size()+1.0)));
+            break;
+          case Local:
+            if(drec->voCharges[indTries[i]].temps>0){
+              dtmp+=(tmpDest[indTries[i]]=(int)rint(drec->voCharges[indTries[i]].nbT*(somme-drec->voCharges[indTries[i]].temps)/drec->voCharges[indTries[i]].temps));//(int)rint(diffs[indTries[i]].nbT/2.0));//(voisins.size()+1.0)));
+            }else{
+              // On n'a pas l'info de temps restant sur le proc destination alors
+              // on n'a aucune idée de sa vitesse et donc du nombre de tâches à envoyer...
+              // Le plus raisonnable est de considérer la même vitesse que le proc source
+              dtmp+=(tmpDest[indTries[i]]=(int)rint(denv->charge.nbT*(somme-drec->voCharges[indTries[i]].temps)/denv->charge.temps));
+            }
+            break;
+          }
+          // Calcul de la somme des tâches à envoyer
+          if((polit==Unique && i>=1) ||
+             ((polit==Unite || polit==AM)
+              && denv->charge.nbT<dtmp+drec->voCharges[indTries[i]].nbT+tmpDest[indTries[i]]) ||
+             (polit==Local && drec->voCharges[indTries[i]].temps>=somme)
+             ){
+            limite=true;
+            indLim=i;
+            if(variante & LL){
+              indLim++;
+              sommeTE+=tmpDest[indTries[i]];
+            }
+          }else{
+            sommeTE+=tmpDest[indTries[i]];
+          }
+        }
+
+        INFO1("Somme TE = %d",sommeTE);
+
+        // Isolation des tâches à envoyer
+        if(sommeTE<listeT.size()){
+          for(i=0;i<sommeTE;++i){
+            listeTE.push_back(listeT.back());
+            listeT.pop_back();
+          }
+
+          // Activation de la répartition
+          for(i=0;i<indLim;++i){
+            eenv->dest[indTries[i]]=tmpDest[indTries[i]];
+            INFO2("EQU %s : %d",MSG_host_get_name(voisins[indTries[i]]),eenv->dest[indTries[i]]);
+          }
+        }
+        indTries.clear();
+      }
+      tCycD=tCycF;
+    }
+
+    // MAJ intervalle de temps de équilibrages
+    drec->inter=(1.0-ALPHA)*drec->inter+ALPHA*intervalle;
+    *_sleep=drec->inter;
+
+    // MAJ état de terminaison
+    fini=(listeT.size()==0 && listeTNE.size()==0 && listeTR.size()==0 && nbTerms==MSG_get_host_number());
+  }
+  tGlobalFin=MSG_get_clock();
+
+  // Calcul des temps min et max
+  if(tGlobalDeb<tGDMin){
+    tGDMin=tGlobalDeb;
+  }
+  if(tGlobalFin>tGFMax){
+    tGFMax=tGlobalFin;
+  }  
+
+  // Affichage fin
+  INFO3("Fin calculs sur proc %s : %d (%d)",nomHote.c_str(),nbTachesTraitees,nbTaches[num]);
+  //  INFO5("Fin calculs sur proc %s : %d %d %d %d",nomHote.c_str(),listeT.size(),listeTE.size(),listeTNE.size(),listeTR.size());
+  nbTT+=nbTachesTraitees;
+
+  // Indication terminaison des processus d'envois
+  denv->fini=true;
+  eenv->fini=true;
+  // Attente d'arrêt des comms d'équilibrage en cours
+  while(nbArretEnvs<2*MSG_get_host_number()){
+    //    INFO1("Attente barrière envois sur %s",nomHote.c_str());
+    MSG_process_sleep(*_sleep);
+  }
+  // Indication terminaison des processus de réceptions
+  drec->fini=true;
+  erec->fini=true;
+  // Attente d'arrêt des comms d'infos en cours
+  while(nbArretRecs<2*MSG_get_host_number()){
+    //    INFO1("Attente barrière réceptions sur %s",nomHote.c_str());
+    MSG_process_sleep(*_sleep);
+  }
+
+  // Calcul et affichage de la durée du calcul, de la distance à l'optimal et du gain
+  tempsCalc=tGFMax-tGDMin;
+  //  tempsOpt=ceil((double)nbTT/MSG_get_host_number())*flopsTache*MSG_get_host_number()/somVit;
+  INFO3("Itérations effectuées : %d  \tTotal itérations : %d  \tSurcoût G : %.2f%%",nbTT,nbIt,100*(1.0-(maxTC-tempsCalc)/(maxTC-tempsOpt)));
+  INFO3("Temps de calcul : %f\tTemps optimal : %f\tSurcoût T : %.2f%%",tempsCalc,tempsOpt,100*(tempsCalc-tempsOpt)/tempsOpt);
+  INFO3("Temps initial   : %f\tGain optimal  : %.2f%%   \tGain réel : %.2f%%",maxTC,100*(maxTC-tempsOpt)/maxTC,100*(maxTC-tempsCalc)/maxTC);
+
+  // Désallocation mémoire
+  delete _sleep;
+  listeT.clear();
+  voisins.clear();
+  diffs.clear();
+  indTries.clear();
+  iterCumulees.clear();
+  delete denv;
+  delete[] drec->connectes;
+  delete[] drec->voCharges;
+  delete drec;
+  delete[] eenv->dest;
+  delete eenv;
+  delete erec;
+
+  return 0;
+}/* end_of_receiver */
+
+
+/** Test function */
+MSG_error_t test_all(const char *platform_file,const char *application_file)
+{
+  MSG_error_t res = MSG_OK;
+  m_host_t *listeHotes=NULL;
+  double maxVit=0,minVit=1e100; // vitesses min et max des procs du système
+  double tempsCalc;
+  int i,j,k;
+                       
+  /*  Simulation setting */
+  MSG_set_channel_number(MAX_CHANNEL);
+  //  MSG_paje_output("equil.trace");
+  MSG_create_environment(platform_file);
+
+  // Allocation du tableau des tâches
+  nbTaches.resize(MSG_get_host_number());
+  // Calcul du nombre initial de tâches locales et comptage du nombre total
+  if(variante & CU){
+    if(numUnique<0){
+      //      numUnique=(myRand()%MSG_get_host_number());
+      numUnique = 0; // On prend vraiment le pire cas
+    }
+    for(i=0;i<MSG_get_host_number();++i){
+      nbTaches[i]=0;
+    }
+    nbTaches[numUnique]=(myRand()%(maxNBT-minNBT+1))+minNBT;
+    nbTI+=nbTaches[numUnique];
+  }else{
+    int nbTG = (myRand()%(maxNBT-minNBT+1))+minNBT;
+    int nbTpP = nbTG / MSG_get_host_number(); // Répartition homogène des
+                                              // tâches sur les procs
+    int surplus = nbTG % MSG_get_host_number();
+    for(i=0 ; i<surplus ; ++i){
+      nbTaches[i] = nbTpP + 1;
+      nbTI += nbTaches[i];
+    }
+    for( ; i<MSG_get_host_number() ; ++i){
+      nbTaches[i] = nbTpP;
+      nbTI += nbTaches[i];
+    }
+  }
+
+  // Allocation et initialisation du tableau des itérations
+  nbIters=new int*[nbTI];
+  nbIt=0;
+  if(variante & AB){
+    /*
+      Répartition pour simuler u processus AdaBoost :
+      maxIt représente le nombre de classifieurs faibles utilisés
+      toutes les tâches prennent maxIt itérations sauf maxIt-1 qui
+      prennent respectivement de 1 à maxIt-1 itérations
+     */
+    for(i=0;i<nbTI;++i){
+      nbIters[i]=new int;
+      *(nbIters[i])=maxIt;
+    }
+    for(i=1;i<maxIt;++i){
+      int indit=myRand()%nbTI;
+      *(nbIters[indit])=i;
+    }
+    for(i=0;i<nbTI;++i){
+      nbIt+=*(nbIters[i]);
+    }
+  }else{
+    nbIters[0]=new int;
+    *(nbIters[0])=(myRand()%(maxIt-minIt+1))+minIt;
+    nbIt+=*(nbIters[0]);
+    for(i=1;i<nbTI;++i){
+      nbIters[i]=new int;
+      if(variante & IL){
+        *(nbIters[i])=*(nbIters[i-1]);
+      }else{
+        *(nbIters[i])=(myRand()%(maxIt-minIt+1))+minIt;
+      }
+      nbIt+=*(nbIters[i]);
+    }
+  }
+
+  // Allocation et calcul des itérations cumulées initiales par proc
+  iterCumulees.resize(MSG_get_host_number(),0);
+  k=0;
+  for(i=0;i<iterCumulees.size();++i){
+    for(j=0;j<nbTaches[i];++j){
+      iterCumulees[i]+=*(nbIters[k++]);
+    }
+  }
+  
+  // Récupération vitesses des machines et temps max de calcul et réglages des tempos
+  listeHotes=MSG_get_host_table();
+  somVit=0;
+  for(i=0;i<MSG_get_host_number();++i){
+    somVit+=MSG_get_host_speed(listeHotes[i]);
+    if(MSG_get_host_speed(listeHotes[i])>maxVit){
+      maxVit=MSG_get_host_speed(listeHotes[i]);
+    }else
+      if(MSG_get_host_speed(listeHotes[i])<minVit){
+        minVit=MSG_get_host_speed(listeHotes[i]);
+      }
+    tempsCalc=iterCumulees[i]*flopsTache/MSG_get_host_speed(listeHotes[i]);
+    if(tempsCalc>maxTC){
+      maxTC=tempsCalc;
+    }
+  }
+  if(SLEEP==0.0){
+    SLEEP=flopsTache/(2*maxVit);
+  }
+  if(INTER==0.0){
+    INTER=0.99*flopsTache*MSG_get_host_number()/somVit; // Réglage délicat car influe sur la vitesse de simu !!!
+  }
+
+  // Calcul du temps optimal
+  tempsOpt=ordoOpt(listeHotes);
+
+  // Affichage des infos générales
+  INFO0("PARAMÈTRES GÉNÉRAUX");
+  INFO0("-------------------");
+  INFO1("     taille données : %f",octetsTache);
+  INFO1("      taille tâches : %f",flopsTache);
+  INFO1("   total itérations : %d",nbIt);
+  INFO1("     temps attentes : %lf",SLEEP);
+  INFO1("intervalle décision : %lf",INTER);
+  INFO1("       coef attente : %f",ALPHA);
+  INFO1("     limite stricte : %s",(variante & LL)?"inactive":"active");
+  INFO1("      charge unique : %s",(variante & CU)?"active":"inactive");
+  INFO1("   itérations liées : %s",(variante & IL)?"active":"inactive");
+  INFO1("  itération vecteur : %s",(variante & IV)?"active":"inactive");
+
+  /*   Application deployment */
+  MSG_function_register("Calculs", calculs);
+  MSG_launch_application(application_file);
+  
+  res = MSG_main();
+
+  nbTaches.clear();
+  delete[] nbIters;
+  return res;
+} /* end_of_test_all */
+
+
+/** Main function */
+int main(int argc, char *argv[])
+{
+  MSG_error_t res = MSG_OK;
+  int i,flags=0,graine;
+  char *nomPF,*nomDP;
+  MSG_global_init(&argc,argv);
+
+  graine=time(NULL);
+  for(i=0;i<argc;++i){
+    if(argv[i][0]=='-'){
+      switch(argv[i][1]){
+      case 'A':
+        variante |= AB;
+        break;
+      case 'a':
+        i++;
+        ALPHA=atof(argv[i]);
+        break;
+      case 'b':
+        i++;
+        BETA=atof(argv[i]);
+        break;
+      case 'c':
+        i++;
+        flopsTache=atof(argv[i]);
+        break;
+      case 'd':
+        i++;
+        nomDP=argv[i];
+        flags+=2;
+        break;
+      case 'f':
+        i++;
+        INTER=atof(argv[i]);
+        break;
+      case 'g':
+        i++;
+        graine=atoi(argv[i]);
+        break;
+      case 'G':
+        i++;
+        if(!lireListe(argv[i], valsAleat)){
+          CRITICAL1 ("Pb while reading random list: %s\n",argv[i]);
+        }
+      case 'i':
+        i++;
+        minIt=atoi(argv[i]);
+        break;
+      case 'I':
+        i++;
+        maxIt=atoi(argv[i]);
+        break;
+      case 'l':
+        variante|=IL;
+        break;
+      case 'L':
+        variante|=LL;
+        break;
+      case 'o':
+        i++;
+        octetsTache=atof(argv[i]);
+        break;
+      case 'p':
+        i++;
+        nomPF=argv[i];
+        flags+=1;
+        break;
+      case 's':
+        i++;
+        SLEEP=atof(argv[i]);
+        break;
+      case 't':
+        i++;
+        minNBT=atoi(argv[i]);
+        break;
+      case 'T':
+        i++;
+        maxNBT=atoi(argv[i]);
+        break;
+      case 'V':
+        variante|=IV;
+        break;
+      case 'u':
+        variante|=CU;
+        if(argc>i+1 && argv[i+1][0]!='-'){
+          i++;
+          numUnique=atoi(argv[i]);
+        }
+        break;
+      case 'z':
+        i++;
+        switch(argv[i][0]){
+        case 'U':
+          polit=Unique;
+          break;
+        case '1':
+          polit=Unite;
+          break;
+        case 'A':
+          polit=AM;
+          break;
+        case 'L':
+          polit=Local;
+          break;          
+        case 'l':
+          polit=Local2;
+          break;          
+        }
+        break;
+      }
+    }
+  }
+
+  if(flags!=3){
+     CRITICAL1 ("Usage : %s -p fichier_plateforme -d fichier_deploiement < options >\n",argv[0]);
+     CRITICAL0 ("   -A             : application AdaBoost");
+     CRITICAL0 ("   -a réel        : poids de la dernière mesure d'intervalle d'attente d'équilibrage");
+     CRITICAL0 ("   -b réel        : poids de la dernière mesure d'intervalle d'attente d'envois/réceptions");
+     CRITICAL0 ("   -c entier      : quantité de calculs par tâche (en flops)");
+     CRITICAL0 ("   -f réel        : intervalle de temps pour les tests d'équilibrages (en ms)");
+     CRITICAL0 ("   -g entier      : initialisation du générateur aléatoire");
+     CRITICAL0 ("   -i entier      : nombre minimal d'itérations par tâche");
+     CRITICAL0 ("   -I entier      : nombre maximal d'itérations par tâche");
+     CRITICAL0 ("   -l             : itérations liées (identiques entre les tâches)");
+     CRITICAL0 ("   -L             : léger dépassement autorisé de la limite de charge locale");
+     CRITICAL0 ("   -o entier      : taille des données relatives à une tâche (en octets)");
+     CRITICAL0 ("   -s réel        : temps de mise en attente des processus (en ms)");
+     CRITICAL0 ("   -t entier      : nombre minimal de tâches");
+     CRITICAL0 ("   -T entier      : nombre maximal de tâches");
+     CRITICAL0 ("   -V             : itérations réalisées sur tout le vecteur local");
+     CRITICAL0 ("   -u             : charge initiale uniquement sur un processeur");
+     CRITICAL0 ("   -z [U 1 A L l] : politique de transfert de charge d'un noeud :");
+     CRITICAL0 ("                    U : transfert vers le moins chargé des voisins");
+     CRITICAL0 ("                    1 : transfert d'une unité de charge à chaque voisin moins chargé");
+     CRITICAL0 ("                    A : transfert selon règles données dans thèse AM");
+     CRITICAL0 ("                    L : répartition équilibrée sur voisins ayant moins de charge");
+     CRITICAL0 ("                        que la moyenne de la source et des destinataires");
+     CRITICAL0 ("                    l : ?");
+     CRITICAL0 ("");
+     CRITICAL1 ("Exemple:\n\t%s -p platform_equil.xml -d deployment_ligne.xml -g 4 -t 1000 -T 100000 -i 250 -I 1000 -f 0.005 -a 0.5 -u -l -L -V\n",argv[0]);
+     exit(1);
+  }
+
+  srand(graine);
+  res = test_all(nomPF,nomDP);
+  INFO1("Total simulation time: %le", MSG_get_clock());
+  MSG_clean();
+
+  if(res==MSG_OK) return 0; 
+  else return 1;
+} /* end_of_main */
+
+double ordoOpt(m_host_t *listeHotes)
+{
+  int i,j,nb=MSG_get_host_number();
+  vector<double> ordo;
+  int ind;
+  double min,tmp,ret=0;
+
+  ordo.resize(nb,0);
+
+  for(j=0;j<nbIt;++j){
+    min=ordo[0]+flopsTache/MSG_get_host_speed(listeHotes[0]);
+    ind=0;
+    for(i=1;i<nb;++i){
+      tmp=ordo[i]+flopsTache/MSG_get_host_speed(listeHotes[i]);
+      if(tmp<min){
+        min=tmp;
+        ind=i;
+      }
+    }
+    ordo[ind]=min;
+    if(ordo[ind]>ret){
+      ret=ordo[ind];
+    }
+  }
+
+  /*
+    for(i=0;i<nb;++i){
+      INFO3("Proc %d : %d %f",i+1,(int)rint(ordo[i]*MSG_get_host_speed(listeHotes[i])/flopsTache),ordo[i]);
+    }
+  */
+  ordo.clear();
+  return ret;
+}
+
+bool lireListe(char *nom, vector<int> &valsAleat)
+{
+  ifstream fic;
+  int i, nb;
+  bool ret = true;
+
+  fic.open(nom);
+  if(fic.good()){
+    fic >> nb;
+    valsAleat.resize(nb);
+    for(i=0; i<nb; ++i){
+      fic >> valsAleat[i];
+    }
+    fic.close();
+  }else{
+    ret = false;
+  }
+  return ret;
+}
+
+int myRand()
+{
+  static int indice = 0;
+
+  if(valsAleat.size() > 0){
+    int val = valsAleat[indice];
+    indice = (indice + 1) % valsAleat.size();
+    return val;
+  }else{
+    return rand();
+  }
+}
diff --git a/simulation/fin.sh b/simulation/fin.sh
new file mode 100755 (executable)
index 0000000..b8ea0c5
--- /dev/null
@@ -0,0 +1,41 @@
+#!/bin/bash
+generePlat -P expe_100/Plat.xml -D expe_100/Dep.xml -n 100 -t A    >>  expe_100/trace
+equil6 -p expe_100/Plat.xml -d expe_100/Dep.xml -g 1 -o 80 -c 1600 -f 0.005 -a 0.5 -L -V -i 100 -I 500 -u -t 10000 -T 10000 2> expe_100/resultat
+                            tail -4 expe_100/resultat >> expe_100/trace
+                            echo "================================================================================" >> expe_100/trace
+                            rm -f expe_100/resultat
+generePlat -P expe_100/Plat.xml -D expe_100/Dep.xml -n 100 -t A    >>  expe_100/trace
+equil6 -p expe_100/Plat.xml -d expe_100/Dep.xml -g 1 -o 80 -c 1600 -f 0.005 -a 0.5 -L -V -i 100 -I 500   -t 10000 -T 10000 2> expe_100/resultat
+                            tail -4 expe_100/resultat >> expe_100/trace
+                            echo "================================================================================" >> expe_100/trace
+                            rm -f expe_100/resultat
+generePlat -P expe_100/Plat.xml -D expe_100/Dep.xml -n 100 -t A   -d -f 0.001 -F 0.25 -i 10.0 >>  expe_100/trace
+equil6 -p expe_100/Plat.xml -d expe_100/Dep.xml -g 1 -o 80 -c 1600 -f 0.005 -a 0.5 -L -V -i 100 -I 500 -u -t 10000 -T 10000 2> expe_100/resultat
+                            tail -4 expe_100/resultat >> expe_100/trace
+                            echo "================================================================================" >> expe_100/trace
+                            rm -f expe_100/resultat
+generePlat -P expe_100/Plat.xml -D expe_100/Dep.xml -n 100 -t A   -d -f 0.001 -F 0.25 -i 10.0 >>  expe_100/trace
+equil6 -p expe_100/Plat.xml -d expe_100/Dep.xml -g 1 -o 80 -c 1600 -f 0.005 -a 0.5 -L -V -i 100 -I 500   -t 10000 -T 10000 2> expe_100/resultat
+                            tail -4 expe_100/resultat >> expe_100/trace
+                            echo "================================================================================" >> expe_100/trace
+                            rm -f expe_100/resultat
+generePlat -P expe_100/Plat.xml -D expe_100/Dep.xml -n 100 -t C    >>  expe_100/trace
+equil6 -p expe_100/Plat.xml -d expe_100/Dep.xml -g 1 -o 80 -c 1600 -f 0.005 -a 0.5 -L -V -i 100 -I 500 -u -t 10000 -T 10000 2> expe_100/resultat
+                            tail -4 expe_100/resultat >> expe_100/trace
+                            echo "================================================================================" >> expe_100/trace
+                            rm -f expe_100/resultat
+generePlat -P expe_100/Plat.xml -D expe_100/Dep.xml -n 100 -t C    >>  expe_100/trace
+equil6 -p expe_100/Plat.xml -d expe_100/Dep.xml -g 1 -o 80 -c 1600 -f 0.005 -a 0.5 -L -V -i 100 -I 500   -t 10000 -T 10000 2> expe_100/resultat
+                            tail -4 expe_100/resultat >> expe_100/trace
+                            echo "================================================================================" >> expe_100/trace
+                            rm -f expe_100/resultat
+generePlat -P expe_100/Plat.xml -D expe_100/Dep.xml -n 100 -t C   -d -f 0.001 -F 0.25 -i 10.0 >>  expe_100/trace
+equil6 -p expe_100/Plat.xml -d expe_100/Dep.xml -g 1 -o 80 -c 1600 -f 0.005 -a 0.5 -L -V -i 100 -I 500 -u -t 10000 -T 10000 2> expe_100/resultat
+                            tail -4 expe_100/resultat >> expe_100/trace
+                            echo "================================================================================" >> expe_100/trace
+                            rm -f expe_100/resultat
+generePlat -P expe_100/Plat.xml -D expe_100/Dep.xml -n 100 -t C   -d -f 0.001 -F 0.25 -i 10.0 >>  expe_100/trace
+equil6 -p expe_100/Plat.xml -d expe_100/Dep.xml -g 1 -o 80 -c 1600 -f 0.005 -a 0.5 -L -V -i 100 -I 500   -t 10000 -T 10000 2> expe_100/resultat
+                            tail -4 expe_100/resultat >> expe_100/trace
+                            echo "================================================================================" >> expe_100/trace
+                            rm -f expe_100/resultat
diff --git a/simulation/generePlat.cpp b/simulation/generePlat.cpp
new file mode 100644 (file)
index 0000000..82b59ec
--- /dev/null
@@ -0,0 +1,493 @@
+#include <iostream>
+#include <fstream>
+#include <sstream>
+#include <string>
+#include <vector>
+#include <cstdlib>
+#include <ctime>
+#include <unistd.h>
+
+using namespace std;
+
+void aide(char *prog);
+void genereLiensLigne(ofstream &fic, int nbNoeuds, int minB, int maxB, double minL, double maxL, bool liensDyns, double minP, double maxP, double intervalle);
+void genereLiensAnneau(ofstream &fic, int nbNoeuds, int minB, int maxB, double minL, double maxL, bool liensDyns, double minP, double maxP, double intervalle);
+void genereLiensComplet(ofstream &fic, int nbNoeuds, int minB, int maxB, double minL, double maxL, bool liensDyns, double minP, double maxP, double intervalle);
+void genereRoutesLigne(ofstream &fic, int nbNoeuds, bool lienUnique);
+void genereRoutesAnneau(ofstream &fic, int nbNoeuds, bool lienUnique);
+void genereRoutesComplet(ofstream &fic, int nbNoeuds, bool lienUnique);
+void genereDeploiementLigne(string &nom, int nbNoeuds);
+void genereDeploiementAnneau(string &nom, int nbNoeuds);
+void genereDeploiementComplet(string &nom, int nbNoeuds);
+
+int main(int argc, char **argv)
+{
+  int opt;
+  int nbNoeuds=10;                    // Taille du cluster
+  char topo='L';                      // Ligne, Anneau ou Complet
+  int minV=98095000, maxV=98095000;   // Vitesses min et max des procs
+  int minB=100000000, maxB=100000000; // Bandes passantes min et max
+  double minL=0.0001, maxL=0.0001;    // Latences min et max
+  bool liensDyns=false;               // Indique si les liens sont intermittants ou pas 
+  double minP=0.001,maxP=1.0;         // Intervalles de période pour les intermittences des liens
+  double intervalle=10.0;             // Taille de l'intervalle de temps pour les traces dynamiques des liens
+  long graine=1;                      // Initialisation générateur aléatoire
+  ofstream ficP;                      // Fichiers Plateforme et Déploiement
+  string nomFicP,nomFicD;             // Noms des fichiers
+  bool lienUnique=false;              // Indique si tous les liens sont identiques
+
+  while ((opt = getopt(argc, argv, "a:b:B:dD:f:F:g:i:l:L:n:P:t:v:V:")) != -1) {
+    switch (opt) {
+    case 'a':
+      graine=time(NULL);
+      break;
+    case 'b':
+      minB=atoi(optarg);
+      break;
+    case 'B':
+      maxB=atoi(optarg);
+      break;
+    case 'd':
+      liensDyns=true;
+      break;
+    case 'D':
+      nomFicD=string(optarg);
+      break;
+    case 'f':
+      minP=atof(optarg);
+      break;
+    case 'F':
+      maxP=atof(optarg);
+      break;
+    case 'g':
+      graine=atoi(optarg);
+      break;
+    case 'i':
+      intervalle=atof(optarg);
+      break;
+    case 'l':
+      minL=atof(optarg);
+      break;
+    case 'L':
+      maxL=atof(optarg);
+      break;
+    case 'n':
+      nbNoeuds=atoi(optarg);
+      break;
+    case 'P':
+      nomFicP=string(optarg);
+      break;
+    case 't':
+      topo=*optarg;
+      break;
+    case 'v':
+      minV=atoi(optarg);
+      break;
+    case 'V':
+      maxV=atoi(optarg);
+      break;
+    default:
+      aide(argv[0]);
+      return 1;
+    }
+  }
+
+  // Vérification de la spécification du nom de fichier
+  if(nomFicP.size()==0 || nomFicD.size()==0){
+    aide(argv[0]);
+    return 1;
+  }else{
+    cout << "Paramètres de génération de la plateforme :" << endl;
+    cout << "-----------------------------------------" << endl;
+    cout << "\tGraine      : " << graine << endl;
+    cout << endl;
+    cout << "\tNb noeuds   : " << nbNoeuds << endl;
+    cout << "\tTopologie   : " << ((topo=='L')?"Ligne":((topo=='A')?"Anneau":"Complet")) << endl;
+    cout << "\tVitesse min : " << minV << endl;
+    cout << "\tVitesse max : " << maxV << endl;
+    cout << "\tDébit min   : " << minB << endl;
+    cout << "\tDébit max   : " << maxB << endl;
+    cout << "\tLatence min : " << minL << endl;
+    cout << "\tLatence max : " << maxL << endl;
+    cout << "\tLiens dyns  : " << ((liensDyns)?"oui":"non") << endl;
+    if(liensDyns){
+      cout << "\t\tPériode min : " << minP << endl;
+      cout << "\t\tPériode max : " << maxP << endl;
+      cout << "\t\tIntervalle  : " << intervalle << endl;
+    }
+    cout << endl;
+    cout << "\tPlateforme  : " << nomFicP << endl;
+    cout << "\tDéploiement : " << nomFicD << endl;
+    cout << "-----------------------------------------" << endl;
+  }
+
+  // Init générateur aléat
+  srand(graine);
+  
+  // Génération du fichier de plateforme
+  ficP.open(nomFicP.c_str());
+  if(ficP.good()){
+    // En-tête
+    ficP << "<?xml version='1.0'?>" << endl;
+    ficP << "<!DOCTYPE platform SYSTEM \"simgrid.dtd\">" << endl;
+    ficP << "<platform version=\"2\">" << endl;
+    // Noeuds
+    if(minV!=maxV){
+      vector<int> puiss;
+      int i;
+      for(i=1;i<=nbNoeuds;++i){
+        int power=(int) (minV + (maxV - minV + 1.0) * rand() / (RAND_MAX + 1.0) );
+        puiss.push_back(power);
+      }
+      puiss[i = (rand() % nbNoeuds)] = maxV;                 // on force la présence des extremum
+      puiss[(i + ( rand() % nbNoeuds ) ) % nbNoeuds] = minV;
+      for(i=0;i<nbNoeuds;++i){
+        ficP << "  <host id=\"" << i+1 << "\" power=\"" << puiss[i] << "\"/>" << endl;
+      }
+      puiss.clear();      
+    }else{
+      for(int i=1;i<=nbNoeuds;++i){
+        ficP << "  <host id=\"" << i << "\" power=\"" << maxV << "\"/>" << endl;
+      }
+    }
+    // Liens
+    if(minB==maxB && minL==maxL && !liensDyns){ // liens identiques partout et statiques
+      ficP << "  <link id=\"unique\" bandwidth=\"" << maxB << "\" latency=\"" << minL << "\"/>" << endl;
+      lienUnique=true;
+    }else{
+      switch(topo){
+      case 'L':
+        genereLiensLigne(ficP, nbNoeuds, minB, maxB, minL, maxL, liensDyns, minP, maxP, intervalle);
+        break;
+      case 'A':
+        genereLiensAnneau(ficP, nbNoeuds, minB, maxB, minL, maxL, liensDyns, minP, maxP, intervalle);
+        break;
+      case 'C':
+        genereLiensComplet(ficP, nbNoeuds, minB, maxB, minL, maxL, liensDyns, minP, maxP, intervalle);
+        break;
+      }
+    }
+    // Routes
+    switch(topo){
+    case 'L':
+      genereRoutesLigne(ficP, nbNoeuds, lienUnique);
+      break;
+    case 'A':
+      genereRoutesAnneau(ficP, nbNoeuds, lienUnique);
+      break;
+    case 'C':
+      genereRoutesComplet(ficP, nbNoeuds, lienUnique);
+      break;
+    }
+    // Fin de description de plateforme
+    ficP << "</platform>" << endl;
+    // Fermeture du fichier
+    ficP.close();
+  }
+
+  // Génération du fichier de déploiement
+  switch(topo){
+  case 'L':
+    genereDeploiementLigne(nomFicD, nbNoeuds);
+    break;
+  case 'A':
+    genereDeploiementAnneau(nomFicD, nbNoeuds);
+    break;
+  case 'C':
+    genereDeploiementComplet(nomFicD, nbNoeuds);
+    break;
+  }
+  
+  return 0;
+}
+
+void aide(char *prog)
+{
+  cout << "Usage : " << prog << " [options]" << endl
+       << "Options :" << endl
+       << "  -b entier  : bande passante min des liens" << endl
+       << "  -B entier  : bande passante max des liens" << endl
+       << "  -d         : liens dynamiques" << endl
+       << "  -D fichier : nom du fichier de déploiement" << endl
+       << "  -f réel    : durée min d'intermittence des liens" << endl
+       << "  -F réel    : durée max d'intermittence des liens" << endl
+       << "  -i réel    : intervalle de temps des intermittences des liens" << endl
+       << "  -l entier  : latence min des liens" << endl
+       << "  -L entier  : latence max des liens" << endl
+       << "  -n entier  : nombre de procs" << endl
+       << "  -P fichier : nom du fichier de plateforme" << endl
+       << "  -t car     : type de topologie (L, A, C)" << endl
+       << "  -v entier  : vitesse min des procs" << endl
+       << "  -V entier  : vitesse max des procs" << endl
+       << endl;
+}
+
+void genereLiensLigne(ofstream &fic, int nbNoeuds, int minB, int maxB, double minL, double maxL, bool liensDyns, double minP, double maxP, double intervalle)
+{
+  ofstream ficState;
+  stringstream nom;
+
+  for(int i=1; i<nbNoeuds; ++i){
+    // Sens i -> i+1
+    fic << "  <link id=\"" << i << "-" << i+1 << "\"";
+    fic << " bandwidth=\"" << (int) (minB + (maxB - minB + 1.0) * rand() / (RAND_MAX + 1.0) ) << "\"";
+    fic << " latency=\"" << (minL + (maxL - minL) * rand() / RAND_MAX ) << "\"";
+    if(liensDyns){
+      // Spécification du fichier d'état dans la description du lien
+      nom.str("state_");
+      nom << i << "-" << i+1 << ".txt";
+      fic << " state_file=\"" << nom.str() << "\"";
+      // Écriture du fichier d'état
+      ficState.open(nom.str().c_str());
+      if(ficState.good()){
+        double somme=0.0;
+        bool etat = rand()%2;
+        ficState << "PERIODICITY " << (minP + (maxP - minP) * rand() / RAND_MAX ) << endl;
+        while(somme<intervalle){
+          double val = (minP + (maxP - minP) * rand() / RAND_MAX );
+          somme+=val;
+          ficState << somme << " " << ((etat==0)?1.0:-1.0) << endl;
+          etat = !etat;
+        }
+        ficState.close();
+      }
+    }
+    fic << "/>" << endl;
+    // Sens i+1 -> i
+    fic << "  <link id=\"" << i+1 << "-" << i << "\"";
+    fic << " bandwidth=\"" << (int) (minB + (maxB - minB + 1.0) * rand() / (RAND_MAX + 1.0) ) << "\"";
+    fic << " latency=\"" << (minL + (maxL - minL) * rand() / RAND_MAX ) << "\"";
+    if(liensDyns){
+      // Spécification du fichier d'état dans la description du lien
+      fic << " state_file=\"" << nom.str() << "\"";
+    }
+    fic << "/>" << endl;
+  }
+}
+
+void genereLiensAnneau(ofstream &fic, int nbNoeuds, int minB, int maxB, double minL, double maxL, bool liensDyns, double minP, double maxP, double intervalle)
+{
+  ofstream ficState;
+  stringstream nom;
+
+  genereLiensLigne(fic, nbNoeuds, minB, maxB, minL, maxL, liensDyns, minP, maxP, intervalle);
+  // Sens dernier -> premier  
+  fic << "  <link id=\"" << nbNoeuds << "-" << 1 << "\"";
+  fic << " bandwidth=\"" << (int) (minB + (maxB - minB + 1.0) * rand() / (RAND_MAX + 1.0) ) << "\"";
+  fic << " latency=\"" << (minL + (maxL - minL) * rand() / RAND_MAX ) << "\"";
+  if(liensDyns){
+    // Spécification du fichier d'état dans la description du lien
+    nom.str("state_");
+    nom << nbNoeuds << "-" << 1 << ".txt";
+    fic << " state_file=\"" << nom.str() << "\"";
+    // Écriture du fichier d'état
+    ficState.open(nom.str().c_str());
+    if(ficState.good()){
+      double somme=0.0;
+      bool etat = rand()%2;
+      ficState << "PERIODICITY " << (minP + (maxP - minP) * rand() / RAND_MAX ) << endl;
+      while(somme<intervalle){
+        double val = (minP + (maxP - minP) * rand() / RAND_MAX );
+        somme+=val;
+        ficState << somme << " " << ((etat==0)?1.0:-1.0) << endl;
+        etat = !etat;
+      }
+      ficState.close();
+    }
+  }
+  fic << "/>" << endl;
+  // Sens premier -> dernier
+  fic << "  <link id=\"" << 1 << "-" << nbNoeuds << "\"";
+  fic << " bandwidth=\"" << (int) (minB + (maxB - minB + 1.0) * rand() / (RAND_MAX + 1.0) ) << "\"";
+  fic << " latency=\"" << (minL + (maxL - minL) * rand() / RAND_MAX ) << "\"";
+  if(liensDyns){
+    // Spécification du fichier d'état dans la description du lien
+    fic << " state_file=\"" << nom.str() << "\"";
+  }
+  fic << "/>" << endl;
+}
+
+void genereLiensComplet(ofstream &fic, int nbNoeuds, int minB, int maxB, double minL, double maxL, bool liensDyns, double minP, double maxP, double intervalle)
+{
+  ofstream ficState;
+  stringstream nom;
+
+  for(int i=1; i<=nbNoeuds ; ++i){
+    for(int j=i+1; j<=nbNoeuds ; ++j){
+      // Sens i -> j
+      fic << "  <link id=\"" << i << "-" << j << "\"";
+      fic << " bandwidth=\"" << (int) (minB + (maxB - minB + 1.0) * rand() / (RAND_MAX + 1.0) ) << "\"";
+      fic << " latency=\"" << (minL + (maxL - minL) * rand() / RAND_MAX ) << "\"";
+      if(liensDyns){
+        // Spécification du fichier d'état dans la description du lien
+        nom.str("state_");
+        nom << i << "-" << j << ".txt";
+        fic << " state_file=\"" << nom.str() << "\"";
+        // Écriture du fichier d'état
+        ficState.open(nom.str().c_str());
+        if(ficState.good()){
+          double somme=0.0;
+          bool etat = rand()%2;
+          ficState << "PERIODICITY " << (minP + (maxP - minP) * rand() / RAND_MAX ) << endl;
+          while(somme<intervalle){
+            double val = (minP + (maxP - minP) * rand() / RAND_MAX );
+            somme+=val;
+            ficState << somme << " " << ((etat==0)?1.0:-1.0) << endl;
+            etat = !etat;
+          }
+          ficState.close();
+        }
+      }
+      fic << "/>" << endl;
+      // Sens j -> i
+      fic << "  <link id=\"" << j << "-" << i << "\"";
+      fic << " bandwidth=\"" << (int) (minB + (maxB - minB + 1.0) * rand() / (RAND_MAX + 1.0) ) << "\"";
+      fic << " latency=\"" << (minL + (maxL - minL) * rand() / RAND_MAX ) << "\"";
+      if(liensDyns){
+        // Spécification du fichier d'état dans la description du lien
+        fic << " state_file=\"" << nom.str() << "\"";
+      }
+      fic << "/>" << endl;
+    }
+  }
+}
+
+void genereRoutesLigne(ofstream &fic, int nbNoeuds, bool lienUnique)
+{
+  for(int i=1; i<nbNoeuds; ++i){
+    // Sens i -> i+1
+    fic << "  <route src=\"" << i << "\" dst=\"" << i+1 << "\">" << endl;
+    if(lienUnique){
+      fic << "    <link:ctn id=\"unique\"/>" << endl;
+    }else{
+      fic << "    <link:ctn id=\"" << i << "-" << i+1 << "\"/>" << endl;
+    }
+    fic << "  </route>" << endl;
+    // Sens i+1 -> i
+    fic << "  <route src=\"" << i+1 << "\" dst=\"" << i << "\">" << endl;
+    if(lienUnique){
+      fic << "    <link:ctn id=\"unique\"/>" << endl;
+    }else{
+      fic << "    <link:ctn id=\"" << i+1 << "-" << i << "\"/>" << endl;
+    }
+    fic << "  </route>" << endl;
+  }
+}
+
+void genereRoutesAnneau(ofstream &fic, int nbNoeuds, bool lienUnique)
+{
+  genereRoutesLigne(fic, nbNoeuds, lienUnique);
+  // Sens dernier -> premier  
+  fic << "  <route src=\"" << nbNoeuds << "\" dst=\"" << 1 << "\">" << endl;
+  if(lienUnique){
+    fic << "    <link:ctn id=\"unique\"/>" << endl;
+  }else{
+    fic << "    <link:ctn id=\"" << nbNoeuds << "-" << 1 << "\"/>" << endl;
+  }
+  fic << "  </route>" << endl;
+  // Sens premier -> dernier
+  fic << "  <route src=\"" << 1 << "\" dst=\"" << nbNoeuds << "\">" << endl;
+  if(lienUnique){
+    fic << "    <link:ctn id=\"unique\"/>" << endl;
+  }else{
+    fic << "    <link:ctn id=\"" << 1 << "-" << nbNoeuds << "\"/>" << endl;
+  }
+  fic << "  </route>" << endl;
+}
+
+void genereRoutesComplet(ofstream &fic, int nbNoeuds, bool lienUnique)
+{
+  for(int i=1; i<=nbNoeuds ; ++i){
+    for(int j=i+1; j<=nbNoeuds ; ++j){
+      // Sens i -> j
+      fic << "  <route src=\"" << i << "\" dst=\"" << j << "\">" << endl;
+      if(lienUnique){
+        fic << "    <link:ctn id=\"unique\"/>" << endl;
+      }else{
+        fic << "    <link:ctn id=\"" << i << "-" << j << "\"/>" << endl;
+      }
+      fic << "  </route>" << endl;
+      // Sens j -> i
+      fic << "  <route src=\"" << j << "\" dst=\"" << i << "\">" << endl;
+      if(lienUnique){
+        fic << "    <link:ctn id=\"unique\"/>" << endl;
+      }else{
+        fic << "    <link:ctn id=\"" << j << "-" << i << "\"/>" << endl;
+      }
+      fic << "  </route>" << endl;
+    }
+  }
+}
+
+void genereDeploiementLigne(string &nom, int nbNoeuds)
+{
+  ofstream fic;
+  
+  fic.open(nom.c_str());
+  if(fic.good()){
+    fic << "<?xml version='1.0'?>" << endl;
+    fic << "<!DOCTYPE platform SYSTEM \"simgrid.dtd\">" << endl;
+    fic << "<platform version=\"2\">" << endl;
+    for(int i=1; i<=nbNoeuds; ++i){
+      // Dépendances du proc i
+      fic << "  <process host=\"" << i << "\" function=\"Calculs\">" << endl;
+      if(i>1)
+        fic << "    <argument value=\"" << i-1 << "\"/>" << endl;
+      if(i<nbNoeuds)
+        fic << "    <argument value=\"" << i+1 << "\"/>" << endl;
+      fic << "  </process>" << endl;
+    }
+    fic << "</platform>" << endl;
+    fic.close();
+  }else{
+    cout << "Problème d'écriture du fichier de déploiement !" << endl;
+  }
+}
+
+void genereDeploiementAnneau(string &nom, int nbNoeuds)
+{
+  ofstream fic;
+  
+  fic.open(nom.c_str());
+  if(fic.good()){
+    fic << "<?xml version='1.0'?>" << endl;
+    fic << "<!DOCTYPE platform SYSTEM \"simgrid.dtd\">" << endl;
+    fic << "<platform version=\"2\">" << endl;
+    for(int i=1; i<=nbNoeuds; ++i){
+      // Dépendances du proc i
+      fic << "  <process host=\"" << i << "\" function=\"Calculs\">" << endl;
+      fic << "    <argument value=\"" << 1+(i-1+nbNoeuds-1)%nbNoeuds << "\"/>" << endl;
+      fic << "    <argument value=\"" << 1+(i%nbNoeuds) << "\"/>" << endl;
+      fic << "  </process>" << endl;
+    }
+    fic << "</platform>" << endl;
+    fic.close();
+  }else{
+    cout << "Problème d'écriture du fichier de déploiement !" << endl;
+  }
+}
+
+void genereDeploiementComplet(string &nom, int nbNoeuds)
+{
+  ofstream fic;
+  
+  fic.open(nom.c_str());
+  if(fic.good()){
+    fic << "<?xml version='1.0'?>" << endl;
+    fic << "<!DOCTYPE platform SYSTEM \"simgrid.dtd\">" << endl;
+    fic << "<platform version=\"2\">" << endl;
+    for(int i=1; i<=nbNoeuds; ++i){
+      // Dépendances du proc i
+      fic << "  <process host=\"" << i << "\" function=\"Calculs\">" << endl;
+      for(int j=1; j<=nbNoeuds; ++j){
+        if(i!=j)
+          fic << "    <argument value=\"" << j << "\"/>" << endl;
+      }
+      fic << "  </process>" << endl;
+    }
+    fic << "</platform>" << endl;
+    fic.close();
+  }else{
+    cout << "Problème d'écriture du fichier de déploiement !" << endl;
+  }
+}
diff --git a/simulation/lanceExpes.sh b/simulation/lanceExpes.sh
new file mode 100755 (executable)
index 0000000..bf90c22
--- /dev/null
@@ -0,0 +1,50 @@
+#!/bin/bash
+
+for i in 10 50 #100
+do
+    mkdir -p expe_$i
+done
+
+for taille in 50
+do
+# paramètres generePlat
+    printf "TAILLE : %d\n" "$taille"
+    for topo in C
+    do
+        printf " Topo : %s\n" "$topo"
+        for procs in " " #"-v 9809500"
+        do
+            printf " Vitesses : %s\n" "$procs"
+            for liens in " " #"-d -f 0.001 -F 0.5 -i 10.0"
+            do 
+                printf "  Liens : %s\n" "$liens"
+# paramètres equil6
+                for unique in "-u" #" "
+                do
+                    printf "   Charge initiale : %s\n" "$unique"
+                    for tache in "-t 10000 -T 10000" #"-t 100000 -T 100000"
+                    do
+                        printf "    Taches : %s\n" "$tache"
+                        for iter in 500 #200 1000
+                        do
+                            printf "     Iters : %s\n" "$iter"
+                            for polit in " " #"-z L"
+                            do
+                                printf "     Politique : %s\n" "$polit"
+                                nomTrace=trace_$topo
+                                echo ./generePlat -P expe_"$taille"/Plat.xml -D expe_"$taille"/Dep.xml -n "$taille" -t $topo $procs $liens
+                                ./generePlat -P expe_"$taille"/Plat.xml -D expe_"$taille"/Dep.xml -n "$taille" -t $topo $procs $liens >> expe_"$taille"/$nomTrace
+                                echo ./equil6 -p expe_"$taille"/Plat.xml -d expe_"$taille"/Dep.xml -g 1 -o 80 -c 1600 -f 0.005 -a 0.5 -L -V -i 100  -I $iter $unique $tache $polit #2> expe_"$taille"/resultat
+                                printf "taille %s topo %s procs %s liens %s unique %s tache %s iter %s politique %s\n" "$taille" "$topo" "$procs" "$liens" "$unique" "$tache" "$iter" "$polit" >> expe_"$taille"/$nomTrace
+                                ./equil6 -p expe_"$taille"/Plat.xml -d expe_"$taille"/Dep.xml -g 1 -o 80 -c 1600 -f 0.005 -a 0.5 -L -V -i 100 -I $iter $unique $tache $polit 2> expe_"$taille"/resultat
+                                tail -4 expe_"$taille"/resultat >> expe_"$taille"/$nomTrace
+                                echo "================================================================================" >> expe_"$taille"/$nomTrace
+                                rm -f *.txt expe_"$taille"/resultat
+                            done
+                        done
+                    done
+                done
+            done
+        done
+    done
+done