Exemple #1
0
 def add_vertex(self, v):
     vaddr = v.data.address
     i = self.support.locate(vaddr)
     if i is not None:
         mo = self.support._map[i]
         if vaddr in mo:
             oldnode = mo.data.val
             if oldnode == v: return 0
             # so v cuts an existing node/block:
             # repair oldblock and fix self
             childs = oldnode.N(+1)
             oldblock = oldnode.data
             oldblock.cut(vaddr)
             Graph.add_vertex(self, v)  # ! avoid recursion for add_edge
             self.support.write(vaddr, v)
             self.add_edge(link(oldnode, v))
             for n in childs:
                 self.add_edge(link(v, n))
                 self.remove_edge(oldnode.e_to(n))
             return 1
         else:  #v does not cut an existing block,
             try:  # but may swallow next one...
                 nextmo = self.support._map[i + 1]
             except IndexError:
                 # no more nodes here so back to default case:
                 pass
             else:
                 nextnode = nextmo.data.val
                 if vaddr + len(v) >= nextnode.data.address:
                     v.data.cut(nextnode.data.address)
     Graph.add_vertex(self, v)  # before support write !!
     self.support.write(vaddr, v)
     return 1
Exemple #2
0
def test_networkx():
    try:
        import networkx
    except ImportError:
        return  # Only run test if networkx is present

    v = ('a', 'b', 'c', 'd')
    V = [Vertex(x) for x in v]
    D = dict(zip(v, V))
    e = ['ab', 'ac', 'bc', 'cd']
    E = [Edge(D[xy[0]], D[xy[1]], data=xy) for xy in e]

    g = Graph(V, E)

    nx_graph = convert_grandalf_graph_to_networkx_graph(g)

    assert set(n for n in nx_graph.nodes()) == set(
        v)  # nodes returns the nodes available (node data)
    assert set(n[0] + n[1] for n in nx_graph.edges()) == set(
        e)  # edges returns list(tuple(node1, node2))

    assert nx_graph.number_of_edges() == len(E)
    assert nx_graph.number_of_nodes() == len(V)

    # Now, let's go back from networkx to grandalf
    grandalf_graph = convert_nextworkx_graph_to_grandalf(nx_graph)

    assert len(list(grandalf_graph.V())) == len(v)
    assert len(list(grandalf_graph.E())) == len(E)
    assert set(n.data for n in grandalf_graph.V()) == set(v)
    assert set(n.v[0].data + n.v[1].data for n in grandalf_graph.E()) == set(e)
Exemple #3
0
def create_scenario():
    '''
    Create something as:
    v4      v0
     \     / |
      \   v1 |
       \ /   |
       v5   /
        \  /
        v2
        |
        v3
    '''
    E = []
    data_to_vertex = {}

    vertices = []
    for i in range(6):
        data = 'v%s' % (i, )
        v = Vertex(data)
        data_to_vertex[data] = v
        v.view = VertexViewer(100, 50)
        vertices.append(v)

    edge = Edge(vertices[0], vertices[1])
    edge.view = EdgeViewer()
    E.append(edge)

    edge = Edge(vertices[0], vertices[2])
    edge.view = EdgeViewer()
    E.append(edge)

    edge = Edge(vertices[1], vertices[5])
    edge.view = EdgeViewer()
    E.append(edge)

    edge = Edge(vertices[2], vertices[3])
    edge.view = EdgeViewer()
    E.append(edge)

    edge = Edge(vertices[4], vertices[5])
    edge.view = EdgeViewer()
    E.append(edge)

    edge = Edge(vertices[5], vertices[2])
    edge.view = EdgeViewer()
    E.append(edge)

    G = Graph(vertices, E)
    assert len(G.C) == 1
    gr = G.C[0]

    # not needed anymore...
    #r = filter(lambda x: len(x.e_in()) == 0, gr.sV)
    #if len(r) == 0:
    #    r = [gr.sV[0]]
    return gr, data_to_vertex
