Skip to content

Commit 203e353

Browse files
committed
First draft of graph loading and intersection with automata.
1 parent 918da2e commit 203e353

File tree

4 files changed

+104
-30
lines changed

4 files changed

+104
-30
lines changed

cfpq_add_context/add_contexts.py

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
from load_graph import load_graph
2+
from intersection import intersection
3+
from gen_automata import generate
4+
import time
5+
6+
def add_context(file_path):
7+
load_graph_start = time.perf_counter()
8+
9+
graph,number_of_contexts = load_graph(file_path)
10+
11+
load_graph_end = time.perf_counter()
12+
print("Graph loaded in ", load_graph_end - load_graph_start)
13+
14+
automata = generate(number_of_contexts)
15+
16+
automata_generation_end = time.perf_counter()
17+
print("Automata generated in ", automata_generation_end - load_graph_end)
18+
19+
result = intersection(graph, automata)
20+
21+
intersection_end = time.perf_counter()
22+
print("Graph and automata intersection competed in ", intersection_end - automata_generation_end)
23+
24+
return result

cfpq_add_context/intersection.py

Lines changed: 7 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55
from graphblas.core.operator import Semiring, Monoid, SelectOp
66
from graphblas.core.dtypes import UINT64
77
from graphblas import op, semiring
8-
from numba import njit, jit
98
import gen_automata
109

1110
import labels
@@ -41,15 +40,6 @@ def bfs (matrix, sources):
4140

4241
return reachable
4342

44-
45-
def filter_reachable_op(reachable_vertices):
46-
_reachable_vertices = set(reachable_vertices)
47-
def inner(x,i,j,k):
48-
return i in _reachable_vertices and j in _reachable_vertices
49-
return inner
50-
51-
SelectOp.register_new("filter_reachable", filter_reachable_op, parameterized=True, is_udt=True)
52-
5343
def filter_not_zero_op(x,i,j,k):
5444
return x > 0
5545

@@ -63,25 +53,10 @@ def intersection (graph, automata) :
6353
print_matrix_to_dot(intersection, "kron.dot")
6454

6555
sources = [i * automata.nrows for i in range(0,graph.nrows)]
66-
#reachable = frozenset(bfs(intersection, sources).to_coo(values=False)[0])
67-
#reachable_vertices = set(bfs(intersection, sources).to_coo(values=False)[0])
6856

6957
reachable_vertices_mask = bfs(intersection, sources).diag(name="reachable_vertices_mask")
7058

71-
#def filter_reachable_op(x,i,j,k):
72-
# return i in reachable_vertices and j in reachable_vertices
73-
74-
#SelectOp.register_new("filter_reachable", filter_reachable_op, is_udt=True)
75-
76-
#print("reachable = ", reachable_vertices)
77-
#print("num of reachable = ", len(reachable_vertices))
78-
#edges = intersection.to_edgelist()
79-
#edges = zip(edges[0],edges[1])
80-
#new_edges = [(_edg[0],_edg[1],_lbl) for (_edg,_lbl) in edges if _edg[0] in reachable_vertices and _edg[1] in reachable_vertices]
81-
#result = Matrix.from_edgelist(new_edges, dtype=intersection.dtype, nrows=intersection.nrows, ncols=intersection.ncols, name = "filtered intersection")
8259
result = Matrix(intersection.dtype, intersection.nrows, intersection.ncols, name = "filtered intersection")
83-
#result << intersection.select(graphblas.select.filter_reachable(reachable_vertices=reachable_vertices))
84-
#result << intersection.select(graphblas.select.filter_reachable)
8560
result << reachable_vertices_mask @ intersection
8661
print_matrix_to_dot(result, "kron_filtered.dot")
8762
return result
@@ -95,7 +70,6 @@ def test():
9570

9671
i = intersection(graph, automata)
9772

98-
#print_matrix_to_dot(intersection, "kron.dot")
9973

10074
def test2():
10175
graph_edges = [(0,0,(labels.mk_open_context(1))),(0,1,(labels.mk_open_context(1))),(1,1,(labels.mk_close_context(1)))]
@@ -146,6 +120,10 @@ def test7():
146120
i = intersection(graph, automata)
147121

