示例#1
0
    def _draw_subgraph(diagram: pydot.Dot,
                       label_last_seen: DefaultDict[str, str],
                       subgraph_name: str,
                       subgraph_ops: List[Union[Op, Trace, Any]]) -> None:
        """Draw a subgraph of ops into an existing `diagram`.

        Args:
            diagram: The diagram to be appended to.
            label_last_seen: A mapping of {data_dict_key: node_id} indicating the last node which generated the key.
            subgraph_name: The name to be associated with this subgraph.
            subgraph_ops: The ops to be wrapped in this subgraph.
        """
        subgraph = pydot.Cluster(style='dashed', graph_name=subgraph_name)
        subgraph.set('label', subgraph_name)
        subgraph.set('labeljust', 'l')
        for idx, op in enumerate(subgraph_ops):
            node_id = str(id(op))
            Traceability._add_node(subgraph, op, node_id)
            if isinstance(op, (Op, Trace)):
                # Need the instance check since subgraph_ops might contain a tf dataset or torch dataloader
                edge_srcs = defaultdict(lambda: [])
                for inp in op.inputs:
                    if inp == '*':
                        continue
                    edge_srcs[label_last_seen[inp]].append(inp)
                for src, labels in edge_srcs.items():
                    diagram.add_edge(pydot.Edge(src=src, dst=node_id, label=f" {', '.join(labels)} "))
                for out in op.outputs:
                    label_last_seen[out] = node_id
            if isinstance(op, Trace) and idx > 0:
                # Invisibly connect traces in order so that they aren't all just squashed horizontally into the image
                diagram.add_edge(pydot.Edge(src=str(id(subgraph_ops[idx - 1])), dst=node_id, style='invis'))
        diagram.add_subgraph(subgraph)
    def _draw_subgraph(diagram: pydot.Dot, label_last_seen: DefaultDict[str,
                                                                        str],
                       subgraph_name: str,
                       subgraph_ops: List[Union[Op, Trace]]) -> None:
        """Draw a subgraph of ops into an existing `diagram`.

        Args:
            diagram: The diagram to be appended to.
            label_last_seen: A mapping of {data_dict_key: node_id} indicating the last node which generated the key.
            subgraph_name: The name to be associated with this subgraph.
            subgraph_ops: The ops to be wrapped in this subgraph.
        """
        subgraph = pydot.Cluster(style='dashed', graph_name=subgraph_name)
        subgraph.set('label', subgraph_name)
        subgraph.set('labeljust', 'l')
        for idx, op in enumerate(subgraph_ops):
            node_id = str(id(op))
            if isinstance(op, ModelOp):
                label = f"{op.__class__.__name__} ({FEID(id(op))}): {op.model.model_name}"
                model_ref = Hyperref(Marker(name=str(op.model.model_name),
                                            prefix='subsec'),
                                     text=NoEscape(r'\textcolor{blue}{') +
                                     bold(op.model.model_name) +
                                     NoEscape('}')).dumps()
                texlbl = f"{HrefFEID(FEID(id(op)), name=op.__class__.__name__).dumps()}: {model_ref}"
            else:
                label = f"{op.__class__.__name__} ({FEID(id(op))})"
                texlbl = HrefFEID(FEID(id(op)),
                                  name=op.__class__.__name__).dumps()
            subgraph.add_node(pydot.Node(node_id, label=label, texlbl=texlbl))
            edge_srcs = defaultdict(lambda: [])
            for inp in op.inputs:
                if inp == '*':
                    continue
                edge_srcs[label_last_seen[inp]].append(inp)
            for src, labels in edge_srcs.items():
                diagram.add_edge(
                    pydot.Edge(src=src,
                               dst=node_id,
                               label=f" {', '.join(labels)} "))
            for out in op.outputs:
                label_last_seen[out] = node_id
            if isinstance(op, Trace) and idx > 0:
                # Invisibly connect traces in order so that they aren't all just squashed horizontally into the image
                diagram.add_edge(
                    pydot.Edge(src=str(id(subgraph_ops[idx - 1])),
                               dst=node_id,
                               style='invis'))
        diagram.add_subgraph(subgraph)