Exemple #4
0
 def initView(self):
     cfg = self.func.cfg
     vertexs = {}
     done = set()
     for block in cfg.blocks:
         if block in done:
             continue
         done.add(block)
         startLockey = block.loc_key
         endLockey = block.loc_key
         blocks = [block]
         while (block.lines[-1].name == 'CALL') and (len(cfg.predecessors(block.get_next())) == 1):
             nextLockey = block.get_next()
             if block.loc_key in cfg.successors(nextLockey):
                 break
             block = cfg.loc_key_to_block(nextLockey)
             blocks.append(block)
             endLockey = block.loc_key
             done.add(block)
         vertex = Vertex(startLockey)
         vertexs[startLockey] = vertex
         vertex.view = AsmBlockView(startLockey, endLockey, blocks, self.func)
     edges = []
     for src in vertexs.values():
         successLocKeys = cfg.successors(src.view.endLockey)
         for key in successLocKeys:
             vSrc = vertexs[src.view.lockey]
             vDst = vertexs[key]
             edge = Edge(vSrc, vDst)
             edge.view = BasicEdge(vDst)
             edges.append(edge)
             vSrc.view.outBlocks.append(vDst.view)
             vDst.view.inBlocks.append(vSrc.view)
     self.graph = Graph(vertexs.values(), edges)
     sugLayout = SugiyamaLayout(self.graph.C[0])
     sugLayout.route_edge = route_with_lines
     sugLayout.init_all()
     sugLayout.draw()
     for v in vertexs.values():
         self.addBlock(v.view, v.view.xy[0] - (v.view.w / 2), v.view.xy[1] - (v.view.h / 2))
         v.view.gotoAddress.connect(self.selectAddress)
     for e in edges:
         srcView = e.v[0].view
         srcBlock = e.v[0].data
         dstBlock = e.v[1].data
         if len(srcView.outBlocks) == 1:
             color = Qt.darkBlue
         elif dstBlock == cfg.successors(srcBlock)[0]:
             color = Qt.darkRed
         else:
             color = Qt.darkGreen
         edge_view = e.view
         edge_view.color = color
         self.scene.addItem(edge_view)
Exemple #5
0
def convert_nextworkx_graph_to_grandalf(G):
    from grandalf.graphs import Graph, Vertex, Edge
    V = []
    data_to_V = {}
    for x in G.nodes():
        vertex = Vertex(x)
        V.append(vertex)
        data_to_V[x] = vertex
    E = [Edge(data_to_V[xy[0]], data_to_V[xy[1]], data=xy) for xy in G.edges()]
    g = Graph(V, E)
    return g
Exemple #6
0
def convert_nextworkx_graph_to_grandalf(G):
    '''
    Converts a networkx graph to a grandalf graph.
    
    Note that the edge concept is the same, but a vertex in grandalf is called a node in networkx.
    '''
    V = []
    data_to_V = {}
    for x in G.nodes():
        vertex = Vertex(x)
        V.append(vertex)
        data_to_V[x] = vertex

    E = [Edge(data_to_V[xy[0]], data_to_V[xy[1]], data=xy) for xy in G.edges()]
    g = Graph(V, E)
    return g
Exemple #7
0
    def __init__(self, vertexes, edges):
        #
        # Just a reminder about naming conventions:
        # +------------X
        # |
        # |
        # |
        # |
        # Y
        #

        V = {v: Vertex(" {} ".format(v)) for v in vertexes}
        # NOTE: reverting edges to correctly orientate the graph
        E = [Edge(V[e], V[s]) for s, e in edges]
        V = V.values()
        g = Graph(V, E)

        class VertexViewer(object):
            h = 3  # top and bottom box edges + text

            def __init__(self, name):
                self.w = len(name) + 2  # right and left bottom edges + text

        for v in V:
            v.view = VertexViewer(v.data)

        # NOTE: determine min box length to create the best layout
        minw = min([v.view.w for v in V])

        for e in E:
            e.view = EdgeViewer()

        sug = SugiyamaLayout(g.C[0])
        gr = g.C[0]
        r = list(filter(lambda x: len(x.e_in()) == 0, gr.sV))

        sug.init_all(roots=r, optimize=True)

        sug.yspace = VertexViewer.h
        sug.xspace = minw
        sug.route_edge = route_with_lines

        sug.draw()

        self.sug = sug
