-> wait for a message...
-> how does it work with opt::bookkeeping ???
-* implement automatic process topology
- (line, ring, star, btree, clique, hypercube, etc..)
+* for automatic process topology,
+ -> implement some random initial distribution of load
* add synchronized mode
-
#include "deployment.h"
-#include <vector>
+#include <iomanip>
+#include <sstream>
#include <msg/msg.h>
#include <xbt/dynar.h>
-#include <xbt/sysdep.h>
+#include <xbt/log.h>
#include "hostdata.h"
+#include "options.h"
+XBT_LOG_EXTERNAL_DEFAULT_CATEGORY(depl);
void MY_launch_application()
{
- xbt_assert(hostdata::size() >= 2);
+ deployment_generator* gen;
+ gen = opt::topologies.new_instance(opt::auto_depl::topology);
+ gen->generate();
+ gen->deploy();
+ delete gen;
+}
+
+deployment_generator::deployment_generator()
+ : hosts(opt::auto_depl::nhosts)
+{
+ set_load(0, opt::auto_depl::load);
+}
+void deployment_generator::set_load(int host, double load)
+{
+ hosts[host].load = load;
+}
+
+void deployment_generator::set_neighbor(int host, int neighbor)
+{
+ hosts[host].neighbors.push_back(neighbor);
+}
+
+void deployment_generator::set_link(int host1, int host2)
+{
+ set_neighbor(host1, host2);
+ set_neighbor(host2, host1);
+}
+
+void deployment_generator::deploy()
+{
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_t args = xbt_dynar_new(sizeof(const char*), NULL);
+ for (unsigned i = 0 ; i < hosts.size() ; ++i) {
+ const char* hostname = hostdata::at(i).get_name();
+ std::ostringstream oss;
+ oss << std::setprecision(12) << hosts[i].load;
+ std::string strload = oss.str();
+ DEBUG2("%s/load -> \"%s\"", hostname, strload.c_str());
+ xbt_dynar_push_as(args, const char*, strload.c_str());
+ for (unsigned j = 0 ; j < hosts[i].neighbors.size() ; ++j) {
+ int neighbor = hosts[i].neighbors[j];
+ const char* neighbor_name = hostdata::at(neighbor).get_name();
+ DEBUG2("%s/neighbor -> \"%s\"", hostname, neighbor_name);
+ xbt_dynar_push_as(args, const char*, neighbor_name);
+ }
+ MSG_set_function(hostname, func, args);
+ xbt_dynar_reset(args);
+ }
+ xbt_dynar_free(&args);
+}
- xbt_dynar_push_as(p0_args, const char*, "33");
- xbt_dynar_push_as(p0_args, const char*, hostdata::at(1).get_name());
+void deployment_line::generate()
+{
+ for (unsigned i = 0 ; i < size() - 1 ; ++i)
+ set_link(i, i + 1);
+}
+
+void deployment_ring::generate()
+{
+ set_neighbor(0, size() - 1);
+ for (unsigned i = 0 ; i < size() - 1 ; ++i)
+ set_link(i, i + 1);
+ set_neighbor(size() - 1, 0);
+}
- xbt_dynar_push_as(p1_args, const char*, "42");
- xbt_dynar_push_as(p1_args, const char*, hostdata::at(0).get_name());
+void deployment_star::generate()
+{
+ for (unsigned i = 1 ; i < size() ; ++i)
+ set_link(0, i);
+}
- MSG_set_function(hostdata::at(0).get_name(), func, p0_args);
- MSG_set_function(hostdata::at(1).get_name(), func, p1_args);
+void deployment_clique::generate()
+{
+ for (unsigned i = 0 ; i < size() ; ++i)
+ for (unsigned j = 0 ; j < i ; ++j)
+ set_link(i, j);
+}
+
+void deployment_btree::generate()
+{
+ for (unsigned i = 0 ; i < size() / 2 ; ++i) {
+ unsigned left_child = 2 * i + 1;
+ unsigned right_child = 2 * i + 2;
+ if (left_child < size()) {
+ set_link(i, left_child);
+ if (right_child < size())
+ set_link(i, right_child);
+ }
+ }
+}
+
+// void deployment_torus::generate()
+// {
+// }
+
+void deployment_hcube::generate()
+{
+ for (unsigned i = 0 ; i < size() ; ++i)
+ for (unsigned j = 0 ; j < i ; ++j) {
+ // Adapted from rom http://en.wikipedia.org/wiki/Hamming_distance
+ unsigned dist = 0;
+ unsigned val = i ^ j;
- xbt_dynar_free(&p0_args);
- xbt_dynar_free(&p1_args);
+ // Count the number of set bits
+ while (val && dist < 2) {
+ ++dist;
+ val &= val - 1;
+ }
+ if (dist == 1)
+ set_link(i, j);
+ }
}
#ifndef DEPLOYMENT_H
#define DEPLOYMENT_H
+#include <vector>
+
void MY_launch_application();
+class deployment_generator {
+public:
+ deployment_generator();
+
+ size_t size() const { return hosts.size(); }
+ void set_load(int host, double load);
+ void set_neighbor(int host, int neighbor);
+ void set_link(int host1, int host2);
+
+ virtual void generate() = 0;
+ void deploy();
+
+private:
+ struct host_parameters {
+ double load;
+ std::vector<int> neighbors;
+ };
+
+ std::vector<host_parameters> hosts;
+};
+
+#define DEPLOYMENT(name) \
+ class deployment_ ## name: public deployment_generator { \
+ public: void generate(); \
+ }
+
+DEPLOYMENT(line);
+DEPLOYMENT(ring);
+DEPLOYMENT(star);
+DEPLOYMENT(clique);
+DEPLOYMENT(btree);
+// DEPLOYMENT(torus);
+DEPLOYMENT(hcube);
+
+#undef DEPLOYMENT
+
#endif // !DEPLOYMENT_H
// Local variables:
// Creates log categories
XBT_LOG_NEW_CATEGORY(simu, "Simulation messages");
XBT_LOG_NEW_SUBCATEGORY(main, simu, "Messages from global infrastructure");
+XBT_LOG_NEW_SUBCATEGORY(depl, main, "Messages from auto deployment");
XBT_LOG_NEW_SUBCATEGORY(comm, simu, "Messages from asynchronous pipes");
XBT_LOG_NEW_SUBCATEGORY(proc, simu, "Messages from base process class");
XBT_LOG_NEW_SUBCATEGORY(loba, simu, "Messages from load-balancer");
const std::string& get_descr(iterator& it) const
{ return it->second->description; }
- size_t size() const { return assoc.size(); }
+ 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(); }
NOL_INSERT("simple", "balance with least loaded neighbor", loba_simple);
}
-#if 0
topologies_type topologies;
topologies_type::topologies_type()
{
- NOL_INSERT("line", "line topology, initial load at one end", xxx);
- NOL_INSERT("ring", "ring topology", xxx);
- NOL_INSERT("star", "star topology, initial load at center", xxx);
- NOL_INSERT("clique", "all connected topology", xxx);
- NOL_INSERT("btree", "binary tree topologym intiial load at root", xxx);
- NOL_INSERT("hcube", "hypercube topology", xxx);
+ NOL_INSERT("line", "line topology, initial load at one end",
+ deployment_line);
+ NOL_INSERT("ring", "ring topology", deployment_ring);
+ NOL_INSERT("star", "star topology, initial load at center",
+ deployment_star);
+ NOL_INSERT("clique", "all connected topology", deployment_clique);
+ NOL_INSERT("btree", "binary tree topologym intiial load at root",
+ deployment_btree);
+ // NOL_INSERT("torus", "torus topology", deployment_torus);
+ NOL_INSERT("hcube", "hypercube topology", deployment_hcube);
}
-#endif
} // namespace opt
std::istringstream(optarg) >> opt::auto_depl::nhosts;
break;
case 'T':
- opt::auto_depl::topology = optarg;
+ opt::auto_depl::topology = optarg;
+ if (!opt::topologies.exists(opt::auto_depl::topology)) {
+ ERROR1("unknownw topology -- %s",
+ opt::auto_depl::topology.c_str());
+ result = 0;
+ }
break;
case 'V':
opt::version_requested = true;
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";
#include <string>
#include "cost_func.h"
+#include "deployment.h"
#include "named_object_list.h"
#include "process.h"
loba_algorithms_type();
} loba_algorithms;
-#if 0
extern struct topologies_type:
- public named_object_list<xxx> {
+ public named_object_list<deployment_generator> {
topologies_type();
} topologies;
-#endif
// Utility functions
int parse_args(int* argc, char* argv[]);