Skip to content

Commit ce97107

Browse files
author
Will Kimmerer
authored
Libgb rewrite (#62)
* not compiling * still * matvec libgb->LibGraphBLAS * libgb -> LibGraphBLAS * all libgb eradicated * missing LibGraphBLAS namespace * add early aliasing support. fix test failures * fix tests * rm FiniteDiff dependency * move FiniteDiff * fix FiniteDiff removal
1 parent e215823 commit ce97107

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

41 files changed

+955
-824
lines changed

Project.toml

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@ version = "0.5.0"
55

66
[deps]
77
ChainRulesCore = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4"
8-
FiniteDifferences = "26cc04aa-876d-5657-8c51-4c34ba976000"
98
Libdl = "8f399da3-3557-5675-b5ff-fb832c97cbdb"
109
LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e"
1110
MacroTools = "1914dd2f-81c6-5fcd-8719-6d5c9610ff09"
@@ -18,9 +17,8 @@ SuiteSparse = "4607b0f0-06f3-5cda-b6b1-a6196a1729e9"
1817

1918
[compat]
2019
ChainRulesCore = "1"
21-
FiniteDifferences = "0.12"
2220
MacroTools = "0.5"
2321
Preferences = "1"
24-
SSGraphBLAS_jll = "6.0"
22+
SSGraphBLAS_jll = "6.2.1"
2523
SpecialFunctions = "2"
2624
julia = "1.6"

src/SuiteSparseGraphBLAS.jl

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -23,15 +23,15 @@ using SpecialFunctions: lgamma, gamma, erf, erfc
2323
using Base.Broadcast
2424
include("abstracts.jl")
2525
include("libutils.jl")
26-
include("lib/LibGraphBLAS.jl")
27-
using .libgb
28-
include("operators/libgbops.jl")
2926

30-
# Globals
27+
include("lib/LibGraphBLAS_gen.jl")
28+
using .LibGraphBLAS
3129

30+
include("operators/libgbops.jl")
3231

33-
include("types.jl")
3432
include("gbtypes.jl")
33+
include("types.jl")
34+
3535

3636

3737
include("constants.jl")
@@ -88,7 +88,7 @@ include("asjulia.jl")
8888
include("spmgb/sparsemat.jl")
8989

9090
export SparseArrayCompat
91-
export libgb
91+
export LibGraphBLAS
9292
export UnaryOps, BinaryOps, Monoids, Semirings #Submodules
9393
export UnaryOp, BinaryOp, Monoid, Semiring #UDFs
9494
export Descriptor #Types
@@ -124,19 +124,19 @@ function __init__()
124124
#The artifact does dlopen for us.
125125
libgraphblas_handle[] = SSGraphBLAS_jll.libgraphblas_handle
126126
end
127-
_load_globaltypes()
128127
# We initialize GraphBLAS by giving it Julia's GC wrapped memory management functions.
129128
# In the future this should hopefully allow us to do no-copy passing of arrays between Julia and SS:GrB.
130129
# In the meantime it helps Julia respond to memory pressure from SS:GrB and finalize things in a timely fashion.
131-
libgb.GxB_init(libgb.GrB_NONBLOCKING, cglobal(:jl_malloc), cglobal(:jl_calloc), cglobal(:jl_realloc), cglobal(:jl_free))
130+
@wraperror LibGraphBLAS.GxB_init(LibGraphBLAS.GrB_NONBLOCKING, cglobal(:jl_malloc), cglobal(:jl_calloc), cglobal(:jl_realloc), cglobal(:jl_free))
132131
gbset(:nthreads, Sys.CPU_THREADS ÷ 2)
133132
# Eagerly load selectops constants.
134133
_loadselectops()
134+
ALL.p = load_global("GrB_ALL", LibGraphBLAS.GrB_Index)
135135
# Set printing done by SuiteSparse:GraphBLAS to base-1 rather than base-0.
136136
gbset(BASE1, 1)
137137
atexit() do
138138
# Finalize the lib, for now only frees a small internal memory pool.
139-
libgb.GrB_finalize()
139+
@wraperror LibGraphBLAS.GrB_finalize()
140140
@static if artifact_or_path != "default"
141141
dlclose(libgraphblas_handle[])
142142
end

src/asjulia.jl

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -34,8 +34,8 @@ function asCSCVectors(f::Function, A::GBMatrix{T}; freeunpacked=false) where {T}
3434
f(colptr, rowidx, values, A)
3535
finally
3636
if freeunpacked
37-
ccall(:jl_free, Cvoid, (Ptr{libgb.GrB_Index},), pointer(colptr))
38-
ccall(:jl_free, Cvoid, (Ptr{libgb.GrB_Index},), pointer(rowidx))
37+
ccall(:jl_free, Cvoid, (Ptr{LibGraphBLAS.GrB_Index},), pointer(colptr))
38+
ccall(:jl_free, Cvoid, (Ptr{LibGraphBLAS.GrB_Index},), pointer(rowidx))
3939
ccall(:jl_free, Cvoid, (Ptr{T},), pointer(values))
4040
else
4141
_packcscmatrix!(A, colptr, rowidx, values)
@@ -50,8 +50,8 @@ function asCSRVectors(f::Function, A::GBMatrix{T}; freeunpacked=false) where {T}
5050
f(rowptr, colidx, values, A)
5151
finally
5252
if freeunpacked
53-
ccall(:jl_free, Cvoid, (Ptr{libgb.GrB_Index},), pointer(rowptr))
54-
ccall(:jl_free, Cvoid, (Ptr{libgb.GrB_Index},), pointer(colidx))
53+
ccall(:jl_free, Cvoid, (Ptr{LibGraphBLAS.GrB_Index},), pointer(rowptr))
54+
ccall(:jl_free, Cvoid, (Ptr{LibGraphBLAS.GrB_Index},), pointer(colidx))
5555
ccall(:jl_free, Cvoid, (Ptr{T},), pointer(values))
5656
else
5757
_packcsrmatrix!(A, rowptr, colidx, values)
@@ -62,13 +62,13 @@ end
6262

6363
function asSparseMatrixCSC(f::Function, A::GBMatrix{T}; freeunpacked=false) where {T}
6464
colptr, rowidx, values = _unpackcscmatrix!(A)
65-
array = SparseMatrixCSC{T, libgb.GrB_Index}(size(A, 1), size(A, 2), colptr, rowidx, values)
65+
array = SparseMatrixCSC{T, LibGraphBLAS.GrB_Index}(size(A, 1), size(A, 2), colptr, rowidx, values)
6666
result = try
6767
f(array, A)
6868
finally
6969
if freeunpacked
70-
ccall(:jl_free, Cvoid, (Ptr{libgb.GrB_Index},), pointer(colptr))
71-
ccall(:jl_free, Cvoid, (Ptr{libgb.GrB_Index},), pointer(rowidx))
70+
ccall(:jl_free, Cvoid, (Ptr{LibGraphBLAS.GrB_Index},), pointer(colptr))
71+
ccall(:jl_free, Cvoid, (Ptr{LibGraphBLAS.GrB_Index},), pointer(rowidx))
7272
ccall(:jl_free, Cvoid, (Ptr{T},), pointer(values))
7373
else
7474
_packcscmatrix!(A, colptr, rowidx, values)
@@ -79,13 +79,13 @@ end
7979

8080
function asSparseVector(f::Function, A::GBVector{T}; freeunpacked=false) where {T}
8181
colptr, rowidx, values = _unpackcscmatrix!(A)
82-
vector = SparseVector{T, libgb.GrB_Index}(size(A, 1), rowidx, values)
82+
vector = SparseVector{T, LibGraphBLAS.GrB_Index}(size(A, 1), rowidx, values)
8383
result = try
8484
f(vector, A)
8585
finally
8686
if freeunpacked
87-
ccall(:jl_free, Cvoid, (Ptr{libgb.GrB_Index},), pointer(colptr))
88-
ccall(:jl_free, Cvoid, (Ptr{libgb.GrB_Index},), pointer(rowidx))
87+
ccall(:jl_free, Cvoid, (Ptr{LibGraphBLAS.GrB_Index},), pointer(colptr))
88+
ccall(:jl_free, Cvoid, (Ptr{LibGraphBLAS.GrB_Index},), pointer(rowidx))
8989
ccall(:jl_free, Cvoid, (Ptr{T},), pointer(values))
9090
else
9191
_packcscmatrix!(A, colptr, rowidx, values)

src/chainrules/chainruleutils.jl

Lines changed: 0 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,7 @@
1-
using FiniteDifferences
21
import LinearAlgebra
32
import ChainRulesCore: frule, rrule
43
using ChainRulesCore
54
const RealOrComplex = Union{Real, Complex}
65

7-
#Required for ChainRulesTestUtils
8-
function FiniteDifferences.to_vec(M::GBMatrix)
9-
x, back = FiniteDifferences.to_vec(Matrix(M))
10-
function backtomat(xvec)
11-
M2 = GBMatrix(back(xvec))
12-
return mask(M2, M; structural=true)
13-
end
14-
return x, backtomat
15-
end
16-
17-
function FiniteDifferences.to_vec(v::GBVector)
18-
x, back = FiniteDifferences.to_vec(Vector(v))
19-
function backtovec(xvec)
20-
v2 = GBVector(back(xvec))
21-
return mask(v2, v; structural=true)
22-
end
23-
return x, backtovec
24-
end
25-
266
# LinearAlgebra.norm doesn't like the nothings.
277
LinearAlgebra.norm(A::GBArray, p::Real=2) = norm(nonzeros(A), p)

src/constants.jl

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,14 @@ const GBVecOrMat{T} = Union{GBVector{T}, GBMatrix{T}}
22
const GBMatOrTranspose{T} = Union{GBMatrix{T}, Transpose{T, GBMatrix{T}}}
33
const GBVecOrTranspose{T} = Union{GBVector{T}, Transpose{T, GBVector{T}}}
44
const GBArray{T} = Union{GBVecOrTranspose{T}, GBMatOrTranspose{T}}
5-
const ptrtogbtype = Dict{Ptr, AbstractGBType}()
5+
const ptrtogbtype = IdDict{Ptr, GBType}()
66

77
const GrBOp = Union{
8-
libgb.GrB_Monoid,
9-
libgb.GrB_UnaryOp,
10-
libgb.GrB_Semiring,
11-
libgb.GrB_BinaryOp,
12-
libgb.GxB_SelectOp
8+
LibGraphBLAS.GrB_Monoid,
9+
LibGraphBLAS.GrB_UnaryOp,
10+
LibGraphBLAS.GrB_Semiring,
11+
LibGraphBLAS.GrB_BinaryOp,
12+
LibGraphBLAS.GxB_SelectOp
1313
}
1414

1515
const TypedOp = Union{
@@ -32,3 +32,5 @@ const OperatorUnion = Union{
3232
AbstractOp,
3333
GrBOp
3434
}
35+
36+
const ALL = GBAllType(C_NULL)

src/descriptors.jl

Lines changed: 93 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -14,83 +14,140 @@ a function, defaults to avoid hyperthreading, which is typically most performant
1414
"""
1515
mutable struct Descriptor <: AbstractDescriptor
1616
name::String
17-
p::libgb.GrB_Descriptor
18-
function Descriptor(name, p::libgb.GrB_Descriptor)
17+
p::LibGraphBLAS.GrB_Descriptor
18+
function Descriptor(name, p::LibGraphBLAS.GrB_Descriptor)
1919
d = new(name, p)
2020
function f(descriptor)
21-
libgb.GrB_Descriptor_free(Ref(descriptor.p))
21+
LibGraphBLAS.GrB_Descriptor_free(Ref(descriptor.p))
2222
end
2323
return finalizer(f, d)
2424
end
2525
end
2626

2727
function Descriptor(;kwargs...)
28-
desc = Descriptor("", libgb.GrB_Descriptor_new())
28+
d = Ref{LibGraphBLAS.GrB_Descriptor}()
29+
@wraperror LibGraphBLAS.GrB_Descriptor_new(d)
30+
desc = Descriptor("", d[])
2931
for (s, x) in kwargs
3032
setproperty!(desc, s, x)
3133
end
3234
return desc
3335
end
3436

35-
Base.unsafe_convert(::Type{libgb.GrB_Descriptor}, d::Descriptor) = d.p
37+
Base.unsafe_convert(::Type{LibGraphBLAS.GrB_Descriptor}, d::Descriptor) = d.p
38+
39+
# Todo: improve these. They can't be wrapped by ccall because they're "generic"?
40+
# Or at least not wrapped by Clang.jl
41+
function GxB_Desc_get(desc, field)
42+
if field [LibGraphBLAS.GrB_OUTP, LibGraphBLAS.GrB_MASK, LibGraphBLAS.GrB_INP0, LibGraphBLAS.GrB_INP1]
43+
T = LibGraphBLAS.GrB_Desc_Value
44+
elseif field [LibGraphBLAS.GxB_DESCRIPTOR_NTHREADS, LibGraphBLAS.GxB_AxB_METHOD, LibGraphBLAS.GxB_SORT]
45+
T = Cint
46+
elseif field [LibGraphBLAS.GxB_DESCRIPTOR_CHUNK]
47+
T = Cdouble
48+
else
49+
error("Not a valid Descriptor option.")
50+
end
51+
v = Ref{T}()
52+
@wraperror ccall(
53+
(:GxB_Desc_get, libgraphblas),
54+
LibGraphBLAS.GrB_Info,
55+
(LibGraphBLAS.GrB_Descriptor, UInt32, Ptr{Cvoid}),
56+
desc,
57+
field,
58+
v
59+
)
60+
return v[]
61+
end
62+
63+
function GxB_Desc_set(d, field, value)
64+
if field [LibGraphBLAS.GrB_OUTP, LibGraphBLAS.GrB_MASK, LibGraphBLAS.GrB_INP0, LibGraphBLAS.GrB_INP1]
65+
@wraperror ccall(
66+
(:GxB_Desc_set, libgraphblas),
67+
LibGraphBLAS.GrB_Info,
68+
(LibGraphBLAS.GrB_Descriptor, LibGraphBLAS.GrB_Desc_Field, LibGraphBLAS.GrB_Desc_Value),
69+
d,
70+
field,
71+
value
72+
)
73+
elseif field [LibGraphBLAS.GxB_DESCRIPTOR_NTHREADS, LibGraphBLAS.GxB_AxB_METHOD, LibGraphBLAS.GxB_SORT]
74+
@wraperror ccall(
75+
(:GxB_Desc_set, libgraphblas),
76+
LibGraphBLAS.GrB_Info,
77+
(LibGraphBLAS.GrB_Descriptor, LibGraphBLAS.GrB_Desc_Field, Cint),
78+
d,
79+
field,
80+
value
81+
)
82+
elseif field [LibGraphBLAS.GxB_DESCRIPTOR_CHUNK]
83+
@wraperror ccall(
84+
(:GxB_Desc_set, libgraphblas),
85+
LibGraphBLAS.GrB_Info,
86+
(LibGraphBLAS.GrB_Descriptor, LibGraphBLAS.GrB_Desc_Field, Cdouble),
87+
d,
88+
field,
89+
value
90+
)
91+
end
92+
end
3693

3794
function Base.getproperty(d::Descriptor, s::Symbol)
3895
if s === :p
3996
return getfield(d, s)
4097
elseif s === :replace_output
41-
x = libgb.GxB_Desc_get(d, libgb.GrB_OUTP)
42-
if x == libgb.GrB_REPLACE
98+
x = GxB_Desc_get(d, LibGraphBLAS.GrB_OUTP)
99+
if x == LibGraphBLAS.GrB_REPLACE
43100
return true
44101
else
45102
return false
46103
end
47104
elseif s === :complement_mask
48-
x = libgb.GxB_Desc_get(d, libgb.libgb.GrB_MASK)
49-
if x == libgb.GrB_COMP || x == libgb.GrB_STRUCT_COMP
105+
x = GxB_Desc_get(d, LibGraphBLAS.GrB_MASK)
106+
if x == LibGraphBLAS.GrB_COMP || x == LibGraphBLAS.GrB_STRUCT_COMP
50107
return true
51108
else
52109
return false
53110
end
54111
elseif s === :structural_mask
55-
x = libgb.GxB_Desc_get(d, libgb.GrB_MASK)
56-
if x == libgb.GrB_STRUCTURE || x == libgb.GrB_STRUCT_COMP
112+
x = GxB_Desc_get(d, LibGraphBLAS.GrB_MASK)
113+
if x == LibGraphBLAS.GrB_STRUCTURE || x == LibGraphBLAS.GrB_STRUCT_COMP
57114
return true
58115
else
59116
return false
60117
end
61118
elseif s === :transpose_input1
62-
x = libgb.GxB_Desc_get(d, libgb.GrB_INP0)
63-
if x == libgb.GrB_TRAN
119+
x = GxB_Desc_get(d, LibGraphBLAS.GrB_INP0)
120+
if x == LibGraphBLAS.GrB_TRAN
64121
return true
65122
else
66123
return false
67124
end
68125
elseif s === :transpose_input2
69-
x = libgb.GxB_Desc_get(d, libgb.GrB_INP1)
70-
if x == libgb.GrB_TRAN
126+
x = GxB_Desc_get(d, LibGraphBLAS.GrB_INP1)
127+
if x == LibGraphBLAS.GrB_TRAN
71128
return true
72129
else
73130
return false
74131
end
75132
elseif s === :nthreads
76-
return libgb.GxB_Desc_get(d, libgb.GxB_DESCRIPTOR_NTHREADS)
133+
return GxB_Desc_get(d, LibGraphBLAS.GxB_DESCRIPTOR_NTHREADS)
77134
elseif s === :chunk
78-
return libgb.GxB_Desc_get(d, libgb.GxB_DESCRIPTOR_CHUNK)
135+
return GxB_Desc_get(d, LibGraphBLAS.GxB_DESCRIPTOR_CHUNK)
79136
elseif s === :sort
80-
if libgb.GxB_Desc_get(d, libgb.GxB_SORT) == libgb.GxB_DEFAULT
137+
if GxB_Desc_get(d, LibGraphBLAS.GxB_SORT) == LibGraphBLAS.GxB_DEFAULT
81138
return false
82139
else
83140
return true
84141
end
85142
elseif s === :axb_method
86-
x = libgb.GxB_Desc_get(d, libgb.GxB_AxB_METHOD)
87-
if x == libgb.GxB_AxB_GUSTAVSON
143+
x = GxB_Desc_get(d, LibGraphBLAS.GxB_AxB_METHOD)
144+
if x == LibGraphBLAS.GxB_AxB_GUSTAVSON
88145
return :gustavson
89-
elseif x == libgb.GxB_AxB_DOT
146+
elseif x == LibGraphBLAS.GxB_AxB_DOT
90147
return :dot
91-
elseif x == libgb.AxB_HASH
148+
elseif x == LibGraphBLAS.AxB_HASH
92149
return :hash
93-
elseif x == libgb.GxB_AxB_SAXPY
150+
elseif x == LibGraphBLAS.GxB_AxB_SAXPY
94151
return :saxpy
95152
else
96153
return :default
@@ -105,38 +162,38 @@ function Base.setproperty!(d::Descriptor, s::Symbol, x)
105162
setfield!(d, s, x)
106163
return nothing
107164
elseif s === :replace_output
108-
x ? (y = libgb.GrB_REPLACE) : (y = libgb.GxB_DEFAULT)
109-
libgb.GxB_Desc_set(d, libgb.GrB_OUTP, y)
165+
x ? (y = LibGraphBLAS.GrB_REPLACE) : (y = LibGraphBLAS.GxB_DEFAULT)
166+
GxB_Desc_set(d, LibGraphBLAS.GrB_OUTP, y)
110167
elseif s === :complement_mask
111168
if x == false
112169
if d.structural_mask
113-
libgb.GxB_Desc_set(d, libgb.GrB_MASK, libgb.GrB_STRUCTURE)
170+
GxB_Desc_set(d, LibGraphBLAS.GrB_MASK, LibGraphBLAS.GrB_STRUCTURE)
114171
else
115-
libgb.GxB_Desc_set(d, libgb.GrB_MASK, libgb.GxB_DEFAULT)
172+
GxB_Desc_set(d, LibGraphBLAS.GrB_MASK, LibGraphBLAS.GxB_DEFAULT)
116173
end
117174
else
118-
libgb.GxB_Desc_set(d, libgb.GrB_MASK, libgb.GrB_COMP)
175+
GxB_Desc_set(d, LibGraphBLAS.GrB_MASK, LibGraphBLAS.GrB_COMP)
119176
end
120177
elseif s === :structural_mask
121178
if x == false
122179
if d.complement_mask
123-
libgb.GxB_Desc_set(d, libgb.GrB_MASK, libgb.GrB_COMP)
180+
GxB_Desc_set(d, LibGraphBLAS.GrB_MASK, LibGraphBLAS.GrB_COMP)
124181
else
125-
libgb.GxB_Desc_set(d, libgb.GrB_MASK, libgb.GxB_DEFAULT)
182+
GxB_Desc_set(d, LibGraphBLAS.GrB_MASK, LibGraphBLAS.GxB_DEFAULT)
126183
end
127184
else
128-
libgb.GxB_Desc_set(d, libgb.GrB_MASK, libgb.GrB_STRUCTURE)
185+
GxB_Desc_set(d, LibGraphBLAS.GrB_MASK, LibGraphBLAS.GrB_STRUCTURE)
129186
end
130187
elseif s === :transpose_input1
131-
libgb.GxB_Desc_set(d, libgb.GrB_INP0, x ? libgb.GrB_TRAN : libgb.GxB_DEFAULT)
188+
GxB_Desc_set(d, LibGraphBLAS.GrB_INP0, x ? LibGraphBLAS.GrB_TRAN : LibGraphBLAS.GxB_DEFAULT)
132189
elseif s === :transpose_input2
133-
libgb.GxB_Desc_set(d, libgb.GrB_INP1, x ? libgb.GrB_TRAN : libgb.GxB_DEFAULT)
190+
GxB_Desc_set(d, LibGraphBLAS.GrB_INP1, x ? LibGraphBLAS.GrB_TRAN : LibGraphBLAS.GxB_DEFAULT)
134191
elseif s === :nthreads
135-
libgb.GxB_Desc_set(d, libgb.GxB_DESCRIPTOR_NTHREADS, x)
192+
GxB_Desc_set(d, LibGraphBLAS.GxB_DESCRIPTOR_NTHREADS, x)
136193
elseif s === :chunk
137-
libgb.GxB_Desc_set(d, libgb.GxB_DESCRIPTOR_CHUNK, x)
194+
GxB_Desc_set(d, LibGraphBLAS.GxB_DESCRIPTOR_CHUNK, x)
138195
elseif s === :sort
139-
libgb.GxB_Desc_set(d, libgb.GxB_SORT, x ? 3 : 0)
196+
GxB_Desc_set(d, LibGraphBLAS.GxB_SORT, x ? 3 : 0)
140197
end
141198
end
142199
function Base.propertynames(::Descriptor)

0 commit comments

Comments
 (0)