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

Private GIT Repository
Add more documentation.
authorArnaud Giersch <arnaud.giersch@iut-bm.univ-fcomte.fr>
Thu, 16 Dec 2010 17:51:41 +0000 (18:51 +0100)
committerArnaud Giersch <arnaud.giersch@iut-bm.univ-fcomte.fr>
Thu, 16 Dec 2010 17:51:41 +0000 (18:51 +0100)
13 files changed:
README
TODO
communicator.h
cost_func.h
deployment.h
hostdata.cpp
hostdata.h
loba_simple.cpp
named_object_list.h
neighbor.h
process.cpp
process.h
simgrid_features.h

diff --git a/README b/README
index db47b28872728d02432899de5b1f9b645dc7454f..d34cb4bf903697082eabe3d3d8a25e7fe9b7408c 100644 (file)
--- a/README
+++ b/README
@@ -1,3 +1,14 @@
+Contenu
+=======
+* Compilation de SimGrid
+* Compilation...
+* Utilisation
+* Communications
+* Pour ajouter un nouvel algorithme d'équilibrage
+* Pour ajouter une nouvelle option au programme
+* Liste des fichiers
+----------------------------------------------------------------------
+
 Compilation de SimGrid
 ======================
 
@@ -15,18 +26,92 @@ d'installation de SimGrid (par ex. /usr/local).
 Utilisation
 ===========
 
-Pour avoir l'aide en ligne :
-$ ./loba -hhh
+Idée générale : on dispose d'une plate-forme (décrite dans le fichier
+XML qui va bien), et on déploie dessus une application.  La notion de
+voisinage entre les processus est *liée à l'application*.  Il faut
+évidemment que la plate-forme sous-jacente autorise les communications
+entre voisins...
+
+Pour avoir l'aide en ligne sur les différents paramètres :
+    $ ./loba -h                 (ou -hh, ou -hhh, pour plus de détails)
 
 Pour changer le niveau de détail des affichages :
         --log=category.thres:level
     avec
         category : simu, main, depl, comm, proc, loba
     et
