Skip to content

Commit 1771316

Browse files
author
Will Kimmerer
committed
docs updates, relax restrictions on TypedOps
1 parent 8b7bdb7 commit 1771316

File tree

10 files changed

+209
-154
lines changed

10 files changed

+209
-154
lines changed

docs/make.jl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,8 @@ makedocs(
1515
"binaryops.md",
1616
"monoids.md",
1717
"semirings.md",
18-
"selectops.md",
19-
"udfs.md"
18+
"selectops.md"#,
19+
#"udfs.md"
2020
],
2121
"Utilities" => "utilities.md"
2222
]

docs/src/binaryops.md

Lines changed: 85 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -3,23 +3,91 @@
33
Binary operators are defined on three domains $D_1 \times D_2 \rightarrow D_3$.
44
However, the vast majority of binary operators are defined on a single domain.
55

6-
## Built-Ins
6+
`BinaryOp`s are in almost every GraphBLAS operation. They are the primary `op` argument for [`emul`](@ref), [`eadd`](@ref), and [`apply`](@ref). `BinaryOp`s which are also monoids may be used in [`reduce`](@ref). And every GraphBLAS operation which takes an `accum` keyword argument accepts a `BinaryOp`.
7+
8+
In 99% of cases you should pass Julia functions, which will be mapped to built-in operators, or used to create a new user-defined operator.
9+
10+
```@repl
11+
using SuiteSparseGraphBLAS
12+
13+
x = GBMatrix([[1,2] [3,4]])
14+
15+
x .+ x
16+
eadd(x, x, +)
17+
18+
x .^ x
19+
emul(x, x, ^)
20+
21+
x2 = Float64.(x)
22+
eadd!(x2, x, x, +; accum=/)
23+
```
724

8-
All built-in binary operators can be found in the `BinaryOps` submodule.
25+
Internally functions are lowered like this:
926