Exemple #8
0
def sugiyama_layout(g):
    """
    Position nodes using Sugiyama algorithm.
    Returns dictionary of positions keyed by node.

    :param g: NetworkX graph. A position will be assigned to every node in G.

    :type g: networkx.classes.digraph.DiGraph
    :return: dict
    """

    # verteces (for grandalf lib)
    vertices = {node: Vertex(node) for node in g.nodes}
    # edges (for grandalf lib)
    edges = [
        Edge(vertices[v_from], vertices[v_to]) for v_from, v_to in g.edges
    ]
    # build graph
    for v_name in vertices:
        vertices[v_name].view = _DefaultView()
    g = Graph(vertices.values(), edges)

    sug = SugiyamaLayout(g.C[0])
    sug.init_all(optimize=True)
    sug.draw()

    pos_names = []
    pos_xs = []
    pos_ys = []
    for v in g.C[0].sV:
        pos_names.append(v.data)
        pos_xs.append(v.view.xy[0])
        pos_ys.append(v.view.xy[1])

    scaler = MinMaxScaler()
    scaled_x = scaler.fit_transform(np.array(pos_xs).reshape(-1, 1))[:, 0]
    scaled_y = scaler.fit_transform(np.array(pos_ys).reshape(-1, 1))[:, 0]

    pos = {
        pos_names[i]: np.array([scaled_x[i], scaled_y[i]])
        for i in range(len(pos_names))
    }
    return pos
Exemple #9
0
def _build_sugiyama_layout(vertexes: Union[List, Dict, ValuesView],
                           edges: List) -> SugiyamaLayout:
    #
    # Just a reminder about naming conventions:
    # +------------X
    # |
    # |
    # |
    # |
    # Y
    #

    vertexes = {v: Vertex(f" {v} ") for v in vertexes}
    # NOTE: reverting edges to correctly orientate the graph
    edges = [Edge(vertexes[e], vertexes[s]) for s, e in edges]
    vertexes = vertexes.values()
    graph = Graph(vertexes, edges)

    for vertex in vertexes:
        vertex.view = VertexViewer(vertex.data)

    # NOTE: determine min box length to create the best layout
    minw = min(v.view.w for v in vertexes)

    for edge in edges:
        edge.view = EdgeViewer()

    sug = SugiyamaLayout(graph.C[0])
    graph = graph.C[0]
    roots = list(filter(lambda x: len(x.e_in()) == 0, graph.sV))

    sug.init_all(roots=roots, optimize=True)

    sug.yspace = VertexViewer.HEIGHT
    sug.xspace = minw
    sug.route_edge = route_with_lines

    sug.draw()

    return sug
Exemple #10
0
    def create_graph(self, go_id):
        done = []

        def create_edges_with_parents(child_vertex):
            for parent_term in child_vertex.data.parents:
                e = (child_vertex.data.id, parent_term.id)
                if e in done:
                    continue
                parent_vertex = vertices[parent_term.id]
                edge = ViewEdge(parent_vertex, child_vertex)
                graph.add_edge(edge)
                done.append(e)
                create_edges_with_parents(parent_vertex)

        graph = Graph()
        dag = self.analysis.go_dag
        term = dag[go_id]
        vertices = {
            term: ViewVertex(dag[term], *self.node_size)
            for term in term.get_all_parents()
        }
        create_edges_with_parents(ViewVertex(term, *self.node_size))
        return graph
