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

Private GIT Repository
Add load balancing algorithm selection facility.
authorArnaud Giersch <arnaud.giersch@iut-bm.univ-fcomte.fr>
Wed, 15 Dec 2010 17:10:07 +0000 (18:10 +0100)
committerArnaud Giersch <arnaud.giersch@iut-bm.univ-fcomte.fr>
Wed, 15 Dec 2010 17:10:07 +0000 (18:10 +0100)
Plus...
* add named_object_list templates
* first tests with MSG_set_function in MY_launch_application
* some preliminary work for topology selection
* rename loba_least_loaded -> loba_simple
* some minor cleanups

12 files changed:
Makefile
TODO
deployment.cpp
hostdata.cpp
loba_least_loaded.h [deleted file]
loba_simple.cpp [moved from loba_least_loaded.cpp with 91% similarity]
loba_simple.h [new file with mode: 0644]
main.cpp
named_object_list.h [new file with mode: 0644]
options.cpp
options.h
process.cpp

index f2d206cb76a4d126d819685e72da4fe378181a45..2ab9e7bee0393c381fbc4a02d3e0842ea03d6608 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -12,9 +12,10 @@ CPPFLAGS += -I $(SIMGRID_INSTALL_DIR)/include
 CPPFLAGS += $(CHECK_FLAGS)
 
 CFLAGS += -std=c99
-CFLAGS += -fgnu89-inline       # workaround simgrid bug
+#CFLAGS += -fgnu89-inline      # workaround simgrid bug
 CFLAGS += $(OPTIM_FLAGS) $(DEBUG_FLAGS)
 
+#CXXFLAGS += -std=c++0x
 CXXFLAGS += $(OPTIM_FLAGS) $(DEBUG_FLAGS)
 
 LDFLAGS += -L $(SIMGRID_INSTALL_DIR)/lib
@@ -52,7 +53,7 @@ TARGETS := loba simple_async
 
 $(shell $(SETLOCALVERSION))
 
-.PHONY: all depend clean
+.PHONY: all clean realclean
 
 all: $(TARGETS)
 
@@ -71,7 +72,11 @@ realclean: clean
 
 version.o: $(patsubst %.cpp,%.o,$(filter-out version.cpp, $(SRC.loba)))
 
+ifneq ($(MAKECMDGOALS),clean)
+ifneq ($(MAKECMDGOALS),realclean)
 -include $(DEP)
+endif
+endif
 
 .SECONDEXPANSION:
 $(TARGETS): $$(patsubst %.cpp,%.o,$$(SRC.$$@))
diff --git a/TODO b/TODO
index 07ec631483382a32bc335eca247ec22314483c6e..1b4de1373cfb989d14e005532013a1d06944b581 100644 (file)
--- a/TODO
+++ b/TODO
@@ -1,5 +1,4 @@
 * implement loba_* algorithms (start with some trivial one)
-* add loba algorithm selection (-a number ?)
 
 * fix process::run when load is 0
    -> wait for a message...
@@ -8,10 +7,5 @@
 * implement automatic process topology 
    (line, ring, star, btree, clique, hypercube, etc..)
 
-   use MSG_process_create_with_arguments
-        name            function name (is duped...)
-        code            use MSG_get_registered_function
-        data            NULL
-        argc
-        argv            argv[0] = process_name
+* add synchronized mode
 
index db02f0d441031a0195f86b2fe942847e963fffdc..a0fad272fdf8f1db947c683a674d7748c57acee3 100644 (file)
@@ -1,9 +1,29 @@
 #include "deployment.h"
 
-namespace {
+#include <vector>
+#include <msg/msg.h>
+#include <xbt/dynar.h>
+#include <xbt/sysdep.h>
+#include "hostdata.h"
 
-}
 
 void MY_launch_application()
 {
+    xbt_assert(hostdata::size() >= 2);
+
+    const char* func = "simulation_main";
+    xbt_dynar_t p0_args = xbt_dynar_new(sizeof(const char*), NULL);
+    xbt_dynar_t p1_args = xbt_dynar_new(sizeof(const char*), NULL);
+
+    xbt_dynar_push_as(p0_args, const char*, "33");
+    xbt_dynar_push_as(p0_args, const char*, hostdata::at(1).get_name());
+
+    xbt_dynar_push_as(p1_args, const char*, "42");
+    xbt_dynar_push_as(p1_args, const char*, hostdata::at(0).get_name());
+
+    MSG_set_function(hostdata::at(0).get_name(), func, p0_args);
+    MSG_set_function(hostdata::at(1).get_name(), func, p1_args);
+
+    xbt_dynar_free(&p0_args);
+    xbt_dynar_free(&p1_args);
 }