10-
```@eval
11-
using Pkg
12-
Pkg.activate("..")
13-
cd("..")
27+
```@repl
1428
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)
21-
22-
v1 = "`" .* string.(v1) .* "`"
23-
v2 = "`" .* string.(v2) .* "`"
24-
Latexify.mdtable(hcat(v1,v2,v4); head, latex=false)
25-
```
29+
30+
op = BinaryOp(+)
31+
32+
typedop = op(Int64, Int64)
33+
34+
eadd(GBVector([1,2]), GBVector([3,4]), typedop)
35+
```
36+
37+
## Built-Ins
38+
39+
All built-in binary operators can be found below:
40+
41+
| Julia Function | GraphBLAS Name | Notes |
42+
|:----------------|----------------:|------------------------------------------------------ |
43+
| `first` | `FIRST` | `first(x, y) = x` |
44+
| `second` | `SECOND` | `second(x, y) = y` |
45+
| `any` | `ANY` | `any(x, y) = 1` if `x` **or** `y` are stored values |
46+
| `pair` | `PAIR` | `any(x, y) = 1` if `x` **and** `y` are stored values |
47+
| `+` | `PLUS` | |
48+
| `-` | `MINUS` | |
49+
| `rminus` | `RMINUS` | |
50+
| `*` | `TIMES` | |
51+
| `/` | `DIV` | |
52+
| `\` | `RDIV` | |
53+
| `^` | `POW` | |
54+
| `iseq` | `ISEQ` | `iseq(x::T, y::T) = T(x == y)` |
55+
| `isne` | `ISNE` | `isne(x::T, y::T) = T(x != y)` |
56+
| `min` | `MIN` | |
57+
| `max` | `MAX` | |
58+
| `isgt` | `ISGT` | `isgt(x::T, y::T) = T(x > y)` |
59+
| `islt` | `ISLT` | `islt(x::T, y::T) = T(x < y)` |
60+
| `isge` | `ISGE` | `isge(x::T, y::T) = T(x >= y)` |
61+
| `isle` | `ISLE` | `isle(x::T, y::T) = T(x <= y)` |
62+
| `` | `LOR` | |
63+
| `` | `LAND` | |
64+
| `lxor` | `LXOR` | |
65+
| `==` | `EQ` | |
66+
| `!=` | `NE` | |
67+
| `>` | `GT` | |
68+
| `<` | `LT` | |
69+
| `>=` | `GE` | |
70+
| `<=` | `LE` | |
71+
| `xnor` | `LXNOR` | |
72+
| `atan` | `ATAN2` | |
73+
| `hypot` | `HYPOT` | |
74+
| `fmod` | `FMOD` | |
75+
| `rem` | `REMAINDER` | |
76+
| `ldexp` | `LDEXP` | |
77+
| `copysign` | `COPYSIGN` | |
78+
| `complex` | `CMPLX` | |
79+
| `\|` | `BOR` | |
80+
| `&` | `BAND` | |
81+
| `` | `BXOR` | |
82+
| `bget` | `BGET` | |
83+
| `bset` | `BSET` | |
84+
| `bclr` | `BCLR` | |
85+
| `>>` | `BSHIFT` | |
86+
| `firsti0` | `FIRSTI` | `firsti0(A[i,j], B[k,l]) = i - 1` |
87+
| `firsti` | `FIRSTI1` | `firsti(A[i,j], B[k,l]) = i` |
88+
| `firstj0` | `FIRSTJ` | `firstj0(A[i,j], B[k,l]) = j - 1` |
89+
| `firstj` | `FIRSTJ1` | `firstj(A[i,j], B[k,l]) = j` |
90+
| `secondi0` | `SECONDI` | `secondi0(A[i,j], B[k,l]) = k - 1` |
91+
| `secondi` | `SECONDI1` | `secondi(A[i,j], B[k,l]) = k` |
92+
| `secondj0` | `SECONDJ` | `secondj0(A[i,j], B[k,l]) = l - 1` |
93+
| `secondj` | `SECONDJ1` | `secondj(A[i,j], B[k,l]) = l` |

docs/src/monoids.md

Lines changed: 17 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -9,26 +9,20 @@ Monoids are used primarily in the `reduce`(@ref) operation. Their other use is a
99

1010
## Built-Ins
1111

12-
All built-in monoids can be found in the `Monoids` submodule.
13-
14-
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).
15-
16-
!!! note "Note"
17-
In the case of floating point numbers +∞ and -∞ have their typical meanings. However, for integer types they indicate `typemax` and `typemin` respectively.
18-
19-
```@docs
20-
SuiteSparseGraphBLAS.Monoids.MAX_MONOID
21-
SuiteSparseGraphBLAS.Monoids.MIN_MONOID
22-
SuiteSparseGraphBLAS.Monoids.PLUS_MONOID
23-
SuiteSparseGraphBLAS.Monoids.TIMES_MONOID
24-
SuiteSparseGraphBLAS.Monoids.ANY_MONOID
25-
SuiteSparseGraphBLAS.Monoids.BAND_MONOID
26-
SuiteSparseGraphBLAS.Monoids.BOR_MONOID
27-
SuiteSparseGraphBLAS.Monoids.BXNOR_MONOID
28-
SuiteSparseGraphBLAS.Monoids.BXOR_MONOID
29-
SuiteSparseGraphBLAS.Monoids.EQ_MONOID
30-
SuiteSparseGraphBLAS.Monoids.LAND_MONOID
31-
SuiteSparseGraphBLAS.Monoids.LOR_MONOID
32-
SuiteSparseGraphBLAS.Monoids.LXNOR_MONOID
33-
SuiteSparseGraphBLAS.Monoids.LXOR_MONOID
34-
```
12+
| Julia Function | GraphBLAS Name | Notes |
13+
|----------------|----------------|-----------------------------------------------------------------------|
14+
| `max` | `MAX_MONOID` | identity: `typemax`, terminal: `typemin` |
15+
| `min` | `MIN_MONOID` | identity: `typemin`, terminal: `typemax` |
16+
| `+` | `PLUS_MONOID` | identity: `zero` |
17+
| `*` | `TIMES_MONOID` | identity: `one`, terminal: `zero` (terminal only for non-Float types) |
18+
| `any` | `ANY_MONOID` | identity, terminal: any value in domain |
19+
| `&` | `BAND_MONOID` | identity: `typemax`, terminal: `zero` |
20+
| `\|` | `BOR_MONOID` | identity: `zero`, terminal: `typemax` |
21+
| `` | `BXOR_MONOID` | identity: `zero` |
22+
| `lxor` | `LXOR_MONOID` | identity: `false` |
23+
| `==` | `LXNOR_MONOID` | identity: `true` |
24+
| `` | `LOR_MONOID` | identity: `false`, term: `true` |
25+
| `` | `LAND_MONOID` | identity: `true`, term: `false` |
26+
| | | |
27+
| | | |
28+
| | | |

docs/src/operators.md

Lines changed: 29 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
11
# Basics
22

3+
Operators are one of the basic objects of GraphBLAS. In Julia, however, users must only interact directly with operators on rare occasions, and should instead pass functions to GraphBLAS operations.
4+
35
There are five operator types in SuiteSparseGraphBLAS. Four are defined for all GraphBLAS implementations: `UnaryOp`, `BinaryOp`, `Monoid`, and `Semiring`.
46
One is an extension to the `v1.3` specification: `SelectOp`.
57

68
!!! danger "Note"
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)`.
9+
Operators are **not** callable objects like functions. They **do** behave like functions when used as arguments to higher-order functions (operations in the language of GraphBLAS).
910

