Graph AlgebraGraph Algebra
!2
Use casesUse cases
Realtime
Recommendation
Fraud detection
Navigation & Traffic
management
Navigation & Traffic
management
RedisGraph
ImplementationImplementation
Adjacency list
Adjacency matrix
0 0 1
1 0 1
0 0 0
Graph Algorithms in the
language of Linear Algebra
!12
readth-first search example
A(i, j) = 1 for edge (j, i)
A is binary; dot (.) is zero for clarity
. . . 1 . . .
1 . . . . . .
. . . 1 . 1 1
1 . . . . . 1
. 1 . . . . 1
. . 1 . 1 . .
. 1 . . . . .
A(i, j) = 1 for edge (
A is binary; dot (.) is
. . . 1 . . .
1 . . . . . .
. . . 1 . 1 1
1 . . . . . 1
. 1 . . . . 1
. . 1 . 1 . .
. 1 . . . . .
!13
h-first search: initializations
v = zeros (n,1) ; // result
q = false (n,1) ; // current level
q (source) = true ;
v: q:
. .
. .
. .
. 1
. .
. .
. .
readth-first search example
A(i, j) = 1 for edge (j, i)
A is binary; dot (.) is zero for clarity
. . . 1 . . .
1 . . . . . .
. . . 1 . 1 1
1 . . . . . 1
. 1 . . . . 1
. . 1 . 1 . .
. 1 . . . . .
!14
GrB assign (v, q, NULL, level, GrB ALL, n, NULL)
v <q> = level ; // assig
v: q:
. .
. .
. .
1 1
. .
. .
. .
gn (v, q, NULL, level, GrB ALL, n, NULL)
v <q> = level ; // assign level
v: q:
. .
. .
. .
1 1
. .
. .
. .
!15
GrB mxv (q, v, NULL, GxB LOR LAND BOOL, A, q, desc)
first part of q<!>=A*q:
t = A*q ;
xv (q, v, NULL, GxB LOR LAND BOOL, A, q, desc)
first part of q<!>=A*q:
t = A*q ;
!16
GrB mxv (q, v, NULL, GxB LOR LAND BOOL, A, q, desc)
second part of q<!>=A*q:
q = false (n,1) ;
q <!v> = t ;
v: t=A*q: q<!v>=t
. 1 1
. . .
. 1 1
1 . .
. . .
. . .
. . .
v (q, v, NULL, GxB LOR LAND BOOL, A, q, desc)
second part of q<!>=A*q:
q = false (n,1) ;
q <!v> = t ;
v: t=A*q: q<!v>=t
. 1 1
. . .
. 1 1
1 . .
. . .
. . .
. . .
gn (v, q, NULL, level, GrB ALL, n, NULL)
v <q> = level ; // assign level
v: q:
2 1
. .
2 1
1 .
. .
. .
. .
GrB assign (v, q, NULL, level, GrB ALL, n, NULL)
v <q> = level ; // a
v: q:
2 1
. .
2 1
1 .
. .
. .
. .
GrB mxv (q, v, NULL, GxB LOR LAND BOOL, A, q, desc
first part of q<!>=A*q:
t = A*q ;
q, v, NULL, GxB LOR LAND BOOL, A, q, desc)
first part of q<!>=A*q:
t = A*q ;
Binary matrix
1 bit per matrix cell
1,000,000 X 1,000,000
One 10^12 (trillion) bits = 125GB
……………………………………………………….
……………………………………………………….
……………………………………………………….
……………………………………………………….
……………………………………………………….
……………………………………………………….
……………………………………………………….
……………………………………………………….
……………………………………………………….
……………………………………………………….
……………………………………………………….
……………………………………………………….
……………………………………………………….
……………………………………………………….
!19
Real world graphs
Most real world graphs are sparse
Facebook
2 billion users
338 friends for user on average
2,000,000,000 * 338 / 2,000,000,000^2
0.000000169% utilisation
!20
Sparse matrixSparse matrix
Graph BLAS
Tim Davis John GilbertJeremy Kepner
GrB_Info GrB_mxm
(
GrB_Matrix C,
const GrB_Matrix Mask,
const GrB_BinaryOp accum,
const GrB_Semiring semiring,
const GrB_Matrix A,
const GrB_Matrix B,
const GrB_Descriptor desc
);
RedisGraph
+

GraphBLAS
Friend of a friend
MATCH (src)-[:friend]->(f)-[:friend]->(foaf)
WHERE src.age > 30
RETURN foaf
src f foaf
friend friend
!25
Friend of a friend
MATCH (src)-[:friend]->(f)-[:friend]->(foaf)
WHERE src.age > 30
RETURN foaf
src f foaf
friend friend
!26
Friend of a friend
MATCH (src)-[:friend]->(f)-[:friend]->(foaf)
WHERE src.age > 30
RETURN foaf
src f foaf
friend friend
!27
Friend of a friend
MATCH (src)-[:friend]->(f)-[:friend]->(foaf)
WHERE src.age > 30
RETURN foaf
src f foaf
friend friend
!28
Execution plan
Index scan
Expand
Expand
Project
src.age > 30
(src)-[:follows]->(f)
(f)-[:follows]->(foaf)
RETURN foaf
!29
Execution plan
Index scan
Expand
Expand
Project
!30
src.age > 30
(src)-[:follows]->(f)
(f)-[:follows]->(foaf)
RETURN foaf
Execution plan
Index scan
Expand
Expand
Project
!31
src.age > 30
(src)-[:follows]->(f)
(f)-[:follows]->(foaf)
RETURN foaf
Execution plan
Index scan
Expand
Expand
Project
!32
src.age > 30
(src)-[:follows]->(f)
(f)-[:follows]->(foaf)
RETURN foaf
Execution plan
Index scan
Expand
Expand
Project
!33
src.age > 30
(src)-[:follows]->(f)
(f)-[:follows]->(foaf)
RETURN foaf
Execution plan
Index scan
Expand
Expand
Project
!34
src.age > 30
(src)-[:follows]->(f)
(f)-[:follows]->(foaf)
RETURN foaf
Execution plan
Index scan
Expand
Expand
Project
!35
src.age > 30
(src)-[:follows]->(f)
(f)-[:follows]->(foaf)
RETURN foaf
Execution plan
Index scan
Expand
Expand
Project
!36
src.age > 30
(src)-[:follows]->(f)
(f)-[:follows]->(foaf)
RETURN foaf
Execution plan
Index scan
Expand
Expand
Project
!37
src.age > 30
(src)-[:follows]->(f)
(f)-[:follows]->(foaf)
RETURN foaf
Cypher to
Algebraic expressions
MATCH

(src)-[:friend]->(f)-[:friend]->(foaf)
WHERE src.age > 30
RETURN foaf
=
Age_Filter * Friendship * Friendship
!39
0 0 0 0 0 0
0 1 0 0 0 0
0 0 1 0 0 0
0 0 0 1 0 0
0 0 0 0 0 0
0 0 0 0 0 1
Age Filter
0 1 0 0 1 0
0 0 1 0 0 0
1 0 0 0 1 1
0 0 0 0 1 0
1 0 1 0 0 0
0 1 0 1 0 0
Friendships
0 1 0 0 1 0
0 0 1 0 0 0
1 0 0 0 1 1
0 0 0 0 1 0
1 0 1 0 0 0
0 1 0 1 0 0
Friendships
* *
!40
Matrix multiplication
is associative
(A*B)*C = A*(B*C)
!41
0 1 0 0 1 0
0 0 1 0 0 0
1 0 0 0 1 1
0 0 0 0 1 0
1 0 1 0 0 0
0 1 0 1 0 0
Friendships
0 1 0 0 1 0
0 0 1 0 0 0
1 0 0 0 1 1
0 0 0 0 1 0
1 0 1 0 0 0
0 1 0 1 0 0
Friendships
*
1 0 1 0 0 0
1 0 0 0 1 1
1 1 1 1 1 0
1 0 1 0 0 0
1 1 0 0 1 1
0 0 1 0 1 0
Friendships ^2
=
number of none zero values = 18
!42
Age Filter
0 1 0 0 1 0
0 0 1 0 0 0
1 0 0 0 1 1
0 0 0 0 1 0
1 0 1 0 0 0
0 1 0 1 0 0
Friendships
0 0 0 0 0 0
0 0 1 0 0 0
1 0 0 0 1 1
0 0 0 0 1 0
0 0 0 0 0 0
0 1 0 1 0 0
Filtered friendships

src > 30
* =
number of none zero values = 7
0 0 0 0 0 0
0 1 0 0 0 0
0 0 1 0 0 0
0 0 0 1 0 0
0 0 0 0 0 0
0 0 0 0 0 1
!43
0 1 0 0 1 0
0 0 1 0 0 0
1 0 0 0 1 1
0 0 0 0 1 0
1 0 1 0 0 0
0 1 0 1 0 0
Friendships
0 0 0 0 0 0
0 0 1 0 0 0
1 0 0 0 1 1
0 0 0 0 1 0
0 0 0 0 0 0
0 1 0 1 0 0
Filtered friendships

src > 30
* =
0 0 0 0 0 0
1 0 0 0 1 1
1 1 1 1 1 0
1 0 1 0 0 0
0 0 0 0 0 0
0 0 1 0 1 0
FOF
!44
0 0 0 0 0 0
1 0 0 0 1 1
1 1 1 1 1 0
1 0 1 0 0 0
0 0 0 0 0 0
0 0 1 0 1 0
1
5
4
2
63
!45
0 0 0 0 0 0
1 0 0 0 1 1
1 1 1 1 1 0
1 0 1 0 0 0
0 0 0 0 0 0
0 0 1 0 1 0
1
5
4
2
63
!46
Variable length
MATCH (src)-[:friend*2..4]->(foaf)
WHERE src.age > 30
RETURN foaf
src F2 foaf
friend
F3 F4
!47
MATCH (src)-[:friend*2..4]->(foaf)
WHERE src.age > 30
RETURN foaf
=
Age_Filter * (Friendship^2 + Friendship^3 + Friendship^4)


M = AF;

R = 0;

For i=0; i < 3; i++

M = M*F

R = R+M
!48
bidirectional edge
MATCH (A)-[:follows]-(B)
RETURN A, B
A B
Knows
!49
Follows + Follows^T
!50
0 1 0 0 1 0
0 0 1 0 0 0
1 0 0 0 1 1
0 0 0 0 1 0
1 0 1 0 0 0
0 1 0 1 0 0
Follows
0 0 1 0 1 0
1 0 0 0 0 1
0 1 0 0 1 0
0 0 0 0 0 1
1 0 1 1 0 0
0 0 1 0 0 0
Follows^T
0 1 1 0 1 0
1 0 1 0 0 1
1 1 0 0 1 1
0 0 0 0 1 1
1 0 1 1 0 0
0 1 1 1 0 0
Symmetric Follows
+ *
!51
1
5
4
2
63
0 1 1 0 1 0
1 0 1 0 0 1
1 1 0 0 1 1
0 0 0 0 1 1
1 0 1 1 0 0
0 1 1 1 0 0
!52
Graph distribution
Block multiplication
A*B=C
A B C
A1
A3 A4
A2 B1 B2
B4B3
C1 C2
C3 C4
!53
Graph distribution
Block multiplication
A*B=C
A B C
A1
A3 A4
A2 B1 B2
B4B3
A1*B1+

A2*B3
A1*B2+

A2*B4
A3*B1+

A4*B3
A3*B2+

A4*B4
!54
BenchmarksBenchmarks
Massive Insertion Workload
!56
~1M nodes, ~3M edges
RedisGraph
Titan
OrientDB
Neo4j
Insert time in seconds
0 75 150 225
24.69
252.15
104.27
0.53
Find Neighbours
!57
~1M nodes, ~3M edges
RedisGraph
Titan
OrientDB
Neo4j
Query processing time in seconds
0 7.5 15 22.5
4.51
9.34
20.71
0.05
Find Adjacent Nodes
!58
~1M nodes, ~3M edges
RedisGraph
Titan
OrientDB
Neo4j
Query processing time in seconds
0 12.5 25 37.5
1.46
6.15
42.82
0.05
Shortest Path
!59
~1M nodes, ~3M edges
RedisGraph
Titan
OrientDB
Neo4j
Query processing time in seconds
0 7.5 15 22.5
0.08
23.47
24.87
0.001
Thanks
@roilipman

Graph Algebra