148122
def test8():
149-
automata1 = gen_automata.generate(1)
150-
automata2 = gen_automata.generate(1)
151-
i = intersection(automata1, automata2)
123+
graph_edges = [(0,0,1),(0,1,2),(1,1,3),(0,2,4),(2,0,5),(2,2,3)]
124+
125+
graph1 = Matrix.from_edgelist(graph_edges,dtype=UINT64, nrows=6, ncols=6, name="graph1")
126+
graph2 = Matrix.from_edgelist(graph_edges,dtype=UINT64, nrows=6, ncols=6, name="graph2")
127+
128+
i = graph1.kronecker(graph2)
129+
print_matrix_to_dot(i, "kron_build.dot")

cfpq_add_context/labels.py

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,12 @@
1616
SIGMA_WITHOUT_OPEN_CONTEXTS = 0b0000000000000000000001111111111111111111111111111111111111111111
1717
NOTHING = 0b0000000000000000000000000000000000000000000000000000000000000000
1818

19+
ASSIGN = 1
20+
ASSIGN_R = 2
21+
ALLOC = 3
22+
ALLOC_R = 4
23+
OFFSET = 5
24+
1925
def intersection_op (x:int, y:int) -> int:
2026
return (NOTHING - (x == y or (x & y == x and (y == SIGMA or y == SIGMA_WITHOUT_CONTEXTS or y == ALL_OPEN_CONTEXTS or y == SIGMA_WITHOUT_OPEN_CONTEXTS)))) & x
2127

@@ -27,4 +33,8 @@ def mk_open_context(x:int) -> int :
2733
def mk_close_context(x:int) -> int :
2834
return NOTHING | (x << 22)
2935
def mk_other(x:int) -> int :
30-
return NOTHING | x
36+
return NOTHING | x
37+
def mk_load(i):
38+
return mk_other(2 * i + OFFSET)
39+
def mk_store (i):
40+
return mk_other(2 * i + 1 + OFFSET)

cfpq_add_context/load_graph.py

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
import graphblas
2+
3+
from graphblas.core.matrix import Matrix
4+
from graphblas.core.dtypes import UINT64
5+
6+
import labels
7+
from utils import print_matrix_to_dot
8+
9+
10+
11+
def load_graph(file_path):
12+
nvertices = 0
13+
number_of_contexts = 0
14+
def get_edge_lbl(data_arr):
15+
_context = 0
16+
nonlocal number_of_contexts
17+
if len(data_arr) == 4:
18+
if "load" in data_arr[2]:
19+
return labels.mk_load(int(data_arr[3]))
20+
else:
21+
return labels.mk_store(int(data_arr[3]))
22+
elif data_arr[2] == "assign":
23+
return labels.mk_other(labels.ASSIGN)
24+
elif data_arr[2] == "assign_r":
25+
return labels.mk_other(labels.ASSIGN_R)
26+
elif data_arr[2] == "alloc":
27+
return labels.mk_other(labels.ALLOC)
28+
elif data_arr[2] == "alloc_r":
29+
return labels.mk_other(labels.ALLOC_R)
30+
elif "open" in data_arr[2]:
31+
if "_r_" in data_arr[2]:
32+
_context = 2 * int(data_arr[2].split('_')[2])
33+
else:
34+
_context = 2 * int(data_arr[2].split('_')[1]) + 1
35+
number_of_contexts = max(number_of_contexts, _context)
36+
return labels.mk_open_context(_context)
37+
else:
38+
if "_r_" in data_arr[2]:
39+
_context = 2 * int(data_arr[2].split('_')[2])
40+
else:
41+
_context = 2 * int(data_arr[2].split('_')[1]) + 1
42+
number_of_contexts = max(number_of_contexts, _context)
43+
return labels.mk_close_context(_context)
44+
45+
def handle_line(line):
46+
nonlocal nvertices
47+
data = line.strip().split()
48+
_lbl = get_edge_lbl(data)
49+
_from = int(data[0])
50+
_to = int(data[1])
51+
52+
_max = max(_from,_to)
53+
nvertices = max(nvertices, _max)
54+
55+
return (_from, _to, _lbl)
56+
57+
with open (file_path,'r') as file:
58+
edges = [handle_line(line) for line in file if len(line.strip()) > 0]
59+
result = Matrix.from_edgelist(edges, dtype=UINT64, nrows=nvertices + 1, ncols=nvertices + 1, name="graph")
60+
print_matrix_to_dot(result, "graph.dot")
61+
return (result, (number_of_contexts // 2) + 1)
62+

0 commit comments

Comments
 (0)