示例#3
0
    def draw(self, path: str, format: str = "raw") -> None:

        node_aggr = {}
        for node in self._nodes:
            level = node.get_level()
            label = node.get_label()
            identifier = node.get_id()
            if node_aggr.get(level) is None:
                node_aggr[level] = {}
            if level != 0:
                gv_cluster = GVCluster(identifier)
                gv_cluster.set("label", label)
                node_aggr[level][identifier] = gv_cluster
            else:
                gv_node = GVNode(identifier)
                gv_node.set("label", label)
                node_aggr[level][identifier] = gv_node

        gv_dot = GVDot()
        gv_dot.set("ranksep", "1.0 equally")

        if self._lable is not None:
            gv_dot.set("label", self._lable)

        for node in self._nodes:
            level = node.get_level()
            parent = node.get_parent()
            parent_level = node.get_parent_level()
            identifier = node.get_id()
            if level != 0:
                if parent is not None:
                    node_aggr[parent_level][parent].add_subgraph(node_aggr[level][identifier])
                else:
                    gv_dot.add_subgraph(node_aggr[level][identifier])
            else:
                if parent is not None:
                    node_aggr[parent_level][parent].add_node(node_aggr[level][identifier])
                else:
                    gv_dot.add_node(node_aggr[level][identifier])

        for edge in self._edges:
            label = edge.get_label()
            gv_edge = GVEdge(edge.get_src(), edge.get_dst())
            if label is not None:
                gv_edge.set("label", edge.get_label())
            gv_dot.add_edge(gv_edge)

        gv_dot.write(path, format=format)
示例#4
0
graph.set_node_defaults(shape = "record")
teacher = Node("Teacher", label = "{Nastavnik|+ime:String \n+prezime:String|\n}")
course = Node("Course", label = "{Kurs|\n|\n}")
student = Node("Student", label = "{Student|\n|\n}")
lesson = Node("Lesson", label = "{Predavanja|\n|\n}")
tutorial = Node("Tutorial", label = "{Konsultacije|\n |\n}")
assessment = Node("Assessment", label = "{Ocenjivanje|\n|\n}")
coursework = Node("Coursework", label = "{Predispitne obaveze|\n|\n}")
exam = Node("Exam", label = "{Ispit|\n|\n }")

S = Subgraph(rank='same')
S.add_node(teacher)
S.add_node(student)
S.add_node(course)

graph.add_subgraph(S)

graph.add_node(lesson)
graph.add_node(tutorial)
graph.add_node(assessment)
graph.add_node(coursework)
graph.add_node(exam)

graph.write_png("objektni_primer.png");
edge1 = Edge(teacher, course, label = "Predaje", arrowhead = "none", 
             arrowtail = "normal", headlabel = "1", taillabel = "1")
edge2 = Edge(student, course, label = "Pohađa",  arrowhead="none",
         arrowtail="normal",headlabel="1",taillabel="1")
