You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: docs/src/index.md
+53-31Lines changed: 53 additions & 31 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -1,7 +1,8 @@
1
1
# SuiteSparseGraphBLAS.jl
2
2
3
-
SuiteSparseGraphBLAS.jl is a package for sparse linear algebra on arbitrary semirings, with a particular focus on graph computations.
4
-
It aims to provide a Julian wrapper over Tim Davis' SuiteSparse:GraphBLAS reference implementation of the GraphBLAS C specification.
3
+
Fast sparse linear algebra is an essential part of the scientific computing toolkit. Outside of the usual applications, like differential equations, sparse linear algebra provides an elegant way to express graph algorithms on adjacency and incidence matrices. The GraphBLAS standard specifies a set of operations for computing sparse matrix graph algorithm in a vein similar to the BLAS or LAPACK standards.
4
+
5
+
SuiteSparseGraphBLAS.jl is a blazing fast package for shared memory sparse matrix operations which wraps Tim Davis' SuiteSparse:GraphBLAS implementation of the GraphBLAS C specification.
5
6
6
7
# Installation
7
8
@@ -18,26 +19,27 @@ using Pkg
18
19
Pkg.add("SuiteSparseGraphBLAS")
19
20
```
20
21
21
-
The SuiteSparse:GraphBLAS binaryis installed automatically as `SSGraphBLAS_jll`.
22
+
The SuiteSparse:GraphBLAS binary, SSGraphBLAS_jll.jl, is installed automatically.
22
23
23
-
Then in the REPL or script `using SuiteSparseGraphBLAS` will import the package.
24
+
Then in the REPL or script `using SuiteSparseGraphBLAS` will make the package available for use.
24
25
25
26
# Introduction
26
27
27
28
GraphBLAS harnesses the well-understood duality between graphs and matrices.
28
29
Specifically a graph can be represented by the [adjacency matrix](https://en.wikipedia.org/wiki/Adjacency_matrix) and/or [incidence matrix](https://en.wikipedia.org/wiki/Incidence_matrix), or one of the many variations on those formats.
29
30
With this matrix representation in hand we have a method to operate on the graph with linear algebra.
30
31
31
-
Below is an example of the adjacency matrix of a directed graph, and finding the neighbors of a single vertex using basic matrix-vector multiplication on the arithemtic semiring.
32
+
One important algorithm that maps well to linear algebra is Breadth First Search (BFS).
33
+
A simple BFS is just a matrix-vector multiplication, where `A` is the adjacency matrix and `v` is the set of source nodes, as illustrated below.
32
34
33
35

34
36
35
37
## GBArrays
36
38
37
-
The core SuiteSparseGraphBLAS.jl array types are `GBVector` and `GBMatrix` which are subtypes `SparseArrays.AbstractSparseVector` and `SparseArrays.AbstractSparseMatrix` respectively.
39
+
The core SuiteSparseGraphBLAS.jl array types are `GBVector` and `GBMatrix` which are subtypes `SparseArrays.AbstractSparseVector` and `SparseArrays.AbstractSparseMatrix` respectively. There are also several auxiliary array types that restrict one or more behaviors, like row or column orientation. More info on those types can be found ### HERE ###
38
40
39
41
!!! note "GBArray"
40
-
These docs will often refer to the `GBArray` type, which is the union of `GBVector`, `GBMatrix` and their lazy Transpose objects.
42
+
These docs will often refer to the `GBArray` type, which is the union of `AbstractGBVector`, `AbstractGBMatrix` and their lazy Transpose objects.
41
43
42
44
```@setup intro
43
45
using SuiteSparseGraphBLAS
@@ -59,7 +61,8 @@ Here we can already see several differences compared to `SparseArrays.SparseMatr
59
61
The first is that `A` is stored in `hypersparse` format, and by row.
60
62
61
63
`GBArrays` are (technically) opaque to the user in order to allow the library author to choose the best storage format.\
62
-
GraphBLAS takes advantage of this by storing matrices in one of four formats: `dense`, `bitmap`, `sparse-compressed`, or `hypersparse-compressed`; and in either `row` or `column` major orientation.
64
+
GraphBLAS takes advantage of this by storing matrices in one of four formats: `dense`, `bitmap`, `sparse-compressed`, or `hypersparse-compressed`; and in either `row` or `column` major orientation.\
65
+
Different matrices may be better suited to storage in one of those formats, and certain operations may perform differently on `row` or `column` major matrices.
63
66
64
67
!!! warning "Default Orientation"
65
68
The default orientation of a `GBMatrix` is by-row, the opposite of Julia arrays. However, a `GBMatrix` constructed from a `SparseMatrixCSC` or
@@ -72,31 +75,38 @@ Information about storage formats, orientation, conversion, construction and mor
72
75
The second difference is that a `GBArray` doesn't assume the fill-in value of a sparse array.\
73
76
Since `A[1,5]` isn't stored in the matrix (it's been "compressed" out), we return `nothing`.\
74
77
75
-
This matches the GraphBLAS spec, where `NO_VALUE` is returned, rather than `zero(eltype(A))`.
78
+
This better matches the GraphBLAS spec, where `NO_VALUE` is returned, rather than `zero(eltype(A))`. This is better suited to graph algorithms where returning `zero(eltype(A))` might imply the presence of an edge with weight `zero`.\
79
+
However this behavior can be changed with the [`setfill!`](@ref) and [`setfill`](@ref) functions.
80
+
81
+
```@repl intro
82
+
A[1, 1] === nothing
83
+
84
+
B = setfill(A, 0) # no-copy alias
85
+
B[1, 1]
86
+
```
76
87
77
88
An empty matrix and vector won't do us much good, so let's see how to construct the matrix and vector from the graphic above. Both `A` and `v` below are constructed from coordinate format or COO.
|`mxm`, `mxv`, `vxm`|``\bf C \langle M \rangle = C \odot AB``|`mul[!]` or `*`|
94
104
|`eWiseMult`|``\bf C \langle M \rangle = C \odot (A \otimes B)``|`emul[!]` or `.` broadcasting |
95
105
|`eWiseAdd`|``\bf C \langle M \rangle = C \odot (A \oplus B)``|`eadd[!]`|
96
-
|`extract`|``\bf C \langle M \rangle = C \odot A(I,J)``|`extract[!]`, `getindex`or `A[i...]`|
97
-
|`subassign`|``\bf C (I,J) \langle M \rangle = C(I,J) \odot A``|`subassign[!]`, `setindex!`or `A[i...]=3.5`|
106
+
|`extract`|``\bf C \langle M \rangle = C \odot A(I,J)``|`extract[!]`, `getindex`|
107
+
|`subassign`|``\bf C (I,J) \langle M \rangle = C(I,J) \odot A``|`subassign[!]`or `setindex!`|
98
108
|`assign`|``\bf C \langle M \rangle (I,J) = C(I,J) \odot A``|`assign[!]`|
99
-
|`apply`|``{\bf C \langle M \rangle = C \odot} f{\bf (A)}``|`map[!]` or `.` broadcasting |
109
+
|`apply`|``{\bf C \langle M \rangle = C \odot} f{\bf (A)}``|`apply[!]`, `map[!]` or `.` broadcasting |
100
110
||``{\bf C \langle M \rangle = C \odot} f({\bf A},y)``||
101
111
||``{\bf C \langle M \rangle = C \odot} f(x,{\bf A})``||
102
112
|`select`|``{\bf C \langle M \rangle = C \odot} f({\bf A},k)``|`select[!]`|
@@ -105,41 +115,53 @@ GraphBLAS operations are, where possible, methods of existing Julia functions l
105
115
|`transpose`|``\bf C \langle M \rangle = C \odot A^{\sf T}``|`gbtranspose[!]`, lazy: `transpose`, `'`|
106
116
|`kronecker`|``\bf C \langle M \rangle = C \odot \text{kron}(A, B)``|`kron[!]`|
107
117
108
-
where ``\bf M`` is a `GBArray` mask, ``\odot`` is a binary operator for accumulating into ``\bf C``, and ``\otimes`` and ``\oplus`` are a binary operation and commutative monoid respectively.
118
+
where ``\bf M`` is a `GBArray` mask, ``\odot`` is a binary operator for accumulating into ``\bf C``, and ``\otimes`` and ``\oplus`` are a binary operation and commutative monoid respectively. ``f`` is either a unary or binary operator.
109
119
110
120
## GraphBLAS Operators
111
121
122
+
Many GraphBLAS operations take additional arguments called *operators*. In the table above operators are denoted by ``\odot``, ``\otimes``, and ``\oplus`` and ``f``, and they behave similar to the function argument of `map`. A closer look at operators can be found in [Operators](@ref)
123
+
112
124
A GraphBLAS operator is a unary or binary function, the commutative monoid form of a binary function,
113
125
or a semiring, made up of a binary op and a commutative monoid.
114
126
SuiteSparse:GraphBLAS ships with many of the common unary and binary operators as built-ins,
115
127
along with monoids and semirings built commonly used in graph algorithms.
116
-
In most cases these operators can be used with familiar Julia syntax and functions, which then map to
117
-
objects found in the submodules below:
128
+
These built-in operators are *fast*, and should be used where possible. However, users are also free to provide their own functions as operators when necessary.
118
129
119
-
-`UnaryOps` such as `SIN`, `SQRT`, `ABS`
120
-
-`BinaryOps` such as `GE`, `MAX`, `POW`, `FIRSTJ`
121
-
-`Monoids` such as `PLUS_MONOID`, `LXOR_MONOID`
122
-
-`Semirings` such as `PLUS_TIMES` (the arithmetic semiring), `MAX_PLUS` (a tropical semiring), `PLUS_PLUS`, ...
130
+
SuiteSparseGraphBLAS.jl will *mostly* take care of operators behind the scenes, and in most cases users should pass in normal functions like `+` and `sin`. For example:
123
131
124
-
The above objects should, in almost all cases, be used by instead passing the equivalent functions, `sin` for `SIN`, `+` for `PLUS_MONOID` etc.
132
+
```@repl intro
133
+
emul(A, A, ^) # elementwise exponent
125
134
126
-
A user may choose to call a function in multiple different forms: `A .+ B`, `eadd(A, B, +)`,
127
-
or `eadd(A, B, BinaryOps.PLUS)`.
135
+
map(sin, A)
136
+
```
137
+
138
+
Broadcasting functionality is also supported, `A .^ A` will lower to `emul(A, A, ^)`, and `sin.(A)` will lower to `map(sin, A)`.
139
+
140
+
Matrix multiplication, which accepts a semiring, can be called with either `*(max, +)(A, B)` or
141
+
`mul(A, B, (max, +))`.
142
+
143
+
We can also use functions that are not already built into SuiteSparseGraphBLAS.jl:
144
+
145
+
```@repl intro
146
+
M = GBMatrix([[1,2] [3,4]])
147
+
increment(x) = x + 1
148
+
map(increment, M)
149
+
```
128
150
129
-
Functions which only accept monoids like `reduce` will automatically find the correct monoid,
130
-
so a call to `reduce(+, A)`, will lower to `reduce(Monoids.PLUS_MONOID, A)`.
151
+
Unfortunately this has a couple problems. The first is that it's slow.\
152
+
Compared to `A .+ 1` which lowers to `apply(+, A, 1)` the `map` call above is ~2.5x slower due to function pointer overhead.
131
153
132
-
Matrix multiplication, which accepts a semiring, can be called with either `*(max, +)(A, B)`,
133
-
`mul(A, B, (max, +))`, or `mul(A, B, Semirings.MAX_PLUS)`.
154
+
The second is that everytime we call `map(increment, M)` we will be re-creating the function pointer for `increment` matched to the type of `M`.\
155
+
To avoid this there's a convenience macro [`@unop`](@ref) which will provide a permanent constant which is used every time `increment` is called with a GraphBLAS operation. See [Operators](@ref) for more information.
134
156
135
157
!!! warning "Performance of User Defined Functions"
136
158
Operators which are not already built-in are automatically constructed using function pointers when called.
137
159
Note, however, that their performance is significantly degraded compared to built-in operators,
138
-
and where possible user code should avoid this capability.
160
+
and where possible user code should avoid this capability. See [Operators](@ref).
139
161
140
162
## Example
141
163
142
-
Here is an example of two different methods of triangle counting with GraphBLAS.
164
+
Here is a quick example of two different methods of triangle counting with GraphBLAS.
143
165
The methods are drawn from the LAGraph [repo](https://github.com/GraphBLAS/LAGraph).
144
166
145
167
Input `A` must be a square, symmetric matrix with any element type.
0 commit comments