/* Function used by graphicator (transform a SimGrid platform file in a graphviz dot file with the network topology) */
XBT_PUBLIC void platform_graph_export_graphviz(const std::string& output_filename);
+/* Function used by graphicator (transform a SimGrid platform file in a CSV file with the network topology) */
+XBT_PUBLIC void platform_graph_export_csv(const std::string& output_filename);
} // namespace instr
} // namespace simgrid
}
void get_graph(const s_xbt_graph_t* graph, std::map<std::string, xbt_node_t, std::less<>>* nodes,
- std::map<std::string, xbt_edge_t, std::less<>>* edges) override
- {
- /* the old and generic implementation of get_graph doesn't make sense for complex clusters */
- THROW_UNIMPLEMENTED;
- };
+ std::map<std::string, xbt_edge_t, std::less<>>* edges) override;
unsigned long node_pos(unsigned long id) const { return id * num_links_per_node_; }
unsigned long node_pos_with_loopback(unsigned long id) const { return node_pos(id) + (has_loopback_ ? 1 : 0); }
xbt_graph_free_graph(g, xbt_free_f, xbt_free_f, nullptr);
}
+void platform_graph_export_csv(const std::string& output_filename) {
+ auto* g = xbt_graph_new_graph(0, nullptr);
+ std::map<std::string, xbt_node_t, std::less<>> nodes;
+ std::map<std::string, xbt_edge_t, std::less<>> edges;
+ s4u::Engine::get_instance()->get_netzone_root()->extract_xbt_graph(g, &nodes, &edges);
+
+ std::ofstream fs;
+ fs.open(output_filename, std::ofstream::out);
+ xbt_assert(not fs.fail(), "Failed to open %s", output_filename.c_str());
+
+ fs << "src,dst" << std::endl;
+ for (auto const& elm : edges) {
+ const char* src_s = static_cast<char*>(elm.second->src->data);
+ const char* dst_s = static_cast<char*>(elm.second->dst->data);
+ fs << src_s << "," << dst_s << std::endl;
+ }
+ fs.close();
+ xbt_graph_free_graph(g, xbt_free_f, xbt_free_f, nullptr);
+}
+
/* Callbacks */
static std::vector<NetZoneContainer*> currentContainer; /* push and pop, used only in creation */
static void on_netzone_creation(s4u::NetZone const& netzone)
return it == gateways_.end() ? nullptr : it->second;
}
+void ClusterBase::get_graph(const s_xbt_graph_t* graph, std::map<std::string, xbt_node_t, std::less<>>* nodes,
+ std::map<std::string, xbt_edge_t, std::less<>>* edges)
+{
+ std::vector<NetPoint*> vertices = get_vertices();
+
+ for (auto const& my_src : vertices) {
+ for (auto const& my_dst : vertices) {
+ if (my_src == my_dst)
+ continue;
+
+ Route route;
+
+ get_local_route(my_src, my_dst, &route, nullptr);
+
+ XBT_DEBUG("get_route_and_latency %s -> %s", my_src->get_cname(), my_dst->get_cname());
+
+ xbt_node_t current;
+ xbt_node_t previous;
+ const char* previous_name;
+ const char* current_name;
+
+ if (route.gw_src_) {
+ previous = new_xbt_graph_node(graph, route.gw_src_->get_cname(), nodes);
+ previous_name = route.gw_src_->get_cname();
+ } else {
+ previous = new_xbt_graph_node(graph, my_src->get_cname(), nodes);
+ previous_name = my_src->get_cname();
+ }
+
+ for (auto const& link : route.link_list_) {
+ const char* link_name = link->get_cname();
+ current = new_xbt_graph_node(graph, link_name, nodes);
+ current_name = link_name;
+ new_xbt_graph_edge(graph, previous, current, edges);
+ XBT_DEBUG(" %s -> %s", previous_name, current_name);
+ previous = current;
+ previous_name = current_name;
+ }
+
+ if (route.gw_dst_) {
+ current = new_xbt_graph_node(graph, route.gw_dst_->get_cname(), nodes);
+ current_name = route.gw_dst_->get_cname();
+ } else {
+ current = new_xbt_graph_node(graph, my_dst->get_cname(), nodes);
+ current_name = my_dst->get_cname();
+ }
+ new_xbt_graph_edge(graph, previous, current, edges);
+ XBT_DEBUG(" %s -> %s", previous_name, current_name);
+ }
+ }
+}
+
void ClusterBase::fill_leaf_from_cb(unsigned long position, const std::vector<unsigned long>& dimensions,
const s4u::ClusterCallbacks& set_callbacks, NetPoint** node_netpoint,
s4u::Link** lb_link, s4u::Link** limiter_link)
int main(int argc, char** argv)
{
simgrid::s4u::Engine e(&argc, argv);
- xbt_assert(argc == 3, "Usage: %s <platform_file.xml> <graphviz_file.dot>", argv[0]);
+ xbt_assert(argc == 3, "Usage: %s <platform_file.xml> <graphviz_file.dot|graphviz_file.csv>", argv[0]);
e.load_platform(argv[1]);
- simgrid::instr::platform_graph_export_graphviz(argv[2]);
+
+ const std::string outputfile(argv[2]);
+ const std::string extension = outputfile.substr(outputfile.find_last_of(".") + 1);
+ if(extension == "csv") {
+ printf("Dumping to CSV file\n");
+ simgrid::instr::platform_graph_export_csv(outputfile);
+ }
+ else if(extension == "dot") {
+ printf("Dumping to DOT file\n");
+ simgrid::instr::platform_graph_export_graphviz(outputfile);
+ }
+ else {
+ xbt_assert(false, "Unknown output file format, please use '.dot' or .csv' extension\n");
+ }
return 0;
}
#!/usr/bin/env tesh
$ ${bindir:=.}/graphicator ${srcdir:=.}/teshsuite/platforms/one_cluster.xml test.dot
+> Dumping to DOT file
$ cat test.dot
> graph test {
> }
$ rm -f test.dot
+
+$ ${bindir:=.}/graphicator ${srcdir:=.}/teshsuite/platforms/one_cluster.xml test.csv
+> Dumping to CSV file
+
+$ cat test.csv
+> src,dst
+> bob_cluster_link_0_DOWN,bob_cluster_backbone
+> bob_cluster_link_0_UP,bob_cluster_backbone
+> bob_cluster_link_2_DOWN,bob_cluster_backbone
+> bob_cluster_link_2_UP,bob_cluster_backbone
+> bob_cluster_link_3_DOWN,bob_cluster_backbone
+> bob_cluster_link_3_UP,bob_cluster_backbone
+> bob_cluster_link_4_DOWN,bob_cluster_backbone
+> bob_cluster_link_4_UP,bob_cluster_backbone
+> bob_cluster_link_6_DOWN,bob_cluster_backbone
+> bob_cluster_link_6_UP,bob_cluster_backbone
+> bob0.hamburger.edu,bob_cluster_link_0_DOWN
+> bob0.hamburger.edu,bob_cluster_link_0_UP
+> bob2.hamburger.edu,bob_cluster_link_2_DOWN
+> bob2.hamburger.edu,bob_cluster_link_2_UP
+> bob3.hamburger.edu,bob_cluster_link_3_DOWN
+> bob3.hamburger.edu,bob_cluster_link_3_UP
+> bob4.hamburger.edu,bob_cluster_link_4_DOWN
+> bob4.hamburger.edu,bob_cluster_link_4_UP
+> bob6.hamburger.edu,bob_cluster_link_6_DOWN
+> bob6.hamburger.edu,bob_cluster_link_6_UP
+> bob_cluster_backbone,bob_cluster
+> bobbob_cluster_router.hamburger.edu,bob_cluster
+
+$ rm -f test.csv