edge3 = Edge(lesson, course, arrowhead="diamond",arrowtail="normal")
edge4 = Edge(tutorial, course, arrowhead="diamond",arrowtail="normal")
edge5 = Edge(assessment, course, arrowhead="diamond",arrowtail="normal")
示例#5
0
class SysCDiagramPlugin():

    def initPlugin(self, signalproxy):
        """Initialise the systemc block diagram plugin"""

        self.signalproxy = signalproxy
        self.do = signalproxy.distributedObjects

        # systemc stuff and and pointer type strings needed for casting in gdb
        # because systemc objects can be systemc modules, systemc ports, etc.
        self.ctx = None
        self.ctx_pointer = None
        self.ctx_func = "sc_get_curr_simcontext()"
        self.ctx_found = False

        self.ctx_type = "(sc_core::sc_simcontext*)"
        self.port_type = "(sc_core::sc_port_base*)"
        self.module_type = "(sc_core::sc_module*)"
        self.object_type = "(sc_core::sc_object*)"
        self.prim_channel_type = "(sc_core::sc_prim_channel*)"

        # dict with a string that represents the pointer as key and
        # a nested dict with parent, children, etc as key-values
        #   dst_dict[ptr] = {"wrapper":    vw,
        #                    "name":       None,
        #                    "parent_ptr": None,
        #                    "children":   {}}
        self.sysc_modules = {}
        self.sysc_objects = {}
        self.sysc_ports = {}
        self.sysc_prim_channels = {}

        # because of how we built the interface for the tracepoints on the
        # datagraph we first need to create an file obj. We choose StringIO
        # because it uses a string as buffer and does not acces the filesystem
        self._file_obj = StringIO()
        self.image = SVGImage("SystemC Block Diagram", self._file_obj)
        self.image_wrapper = SVGDataGraphVW(self.image, self.do)

        self.signalproxy.inferiorStoppedNormally.connect(self.update)

        # hook Datagraph variable wrapper into the datagraph controller
        # after self.action.commit is called the image will be displayed at the
        # datagraph
        self.action = self.do.actions.\
            getAddSVGToDatagraphAction(self.image_wrapper,
                                       self.do.
                                       datagraphController.addVar)

        # pydot graph visualization library
        self.block_diagram = Dot(graph_type='digraph')
        self.block_diagram.set_graph_defaults(compound='true',
                                              splines='ortho',
                                              rankdir='LR')
        self.block_diagram.set_node_defaults(shape='box')

        # Needed for creating the right variables and variable wrappers from
        # the systemc pointers
        self.vwFactory = VarWrapperFactory()
        self.variableList = VariableList(self.vwFactory, self.do)

    def deInitPlugin(self):
        pass

    def evaluateExp(self, exp):
        return self.signalproxy.gdbEvaluateExpression(exp)

    def showDiagram(self):
        self.action.commit()

    def update(self):
        if not self.ctx_found and self.ctx is None:
            self.__findSimContext()
            if self.ctx is None:
                return
        else:
            # don't try to analyze if elaboration is not done
            if not cpp2py(self.ctx["m_elaboration_done"].value):
                return

        # prepare for easy information collection
        object_vec = self.ctx["m_child_objects"]

        # find all relevant information
        self.__findSysCObjects(object_vec, self.object_type, self.sysc_objects)

        # if there are no objects to draw than skip the drawing part
        # this might happen if you set the breakpoint before any objects are
        # created. This is actually catched above, but there might also be a
        # design with no objects.
        if len(self.sysc_objects.keys()) == 0:
            return

        clusters = {}
        nodes = {}

        # build pydot hierachy and add all subgraphs and nodes to the main
        # graph
        self.__buildHierachy(self.sysc_objects, clusters, nodes)
        for sptr in clusters:
            self.block_diagram.add_subgraph(clusters[sptr])
        for sptr in nodes:
            self.block_diagram.add_node(nodes[sptr])

        self._file_obj.write(self.block_diagram.create_svg())
        self.signalproxy.inferiorStoppedNormally.disconnect(self.update)
        self.showDiagram()

    def __buildHierachy(self, obj_dict, clusters, nodes):
        """ Build Cluster and Node hierachy for pydot
        """
        for ptr in obj_dict:
            obj = obj_dict[ptr]
            if ptr in (self.sysc_ports.keys()+self.sysc_prim_channels.keys()):
                continue

            if len(obj["children"].keys()) == 0:
                node = Node(obj["name"])
                nodes[ptr] = node
            else:
                clust = Cluster(obj["name"].replace(".", "_"),
                                color='red',
                                label=obj["name"])
                c_clusters = {}
                c_nodes = {}
                self.__buildHierachy(obj["children"], c_clusters, c_nodes)
                for sptr in c_clusters:
                    clust.add_subgraph(c_clusters[sptr])
                for sptr in c_nodes:
                    clust.add_node(c_nodes[sptr])
                clusters[ptr] = clust

    def __findSysCObjects(self, obj_vec, obj_type, dst_dict):
        """ Find sc_object from module, port and prim channel registry
        """
        for i in obj_vec.childs:
            ptr = i.value
            var = "(*{}{})".format(obj_type, ptr)
            vw = self.variableList.addVarByName(var)
            dst_dict[ptr] = {"wrapper":    vw,
                             "name":       None,
                             "parent_ptr": None,
                             "children":   {}}

            for member in vw.childs:
                if member.exp == "m_name":
                    dst_dict[ptr]["name"] = member.value.strip('"')

                elif member.exp == "m_child_objects":
                    children = {}
                    self.__findSysCObjects(vw["m_child_objects"],
                                           obj_type,
                                           children)
                    dst_dict[ptr]["children"] = children

                elif member.exp == "m_parent":
                    dst_dict[ptr]["parent_ptr"] = member.value

    def __findSimContext(self):
        """ Find systemc simulation context
        """
        self.ctx_pointer = self.evaluateExp(self.ctx_func)
        if self.ctx is None:
            frame = 0
            depth = self.signalproxy.gdbGetStackDepth()
            while (self.ctx_pointer is None) and frame <= depth:
                frame += 1
                self.signalproxy.gdbSelectStackFrame(frame)
                self.ctx_pointer = self.evaluateExp(self.ctx_func)
            else:
                if self.ctx_pointer is None:
                    self.ctx_found = False
                    return
                else:
                    self.ctx_found = True
                    self.ctx = self.do.variablePool.getVar(self.ctx_func)["*"]
        else:
            self.ctx_found = True
            self.ctx = self.do.variablePool.getVar(self.ctx_func)["*"]