1011
Typically operators are positional arguments in one of two places.
1112
For operations with a clear default operator they appear as the last positional argument:
@@ -17,18 +18,21 @@ For operations with a clear default operator they appear as the last positional
1718

1819
For other operations without a clear default operator they appear as the first argument:
1920

20-
- [`map(op::Union{UnaryOp, Function}, A)`](@ref map)
21+
- [`apply(op::Union{UnaryOp, Function}, A)`](@ref apply)
2122
- [`reduce(op::Union{BinaryOp, Function}, A)`](@ref reduce)
2223
- [`select(op::Union{SelectOp, Function}, A)`](@ref select)
2324

25+
!!! note "Built-in vs User-defined operators"
26+
27+
GraphBLAS supports both built-in and user-defined operators. Built-in operators are precompiled C functions, while user-defined operators are function pointers to Julia functions.
28+
29+
Built-in operators are typically much faster than user-defined ones. See the page for the particular operator type (unary, binary, select, etc.) for more information.
30+
31+
2432
## UnaryOps, BinaryOps, Monoids, and Semirings
2533

2634
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.
2735

28-
Each operator is represented as its own concrete type for dispatch purposes.
29-
For instance `BinaryOps.PLUS <: AbstractBinaryOp <: AbstractOp`.
30-
Operators are effectively dictionaries containing the type-specific operators indexed by the `DataType` of their arguments.
31-
3236
### Supported Types
3337

3438
SuiteSparseGraphBLAS.jl natively supports the following types:
@@ -39,42 +43,44 @@ SuiteSparseGraphBLAS.jl natively supports the following types:
3943
- Float32 and Float64
4044
- ComplexF32 and ComplexF64
4145

42-
The supported types can be found as in the example below:
46+
### Lowering
47+
48+
Operators are lowered from a Julia function to a container like `BinaryOp` or `Semiring`. After this they are lowered once again using the type to a `TypedBinaryOp`, `TypedSemiring`, etc. The `TypedBinaryOp` contains the reference to the C-side GraphBLAS operator. Typed operators, like `TypedSemiring` are constants, found in a submodule (`SuiteSparseGraphBLAS.Semirings` in the case of `TypedSemiring`s).
49+
4350
```@setup operators
4451
using SuiteSparseGraphBLAS
4552
```
4653
```@repl operators
47-
Semiring(max, +)
48-
Semirings.MAX_PLUS
49-
Semirings.MAX_PLUS[Float64]
54+
b = BinaryOp(+)
55+
b(Int32)
56+
57+
s = Semiring(max, +)
58+
s(Float64)
5059
```
5160

52-
All operations will accept the function/tuple form, the `DataType` form, or the `TypedSemiring` form.
53-
Unless you need to specifically cast the arguments to a specific type there is no need to specify the operator type.
61+
All operations should accept the function/tuple form, the `Semiring{typeof(max), typeof(+)}` form, or the `TypedSemiring` form.
62+
Unless you need to specifically cast the arguments to a specific type there is generally no need to use the latter two forms.
5463

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

5766
```@docs
5867
xtype
5968
ytype
6069
ztype
6170
```
62-
```@docs
63-
validtypes
64-
```
6571

6672
Some examples of these functions are below.
6773
Note the difference between `ISGT` which returns a result with the same type as the input, and `GT` which returns a `Boolean`.
6874

6975
```@repl operators
70-
xtype(Semirings.LOR_GT[Float64])
71-
ztype(Semirings.LOR_GT[Float64])
72-
xtype(BinaryOps.ISGT[Int8])
73-
ztype(BinaryOps.ISGT[Int8])
74-
ztype(BinaryOps.GT[Int8])
76+
xtype(Semirings.LOR_GT_UINT16)
77+
ztype(Semirings.LOR_GT_FP64)
78+
xtype(BinaryOps.ISGT_INT8)
79+
ztype(BinaryOps.ISGT_INT8)
80+
ztype(BinaryOps.GT_INT8)
7581
```
7682

