dot_writer_ruby.py revision 13992
113992Stiago.muck@arm.com# Copyright (c) 2019 ARM Limited 213992Stiago.muck@arm.com# All rights reserved. 313992Stiago.muck@arm.com# 413992Stiago.muck@arm.com# The license below extends only to copyright in the software and shall 513992Stiago.muck@arm.com# not be construed as granting a license to any other intellectual 613992Stiago.muck@arm.com# property including but not limited to intellectual property relating 713992Stiago.muck@arm.com# to a hardware implementation of the functionality of the software 813992Stiago.muck@arm.com# licensed hereunder. You may use the software subject to the license 913992Stiago.muck@arm.com# terms below provided that you ensure that this notice is replicated 1013992Stiago.muck@arm.com# unmodified and in its entirety in all distributions of the software, 1113992Stiago.muck@arm.com# modified or unmodified, in source code or in binary form. 1213992Stiago.muck@arm.com# 1313992Stiago.muck@arm.com# Redistribution and use in source and binary forms, with or without 1413992Stiago.muck@arm.com# modification, are permitted provided that the following conditions are 1513992Stiago.muck@arm.com# met: redistributions of source code must retain the above copyright 1613992Stiago.muck@arm.com# notice, this list of conditions and the following disclaimer; 1713992Stiago.muck@arm.com# redistributions in binary form must reproduce the above copyright 1813992Stiago.muck@arm.com# notice, this list of conditions and the following disclaimer in the 1913992Stiago.muck@arm.com# documentation and/or other materials provided with the distribution; 2013992Stiago.muck@arm.com# neither the name of the copyright holders nor the names of its 2113992Stiago.muck@arm.com# contributors may be used to endorse or promote products derived from 2213992Stiago.muck@arm.com# this software without specific prior written permission. 2313992Stiago.muck@arm.com# 2413992Stiago.muck@arm.com# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 2513992Stiago.muck@arm.com# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 2613992Stiago.muck@arm.com# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 2713992Stiago.muck@arm.com# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 2813992Stiago.muck@arm.com# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 2913992Stiago.muck@arm.com# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 3013992Stiago.muck@arm.com# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 3113992Stiago.muck@arm.com# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 3213992Stiago.muck@arm.com# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 3313992Stiago.muck@arm.com# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 3413992Stiago.muck@arm.com# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 3513992Stiago.muck@arm.com# 3613992Stiago.muck@arm.com# Authors: Tiago Muck 3713992Stiago.muck@arm.com 3813992Stiago.muck@arm.com# Creates a visual representation of a Ruby network topology 3913992Stiago.muck@arm.com 4013992Stiago.muck@arm.comimport os 4113992Stiago.muck@arm.comimport m5 4213992Stiago.muck@arm.comfrom m5.util import warn 4313992Stiago.muck@arm.comtry: 4413992Stiago.muck@arm.com import pydot 4513992Stiago.muck@arm.comexcept: 4613992Stiago.muck@arm.com pydot = False 4713992Stiago.muck@arm.com 4813992Stiago.muck@arm.com 4913992Stiago.muck@arm.comdef _dot_rgb_to_html(r, g, b): 5013992Stiago.muck@arm.com return "#%.2x%.2x%.2x" % (r, g, b) 5113992Stiago.muck@arm.com 5213992Stiago.muck@arm.comdef _dot_create_router_node(full_path, label): 5313992Stiago.muck@arm.com return pydot.Node( \ 5413992Stiago.muck@arm.com full_path, \ 5513992Stiago.muck@arm.com shape = "Mrecord", \ 5613992Stiago.muck@arm.com label = label, \ 5713992Stiago.muck@arm.com style = "\"rounded, filled\"", \ 5813992Stiago.muck@arm.com color = "#000000", \ 5913992Stiago.muck@arm.com fillcolor = _dot_rgb_to_html(204, 230, 252), \ 6013992Stiago.muck@arm.com fontname = "Arial", \ 6113992Stiago.muck@arm.com fontsize = "14", \ 6213992Stiago.muck@arm.com fontcolor = "#000000" \ 6313992Stiago.muck@arm.com ) 6413992Stiago.muck@arm.com 6513992Stiago.muck@arm.comdef _dot_create_ctrl_node(full_path, label): 6613992Stiago.muck@arm.com return pydot.Node( \ 6713992Stiago.muck@arm.com full_path, \ 6813992Stiago.muck@arm.com shape = "Mrecord", \ 6913992Stiago.muck@arm.com label = label, \ 7013992Stiago.muck@arm.com style = "\"rounded, filled\"", \ 7113992Stiago.muck@arm.com color = "#000000", \ 7213992Stiago.muck@arm.com fillcolor = _dot_rgb_to_html(229, 188, 208), \ 7313992Stiago.muck@arm.com fontname = "Arial", \ 7413992Stiago.muck@arm.com fontsize = "14", \ 7513992Stiago.muck@arm.com fontcolor = "#000000" \ 7613992Stiago.muck@arm.com ) 7713992Stiago.muck@arm.com 7813992Stiago.muck@arm.com 7913992Stiago.muck@arm.comdef _dot_create(network, callgraph): 8013992Stiago.muck@arm.com for r in network.routers: 8113992Stiago.muck@arm.com callgraph.add_node(_dot_create_router_node(r.path(), 8213992Stiago.muck@arm.com 'R %d' % r.router_id)) 8313992Stiago.muck@arm.com 8413992Stiago.muck@arm.com # One link for each direction but draw one edge only 8513992Stiago.muck@arm.com connected = dict() 8613992Stiago.muck@arm.com for link in network.int_links: 8713992Stiago.muck@arm.com if (link.src_node.path() in connected) and \ 8813992Stiago.muck@arm.com (connected[link.src_node.path()] == link.dst_node.path()): 8913992Stiago.muck@arm.com continue 9013992Stiago.muck@arm.com callgraph.add_edge( 9113992Stiago.muck@arm.com pydot.Edge(link.src_node.path(), link.dst_node.path()) 9213992Stiago.muck@arm.com ) 9313992Stiago.muck@arm.com connected[link.dst_node.path()] = link.src_node.path() 9413992Stiago.muck@arm.com 9513992Stiago.muck@arm.com for link in network.ext_links: 9613992Stiago.muck@arm.com ctrl = link.ext_node 9713992Stiago.muck@arm.com label = ctrl._name 9813992Stiago.muck@arm.com if hasattr(ctrl, '_node_type'): 9913992Stiago.muck@arm.com label += ' (' + ctrl._node_type + ')' 10013992Stiago.muck@arm.com callgraph.add_node( 10113992Stiago.muck@arm.com _dot_create_ctrl_node(ctrl.path(), label) 10213992Stiago.muck@arm.com ) 10313992Stiago.muck@arm.com 10413992Stiago.muck@arm.com callgraph.add_edge( 10513992Stiago.muck@arm.com pydot.Edge(link.ext_node.path(), link.int_node.path()) 10613992Stiago.muck@arm.com ) 10713992Stiago.muck@arm.com 10813992Stiago.muck@arm.comdef _do_dot(network, outdir, dotFilename): 10913992Stiago.muck@arm.com callgraph = pydot.Dot(graph_type='graph', rankdir='LR') 11013992Stiago.muck@arm.com _dot_create(network, callgraph) 11113992Stiago.muck@arm.com dot_filename = os.path.join(outdir, dotFilename) 11213992Stiago.muck@arm.com callgraph.write(dot_filename) 11313992Stiago.muck@arm.com try: 11413992Stiago.muck@arm.com # dot crashes if the figure is extremely wide. 11513992Stiago.muck@arm.com # So avoid terminating simulation unnecessarily 11613992Stiago.muck@arm.com callgraph.write_svg(dot_filename + ".svg", prog='neato') 11713992Stiago.muck@arm.com callgraph.write_pdf(dot_filename + ".pdf", prog='neato') 11813992Stiago.muck@arm.com except: 11913992Stiago.muck@arm.com warn("failed to generate dot output from %s", dot_filename) 12013992Stiago.muck@arm.com 12113992Stiago.muck@arm.com 12213992Stiago.muck@arm.comdef do_ruby_dot(root, outdir, dotFilename): 12313992Stiago.muck@arm.com if not pydot: 12413992Stiago.muck@arm.com return 12513992Stiago.muck@arm.com 12613992Stiago.muck@arm.com # Generate a graph for all ruby systems 12713992Stiago.muck@arm.com networks = [] 12813992Stiago.muck@arm.com for obj in root.descendants(): 12913992Stiago.muck@arm.com if isinstance(obj, m5.objects.RubyNetwork): 13013992Stiago.muck@arm.com networks.append(obj) 13113992Stiago.muck@arm.com 13213992Stiago.muck@arm.com for network in networks: 13313992Stiago.muck@arm.com # We assume each ruby system has a single network 13413992Stiago.muck@arm.com rubydotFilename = dotFilename.replace(".dot", 13513992Stiago.muck@arm.com "." + network.get_parent().path() + ".dot") 13613992Stiago.muck@arm.com _do_dot(network, outdir, rubydotFilename) 137