Skip to content

Commit f247011

Browse files
author
Wimmerer
committed
docs and fix world age issue
1 parent c931697 commit f247011

File tree

13 files changed

+126
-68
lines changed

13 files changed

+126
-68
lines changed

docs/src/arrays.md

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -38,15 +38,20 @@ SuiteSparseGraphBLAS.GBVector(::AbstractVector{<:Integer}, ::AbstractVector)
3838

3939
# Indexing
4040

41-
Normal AbstractArray and SparseArray indexing should work here. Including indexing by scalars, vectors, and ranges.
41+
The usual AbstractArray and SparseArray indexing capabilities are available. Including indexing by scalars, vectors, and ranges.
4242

4343
!!! danger "Indexing Structural Zeros"
44-
When indexing a `SparseMatrixCSC` from `SparseArrays` a structural, or implicit, zero will be returned as `zero(T)` where `T` is the elemtn type of the matrix.
44+
When indexing a `SparseMatrixCSC` from `SparseArrays` a structural, or implicit, zero will be returned as `zero(T)` where `T` is the element type of the matrix.
4545

46-
When indexing a GBArray a structural zero is instead returned as `nothing`. While this is a significant departure from the `SparseMatrixCSC` it more closely matches the GraphBLAS spec, and enables the consuming method to determine the value of implicit zeros.
46+
When indexing a GBArray structural zeros are instead returned as `nothing`.
47+
While this is a significant departure from the `SparseMatrixCSC` it more closely matches the GraphBLAS spec,
48+
and enables the consuming method to determine the value of implicit zeros.
4749

4850
For instance with an element type of `Float64` you may want the zero to be `0.0`, `-∞` or `+∞` depending on your algorithm. In addition, for graph algorithms there may be a distinction between an implicit zero, indicating the lack of an edge between two vertices in an adjacency matrix, and an explicit zero where the edge exists but has a `0` weight.
4951

52+
Better compatibility with `SparseMatrixCSC` and the ability to specify the value of implicit zeros is provided
53+
by `SuiteSparseGraphBLAS.SparseArrayCompat.SparseMatrixGB` array type.
54+
5055
```@repl mat
5156
A = GBMatrix([1,1,2,2,3,4,4,5,6,7,7,7], [2,4,5,7,6,1,3,6,3,3,4,5], [1:12...])
5257
SparseMatrixCSC(A)
@@ -65,6 +70,11 @@ The functionality illustrated above extends to `GBVector` as well.
6570
The lazy Julia `transpose` is available, and the adjoint operator `'` is also
6671
overloaded to be equivalent.
6772

73+
!!! danger "Adjoint vs Transpose"
74+
The adjoint operator `'` currently transposes matrices rather than performing the
75+
conjugate transposition. In the future this will change to the complex conjugate
76+
for complex types, but currently you must do `map(conj, A')` to achieve this.
77+
6878
# Utilities
6979

7080
```@docs

docs/src/binaryops.md

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,21 @@ However, the vast majority of binary operators are defined on a single domain.
55

66
## Built-Ins
77

8-
All built-in binary oeprators can be found in the `BinaryOps` submodule.
8+
All built-in binary operators can be found in the `BinaryOps` submodule.
99

10-
The documentation below uses `T` to refer to any of the valid primitive types listed in [Supported Types](@ref), `` to refer to integers (signed and unsigned), `F` to refer to floating point types, `` to refer to real numbers (non-complex numbers).
10+
```@eval
11+
using Pkg
12+
Pkg.activate("..")
13+
cd("..")
14+
using SuiteSparseGraphBLAS
15+
using Latexify
16+
head = ["UnaryOp", "Function Form", "Types"]
17+
v1 = filter((x) -> getproperty(BinaryOps, x) isa SuiteSparseGraphBLAS.AbstractBinaryOp, names(BinaryOps))
18+
ops = getproperty.(Ref(BinaryOps), v1)
19+
v2 = convert(Vector{Any}, SuiteSparseGraphBLAS.juliaop.(ops))
20+
v4 = SuiteSparseGraphBLAS.validtypes.(ops)
1121
12-
```@autodocs
13-
Modules = [SuiteSparseGraphBLAS]
14-
Pages = ["binaryops.jl"]
22+
v1 = "`" .* string.(v1) .* "`"
23+
v2 = "`" .* string.(v2) .* "`"
24+
Latexify.mdtable(hcat(v1,v2,v4); head, latex=false)
1525
```

docs/src/index.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,10 +20,11 @@ Pkg.add("SuiteSparseGraphBLAS")
2020

2121
The SuiteSparse:GraphBLAS binary is installed automatically as `SSGraphBLAS_jll`.
2222