index a92527e8a0bb7555fc43a6839135cc66fe02d6ba..c15c0eefa325f963b83ea7b9eacfb5b341540113 100644 (file)
@@ -4,6 +4,7 @@
 #include <algorithm>
 #include <stdexcept>
 #include <xbt/log.h>
+#include <xbt/sysdep.h>
 #include "misc.h"
 
 XBT_LOG_EXTERNAL_DEFAULT_CATEGORY(main);
diff --git a/loba_least_loaded.h b/loba_least_loaded.h
deleted file mode 100644 (file)
index 893a48a..0000000
+++ /dev/null
@@ -1,19 +0,0 @@
-#ifndef LOBA_LEAST_LOADED
-#define LOBA_LEAST_LOADED
-
-#include "process.h"
-
-class loba_least_loaded: public process {
-public:
-    loba_least_loaded(int argc, char* argv[]): process(argc, argv) { }
-    ~loba_least_loaded()                                           { }
-
-private:
-    double load_balance(double my_load);
-};
-
-#endif //!LOBA_LEAST_LOADED
-
-// Local variables:
-// mode: c++
-// End:
similarity index 91%
rename from loba_least_loaded.cpp
rename to loba_simple.cpp
index 9927fd936e5085b5ca4ce2dc330fa6baada960d4..7d4937c234696b5128e924db1acd8c337e1be70a 100644 (file)
@@ -1,4 +1,4 @@
-#include "loba_least_loaded.h"
+#include "loba_simple.h"
 
 #include <xbt/log.h>
 
@@ -8,7 +8,7 @@ XBT_LOG_EXTERNAL_DEFAULT_CATEGORY(loba);
  *   load balance with a least-loaded neighbor,
  *   without breaking the ping-pong condition
  */