Exemple #11
0
 def initView(self):
     vertexs = {}
     for lockey, block in self.ircfg.blocks.items():
         vertexs[lockey] = Vertex(block)
         vertexs[lockey].view = IRBlockView(lockey, block, False)
     edges = []
     for src in vertexs:
         successLocKeys = self.ircfg.successors(src)
         for key in successLocKeys:
             if key in vertexs:
                 vSrc = vertexs[src]
                 vDst = vertexs[key]
                 edge = Edge(vSrc, vDst)
                 edge.view = BasicEdge(vDst)
                 edges.append(edge)
                 vSrc.view.outBlocks.append(vDst.view)
                 vDst.view.inBlocks.append(vSrc.view)
     self.graph = Graph(vertexs.values(), edges)
     sugLayout = SugiyamaLayout(self.graph.C[0])
     sugLayout.route_edge = route_with_lines
     sugLayout.init_all()
     sugLayout.draw()
     for v in vertexs.values():
         self.addBlock(v.view, v.view.xy[0] - (v.view.w / 2), v.view.xy[1] - (v.view.h / 2))
     for e in edges:
         srcView = e.v[0].view
         srcBlock = e.v[0].data
         dstBlock = e.v[1].data
         if len(srcView.outBlocks) == 1:
             color = Qt.darkBlue
         elif dstBlock.loc_key == self.ircfg.successors(srcBlock.loc_key)[0]:
             color = Qt.darkRed
         else:
             color = Qt.darkGreen
         edge_view = e.view
         edge_view.color = color
         self.scene.addItem(edge_view)
def graphchain(chain, start, thres=0.0, limit=4):
    from grandalf.graphs import Vertex, Edge, Graph
    L = len(chain[0])
    done = [False] * L
    V = [Vertex(x) for x in range(L)]
    if isinstance(start, str): start = data.index(start)
    E = []
    pool = [start]
    done[start] = True
    while len(pool) > 0:
        v = pool.pop(0)
        c = chain[v]
        l = filter(lambda x: x[1] > thres, c)
        d = [n[0] for n in l[:limit]]
        for i, n in enumerate(d):
            E.append(Edge(V[v], V[n], w=l[i][1]))
            if not done[n]:
                pool.append(n)
                done[n] = True
        if not pool and False in done:
            n = done.index(False)
            pool.append(n)
            done[n] = True
    return Graph(V, E)
