Skip to content

Commit c931697

Browse files
author
Will Kimmerer
authored
SparsematrixGB (#60)
* constructors for SpMGB * initial working version * broadcasting/mapping * fix emul for SpMGB * tests * fix some tests * constructors for SpMGB * initial working version * broadcasting/mapping * fix emul for SpMGB * tests * fix some tests * eunion * fix test
1 parent f7bef67 commit c931697

File tree

8 files changed

+426
-14
lines changed

8 files changed

+426
-14
lines changed

src/SuiteSparseGraphBLAS.jl

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,8 @@ include("chainrules/constructorrules.jl")
9191
#include("random.jl")
9292
include("misc.jl")
9393
include("asjulia.jl")
94+
include("sparsemat.jl")
95+
export SparseArrayCompat
9496
export libgb
9597
export UnaryOps, BinaryOps, Monoids, Semirings #Submodules
9698
export UnaryOp, BinaryOp, Monoid, Semiring #UDFs
@@ -113,7 +115,7 @@ export clear!, extract, extract!, subassign!, assign!, hvcat! #array functions
113115

114116
#operations
115117
export mul, select, select!, eadd, eadd!, emul, emul!, map, map!, gbtranspose, gbtranspose!,
116-
gbrand
118+
gbrand, eunion, eunion!
117119
# Reexports from LinAlg
118120
export diag, diagm, mul!, kron, kron!, transpose, reduce, tril, triu
119121

src/chainrules/constructorrules.jl

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,6 @@ function rrule(::Type{<:GBVector}, I::AbstractVector{U}, v::Vector{T}) where {U<
6565
return GBVector(I, v), vecpullback
6666
end
6767

68-
6968
# Sparse Matrix
7069
function frule(
7170
(_,_,_,Δv),
@@ -78,7 +77,7 @@ function frule(
7877
end
7978

8079
function rrule(
81-
::Type{<:GBVector},
80+
::Type{<:GBMatrix},
8281
I::AbstractVector{U},
8382
J::AbstractVector{U},
8483
v::Vector{T}

src/lib/LibGraphBLAS.jl

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1571,6 +1571,14 @@ function GrB_Matrix_eWiseAdd_BinaryOp(C, Mask, accum, add, A, B, desc)
15711571
@wraperror ccall((:GrB_Matrix_eWiseAdd_BinaryOp, libgraphblas), GrB_Info, (GrB_Matrix, GrB_Matrix, GrB_BinaryOp, GrB_BinaryOp, GrB_Matrix, GrB_Matrix, GrB_Descriptor), C, Mask, accum, add, A, B, desc)
15721572
end
15731573

1574+
function GxB_Matrix_eWiseUnion(C, Mask, accum, add, A, alpha, B, beta, desc)
1575+
ccall((:GxB_Matrix_eWiseUnion, libgraphblas), GrB_Info, (GrB_Matrix, GrB_Matrix, GrB_BinaryOp, GrB_BinaryOp, GrB_Matrix, GrB_Scalar, GrB_Matrix, GrB_Scalar, GrB_Descriptor), C, Mask, accum, add, A, alpha, B, beta, desc)
1576+
end
1577+
1578+
function GxB_Vector_eWiseUnion(w, mask, accum, add, u, alpha, v, beta, desc)
1579+
ccall((:GxB_Vector_eWiseUnion, libgraphblas), GrB_Info, (GrB_Vector, GrB_Vector, GrB_BinaryOp, GrB_BinaryOp, GrB_Vector, GrB_Scalar, GrB_Vector, GrB_Scalar, GrB_Descriptor), w, mask, accum, add, u, alpha, v, beta, desc)
1580+
end
1581+
15741582
function GrB_Vector_extract(w, mask, accum, u, I, ni, desc)
15751583
I = tozerobased(I)
15761584
@wraperror ccall((:GrB_Vector_extract, libgraphblas), GrB_Info, (GrB_Vector, GrB_Vector, GrB_BinaryOp, GrB_Vector, Ptr{GrB_Index}, GrB_Index, GrB_Descriptor), w, mask, accum, u, I, ni, desc)

src/matrix.jl

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -225,9 +225,6 @@ function Base.show(io::IO, ::MIME"text/plain", A::GBMatrix)
225225
gxbprint(io, A)
226226
end
227227

228-
SparseArrays.nonzeros(A::GBArray) = findnz(A)[end]
229-
230-
231228
# Indexing functions
232229
####################
233230

src/operations/ewise.jl

Lines changed: 106 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ union equivalent see [`eadd!`](@ref).
1111
# Arguments
1212
- `C::GBArray`: the output vector or matrix.
1313
- `A, B::GBArray`: A GBVector or GBMatrix, possibly transposed.
14-
- `op::Union{Function, AbstractBinaryOp, Monoid} = *`: the binary operation which is
14+
- `op::Union{Function, AbstractBinaryOp, Monoid} = *`: the binary operation which is
1515
applied such that `C[i,j] = op(A[i,j], B[i,j])` for all `i,j` present in both `A` and `B`.
1616
1717
# Keywords
@@ -53,15 +53,15 @@ end
5353
"""
5454
emul(A::GBArray, B::GBArray, op = *; kwargs...)::GBMatrix
5555
56-
Apply the binary operator `op` elementwise on the set intersection of `A` and `B`.
56+
Apply the binary operator `op` elementwise on the set intersection of `A` and `B`.
5757
When `op = *` this is equivalent to `A .* B`, however any binary operator may be substituted.
5858
5959
The pattern of the result is the set intersection of `A` and `B`. For a set
6060
union equivalent see [`eadd`](@ref).
6161
6262
# Arguments
6363
- `A, B::GBArray`: A GBVector or GBMatrix, possibly transposed.
64-
- `op::Union{Function, AbstractBinaryOp, Monoid} = *`: the binary operation which is
64+
- `op::Union{Function, AbstractBinaryOp, Monoid} = *`: the binary operation which is
6565
applied such that `C[i,j] = op(A[i,j], B[i,j])` for all `i,j` present in both `A` and `B`.
6666
6767
# Keywords
@@ -107,7 +107,7 @@ For a set intersection equivalent see [`emul!`](@ref).
107107
# Arguments
108108
- `C::GBArray`: the output vector or matrix.
109109
- `A, B::GBArray`: A GBVector or GBMatrix, possibly transposed.
110-
- `op::Union{Function, AbstractBinaryOp, Monoid} = +`: the binary operation which is
110+
- `op::Union{Function, AbstractBinaryOp, Monoid} = +`: the binary operation which is
111111
applied such that `C[i,j] = op(A[i,j], B[i,j])` for all `i,j` present in either `A` and `B`.
112112
113113
# Keywords
@@ -148,7 +148,7 @@ end
148148
"""
149149
eadd(A::GBArray, B::GBArray, op = +; kwargs...)::GBVecOrMat
150150
151-
Apply the binary operator `op` elementwise on the set union of `A` and `B`.
151+
Apply the binary operator `op` elementwise on the set union of `A` and `B`.
152152
When `op = +` this is equivalent to `A .+ B`, however any binary operation may be substituted.
153153
154154
Note that the behavior of `A[i,j] op B[i,j]` may be unintuitive when one operand is an implicit
@@ -159,7 +159,7 @@ For a set intersection equivalent see [`emul`](@ref).
159159
160160
# Arguments
161161
- `A, B::GBArray`: A GBVector or GBMatrix, possibly transposed.
162-
- `op::Union{Function, AbstractBinaryOp, Monoid} = +`: the binary operation which is
162+
- `op::Union{Function, AbstractBinaryOp, Monoid} = +`: the binary operation which is
163163
applied such that `C[i,j] = op(A[i,j], B[i,j])` for all `i,j` present in either `A` and `B`.
164164
165165
# Keywords
@@ -185,6 +185,96 @@ function eadd(
185185
return eadd!(C, A, B, op; mask, accum, desc)
186186
end
187187

188+
189+
"""
190+
eunion!(C::GBVecOrMat, A::GBArray{T}, α::T B::GBArray, β::T, op = +; kwargs...)::GBVecOrMat
191+
192+
Apply the binary operator `op` elementwise on the set union of `A` and `B`. Store or
193+
accumulate the result into C. When `op = +` this is equivalent to `A .+ B`,
194+
however any binary operation may be substituted.
195+
196+
Unlike `eadd!` where an argument missing in `A` causes the `B` element to "pass-through",
197+
`eunion!` utilizes the `α` and `β` arguments for the missing operand elements.
198+
199+
# Arguments
200+
- `C::GBArray`: the output vector or matrix.
201+
- `A, B::GBArray`: A GBVector or GBMatrix, possibly transposed.
202+
- `α, β`: The fill-in value for `A` and `B` respectively.
203+
- `op::Union{Function, AbstractBinaryOp, Monoid} = +`: the binary operation which is
204+
applied such that `C[i,j] = op(A[i,j], B[i,j])` for all `i,j` present in either `A` and `B`.
205+
206+
# Keywords
207+
- `mask::Union{Nothing, GBVecOrMat} = nothing`: optional mask.
208+
- `accum::Union{Nothing, Function, AbstractBinaryOp} = nothing`: binary accumulator operation
209+
such that `C[i,j] = accum(C[i,j], T[i,j])` where T is the result of this function before accum is applied.
210+
- `desc::Union{Nothing, Descriptor} = nothing`
211+
"""
212+
function eunion!(
213+
C::GBVecOrMat,
214+
A::GBArray{T},
215+
α::T,
216+
B::GBArray{U},
217+
β::U,
218+
op::MonoidBinaryOrRig = BinaryOps.PLUS;
219+
mask = nothing,
220+
accum = nothing,
221+
desc = nothing
222+
) where {T, U}
223+
mask, accum = _handlenothings(mask, accum)
224+
desc = _handledescriptor(desc; in1=A, in2 = B)
225+
size(C) == size(A) == size(B) || throw(DimensionMismatch())
226+
op = getoperator(op, optype(A, B))
227+
accum = getaccum(accum, eltype(C))
228+
if op isa TypedBinaryOperator
229+
libgb.GxB_Matrix_eWiseUnion(C, mask, accum, op, parent(A), GBScalar(α), parent(B), GBScalar(β), desc)
230+
return C
231+
else
232+
throw(ArgumentError("$op is not a valid monoid binary op or semiring."))
233+
end
234+
return C
235+
end
236+
237+
"""
238+
eunion(C::GBVecOrMat, A::GBArray{T}, α::T B::GBArray, β::T, op = +; kwargs...)::GBVecOrMat
239+
240+
Apply the binary operator `op` elementwise on the set union of `A` and `B`.
241+
When `op = +` this is equivalent to `A .+ B`, however any binary operation may be substituted.
242+
243+
Unlike `eadd!` where an argument missing in `A` causes the `B` element to "pass-through",
244+
`eunion!` utilizes the `α` and `β` arguments for the missing operand elements.
245+
246+
# Arguments
247+
- `A, B::GBArray`: A GBVector or GBMatrix, possibly transposed.
248+
- `α, β`: The fill-in value for `A` and `B` respectively.
249+
- `op::Union{Function, AbstractBinaryOp, Monoid} = +`: the binary operation which is
250+
applied such that `C[i,j] = op(A[i,j], B[i,j])` for all `i,j` present in either `A` and `B`.
251+
252+
# Keywords
253+
- `mask::Union{Nothing, GBVecOrMat} = nothing`: optional mask.
254+
- `accum::Union{Nothing, Function, AbstractBinaryOp} = nothing`: binary accumulator operation
255+
such that `C[i,j] = accum(C[i,j], T[i,j])` where T is the result of this function before accum is applied.
256+
- `desc::Union{Nothing, Descriptor} = nothing`
257+
"""
258+
function eunion(
259+
A::GBArray{T},
260+
α::T,
261+
B::GBArray{U},
262+
β::U,
263+
op::MonoidBinaryOrRig = BinaryOps.PLUS;
264+
mask = nothing,
265+
accum = nothing,
266+
desc = nothing
267+
) where {T, U}
268+
t = inferoutputtype(A, B, op)
269+
if A isa GBVector && B isa GBVector
270+
C = GBVector{t}(size(A))
271+
else
272+
C = GBMatrix{t}(size(A))
273+
end
274+
return eunion!(C, A, α, B, β, op; mask, accum, desc)
275+
end
276+
277+
188278
function emul!(C, A, B, op::Function; mask = nothing, accum = nothing, desc = nothing)
189279
emul!(C, A, B, BinaryOp(op); mask, accum, desc)
190280
end
@@ -201,12 +291,20 @@ function eadd(A, B, op::Function; mask = nothing, accum = nothing, desc = nothin
201291
eadd(A, B, BinaryOp(op); mask, accum, desc)
202292
end
203293

294+
function eunion!(C, A, α, B, β, op::Function; mask = nothing, accum = nothing, desc = nothing)
295+
eunion!(C, A, α, B, β, BinaryOp(op); mask, accum, desc)
296+
end
297+
298+
function eunion(A, α, B, β, op::Function; mask = nothing, accum = nothing, desc = nothing)
299+
eunion(A, α, B, β, BinaryOp(op); mask, accum, desc)
300+
end
301+
204302
function Base.:+(A::GBArray, B::GBArray)
205-
eadd(A, B, BinaryOps.PLUS)
303+
eadd(A, B, +)
206304
end
207305

208306
function Base.:-(A::GBArray, B::GBArray)
209-
eadd(A, B, BinaryOps.MINUS)
307+
eadd(A, B, -)
210308
end
211309

212310
(A, B, op; mask = nothing, accum = nothing, desc = nothing) =

0 commit comments

Comments
 (0)