-        level : trace, debug, verbose, info, warning, error, critical
+           level : trace, debug, verbose, info, warning, error, critical
+
+Pour plus de détail sur les options de logging :
+    http://simgrid.gforge.inria.fr/doc/group__XBT__log.html#log_use
+
+Communications
+==============
+
+Pour communiquer, chaque processus écoute sur 2 mailboxes (sortes de
+ports) :
+  - une pour les message de contrôle ;
+  - une pour les transferts de charge.
+
+Ceci afin d'éviter de bloquer les échanges d'information pendant un
+transfert de charge.
+
+À la fin, chaque processus envoie un message "CLOSE" à tous ses
+voisins (sur chaque mailbox), et attends d'avoir reçu deux messages par
+voisin (un sur chaque mailbox).
+
+Ceci permet de synchroniser les processus à la terminaison (ça, à la
+rigueur, on s'en fout un peu), et surtout de s'assurer qu'il n'y a
+plus de communication qui « traîne » dans les canaux.
+
+Cela permet aussi de ne pas réarmer les communications non bloquantes
+qu'on ne sait pas annuler proprement (un manque dans SimGrid).
+
+Il ne faut bien sûr plus envoyer de message après avoir envoyé un
+"CLOSE".
+
+Attention : lors du déploiement de l'application, il faut s'assurer que
+la relation de voisinage est symétrique !
+*Ce n'est pas vérifié par le programme.*
+
+Pour ajouter un nouvel algorithme d'équilibrage
+===============================================
+
+1. Imiter ce qui est fait pour loba_simple :
+   - définir une nouvelle classe dérivant de process
+   - attention, il faut construire le process explicitement
+   - redéfinir la méthode load_balance qui :
+     - reçoit en paramètre la charge à prendre en compte ;
+     - peut utiliser et éventuellement réordonner le tableau process::pneigh ;
+     - peut récupérer l'information de charge d'un voisin avec
+           pneigh[i]->get_load() ;
+     - définit la charge à envoyer avec
+           pneigh[i]->set_to_send(quantité) ;
+     - retourne la somme des quantités définies avec set_to_send, 
+       éventuellement à l'aide de la méthode process::sum_of_to_send()
+       qui clacule cette somme.
+
+2. Ajouter l'algorithme dans la liste des options.  Dans options.cpp :
+   - faire le #include adéquat ;
+   - ajouter une ligne NOL_INSERT(...) dans la liste existante
+     (dans loba_algorithms_type::loba_algorithms_type()).
+
+Pour ajouter une nouvelle option au programme
+=============================================
+
+1. Ajouter une variable, déclarée dans options.h et définie dans options.cpp
+   (classement plus ou moins thématique).
+
+2. Toujours dans options.cpp, il faut :
+   - compléter la fonction opt::parse_args(), normalement le 3e paramètre à
+     getopt() et le switch..case qui suit (garder l'ordre alphabétique) ;
+   - compléter la fonction opt::print() (avec le même ordre que en 1.) ;
+   - compléter la fonction opt::usage() (avec le même ordre que en 1.).
+
+3. Utiliser la nouvelle variable au(x) bon(s) endroit(s) !
 
-Fichiers
-========
+Liste de fichiers
+=================
 
 * fichiers de description de plates-formes
 
@@ -53,8 +138,8 @@ Fichiers
     hostdata.h                  gestion des boites de réception, par hôte
     hostdata.cpp
 
-    loba_simple.h               load-balancing simple (à copier pour ajouter
-    loba_simple.cpp             d'autres algorithmes)
+    loba_simple.h               équilibrage simple
+    loba_simple.cpp             (à imiter pour ajouter d'autres algorithmes)
 
     main.cpp                    le programme principal
 
@@ -62,7 +147,7 @@ Fichiers
     misc.cpp
 
     named_object_list.h         gestion d'une table de constructeurs
-                                avec des noms et des descritpions
+                                avec des noms et des descriptions
 
     neighbor.h                  un voisin pour un processus
     neighbor.cpp
diff --git a/TODO b/TODO
index 39591cadb19aa06c9f2711b7368282c24bcfc53a..99b97e0d7a665fef079ce59dd77b7746028d6693 100644 (file)
--- a/TODO
+++ b/TODO
@@ -8,3 +8,5 @@
    -> implement some random initial distribution of load
 
 * add synchronized mode
+
+* translate README file ?
index fb06d3448be6f7710e365ace3a0c60ea61bd6450..465d0cf573b3951abaeb54a109194c207710229d 100644 (file)
@@ -29,12 +29,23 @@ public:
     communicator();
     ~communicator();
 
+    // Start to listen for incoming messages
     void listen();
 
+    // Send a message to the "dest" mailbox
     void send(const char* dest, message* msg);
+
+    // Try to receive a message.  Returns true on success.
+    // If "wait" is true, blocks until success or error.
     bool recv(message*& msg, m_host_t& from, bool wait);
+
+    // Try to flush pending sending communications.
+    // If "wait" is true, blocks until success.
     void flush(bool wait);
 
+    // Advertise that the next "close" message is the last one, and
+    // that we do not await any message after that, either on the
+    // control or the data channel.
     void next_close_on_ctrl_is_last();
     void next_close_on_data_is_last();
 
@@ -48,18 +59,19 @@ private:
     int send_counter;
 
     // Control channel for receiving
-    m_task_t    ctrl_task;
-    msg_comm_t  ctrl_comm;
-    bool        ctrl_close_is_last;
+    m_task_t    ctrl_task;          // receive buffer
+    msg_comm_t  ctrl_comm;          // receive communication
+    bool        ctrl_close_is_last; // do not rearm comm after next close
 
     // Data channel for receiving
-    m_task_t    data_task;
-    msg_comm_t  data_comm;
-    bool        data_close_is_last;
+    m_task_t    data_task;          // receive buffer
+    msg_comm_t  data_comm;          // receive communication
+    bool        data_close_is_last; // do not rearm comm after next close
 
     const char* get_ctrl_mbox() const   { return host->get_ctrl_mbox(); }
     const char* get_data_mbox() const   { return host->get_data_mbox(); }
 
+    // Used to test if a communication is over, and to destroy it if it is.
     static bool comm_test_n_destroy(msg_comm_t comm);
 };
 
index ed97dcf028b207de51e8e4d484081fe0470c0601..d7310d2d412bb789ee1638bba3f09e1e7a8b8d5e 100644 (file)
@@ -4,6 +4,9 @@
 #include <iostream>
 #include <string>
 
+// Define a polynomial function
+// The factors are given at construction time, in a C-style string,
+// separated by commas (eg. "1, 2, 3" for x^2 + 2x +3).
 class cost_func {
 public:
     cost_func(const char* param);
index cba191b62536b568c5a4853cecb783cde74b6840..3e71df584efa6abaa0db0c9186f0262e385e42bb 100644 (file)
@@ -3,8 +3,10 @@
 
 #include <vector>
 
+// Deploy an application automatically, according to the global parameters
 void MY_launch_application();
 
+// Base class for deployment generators...
 class deployment_generator {
 public:
     deployment_generator();
index c15c0eefa325f963b83ea7b9eacfb5b341540113..3ac7b0b540b02f4a5cc3063dadfc0ac2496ae12b 100644 (file)
@@ -6,6 +6,7 @@
 #include <xbt/log.h>
 #include <xbt/sysdep.h>
 #include "misc.h"
+#include "options.h"
 
 XBT_LOG_EXTERNAL_DEFAULT_CATEGORY(main);
 
@@ -25,9 +26,9 @@ void hostdata::create()
 {
     int nhosts = MSG_get_host_number();
     m_host_t* host_list = MSG_get_host_table();
-    // fixme: only sort hosts for automatically created deployment
-    // fixme: add an option to disable sorting
-    std::sort(host_list, host_list + nhosts, m_host_less());
+    // only sort hosts for automatically created deployment
+    if (opt::auto_depl::enabled)
+        std::sort(host_list, host_list + nhosts, m_host_less());
     hosts.assign(host_list, host_list + nhosts);
     xbt_free(host_list);
 
index 59ca35da06bb020cb6bbd771e73b189d6edc51d3..703b7a1b38410f158912ea1a22993c31759c26e8 100644 (file)
@@ -5,6 +5,9 @@
 #include <vector>
 #include <msg/msg.h>
 
+// Helper class that associates instances of itself with each host.
+// Facilitate global operations on hosts, and retreiving of host name
+// and mailboxes.
 class hostdata {
 public:
     static void create();
index 7d4937c234696b5128e924db1acd8c337e1be70a..2cf613f5773d21815376a09b651732ca19e2a2a9 100644 (file)
@@ -14,8 +14,8 @@ double loba_simple::load_balance(double my_load)
     int imax = -1;
     double min = my_load;
     double max = -1.0;
-    for (unsigned i = 0 ; i < neigh.size() ; ++i) {
-        double l = neigh[i].get_load();
+    for (unsigned i = 0 ; i < pneigh.size() ; ++i) {
+        double l = pneigh[i]->get_load();
         if (l >= my_load)
             continue;
         if (l < min) {
@@ -31,7 +31,7 @@ double loba_simple::load_balance(double my_load)
         // found someone
         double balance = (my_load - max) / 2;
         DEBUG6("%d:%g %d:%g %g %g", imin, min, imax, max, my_load, balance);
-        neigh[imin].set_to_send(balance);
+        pneigh[imin]->set_to_send(balance);
         return balance;
     } else {
         return 0.0;
index 2c91263f982325d049c1f32d19f26de2864c4156..929a0dbee112ca1d0796de11534980c9f70b4044 100644 (file)
@@ -4,6 +4,17 @@
 #include <map>
 #include <string>
 
+// Define an associative container that maps a name with a class and a
+// description.  All classes must be derived from a same base class.
+//
+// We can then use the name to create an object of the associated
+// class, and to retrieve a pointer to this object.
+//
+// Furthermore, it is possible to iterate over the elements to get
+// their name and their description.
+
+// I am too lazy to comment the code, which should be obvious...
+
 //===== arity 0 =====
 
 template <typename Base>
@@ -143,6 +154,7 @@ public:
 
 //===================
 
+// "NOL" like in Named_Object_List....
 #define NOL_INSERT(name, descr, class) insert(name, new creator<class>(descr))
 
 #endif // !NAMED_OBJECT_LIST_H
index 7700cb3c9f6fc113cbfd39e1d27cd0b05f364b90..9607c072f49c8dbd5de11adab45e3eaca3746e81 100644 (file)
@@ -9,26 +9,32 @@ public:
     neighbor(const char* hostname);
     ~neighbor();
 
+    // returns name, ctrl or data mbox
     const char* get_name() const        { return host->get_name(); }
     const char* get_ctrl_mbox() const   { return host->get_ctrl_mbox(); }
     const char* get_data_mbox() const   { return host->get_data_mbox(); }
 
+    // Getter and setter for load
     double get_load() const             { return load;   }
     void set_load(double amount)        { load = amount; }
 
+    // Getter and setter for debt
     double get_debt() const             { return debt;   }
     void set_debt(double amount)        { debt = amount; }
 
+    // Getter and setter for to_send
     double get_to_send() const          { return to_send;   }
     void set_to_send(double amount)     { to_send = amount; }
 
 private:
-    const hostdata* host;
+    const hostdata* host;       // pointer to this neighbor's hostdata
 
-    double load;
-    double debt;
+    double load;                // the load information we know for it
+    double debt;                // the load we had to send to it, but
+                                // that we have not currently sent
+                                // (in bookkeeping mode)
 
-    double to_send;
+    double to_send;             // the load we have to send to it
 };
 
 #endif // !NEIGHBOR_H
index ed7be055394eefc015637ae1dc927b76c984ed7d..b0d702644de509e4cc2e12c53212847e924a07ac 100644 (file)
@@ -188,7 +188,6 @@ void process::send()
     using namespace std::tr1;
     using namespace std::tr1::placeholders;
 
-    // fixme: shall we send data at all iterations?
     if (opt::bookkeeping) {
         std::for_each(neigh.begin(), neigh.end(),
                       bind(&process::send1_bookkeeping, this, _1));
@@ -200,7 +199,6 @@ void process::send()
     }
 }
 
-// Returns false if a CLOSE message was received. 
 bool process::receive(recv_wait_mode wait)
 {
     bool result = true;
index 607a6af130e1dc330f555d4b5b23edc45eea8c24..268fac9a2902641225f3145bf9cd3f30283f1aaa 100644 (file)
--- a/process.h
+++ b/process.h
@@ -26,35 +26,58 @@ protected:
     typedef std::vector<neighbor> neigh_type;
     typedef std::vector<neighbor*> pneigh_type;
 
-    neigh_type neigh;
-    pneigh_type pneigh;
+    pneigh_type pneigh;         // list of pointers to neighbors that
+                                // we are free to reorder
+
+    // Returns the sum of "to_send" for all neighbors.
+    double sum_of_to_send() const;
 
 private:
     typedef MAP_TEMPLATE<m_host_t, neighbor*> rev_neigh_type;
-    enum recv_wait_mode { NO_WAIT = 0, WAIT, WAIT_FOR_CLOSE };
 
-    rev_neigh_type rev_neigh;
+    neigh_type neigh;           // list of neighbors (do not alter
+                                // after construction!)
+    rev_neigh_type rev_neigh;   // map m_host_t -> neighbor
 
-    communicator comm;
-    int ctrl_close_pending;
-    int data_close_pending;
+    communicator comm;          // communicator for this process
+    int ctrl_close_pending;     // number of "close" messages to wait
+                                // on ctrl channel
+    int data_close_pending;     // number of "close" messages to wait
+                                // on data channel
 
-    unsigned iter;
+    unsigned iter;              // counter of iterations
 
-    double prev_load_broadcast;
-    double load;
-    double expected_load;
+    double prev_load_broadcast; // used to ensure that we do not send
+                                // a same information messages
+    double load;                // current load
+    double expected_load;       // expected load in bookkeeping mode
 
-    double sum_of_to_send() const;
+    // The load balancing algorithm comes here...
+    // Parameter "my_load" is the load to take into account for myself
+    // (may be load or expected load).
+    // Returns the total load sent to neighbors.
     virtual double load_balance(double my_load);
 
+    // Virtually do some computation
     void compute();
+
+    // Send procedures, with helpers for bookkeeping mode or not
     void send1_no_bookkeeping(neighbor& nb);
     void send1_bookkeeping(neighbor& nb);
     void send();
+
+    // Receive procedure: wait (or not) for a message to come.
+    // Returns false if some "close" message was received, returns true
+    // otherwise.
+    enum recv_wait_mode { NO_WAIT = 0, WAIT, WAIT_FOR_CLOSE };
     bool receive(recv_wait_mode wait);
+
+    // Finalize sends a "close" message to each neighbor and wait for
+    // all of them to answer.
     void finalize1(neighbor& nb);
     void finalize();
+
+    // Print with given priority what we know about our neighbors' loads
     void print_loads(e_xbt_log_priority_t logp = xbt_log_priority_info);
 };
 
index 8fa8d5622241fcc647d52663b917749cbf5df13f..8aef329affebe696888d1f03621b16561c72a3b3 100644 (file)
@@ -1,7 +1,11 @@
 #ifndef SIMGRID_FEATURES_H
 #define SIMGRID_FEATURES_H
 
-// fixme: dirty hack
+// Try to guess if MSG_wait destroys communications or not, because it
+// changed after SimGrid 3.5.
+//
+// Use some define introduced after that.               fixme: dirty hack
+//
 #if defined(XBT_RUNNING_CTX_INITIALIZER)
 #  define MSG_WAIT_DESTROYS_COMMS 0
 #else