示例#6
0
    def graph(self, context=None, **kwargs):
        """
        Returns a graph object

        Keyword Arguments:
            context {bool|None} -- controls the animations (default: {None})

        Returns:
            [pydot.Dot] -- graph object
        """
        graph = Dot(graph_type="digraph",
                    rankdir=("LR" if context is None else "TB"))
        machine_graph = Subgraph(graph_name="cluster_machine",
                                 graph_type="digraph",
                                 label="MACHINE")

        for current_state in sorted(self._states):
            node_args = {}
            shape = "circle"
            shape = ("double"
                     if current_state in self._end_states else "") + shape
            node_args["shape"] = shape

            if context is not None and current_state == self._current_state:
                node_args["fillcolor"] = "cyan"
                node_args["style"] = "filled"

            machine_graph.add_node(Node(current_state, **node_args))

        machine_graph.add_node(Node("0", shape="point"))
        machine_graph.add_edge(Edge("0", self._start_state))

        for current_state in self._states:
            transitions = self._transitions.get(current_state)
            if transitions:
                for current_symbol in transitions:
                    next_symbol, direction, next_state = transitions.get(
                        current_symbol)
                    label = f"'{current_symbol}' '{next_symbol}' {'R' if direction else 'L'}"

                    edge_args = {}
                    if (context and current_state == self._current_state
                            and current_symbol == self._tape[self._head]):
                        edge_args["color"] = "cyan"
                    machine_graph.add_edge(
                        Edge(current_state,
                             next_state,
                             label=label,
                             **edge_args))

        graph.add_subgraph(machine_graph)
        if context is not None:
            tape_graph = Subgraph(graph_name="cluster_tape",
                                  graph_type="digraph",
                                  label="TAPE")
            tape = []
            for index in range(-4 + self._head, 5 + self._head):
                tape.append(
                    f"<t{index}> {self._tape[index] if 0 <= index < len(self._tape) else self._blank_symbol}"
                )

            tape_graph.add_node(
                Node("tape", label="|".join(tape), shape="record"))
            tape_graph.add_node(Node("t0", shape="point"))
            tape_graph.add_edge(Edge("t0", f"tape:t{self._head}"))
            graph.add_subgraph(tape_graph)

        if kwargs.get("filename"):
            graph.write(kwargs.get("filename"), format="png")
            return f"Graph saved to {kwargs.get('filename')}"

        return graph