Exemple #13
0
	def updateLayeredLayoutWithComp(self): 
		class Vtx(object):
			def __init__(self, name, idx, radius = 1, height = 1):
				self.inNodes = set()
				self.outNodes = set()
				self.name = name
				self.idx = idx
				self.comp = None
				self.compIdx = None
				self.pos = None
				self.radius = radius
				self.fontHeight = height
				self.height = max(radius, height)
				self.firstKey = 0.0
				self.secondKey = 0.0
				self.thirdKey = 0.0

			def getLayoutHeight(self):
				return self.height + self.radius

			def setLayoutPos(self,x,y):
				self.pos = (x, y-0.5*(self.height - self.radius))

			def getMinX(self):
				return self.pos[0] - self.radius

			def getMaxX(self):
				return self.pos[0] + self.radius

			def getMinY(self):
				return self.pos[1] - self.radius

			def getMaxY(self):
				return self.pos[1] + self.height

			def getPos(self):
				return self.pos

		if len(self.scene.itemDict) == 0:
			return
		vtxName2Id = {}
		vtxList = []
		edgeList = []
		for name, item in self.scene.itemDict.items():
			ithVtx = len(vtxList)
			v = Vtx(name, ithVtx, item.getRadius(), item.getHeight())
			v.dispName = item.name
			vtxList.append(v)
			vtxName2Id[name] = ithVtx

		for edgeKey, edge in self.scene.edgeDict.items():
			v1 = vtxName2Id[edgeKey[0]]
			v2 = vtxName2Id[edgeKey[1]]
			vtxList[v1].outNodes.add(v2)
			vtxList[v2].inNodes.add(v1)
			edgeList.append((v1,v2))

		# 构造连通分量
		remainSet = set([i for i in range(len(vtxList))])
		compList = []   # [[idx1,idx2,...],[...]]
		while len(remainSet) > 0:
			# 找出剩余一个顶点并加入队列
			ids = [list(remainSet)[0]]
			ithComp = len(compList)
			vtxList[ids[0]].comp = ithComp
			compMap = []
			# 遍历一个连通分量
			while len(ids) > 0:
				newIds = []
				for id in ids:
					# 把一个顶点加入连通分量
					vtx = vtxList[id]
					vtx.compIdx = len(compMap)
					compMap.append(id)
					# 把周围未遍历顶点加入队列
					for inId in vtx.inNodes:
						inVtx = vtxList[inId]
						if inVtx.comp is None:
							inVtx.comp = ithComp
							newIds.append(inId)
					for outId in vtx.outNodes:
						outVtx = vtxList[outId]
						if outVtx.comp is None:
							outVtx.comp = ithComp
							newIds.append(outId)
					remainSet.discard(id)
				ids = newIds

			# 增加一个连通分量
			compList.append(compMap)

		from grandalf.graphs import Vertex, Edge, Graph
		class VtxView(object):
			def __init__(self, w, h):
				self.w = w
				self.h = h

		# 构造每个连通分量的图结构
		offset = (0,0)
		bboxMin = [1e6,1e6]
		bboxMax = [-1e6,-1e6]
		self.scene.boxTest = []
		for ithComp, compMap in enumerate(compList):
			minPnt = [1e6,1e6]
			maxPnt = [-1e6,-1e6]

			# 构造图数据并布局
			V = []
			for oldId in compMap:
				w = vtxList[oldId].getLayoutHeight()
				vtx = Vertex(oldId)
				height = 200
				vtx.view = VtxView(w, height)
				V.append(vtx)

			E = []
			for edgeKey in edgeList:
				if vtxList[edgeKey[0]].comp == ithComp:
					E.append(Edge(V[vtxList[edgeKey[0]].compIdx], V[vtxList[edgeKey[1]].compIdx]))

			g = Graph(V,E)
			from grandalf.layouts import SugiyamaLayout
			packSpace = 4
			sug = SugiyamaLayout(g.C[0])
			sug.xspace = packSpace
			sug.yspace = packSpace
			#sug.order_iter = 32
			sug.dirvh = 3
			sug.init_all()
			sug.draw(10)

			# 统计包围盒
			for v in g.C[0].sV:
				oldV = vtxList[v.data]
				x= v.view.xy[1]
				y= v.view.xy[0]
				oldV.setLayoutPos(x,y)

				minPnt[0] = min(minPnt[0],oldV.getMinX())
				minPnt[1] = min(minPnt[1],oldV.getMinY())
				maxPnt[0] = max(maxPnt[0],oldV.getMaxX())
				maxPnt[1] = max(maxPnt[1],oldV.getMaxY())

			for v in g.C[0].sV:
				oldV = vtxList[v.data]
				posInComp = oldV.getPos()
				newPos = (posInComp[0], posInComp[1]-minPnt[1]+offset[1])
				self.scene.itemDict[oldV.name].setTargetPos(QtCore.QPointF(newPos[0], newPos[1]))
				bboxMin[0] = min(bboxMin[0], newPos[0])
				bboxMin[1] = min(bboxMin[1], newPos[1])
				bboxMax[0] = max(bboxMax[0], newPos[0])
				bboxMax[1] = max(bboxMax[1], newPos[1])

			offset = (offset[0], offset[1]+maxPnt[1]-minPnt[1]+packSpace)

		# 设置四个角的item
		cornerList = self.scene.cornerItem
		mar = 2000
		cornerList[0].setPos(bboxMin[0]-mar, bboxMin[1]-mar)
		cornerList[1].setPos(bboxMin[0]-mar, bboxMax[1]+mar)
		cornerList[2].setPos(bboxMax[0]+mar, bboxMin[1]-mar)
		cornerList[3].setPos(bboxMax[0]+mar, bboxMax[1]+mar)

		# 更新标志数据
		self.itemSet = set(self.scene.itemDict.keys())
		self.edgeNum = len(self.scene.edgeDict)