23+
Then in the REPL or script `using SuiteSparseGraphBLAS` will import the package.
2324
# Introduction
2425

2526
GraphBLAS harnesses the well-understood duality between graphs and matrices.
26-
Specifically a graph can be represented by its [adjacency matrix](https://en.wikipedia.org/wiki/Adjacency_matrix), [incidence matrix](https://en.wikipedia.org/wiki/Incidence_matrix), or the many variations on those formats.
27+
Specifically a graph can be represented by its [adjacency matrix](https://en.wikipedia.org/wiki/Adjacency_matrix), [incidence matrix](https://en.wikipedia.org/wiki/Incidence_matrix), or one of the many variations on those formats.
2728
With this matrix representation in hand we have a method to operate on the graph using linear algebra operations on the matrix.
2829

2930
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.

docs/src/operations.md

Lines changed: 21 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,10 @@ where ``\bf M`` is a `GBArray` mask, ``\odot`` is a binary operator for accumula
2626
!!! note "assign vs subassign"
2727
`subassign` is equivalent to `assign` except that the mask in `subassign` has the dimensions of ``\bf C(I,J)`` vs the dimensions of ``C`` for `assign`, and elements outside of the mask will never be modified by `subassign`. See the [GraphBLAS User Guide](https://github.com/DrTimothyAldenDavis/GraphBLAS/blob/stable/Doc/GraphBLAS_UserGuide.pdf) for more details.
2828

29+
## Operation Documentation
30+
31+
All non-mutating operations below support a mutating form by adding an output array as the first argument as well as the `!` function suffix.
32+
2933
### `mul`
3034
```@docs
3135
mul
@@ -45,37 +49,41 @@ LinearAlgebra.kron
4549

4650
## Common arguments
4751

48-
The operations above have often accept most or all of the following arguments.
52+
The operations typically accept one of the following types in the `op` argument.
4953

5054
### `op` - `UnaryOp`, `BinaryOp`, `Monoid`, `Semiring`, or `SelectOp`:
5155

52-
This is the most important argument for most of the GraphBLAS operations. It determines ``\oplus``, ``\otimes``, or ``f`` in the table above as well as the semiring used in `mul`.
53-
Most operations are restricted to one type of operator.
56+
This argument determines ``\oplus``, ``\otimes``, or ``f`` in the table above as well as the semiring used in `mul`. They typically have synonymous functions in Julia, so `conj` can be used in place of `UnaryOps.CONJ` for instance.
5457

5558
!!! tip "Built-Ins"
5659
The built-in operators can be found in the submodules: `UnaryOps`, `BinaryOps`, `Monoids`, and `Semirings`.
5760

61+
See the [Operators](@ref) section for more information.
62+
5863
### `desc` - `Descriptor`:
5964

6065
The descriptor argument allows the user to modify the operation in some fashion. The most common options are:
6166

62-
- `desc.[input1 | input2] == [DEFAULT | TRANSPOSE]`
67+
- `desc.[transpose_input1 | transpose_input2] == [true | false]`
6368

64-
Transposes the inputs and can be found in `[T0 | T1 | T0T1]`.
6569
Typically you should use Julia's built-in transpose functionality.
6670

67-
- `desc.mask == [DEFAULT | STRUCTURE | COMPLEMENT | STRUCT_COMP]`
71+
- `desc.complement_mask == [true | false]`
72+
73+
If `complement_mask` is set the presence/truth value of the mask is complemented.
6874

69-
If `STRUCTURE` is set the operation will use the presence of a value rather than the value itself to determine whether the index is masked.
70-
If `COMPLEMENT` is set the presence/truth value is complemented (ie. if **no** value is present or the value is **false** that index is masked).
75+
- `desc.structural_mask == [true | false]`
76+
77+
If `structural_mask` is set the presence of a value in the mask determines the presence of values
78+
in the output, rather than the actual value of the mask.
7179

72-
- `desc.output == [DEFAULT | REPLACE]`
80+
- `desc.replace_output == [true | false]`
7381

74-
If `REPLACE` is set the operation will replace all values in the output matrix **after** the accumulation step.
82+
If this option is set the operation will replace all values in the output matrix **after** the accumulation step.
7583
If an index is found in the output matrix, but not in the results of the operation it will be set to `nothing`.
7684

7785

78-
### `accum` - `BinaryOp`:
86+
### `accum` - `BinaryOp | Function`:
7987

8088
The `accum` keyword argument provides a binary operation to accumulate results into the result array.
8189
The accumulation step is performed **before** masking.
@@ -88,16 +96,10 @@ The mask may also be complemented. These options are controlled by the `desc` ar
8896

8997
## Order of Operations
9098

91-
A GraphBLAS operation occurs in the following order (steps are skipped when possible):
99+
A GraphBLAS operation semantically occurs in the following order:
92100

93101
1. Calculate `T = <operation>(args...)`
94102
2. Elementwise accumulate `Z[i,j] = accum(C[i,j], T[i,j])`
95103
3. Optionally masked assignment `C[i,j] = mask[i,j] ? Z[i,j] : [nothing | C[i,j]]`
96104

97-
If `REPLACE` is set the option in step 3. is `nothing`, otherwise it is `C[i,j]`.
98-
99-
## Operation Documentation
100-
101-
All non-mutating operations below support a mutating form by adding an output array as the first argument as well as the `!` function suffix.
102-
103-
105+
If `replace_output` is set the option in step 3. is `nothing`, otherwise it is `C[i,j]`.

docs/src/operators.md

Lines changed: 14 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -3,37 +3,35 @@
33
There are five operator types in SuiteSparseGraphBLAS. Four are defined for all GraphBLAS implementations: `UnaryOp`, `BinaryOp`, `Monoid`, and `Semiring`.
44
One is an extension to the `v1.3` specification: `SelectOp`.
55

6-
!!! note "Operator vs Algebraic Object"
7-
While we will refer to anything in the list above as an operator, semirings and monoids are technically not operators so much as algebraic objects.
8-
96
!!! danger "Note"
10-
Operators are **not** callable objects like functions. They **do** behave like functions as arguments to higher-order functions (operations in the language of GraphBLAS).
7+
Operators are **not** callable objects like functions. They **do** behave like functions as arguments to higher-order functions (operations in the language of GraphBLAS). However `BinaryOp` and `UnaryOp` operators
8+
typically have a synonymous julia function, which can be found using `juliaop(op)`.
119

1210
Typically operators are positional arguments in one of two places.
1311
For operations with a clear default operator they appear as the last positional argument:
1412

15-
- [`emul(A, B, op::BinaryOp)`](@ref emul)
16-
- [`eadd(A, B, op::BinaryOp)`](@ref eadd)
17-
- [`kron(A, B, op::BinaryOp)`](@ref kron)
18-
- [`mul(A, B, op::Semiring)`](@ref mul)
13+
- [`emul(A, B, op::Union{BinaryOp, Function})`](@ref emul)
14+
- [`eadd(A, B, op::Union{BinaryOp, Function})`](@ref eadd)
15+
- [`kron(A, B, op::Union{BinaryOp, Function})`](@ref kron)
16+
- [`mul(A, B, op::Union{Semiring, Tuple{Function, Function}})`](@ref mul)
1917

2018
For other operations without a clear default operator they appear as the first argument:
2119

22-
- [`map(op::UnaryOp, A)`](@ref map) or [`map(op::Monoid, A, x)`](@ref map)
23-
- [`reduce(op::BinaryOp, A)`](@ref reduce)
24-
- [`select(op::SelectOp, A)`](@ref select)
20+
- [`map(op::Union{UnaryOp, Function}, A)`](@ref map)
21+
- [`reduce(op::Union{BinaryOp, Function}, A)`](@ref reduce)
22+
- [`select(op::Union{SelectOp, Function}, A)`](@ref select)
2523

2624
## UnaryOps, BinaryOps, Monoids, and Semirings
2725

28-
Each operator is defined on a specific domain. For some this is the typical primitive datatypes like booleans, floats, and signed and unsigned integers of the typical sizes. A few also accept complex numbers, while most are restricted to some subset of these types.
26+
Each operator is defined on a specific domain. For some this is the usual primitive datatypes like booleans, floats, and signed and unsigned integers of the typical sizes.
2927

30-
Each operator is represented as its own concrete type.
28+
Each operator is represented as its own concrete type for dispatch purposes.
3129
For instance `BinaryOps.PLUS <: AbstractBinaryOp <: AbstractOp`.
3230
Operators are effectively dictionaries containing the type-specific operators indexed by the `DataType` of their arguments.
3331

3432
### Supported Types
3533

36-
GraphBLAS supports the following types:
34+
SuiteSparseGraphBLAS.jl natively supports the following types:
3735

3836
- Booleans
3937
- Integers with sizes 8, 16, 32, 64
@@ -46,11 +44,12 @@ The supported types can be found as in the example below:
4644
using SuiteSparseGraphBLAS
4745
```
4846
```@repl operators
47+
Semiring(max, +)
4948
Semirings.MAX_PLUS
5049
Semirings.MAX_PLUS[Float64]
5150
```
5251

53-
Either form may be passed to all operations, the function will take care of selecting the proper typed operator.
52+
All operations will accept the function/tuple form, the `DataType` form, or the `TypedSemiring` form.
5453
Unless you need to specifically cast the arguments to a specific type there is no need to specify the operator type.
5554

5655
You can determine the available types for an operator and the input and output types of a type-specific operator with the functions below:

docs/src/selectops.md

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,16 @@ Applying `select` with a `SelectOp` will always return a result with the same ty
99

1010
Built-in `SelectOp`s can be found in the `SelectOps` submodule.
1111

12-
```@autodocs
13-
Modules = [SuiteSparseGraphBLAS]
14-
Pages = ["selectops.jl"]
12+
```@docs
13+
SuiteSparseGraphBLAS.TRIL
14+
SuiteSparseGraphBLAS.TRIU
15+
SuiteSparseGraphBLAS.DIAG
16+
SuiteSparseGraphBLAS.OFFDIAG
17+
SuiteSparseGraphBLAS.NONZERO
18+
SuiteSparseGraphBLAS.NE
19+
SuiteSparseGraphBLAS.EQ
20+
SuiteSparseGraphBLAS.GT
21+
SuiteSparseGraphBLAS.GE
22+
SuiteSparseGraphBLAS.LT
23+
SuiteSparseGraphBLAS.LE
1524
```

docs/src/sparsearrays.md

Whitespace-only changes.

docs/src/unaryops.md

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,19 @@ map(UnaryOps.ASIN, y)
1717

1818
## Built-Ins
1919

20-
```@autodocs
21-
Modules = [SuiteSparseGraphBLAS]
22-
Pages = ["unaryops.jl"]
20+
```@eval
21+
using Pkg
22+
Pkg.activate("..")
23+
cd("..")
24+
using SuiteSparseGraphBLAS
25+
using Latexify
26+
head = ["UnaryOp", "Function Form", "Types"]
27+
v1 = filter((x) -> getproperty(UnaryOps, x) isa SuiteSparseGraphBLAS.AbstractUnaryOp, names(UnaryOps))
28+
ops = getproperty.(Ref(UnaryOps), v1)
29+
v2 = convert(Vector{Any}, SuiteSparseGraphBLAS.juliaop.(ops))
30+
v4 = SuiteSparseGraphBLAS.validtypes.(ops)
31+
32+
v1 = "`" .* string.(v1) .* "`"
33+
v2 = "`" .* string.(v2) .* "`"
34+
Latexify.mdtable(hcat(v1,v2,v4); head, latex=false)
2335
```

src/operations/extract.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,7 @@ end
9292
extract(A::GBMatOrTranspose, I, J; kwargs...)::GBMatrix
9393
extract(A::GBVector, I; kwargs...)::GBVector
9494
95-
Extract a submatrix or subvector from `A`
95+
Extract a submatrix or subvector from `A`
9696
9797
# Arguments
9898
- `A::GBArray`: the array being indexed.

src/operators/operatorutils.jl

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@ Base.setindex!(o::AbstractBinaryOp, x, t1::DataType, t2::DataType) = setindex!(o
9191
Base.setindex!(o::AbstractBinaryOp, x, t::DataType) = setindex!(o, x, (t, t))
9292

9393
function addtoop(op::AbstractUnaryOp, type)
94-
f = juliaop(op)
94+
f = Base.invokelatest(juliaop, op)
9595
resulttypes = Base.return_types(f, (type,))
9696
if length(resulttypes) != 1
9797
throw(ArgumentError("Inferred more than one result type for function $(string(f)) on type $type."))
@@ -100,8 +100,8 @@ function addtoop(op::AbstractUnaryOp, type)
100100
end
101101

102102
function addtoop(op::AbstractBinaryOp, type1, type2)
103-
f = juliaop(op)
104-
resulttypes = Base.return_types(f, (type, type2))
103+
f = Base.invokelatest(juliaop, op)
104+
resulttypes = Base.return_types(f, (type1, type2))
105105
if length(resulttypes) != 1
106106
throw(ArgumentError("Inferred more than one result type for function $(string(f)) on type $type."))
107107
end
@@ -113,5 +113,5 @@ function Base.show(io::IO, ::MIME"text/plain", o::AbstractOp)
113113
print(io, o.name, ": ", validtypes(o))
114114
end
115115

116-
function juliaop end
117-
juliaop(op::AbstractMonoid) = juliaop(op(op))
116+
juliaop(op) = nothing
117+
juliaop(op::AbstractMonoid) = juliaop(op(op))

0 commit comments

Comments
 (0)