1 #! /usr/bin/env python3
3 # Copyright (c) 2006-2022. The SimGrid Team. All rights reserved.
5 # This program is free software; you can redistribute it and/or modify it
6 # under the terms of the license (GNU LGPL) which comes with this package.
9 # This script takes as input a C++ platform file, compiles it, then dumps the
10 # routing graph as a CSV and generates an SVG image.
11 # The layout should be alright for any platform file, but the colors are very
12 # ad-hoc for file supernode.cpp : do not hesitate to adapt this script to your needs.
17 import matplotlib.pyplot as plt
20 from palettable.colorbrewer.qualitative import Set1_9
21 colors = Set1_9.hex_colors
23 print('Warning: could not import palettable, will use a default palette.')
29 subprocess.run(cmd.split(), capture_output=True, check=True)
32 def compile_platform(platform_cpp):
33 platform_so = platform_cpp.replace('.cpp', '.so')
34 cmd = f'g++ -g -fPIC -shared -o {platform_so} {platform_cpp} -lsimgrid'
39 def dump_csv(platform_so):
40 platform_csv = platform_so.replace('.so', '.csv')
41 cmd = f'graphicator {platform_so} {platform_csv}'
46 def load_graph(platform_csv):
47 edges = pandas.read_csv(platform_csv)
49 G.add_edges_from([e for _, e in edges.drop_duplicates().iterrows()])
50 print(f'Loaded a graph with {len(G)} vertices with {len(G.edges)} edges')
54 def plot_graph(graph, label=False, groups=[]):
55 # First, we compute the graph layout, i.e. the position of the nodes.
56 # The neato algorithm from graphviz is nicer, but this is an extra-dependency.
57 # The spring_layout is also not too bad.
59 pos = nx.nx_agraph.graphviz_layout(graph, 'neato')
61 print('Warning: could not import pygraphviz, will use another layout algorithm.')
62 pos = nx.spring_layout(graph, k=0.5, iterations=1000, seed=42)
63 plt.figure(figsize=(20, 15))
65 all_nodes = set(graph)
66 # We then iterate on all the specified groups, to plot each of them in the right color.
67 # Note that the order of the groups is important here, as we are looking at substrings in the node names.
68 for i, grp in enumerate(groups):
69 nodes = {u for u in all_nodes if grp in u}
71 nx.draw_networkx_nodes(graph, pos, nodelist=nodes, node_size=50, node_color=colors[i], label=grp.replace('_', ''))
72 nx.draw_networkx_nodes(graph, pos, nodelist=all_nodes, node_size=50, node_color=colors[-1], label='unknown')
73 # Finally we draw the edges, the (optional) labels, and the legend.
74 nx.draw_networkx_edges(graph, pos, alpha=0.3)
76 nx.draw_networkx_labels(graph, pos)
77 plt.legend(scatterpoints = 1)
80 def generate_svg(platform_csv):
81 graph = load_graph(platform_csv)
82 plot_graph(graph, label=False, groups=['router', 'link', 'cpu', '_node', 'supernode', 'cluster'])
83 img = platform_csv.replace('.csv', '.svg')
85 print(f'Generated file {img}')
88 if __name__ == '__main__':
89 if len(sys.argv) != 2:
90 sys.exit(f'Syntax: {sys.argv[0]} platform.cpp')
91 platform_cpp = sys.argv[1]
92 platform_so = compile_platform(platform_cpp)
93 platform_csv = dump_csv(platform_so)
94 generate_svg(platform_csv)