Exemple #14
0
def _layout_graph_sugiyama(graph):
    """
    Arrange the graph automatically using grandalf package
    """

    from grandalf.graphs import Graph, Vertex, Edge
    from grandalf.layouts import SugiyamaLayout

    # Build the viez class for grandalf vertices
    class View(object):
        def __init__(self, w, h):
            self.w = w
            self.h = h
            self.xy = (0, 0)

    # Build the grandalf graph
    ggraph = Graph()

    # Vertices
    vertices_by_id = {}

    all_nodes_by_id = {n.id: n for n in graph.all_nodes()}

    # Get average width for distance between nodes
    avg_width = 0
    avg_height = 0

    for n in all_nodes_by_id.values():
        v = Vertex(n.id)
        if NODE_LAYOUT_DIRECTION == NODE_LAYOUT_HORIZONTAL:
            view = View(n.view.height, n.view.width)
        else:
            view = View(n.view.width, n.view.height)

        avg_width += n.view.width
        avg_height += n.view.height
        v.view = view

        vertices_by_id[n.id] = v

    avg_width /= len(all_nodes_by_id)
    avg_height /= len(all_nodes_by_id)

    for v in vertices_by_id.values():
        ggraph.add_vertex(v)

    # Edges
    inverted_edges = []

    looked_up_nodes = set([])

    for n in all_nodes_by_id.values():

        for cns in n.connected_output_nodes().values():

            for cn in cns:

                e = Edge(vertices_by_id[n.id], vertices_by_id[cn.id])

                if cn.id in looked_up_nodes:
                    inverted_edges.append(e)
                else:
                    looked_up_nodes.add(cn.id)

                ggraph.add_edge(e)

    # Build the layout
    sug = SugiyamaLayout(ggraph.C[0])
    sug.yspace = avg_width if NODE_LAYOUT_DIRECTION == NODE_LAYOUT_HORIZONTAL else avg_height
    sug.xspace = avg_height if NODE_LAYOUT_DIRECTION == NODE_LAYOUT_HORIZONTAL else avg_width
    print(inverted_edges)
    # sug.init_all(inverted_edges=inverted_edges or None)
    sug.init_all()

    sug.draw(10)

    for v in ggraph.C[0].sV:
        node = all_nodes_by_id[v.data]

        if NODE_LAYOUT_DIRECTION == NODE_LAYOUT_HORIZONTAL:
            node.set_pos(*reversed(v.view.xy))
        else:
            node.set_pos(*v.view.xy)
Exemple #15
0
    (1, 9),
    (1, 7),
    (8, 13),
    (1, 6),
    (1, 0),
    (1, 3),
    (8, 14),
    (2, 11),
    (1, 4),
    (8, 12),
    (2, 10),
    (1, 8),
    (2, 1),
]
E = [Edge(V[v], V[w]) for (v, w) in X]
g = Graph(V, E)

print(g.C)
print(g.path(V[1], V[9]))

from grandalf.layouts import SugiyamaLayout


class defaultview(object):
    w, h = 10.0, 10.0


sizeList = [
    (43.366611790964676, 200),
    (53.026383008023586, 200),
    (40.004866773426386, 200),
Exemple #16
0
 def __init__(self, *args, **kargs):
     self.support = MemoryZone()
     Graph.__init__(self, *args, **kargs)
Exemple #17
0
(1,9),
(1,7),
(8,13),
(1,6),
(1,0),
(1,3),
(8,14),
(2,11),
(1,4),
(8,12),
(2,10),
(1,8),
(2,1),
]
E = [Edge(V[v],V[w]) for (v,w) in X]
g = Graph(V,E)

print(g.C)
print(g.path(V[1],V[9]))

from grandalf.layouts import SugiyamaLayout
class defaultview(object):
	w,h = 10.0,10.0

sizeList = [
(43.366611790964676,200),
(53.026383008023586,200),
(40.004866773426386,200),
(68.35051437976315,200),
(48.5669151431107,200),
(69.56377621946662,200),