7783
## SelectOps
7884

7985
The [`SelectOp`](@ref) is a SuiteSparse extension to the specification, although a similar construct is likely to be found in a future specification.
80-
Unlike the other operators there are no type-specific operators, and as such you cannot index into them with types to obtain a type-specific version.
86+
Unlike the other operators there are no type-specific operators, and as such you cannot index into them with types to obtain a type-specific version.

docs/src/selectops.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ Applying `select` with a `SelectOp` will always return a result with the same ty
77

88
## Built-Ins
99

10-
Built-in `SelectOp`s can be found in the `SelectOps` submodule.
10+
Built-in `SelectOp`s can be found in the `SelectOps` submodule. However users should pass the equivalent Julia function when possible.
1111

1212
```@docs
1313
SuiteSparseGraphBLAS.TRIL

docs/src/semirings.md

Lines changed: 5 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -10,45 +10,8 @@ A semiring is denoted by a tuple $(D_1, D_2, D_3, \oplus, \otimes, \mathbb{0})$.
1010

1111
Semirings are used in a single GraphBLAS operation, [`mul[!]`](@ref mul).
1212

13-
## Built-Ins
14-
There are over 200 built-in semirings available as constants in the `Semirings` submodule. These are named `<ADD>_<MULTIPLY>` and include many of the most commonly used semirings such as:
15-
16-
- Arithmetic semiring $(+, \times)$, available as `Semirings.PLUS_TIMES` and as the default operator for `mul[!]`.
17-
- Tropical semirings $(\max, +)$, available as `Semirings.MAX_PLUS`, and $(\min, +)$, available as `Semirings.MIN_PLUS`).
18-
- Boolean semiring $(\vee, \wedge)$ available as `Semirings.LOR_LAND`.
19-
- GF2, the two-element Galois Field $(\text{xor}, \wedge)$, available as `Semirings.LXOR_LAND`.
20-
21-
Below are the built-in semirings available, along with their associated monoids, binary operators, and types.
22-
For common semirings where the binary operator and monoid have equivalent julia functions, those functions are listed.
23-
24-
25-
!!! note
26-
In all cases the input and output types of the semirings are the same, **except** for cases where the "add" types and "multiply" output output types are boolean, such as in `LAND_GE`.
27-
28-
```@eval
29-
using Pkg
30-
Pkg.activate("..")
31-
cd("..")
32-
using SuiteSparseGraphBLAS
33-
using Latexify
34-
head = ["Semiring", "⊕", "⊗", "Types"]
35-
v1 = filter((x) -> getproperty(Semirings, x) isa SuiteSparseGraphBLAS.AbstractSemiring, names(Semirings))
36-
ops = getproperty.(Ref(Semirings), v1)
37-
v2 = convert(Vector{Any}, SuiteSparseGraphBLAS.addop.(ops))
38-
v3 = convert(Vector{Any}, SuiteSparseGraphBLAS.mulop.(ops))
39-
for i in 1:length(v2)
40-
if v2[i] === nothing
41-
x =
42-
v2[i] = replace(summary(SuiteSparseGraphBLAS.monoid(ops[i])), "SuiteSparseGraphBLAS.Monoids." => "")[1:end-2]
43-
end
44-
if v3[i] === nothing
45-
v3[i] = replace(summary(SuiteSparseGraphBLAS.binop(ops[i])), "SuiteSparseGraphBLAS.BinaryOps." => "")[1:end-2]
46-
end
47-
end
48-
v4 = SuiteSparseGraphBLAS.validtypes.(ops)
49-
50-
v1 = "`" .* string.(v1) .* "`"
51-
v2 = "`" .* string.(v2) .* "`"
52-
v3 = "`" .* string.(v3) .* "`"
53-
Latexify.mdtable(hcat(v1,v2,v3,v4); head, latex=false)
54-
```
13+
## Passing to Functions
14+
15+
`mul[!]` is the only function which accepts semirings, and the best method to do so is a tuple of binary functions like `mul(A, B, (max, +))`. An operator form is also available as `*(min, +)(A, B)`.
16+
17+
Semiring objects may be constructed in a similar fashion: `Semiring(max, +)`.

0 commit comments

Comments
 (0)