示例#7
0
def diskusage(db, userName, withIndexes=False, percent=True):
    """Extracts the physical storage of the current user as a picture based on Oracle statistics
The generation of the picture is powered by Graphviz (http://www.graphviz.org)
through the PyDot API (http://www.dkbza.org/pydot.html)
"""
    # Tries to import pydot module
    try:
        from pydot import find_graphviz, Dot, Subgraph, Cluster, Edge, Node
    except ImportError:
        message = _("Function not available because pydot module is not installed.\n\t")
        message += _("Go to http://dkbza.org/pydot.html to get it.")
        raise PysqlException(message)

    # Reads conf
    conf = PysqlConf.getConfig()
    unit = conf.get("unit") # Unit used to format data
    format = conf.get("graph_format") # Output format of the picture
    fontname = conf.get("graph_fontname") # Font used for table names
    fontsize = conf.get("graph_fontsize") # Font size for table names
    fontcolor = conf.get("graph_fontcolor") # Color of table and column names
    tablecolor = conf.get("graph_tablecolor") # Color of tables
    indexcolor = conf.get("graph_indexcolor") # Color of indexes
    bordercolor = conf.get("graph_bordercolor") # Color of borders

    # Gets picture generator
    prog = getProg(find_graphviz(), conf.get("graph_program"), "fdp")

# First step: objects library building
    # Tablespaces
    if userName == db.getUsername().upper():
        tablespaces = db.executeAll(diskusageSql["Tablespaces"])
    else:
        tablespaces = db.executeAll(diskusageSql["TablespacesFromOwner"], [userName])
    tbsBytes = 0
    tbsList = []
    for tablespace in tablespaces:
        tablespaceName = unicode(tablespace[0])

        # Tables from current tablespace
        if userName == db.getUsername().upper():
            tables = db.executeAll(diskusageSql["TablesFromTbs"], [tablespaceName])
        else:
            tables = db.executeAll(diskusageSql["TablesFromOwnerAndTbs"], [userName, tablespaceName])
        tabList = []
        print CYAN + _("Extracting %3d tables from tablespace %s") % (len(tables), tablespaceName) + RESET
        for table in tables:
            tableName = table[0]
            if table[1] is None:
                print RED + _("""Warning: table "%s" removed because no statistics have been found""") \
                           % (tablespaceName + "/" + tableName) + RESET
                continue
            if table[1] == 0:
                print RED + _("""Warning: table "%s" removed because it is empty""") \
                           % (tablespaceName + "/" + tableName) + RESET
                continue
            numRows = int(table[1])
            avgRowLen = float(table[2])
            bytes = int(table[3])
            tbsBytes += bytes
            tabList += [[tableName, bytes, numRows, avgRowLen]]

        if withIndexes:
            # Indexes from current tablespace
            if userName == db.getUsername().upper():
                indexes = db.executeAll(diskusageSql["IndexesFromTbs"], [tablespaceName])
            else:
                indexes = db.executeAll(diskusageSql["IndexesFromOwnerAndTbs"], [userName, tablespaceName])
            idxList = []
            print CYAN + _("Extracting %3d indexes from tablespace %s") % (len(indexes), tablespaceName) + RESET
            for index in indexes:
                indexName = index[0]
                if index[1] is None:
                    print RED + _("""Warning: index "%s" removed because no statistics have been found""") \
                            % (tablespaceName + "/" + indexName) + RESET
                    continue
                if index[1] == 0:
                    print RED + _("""Warning: index "%s" removed because it is empty""") \
                            % (tablespaceName + "/" + indexName) + RESET
                    continue
                numRows = int(index[1])
                distinctKeys = int(index[2])
                bytes = int(index[3])
                tabName = str(index[4])
                tbsBytes += bytes
                idxList += [[indexName, bytes, numRows, distinctKeys, tabName]]
        else:
            print CYAN + _("Not extracting indexes from tablespace %s (ignored)") % (tablespaceName) + RESET
            idxList = []
        tbsList += [[tablespaceName, tbsBytes, tabList, idxList]]