-double loba_least_loaded::load_balance(double my_load)
+double loba_simple::load_balance(double my_load)
 {
     int imin = -1;
     int imax = -1;
diff --git a/loba_simple.h b/loba_simple.h
new file mode 100644 (file)
index 0000000..1a2fd73
--- /dev/null
@@ -0,0 +1,19 @@
+#ifndef LOBA_SIMPLE
+#define LOBA_SIMPLE
+
+#include "process.h"
+
+class loba_simple: public process {
+public:
+    loba_simple(int argc, char* argv[]): process(argc, argv) { }
+    ~loba_simple()                                           { }
+
+private:
+    double load_balance(double my_load);
+};
+
+#endif //!LOBA_SIMPLE
+
+// Local variables:
+// mode: c++
+// End:
index 8c1965a1b257b2a22708f86d145786f5a925e72b..1b462c2549769741c19876caaae41f4d2bbdeba8 100644 (file)
--- a/main.cpp
+++ b/main.cpp
@@ -29,13 +29,13 @@ enum {
     EXIT_FAILURE_CLEAN = 0x08,  // error at cleanup
 };
 
-#include "loba_least_loaded.h"
+#include "loba_simple.h"
 int simulation_main(int argc, char* argv[])
 {
     int result;
     process* proc;
     try {
-        proc = new loba_least_loaded(argc, argv);
+        proc = opt::loba_algorithms.new_instance(opt::loba_algo, argc, argv);
         result = proc->run();
         delete proc;
     }
@@ -84,8 +84,9 @@ int main(int argc, char* argv[])
     TRY {
         exit_status = EXIT_FAILURE_INIT; // =====
 
-        // Register the main function of an agent in a global table.
-        MSG_function_register("simulation_main", simulation_main);
+        // Register the default function of an agent
+        // MSG_function_register("simulation_main", simulation_main);
+        MSG_function_register_default(simulation_main);
 
         // Create the platform and the application.
         MSG_create_environment(opt::platform_file.c_str());
diff --git a/named_object_list.h b/named_object_list.h
new file mode 100644 (file)
index 0000000..d3fb20c
--- /dev/null
@@ -0,0 +1,154 @@
+#ifndef NAMED_OBJECT_LIST_H
+#define NAMED_OBJECT_LIST_H
+
+#include <map>
+#include <string>
+
+//===== arity 0 =====
+
+template <typename Base>
+class named_object_list {
+protected:
+    struct creator_base {
+        std::string description;
+        creator_base(const std::string& descr): description(descr) { }
+        creator_base(const char* descr): description(descr) { }
+        virtual Base* operator()() const = 0;
+    };
+
+    template <typename Derived>
+    struct creator: public creator_base {
+        creator(const std::string& descr): creator_base(descr) { }
+        creator(const char* descr): creator_base(descr) { }
+        Base* operator()() const { return new Derived(); }
+    };
+
+    typedef std::map<std::string, const creator_base*> map_type;
+
+    map_type assoc;
+
+    void insert(const std::string& name, const creator_base* creat)
+    {
+        assoc.insert(std::make_pair(name, creat));
+    }
+
+    void insert(const char* name, const creator_base* creat)
+    {
+        assoc.insert(std::make_pair(std::string(name), creat));
+    }
+
+public:
+    typedef typename map_type::const_iterator iterator;
+
+    named_object_list() { };
+    ~named_object_list()
+    {
+        for (iterator it = begin(); it != end(); ++it)
+            delete it->second;
+    }
+
+    Base* new_instance(const std::string& name) const
+    {
+        iterator it = assoc.find(name);
+        if (it != assoc.end())
+            return (*it->second)();
+        else
+            return NULL;
+    }
+
+    Base* new_instance(const char* name) const
+    {
+        return new_instance(std::string(name));
+    }
+
+    const std::string& get_name(iterator& it) const { return it->first; }
+    const std::string& get_descr(iterator& it) const
+    { return it->second->description; }
+
+    size_t size() const          { return assoc.size();  }
+    iterator begin() const       { return assoc.begin(); }
+    iterator end() const         { return assoc.end();   }
+
+};
+
+//===== arity 2 =====
+
+#include <map>
+#include <string>
+
+template <typename Base, typename Arg1, typename Arg2>
+class named_object_list2 {
+protected:
+    struct creator_base {
+        std::string description;
+        creator_base(const std::string& descr): description(descr) { }
+        creator_base(const char* descr): description(descr) { }
+        virtual Base* operator()(Arg1, Arg2) const = 0;
+    };
+
+    template <typename Derived>
+    struct creator: public creator_base {
+        creator(const std::string& descr): creator_base(descr) { }
+        creator(const char* descr): creator_base(descr) { }
+        Base* operator()(Arg1 arg1, Arg2 arg2) const
+        { return new Derived(arg1, arg2); }
+    };
+
+    typedef std::map<std::string, const creator_base*> map_type;
+
+    map_type assoc;
+
+    void insert(const std::string& name, const creator_base* creat)
+    {
+        assoc.insert(std::make_pair(name, creat));
+    }
+
+    void insert(const char* name, const creator_base* creat)
+    {
+        assoc.insert(std::make_pair(std::string(name), creat));
+    }
+
+public:
+    typedef typename map_type::const_iterator iterator;
+
+    named_object_list2() { };
+    ~named_object_list2()
+    {
+        for (iterator it = begin(); it != end(); ++it)
+            delete it->second;
+    }
+
+    Base* new_instance(const std::string& name, Arg1 arg1, Arg2 arg2) const
+    {
+        iterator it = assoc.find(name);
+        if (it != assoc.end())
+            return (*it->second)(arg1, arg2);
+        else
+            return NULL;
+    }
+
+    Base* new_instance(const char* name, Arg1 arg1, Arg2 arg2) const
+    {
+        return new_instance(std::string(name), arg1, arg2);
+    }
+
+    const std::string& get_name(iterator& it) const { return it->first; }
+    const std::string& get_descr(iterator& it) const
+    { return it->second->description; }
+
+    bool exists(const std::string& name) const
+    { return assoc.find(name) != assoc.end(); }
+    iterator begin() const       { return assoc.begin(); }
+    iterator end() const         { return assoc.end();   }
+
+};
+
+//===================
+
+#define THIS_INSERT(name, descr, class) insert(name, new creator<class>(descr))
+
+#endif // !NAMED_OBJECT_LIST_H
+
+// Local variables:
+// mode: c++
+// End:
index 243ad59be73126b016e7b2ced37aaa3d1287e515..0a9fb5ce1fa1b0b7e76ac88b719fd95b33075311 100644 (file)
@@ -5,22 +5,25 @@
 #include <sstream>
 #include <unistd.h>             // getopt
 #include <xbt/log.h>
-#include "misc.h"
+#include "loba_simple.h"
 
 XBT_LOG_EXTERNAL_DEFAULT_CATEGORY(main);
 
 namespace opt {
 
+    // Global options
     std::string program_name;
-
-    std::string platform_file;
-    std::string deployment_file;
-
     int help_requested = 0;
     bool version_requested = false;
 
+    // Simulation parameters
     unsigned log_rate = 1;
 
+    // Platform and deployment
+    std::string platform_file;
+    std::string deployment_file;
+
+    // Automatic deployment
     namespace auto_depl {
         bool        enabled = false;
         std::string topology;
@@ -28,13 +31,34 @@ namespace opt {
         double      load = 0.0;
     }
 
-    unsigned maxiter = 4;       // fixme
-    bool exit_on_close = false;
-
+    // Load balancing algorithm
+    std::string loba_algo("none");
     bool bookkeeping = false;
 
+    // Application parameters
     cost_func comp_cost("1e9, 0"); // fixme: find better defaults
     cost_func comm_cost("1, 0"); // fixme: find better defaults
+    unsigned maxiter = 4;       // fixme
+    bool exit_on_close = false;
+
+    // Named parameters lists
+    loba_algorithms_type loba_algorithms;
+    loba_algorithms_type::loba_algorithms_type()
+    {
+        THIS_INSERT("none", "no load-balancing", process);
+        THIS_INSERT("simple", "balance with least loaded neighbor",
+                    loba_simple);
+    }
+
+#if 0
+    topologies_type topologies;
+    topologies_type::topologies_type()
+    {
+        THIS_INSERT("none", "no load-balancing", process);
+        THIS_INSERT("simple", "balance with least loaded neighbor",
+                    loba_simple);
+    }
+#endif
 
 } // namespace opt
 
@@ -56,8 +80,11 @@ int opt::parse_args(int* argc, char* argv[])
     
     int c;
     opterr = 0;
-    while ((c = getopt(*argc, argv, "bc:C:ehi:l:L:N:T:V")) != -1) {
+    while ((c = getopt(*argc, argv, "a:bc:C:ehi:l:L:N:T:V")) != -1) {
         switch (c) {
+        case 'a':
+            opt::loba_algo = optarg;
+            break;
         case 'b':
             opt::bookkeeping = true;
             break;
@@ -148,9 +175,19 @@ void opt::print()
 
 void opt::usage()
 {
+    // option(...)
 #define o(opt) "    " << std::setw(14) \
                       << std::left << (opt) << std::right << " "
-#define so(subopt) std::setw(10) << (subopt) << ": "
+    // sub-option(...)
+#define so(subopt) std::setw(18) << (subopt) << " : "
+    // sub-option list
+#define so_list(name) do {                                      \
+        name ## _type::iterator it;                             \
+        for (it = name.begin() ; it != name.end() ; ++it)       \
+            std::clog << so(name.get_name(it))                  \
+                      << name.get_descr(it) << "\n";            \
+    } while (0)
+
 
     std::clog << "Usage: " << opt::program_name
               << " [options] <platform_file> <deployment_file>\n";
@@ -171,6 +208,29 @@ void opt::usage()
               << "print current load every n-th iterations, 0 to disable"
               << " (" << opt::log_rate << ")\n";
 
+    std::clog << "\nAutomatic deployment options\n";
+    std::clog << o("-T name")
+              << "enable automatic deployment with selected topology\n";
+    if (opt::help_requested > 1)
+#if 0
+        so_list(opt::topologies);
+#else
+        std::clog << so("name") << "FIXME\n"; // fixme
+#endif
+    std::clog << o("-L value")
+              << "total load with auto deployment, 0 for number of hosts"
+              << " (" << opt::auto_depl::load << ")\n";
+    std::clog << o("-N value")
+              << "number of hosts to use with auto deployment,"
+              << " 0 for max. (" << opt::auto_depl::nhosts << ")\n";
+
+    std::clog << "\nLoad balancing algorithm\n";
+    std::clog << o("-a name") << "load balancing algorithm"
+              << " (" << opt::loba_algo << ")\n";
+    if (opt::help_requested > 1)
+        so_list(opt::loba_algorithms);
+    std::clog << o("-b") << "enable bookkeeping\n";
+
     std::clog << "\nApplication parameters\n";
     std::clog << o("-c [fn,...]f0")
               << "polynomial factors for computation cost"
@@ -183,23 +243,7 @@ void opt::usage()
               << "maximum number of iterations, 0 for infinity"
               << " (" << opt::maxiter << ")\n";
 
-    std::clog << "\nLoad balancing algorithm\n";
-    std::clog << o("-b") << "enable bookkeeping\n";
-
-    std::clog << "\nAutomatic deployment options\n";
-    std::clog << o("-T type")
-              << "enable automatic deployment with selected topology\n";
-    if (opt::help_requested > 1) {
-        std::clog << so(1) << "pipo\n";
-        std::clog << so(42) << "atchoum\n";
-    }
-    std::clog << o("-L value")
-              << "total load with auto deployment, 0 for number of hosts"
-              << " (" << opt::auto_depl::load << ")\n";
-    std::clog << o("-N value")
-              << "number of hosts to use with auto deployment,"
-              << " 0 for max. (" << opt::auto_depl::nhosts << ")\n";
-
+#undef so_list
 #undef so
 #undef o
 }
index 8d89808be9ed759ddcb1398dcf794fe0046e1307..4e352c604f30fb914429c985dc35d21689df0378 100644 (file)
--- a/options.h
+++ b/options.h
@@ -3,20 +3,25 @@
 
 #include <string>
 #include "cost_func.h"
+#include "named_object_list.h"
+#include "process.h"
 
 // Global parameters, shared by all the processes
 namespace opt {
 
+    // Global options
     extern std::string program_name;
-
-    extern std::string platform_file;
-    extern std::string deployment_file;
-
     extern int help_requested;
     extern bool version_requested;
 
+    // Simulation parameters
     extern unsigned log_rate;
 
+    // Platform and deployment
+    extern std::string platform_file;
+    extern std::string deployment_file;
+
+    // Automatic deployment
     namespace auto_depl {
         extern bool        enabled;
         extern std::string topology;
@@ -24,17 +29,30 @@ namespace opt {
         extern double      load;
     }
 
-    extern std::string topology;
-    extern double init_load;
+    // Load balancing algorithm
+    extern std::string loba_algo;
+    extern bool bookkeeping;
 
+    // Application parameters
+    extern cost_func comp_cost;
+    extern cost_func comm_cost;
     extern unsigned maxiter;
     extern bool exit_on_close;
 
-    extern bool bookkeeping;
+    // Named parameters lists
+    extern struct loba_algorithms_type:
+        public named_object_list2<process, int, char** > {
+            loba_algorithms_type();
+    } loba_algorithms;
 
-    extern cost_func comp_cost;
-    extern cost_func comm_cost;
+#if 0
+    extern struct topologies_type:
+        public named_object_list<xxx> {
+            topologies_type();
+    } topologies;
+#endif
 
+    // Utility functions
     int parse_args(int* argc, char* argv[]);
     void print();
     void usage();
index 3b371239d8b38b09ef39ee6b29b2720bc5878976..ed7be055394eefc015637ae1dc927b76c984ed7d 100644 (file)
@@ -129,6 +129,8 @@ double process::sum_of_to_send() const
 
 double process::load_balance(double /*my_load*/)
 {
+    if (iter == 1)
+        WARN0("process::load_balance is a no-op!");
     return 0.0;
 }