# Second step: objects drawing
    graph = Dot(label=userName, overlap="false", splines="true")

    for tbs in tbsList:
        tbsName = tbs[0]
        tbsBytes = tbs[1]
        tabList = tbs[2]
        idxList = tbs[3]
        subGraph = Subgraph("cluster_" + tbsName, bgcolor="palegreen", \
                          fontname=fontname, fontsize=str(fontsize - 1), \
                          label="%s\\n(%d %s)" % (tbsName, convert(tbsBytes, unit), unit.upper()))
        graph.add_subgraph(subGraph)

        print CYAN + _("Displaying %3d tables for tablespace %s") % (len(tabList), tbsName) + RESET
        for tab in tabList:
            name = tab[0]
            bytes = tab[1]
            numRows = tab[2]      # unused
            avgRowLen = tab[3]    # unused

            # Mathematics at work
            width = 0.2
            height = 0.2
            if percent:
                height += 10 * round(float(bytes) / tbsBytes, 4)
                label = "%s\\n(%.2f %s)" % (name, round(100 * float(bytes) / tbsBytes, 2), "%")

            else:
                height += round(sqrt(bytes) / 8192, 3)
                width += round(sqrt(bytes) / 8192, 3)
                label = "%s\\n(%3d %s)" % (name, convert(bytes, unit), unit.upper())
            subGraph.add_node(Node(name, label=label, shape="box", style="filled", \
                                   color="none", fillcolor=tablecolor, \
                                   fontname=fontname, fontcolor=fontcolor, fixedsize="false", \
                                   fontsize=str(fontsize - 2 - floor((len(label) - 7) / 15)), \
                                   nodesep="0.01", height=str(height), width=str(max(width, 1))))

        print CYAN + _("Displaying %3d indexes for tablespace %s") % (len(idxList), tbsName) + RESET
        for idx in idxList:
            name = idx[0]
            bytes = idx[1]
            numRows = idx[2]      # unused
            distinctKeys = idx[3] # unused
            tabName = idx[4]      # unused

            # Mathematics at work again)
            width = 0.2
            height = 0.2
            if percent:
                height += 10 * round(float(bytes) / tbsBytes, 4)
                label = "%s\\n(%.2f %s)" % (name, round(100 * float(bytes) / tbsBytes, 2), "%")
            else:
                height += round(sqrt(bytes) / 8192, 3)
                width += round(sqrt(bytes) / 8192, 3)
                label = "%s\\n(%3d %s)" % (name, convert(bytes, unit), unit.upper())

            subGraph.add_node(Node(name, label=label, shape="box", style="filled", \
                                color="none", fillcolor=indexcolor, \
                                fontname=fontname, fontcolor=fontcolor, fixedsize="false", \
                                fontsize=str(fontsize - 2 - floor((len(label) - 7) / 15)), \
                                nodesep="0.01", height=str(height), width=str(max(width, 1))))
            #Moving index near by its table (unused because it widens the graph)
            #subGraph.add_edge(Edge(src=name, dst=tabName, constraint="false", style="invis"))

    filename = "du_" + userName + "." + format
    generateImage(graph, filename, prog, format)
    viewImage(filename)