From 621d43e3598b90fc57f5575f3e51030d65c043e3 Mon Sep 17 00:00:00 2001 From: Wimmerer Date: Thu, 30 Jun 2022 00:03:41 -0400 Subject: [PATCH 1/8] initial rebuild with pack/unpack --- src/SuiteSparseGraphBLAS.jl | 5 +- src/abstractgbarray.jl | 44 ++++++-- src/asjulia.jl | 132 ---------------------- src/export.jl | 115 ------------------- src/import.jl | 213 ------------------------------------ src/matrix.jl | 25 ++++- src/mem.jl | 16 +++ src/options.jl | 13 ++- src/pack.jl | 127 ++++++++++++++++++--- src/types.jl | 20 +++- src/unpack.jl | 156 ++++++++++++++++++++++---- src/vector.jl | 15 ++- test/asjulia.jl | 40 ------- test/runtests.jl | 2 - 14 files changed, 364 insertions(+), 559 deletions(-) delete mode 100644 src/asjulia.jl delete mode 100644 src/export.jl delete mode 100644 src/import.jl create mode 100644 src/mem.jl delete mode 100644 test/asjulia.jl diff --git a/src/SuiteSparseGraphBLAS.jl b/src/SuiteSparseGraphBLAS.jl index 0c1abc69..1e582b39 100644 --- a/src/SuiteSparseGraphBLAS.jl +++ b/src/SuiteSparseGraphBLAS.jl @@ -15,7 +15,7 @@ else end using SparseArrays -using SparseArrays: nonzeroinds +using SparseArrays: nonzeroinds, getcolptr, getrowval, getnzval, rowvals using MacroTools using LinearAlgebra using Random: randsubseq, default_rng, AbstractRNG, GLOBAL_RNG @@ -33,6 +33,7 @@ include("libutils.jl") include("lib/LibGraphBLAS_gen.jl") using .LibGraphBLAS +include("mem.jl") include("operators/libgbops.jl") include("gbtypes.jl") @@ -77,7 +78,6 @@ include("operations/resize.jl") include("operations/sort.jl") # include("print.jl") -include("import.jl") include("pack.jl") include("unpack.jl") include("options.jl") @@ -95,7 +95,6 @@ include("serialization.jl") #EXPERIMENTAL include("misc.jl") -include("asjulia.jl") include("mmread.jl") # include("iterator.jl") include("oriented.jl") diff --git a/src/abstractgbarray.jl b/src/abstractgbarray.jl index e9494336..7c8f2ad9 100644 --- a/src/abstractgbarray.jl +++ b/src/abstractgbarray.jl @@ -16,6 +16,35 @@ Does not modify the type or dimensions. """ Base.empty!(A::AbsGBArrayOrTranspose) = @wraperror LibGraphBLAS.GrB_Matrix_clear(gbpointer(parent(A))); return nothing +# TODO: with cheatmalloc we can move from 2x copies -> 1x copy. +# Currently this function copies A to avoid modifying the sparsity of A and +function Base.Matrix(A::AbstractGBMatrix) + sparsity = sparsitystatus(A) + T = sparsity === Dense() ? A : copy(A) # If A is not dense we need to copy to avoid densifying + x = unpack!(T, Dense()) + C = copy(x) + pack!(T, x) + return C +end + +function Base.Vector(v::AbstractGBVector) + sparsity = sparsitystatus(v) + T = sparsity === Dense() ? v : copy(v) # If A is not dense we need to copy to avoid densifying + x = unpack!(T, Dense()) + C = copy(x) + pack!(T, x) + return C +end + +function SparseArrays.SparseMatrixCSC(A::AbstractGBArray) + sparsity = sparsitystatus(A) + T = sparsity === Sparse() ? A : copy(A) + x = unpack!(T, SparseMatrixCSC) + C = copy(x) + pack!(T, x) + return C +end + # AbstractGBMatrix functions: ############################# @@ -317,7 +346,7 @@ Assign a submatrix of `A` to `C`. Equivalent to [`assign!`](@ref) except that - `GrB_DIMENSION_MISMATCH`: If `size(A) != (max(I), max(J))` or `size(A) != size(mask)`. """ function subassign!( - C::AbstractGBMatrix, A::GBArray, I, J; + C::AbstractGBMatrix, A::AbstractGBArray, I, J; mask = nothing, accum = nothing, desc = nothing ) I, ni = idx(I) @@ -346,14 +375,15 @@ function subassign!(C::AbstractGBArray{T}, x, I, J; _subassign(C, x, I, ni, J, nj, mask, getaccum(accum, eltype(C)), desc) increment!(I) increment!(J) - return C + return x end function subassign!(C::AbstractGBArray, x::AbstractArray, I, J; mask = nothing, accum = nothing, desc = nothing) - as(GBMatrix, x) do array - subassign!(C, array, I, J; mask, accum, desc) - end + array = pack!(GBMatrix, x; copytoraw=false) + subassign!(C, array, I, J; mask, accum, desc) + unpack!(array) + return C end """ @@ -381,7 +411,7 @@ Assign a submatrix of `A` to `C`. Equivalent to [`subassign!`](@ref) except that - `GrB_DIMENSION_MISMATCH`: If `size(A) != (max(I), max(J))` or `size(C) != size(mask)`. """ function assign!( - C::AbstractGBMatrix, A::AbstractGBVector, I, J; + C::AbstractGBMatrix, A::AbstractGBArray, I, J; mask = nothing, accum = nothing, desc = nothing ) I, ni = idx(I) @@ -409,7 +439,7 @@ function assign!(C::AbstractGBArray, x, I, J; _assign(gbpointer(C), x, I, ni, J, nj, mask, getaccum(accum, eltype(C)), desc) increment!(I) increment!(J) - return C + return x end function Base.setindex!( diff --git a/src/asjulia.jl b/src/asjulia.jl deleted file mode 100644 index 9000641e..00000000 --- a/src/asjulia.jl +++ /dev/null @@ -1,132 +0,0 @@ -function as(f::Function, type::Type{<:Union{GBMatrix, GBVector}}, A::AbstractArray{T}) where {T} - if !(A isa DenseVecOrMat) - A = A isa AbstractVector ? collect(A) : Matrix(A) - end - if type <:AbstractGBMatrix - array = type{T}(size(A, 1), size(A, 2)) - else - array = type{T}(size(A, 1)) - end - _packdensematrix!(array, A) - _makeshallow!(array) - return f(array) -end - - -function as(f::Function, type::Type{<:Union{Matrix, Vector}}, A::AbstractGBArray{T}; dropzeros=false, freeunpacked=false, dontmodifysparsity = false) where {T} - (type == Matrix && !(A isa AbstractGBMatrix)) && throw(ArgumentError("Cannot wrap $(typeof(A)) in a Matrix.")) - (type == Vector && !(A isa AbstractGBVector)) && throw(ArgumentError("Cannot wrap $(typeof(A)) in a Vector.")) - if gbget(A, SPARSITY_STATUS) != Int64(GBDENSE) - X = similar(A) - if X isa GBVector - X[:] = zero(T) - else - X[:,:] = zero(T) - end - if dontmodifysparsity - A = eadd!(X, A, X) - else - A = eadd!(A, X, A) - end - end - - array = _unpackdensematrix!(A) - result = try - result = f(array) - if result === array - result = copy(result) - end - result - finally - if freeunpacked - ccall(:jl_free, Cvoid, (Ptr{T},), pointer(array)) - else - _packdensematrix!(A, array) - if dropzeros - select!(nonzeros, A) - end - end - end - return result -end - -function as(f::Function, ::Type{SparseMatrixCSC}, A::AbstractGBMatrix{T}; freeunpacked=false) where {T} - colptr, colptrsize, rowidx, rowidxsize, values, valsize = _unpackcscmatrix!(A) - array = SparseMatrixCSC{T, LibGraphBLAS.GrB_Index}(size(A, 1), size(A, 2), colptr, rowidx, values) - result = try - result = f(array) - if result === array - result = copy(result) - end - result - finally - if freeunpacked - ccall(:jl_free, Cvoid, (Ptr{LibGraphBLAS.GrB_Index},), pointer(colptr)) - ccall(:jl_free, Cvoid, (Ptr{LibGraphBLAS.GrB_Index},), pointer(rowidx)) - ccall(:jl_free, Cvoid, (Ptr{T},), pointer(values)) - else - _packcscmatrix!(A, colptr, rowidx, values; colptrsize, rowidxsize, valsize) - end - end - return result -end - -function as(f::Function, ::Type{SparseVector}, A::AbstractGBVector{T}; freeunpacked=false) where {T} - colptr, colptrsize, rowidx, rowidxsize, values, valsize = _unpackcscmatrix!(A) - vector = SparseVector{T, LibGraphBLAS.GrB_Index}(size(A, 1), rowidx, values) - result = try - result = f(vector) - if result === vector - result = copy(result) - end - result - finally - if freeunpacked - ccall(:jl_free, Cvoid, (Ptr{LibGraphBLAS.GrB_Index},), pointer(colptr)) - ccall(:jl_free, Cvoid, (Ptr{LibGraphBLAS.GrB_Index},), pointer(rowidx)) - ccall(:jl_free, Cvoid, (Ptr{T},), pointer(values)) - else - _packcscmatrix!(A, colptr, rowidx, values; colptrsize, rowidxsize, valsize) - end - end - return result -end - - -function Base.Matrix(A::AbstractGBMatrix) - # we use dontmodifysparsity here to avoid the pitfall of densifying A. - return as(Matrix, A; dontmodifysparsity=true) do arr - return copy(arr) - end -end - -function Matrix!(A::AbstractGBMatrix) - return as(Matrix, A; freeunpacked=true) do arr - return copy(arr) - end -end - -function Base.Vector(v::AbstractGBVector) - # we use dontmodifysparsity here to avoid the pitfall of densifying A. - return as(Vector, v; dontmodifysparsity=true) do vec - return copy(vec) - end -end - -function Vector!(v::AbstractGBVector) - return as(Vector, v; freeunpacked=true) do vec - return copy(vec) - end -end - -function SparseArrays.SparseMatrixCSC(A::AbstractGBMatrix) - return as(SparseMatrixCSC, A) do arr - return copy(arr) - end -end - -function SparseArrays.SparseVector(v::AbstractGBVector) - return as(SparseVector, v) do arr - return copy(arr) - end -end diff --git a/src/export.jl b/src/export.jl deleted file mode 100644 index 898d713e..00000000 --- a/src/export.jl +++ /dev/null @@ -1,115 +0,0 @@ - -function _exportdensematrix!( - A::GBVecOrMat{T}; - desc = nothing -) where {T} - desc = _handledescriptor(desc) - nrows = Ref{LibGraphBLAS.GrB_Index}(size(A,1)) - ncols = Ref{LibGraphBLAS.GrB_Index}(size(A,2)) - Csize = Ref{LibGraphBLAS.GrB_Index}(length(A) * sizeof(T)) - values = Ref{Ptr{Cvoid}}(Ptr{T}()) - isuniform = Ref{Bool}(false) - @wraperror LibGraphBLAS.GxB_Matrix_export_FullC( - Ref(A.p), - Ref(gbtype(T).p), - nrows, - ncols, - values, - Csize, - isuniform, - desc - ) - A.p = C_NULL - finalize(A) - return nrows[], ncols[], values[] -end -function _exportdensematrix(A::GBMatrix; desc = nothing) - return _exportdensematrix!(copy(A); desc) -end - -function _exportcscmatrix!( - A::GBMatrix{T}; - desc = nothing - ) where {T} - desc = _handledescriptor(desc) - nrows = Ref{LibGraphBLAS.GrB_Index}(size(A, 1)) - ncols = Ref{LibGraphBLAS.GrB_Index}(size(A, 2)) - t = Ref{LibGraphBLAS.GrB_Type}(gbtype(T).p) - colptr = Ref{Ptr{LibGraphBLAS.GrB_Index}}() - rowidx = Ref{Ptr{LibGraphBLAS.GrB_Index}}() - values = Ref{Ptr{Cvoid}}(Ptr{T}()) - colptrsize = Ref{LibGraphBLAS.GrB_Index}() - rowidxsize = Ref{LibGraphBLAS.GrB_Index}() - Axsize = Ref{LibGraphBLAS.GrB_Index}() - isuniform = Ref{Bool}(false) - isjumbled = C_NULL - - @wraperror LibGraphBLAS.GxB_Matrix_export_CSC( - Ref(A.p), - t, - nrows, - ncols, - colptr, - rowidx, - values, - colptrsize, - rowidxsize, - Axsize, - isuniform, - isjumbled, - desc - ) - A.p = C_NULL - finalize(A) - return (nrows[], ncols[], colptr[], rowidx[], colptrsize[], rowidxsize[], values[], Axsize[]) -end - -function _exportcscmatrix(A::GBMatrix; desc = nothing) - return _exportcscmatrix!(copy(A); desc) -end - -#function SparseArrays.SparseMatrixCSC(A::GBMatrix{T}; desc = nothing) where {T} -# nrows, ncols, colptr, rowidx, colptrsize, rowidxsize, val, valsize = _exportcscmatrix(A; desc) -# outvalues = Vector{T}(undef, valsize ÷ sizeof(T)) -# col = Vector{LibGraphBLAS.GrB_Index}(undef, Int(colptrsize ÷ sizeof(LibGraphBLAS.GrB_Index))) -# row = Vector{LibGraphBLAS.GrB_Index}(undef, Int(rowidxsize ÷ sizeof(LibGraphBLAS.GrB_Index))) -# unsafe_copyto!(pointer(outvalues), Ptr{T}(val), length(outvalues)) -# unsafe_copyto!(pointer(col), Ptr{LibGraphBLAS.GrB_Index}(colptr), length(col)) -# unsafe_copyto!(pointer(row), Ptr{LibGraphBLAS.GrB_Index}(rowidx), length(row)) -# ccall(:jl_free, Cvoid, (Ptr{LibGraphBLAS.GrB_Index},), colptr) -# ccall(:jl_free, Cvoid, (Ptr{LibGraphBLAS.GrB_Index},), rowidx) -# ccall(:jl_free, Cvoid, (Ptr{T},), val) -# return SparseArrays.SparseMatrixCSC(nrows, ncols, col .+= 1, row .+= 1, outvalues) -#end -#function SparseArrays.SparseVector(A::GBMatrix{T}; desc = nothing) where {T} -# SparseVector(SparseMatrixCSC(A; desc)) -#end -# -#function SparseArrays.SparseVector(v::GBVector{T}; desc = nothing) where {T} -# SparseVector(SparseMatrixCSC(GBMatrix(v); desc)) -#end - -function _exportdensevec!( - v::GBVector{T}; - desc = nothing - ) where {T} - desc = _handledescriptor(desc) - n = Ref{LibGraphBLAS.GrB_Index}(size(v,1)) - vsize = Ref{LibGraphBLAS.GrB_Index}(length(v) * sizeof(T)) - values = Ref{Ptr{Cvoid}}(Ptr{T}()) - isuniform = Ref{Bool}(false) - @wraperror LibGraphBLAS.GxB_Vector_export_Full( - Ref(v.p), - Ref(gbtype(T).p), - n, - values, - vsize, - isuniform, - desc - ) - return n[], values[] -end - -function _exportdensevec(v::GBVector; desc = nothing) - return _exportdensevec!(copy(v); desc) -end diff --git a/src/import.jl b/src/import.jl deleted file mode 100644 index a5f5cffd..00000000 --- a/src/import.jl +++ /dev/null @@ -1,213 +0,0 @@ -function _importcscmat( - m::Integer, - n::Integer, - colptr::Ptr{UInt64}, - colsize, - rowindices::Ptr{UInt64}, - rowsize, - values::Ptr{T}, - valsize; - jumbled::Bool = false, - desc = nothing, - iso = false -) where {T} - A = Ref{LibGraphBLAS.GrB_Matrix}() #Pointer to new GBMatrix - m = LibGraphBLAS.GrB_Index(m) #nrows - n = LibGraphBLAS.GrB_Index(n) #ncols - desc = _handledescriptor(desc) - @wraperror LibGraphBLAS.GxB_Matrix_import_CSC( - A, - gbtype(T), - m, - n, - Ref{Ptr{LibGraphBLAS.GrB_Index}}(colptr), - Ref{Ptr{LibGraphBLAS.GrB_Index}}(rowindices), - Ref{Ptr{Cvoid}}(values), - colsize, - rowsize, - valsize, - iso, - jumbled, - desc - ) - return A -end - -function _importcscmat( - m::Integer, - n::Integer, - colptr::Vector{U}, - rowindices::Vector{U}, - values::Vector{T}; - jumbled::Bool = false, - desc = nothing, - iso = false -) where {U, T} - colsize = LibGraphBLAS.GrB_Index(sizeof(colptr)) #Size of colptr vector - rowsize = LibGraphBLAS.GrB_Index(sizeof(rowindices)) #Size of rowindex vector - valsize = LibGraphBLAS.GrB_Index(sizeof(values)) #Size of nzval vector - col = ccall(:jl_malloc, Ptr{LibGraphBLAS.GrB_Index}, (UInt, ), colsize) - unsafe_copyto!(col, Ptr{UInt64}(pointer(decrement!(colptr))), length(colptr)) - row = ccall(:jl_malloc, Ptr{LibGraphBLAS.GrB_Index}, (UInt, ), rowsize) - unsafe_copyto!(row, Ptr{UInt64}(pointer(decrement!(rowindices))), length(rowindices)) - val = ccall(:jl_malloc, Ptr{T}, (UInt, ), valsize) - unsafe_copyto!(val, pointer(values), length(values)) - x = _importcscmat(m, n, col, colsize, row, rowsize, val, valsize; jumbled, desc, iso) - increment!(colptr) - increment!(rowindices) - return x -end - -""" - GBMatrix(S::SparseMatrixCSC) - -Create a GBMatrix from a SparseArrays.SparseMatrixCSC `S`. - -Note, that unlike most other methods of construction, the resulting matrix will be held by column. -Use `gbset(A, :format, :byrow)` to switch to row orientation. -""" -function GBMatrix(S::SparseMatrixCSC{T}; fill::F = nothing) where {T, F} - return GBMatrix{T, F}(_importcscmat(S.m, S.n, S.colptr, S.rowval, S.nzval), fill) -end - -# TODO: should be able to do better here. -function GBMatrix(v::SparseVector) - S = SparseMatrixCSC(v) - return GBMatrix(S) -end - -""" - GBVector(v::SparseVector) - -Create a GBVector from SparseArrays sparse vector `v`. -""" -function GBVector(v::SparseVector{T}; fill::F = nothing) where {T, F} - return GBVector{T, F}(_importcscmat(v.n, 1, [1, length(v.nzind) + 1], v.nzind, v.nzval), fill) -end - -function _importcsrmat( - m::Integer, - n::Integer, - rowptr::Vector{U}, - rowsize, - colindices::Vector{U}, - colsize, - values::Ptr{T}, - valsize; - jumbled::Bool = false, - desc = nothing, - iso = false -) where {U, T} - A = Ref{LibGraphBLAS.GrB_Matrix}() #Pointer to new GBMatrix - m = LibGraphBLAS.GrB_Index(m) #nrows - n = LibGraphBLAS.GrB_Index(n) #ncols - desc = _handledescriptor(desc) - @wraperror LibGraphBLAS.GxB_Matrix_import_CSR( - A, - gbtype(T), - m, - n, - Ref{Ptr{LibGraphBLAS.GrB_Index}}(rowptr), - Ref{Ptr{LibGraphBLAS.GrB_Index}}(colindices), - Ref{Ptr{Cvoid}}(values), - rowsize, - colsize, - valsize, - iso, - jumbled, - desc - ) - return A -end - -function _importcsrmat( - m::Integer, - n::Integer, - rowptr, - colindices, - values::Vector{T}; - jumbled::Bool = false, - desc = nothing, - iso = false -) where {T} - rowsize = LibGraphBLAS.GrB_Index(sizeof(rowptr)) #Size of colptr vector - colsize = LibGraphBLAS.GrB_Index(sizeof(colindices)) #Size of rowindex vector - valsize = LibGraphBLAS.GrB_Index(sizeof(values)) #Size of nzval vector - - # This section comes after some chatting with Keno Fisher. - # Cannot directly pass Julia arrays to GraphBLAS, it expects malloc'd arrays. - # Instead we'll malloc some memory for each of the three vectors, and unsafe_copyto! - # into them. - #NOTE: The use of `:jl_malloc` instead of `Libc.malloc` is because *GraphBLAS* will free - # this memory using `:jl_free`. These functions have to match. - row = ccall(:jl_malloc, Ptr{LibGraphBLAS.GrB_Index}, (UInt, ), rowsize) - unsafe_copyto!(row, Ptr{UInt64}(pointer(colptr .- 1)), length(rowptr)) - col = ccall(:jl_malloc, Ptr{LibGraphBLAS.GrB_Index}, (UInt, ), colsize) - unsafe_copyto!(col, Ptr{UInt64}(pointer(rowindices .- 1)), length(colindices)) - val = ccall(:jl_malloc, Ptr{T}, (UInt, ), valsize) - unsafe_copyto!(val, pointer(values), length(values)) - - return _importcsrmat(m, n, row, rowsize, col, colsize, val, valsize; jumbled, desc, iso) -end - -function _importdensematrix( - m::Integer, n::Integer, A::Ptr{T}, Asize; - desc = nothing, iso = false -) where {T} - C = Ref{LibGraphBLAS.GrB_Matrix}() - m = LibGraphBLAS.GrB_Index(m) - n = LibGraphBLAS.GrB_Index(n) - desc = _handledescriptor(desc) - @wraperror LibGraphBLAS.GxB_Matrix_import_FullC( - C, - gbtype(T), - m, - n, - Ref{Ptr{Cvoid}}(A), - Asize, - iso, - desc - ) - return C -end - -function _importdensematrix( - m::Integer, n::Integer, A::VecOrMat{T}; - desc = nothing, iso = false -) where {T} - m = LibGraphBLAS.GrB_Index(m) - n = LibGraphBLAS.GrB_Index(n) - Asize = LibGraphBLAS.GrB_Index(sizeof(A)) - Ax = ccall(:jl_malloc, Ptr{T}, (UInt, ), Asize) - unsafe_copyto!(Ax, pointer(A), length(A)) - return _importdensematrix(m, n, Ax, Asize; desc, iso) -end - -""" - GBMatrix(M::Matrix) - -Create a GBMatrix from a Julia dense matrix. -Note, that unlike other methods of construction, the resulting matrix will be held by column. -Use `gbset(A, :format, :byrow)` to switch to row orientation. -""" -function GBMatrix(M::Union{AbstractVector{T}, AbstractMatrix{T}}; fill::F = nothing) where {T, F} - if M isa AbstractVector && !(M isa Vector) - M = collect(M) - end - if M isa AbstractMatrix && !(M isa Matrix) - M = Matrix(M) - end - return GBMatrix{T, F}(_importdensematrix(size(M, 1), size(M, 2), M), fill) -end - -""" - GBVector(v::AbstractVector) - -Create a GBVector from a Julia dense vector. -""" -function GBVector(v::AbstractVector{T}; fill::F = nothing) where {T, F} - if !(v isa Vector) - v = collect(v) - end - return GBVector{T, F}(_importdensematrix(size(v, 1), 1, v), fill) -end \ No newline at end of file diff --git a/src/matrix.jl b/src/matrix.jl index b230d8da..1d038015 100644 --- a/src/matrix.jl +++ b/src/matrix.jl @@ -65,8 +65,31 @@ function GBMatrix(v::GBVector) return copy(GBMatrix{eltype(v), typeof(v.fill)}(v.p, v.fill)) end -GBMatrix{T, F}(::Number, ::Number) where {T, F} = throw(ArgumentError("The F parameter is implicit and determined by the `fill` keyword argument to constructors. Users must not specify this manually.")) +GBMatrix{T, F}(::Number, ::Number; fill = nothing) where {T, F} = throw(ArgumentError("The F parameter is implicit and determined by the `fill` keyword argument to constructors. Users must not specify this manually.")) +function GBMatrix(S::SparseMatrixCSC{T}; fill::F = nothing) where {T, F} + A = GBMatrix{T}(size(S)...; fill) + return pack!(A, S) # will copy automatically. +end + +function GBMatrix(M::Union{AbstractVector{T}, AbstractMatrix{T}}; fill::F = nothing) where {T, F} + needcopy = true + if M isa AbstractVector && !(M isa Vector) + M = collect(M) + needcopy = false + end + if M isa AbstractMatrix && !(M isa Matrix) + M = Matrix(M) + needcopy = false + end + A = GBMatrix{T}(size(M, 1), size(M, 2); fill) + return pack!(A, M) # needcopy ? copy(M) : M. Currently copies within pack +end + +function GBMatrix(v::SparseVector{T}; fill::F = nothing) where {T, F} + A = GBMatrix{T}(size(v, 1), 1; fill) + return pack!(A, v) # currently copies within pack! +end # Some Base and basic SparseArrays/LinearAlgebra functions: ########################################################### diff --git a/src/mem.jl b/src/mem.jl new file mode 100644 index 00000000..7c40ce5c --- /dev/null +++ b/src/mem.jl @@ -0,0 +1,16 @@ +function _jlmalloc(size) + return ccall(:jl_malloc, Ptr{Cvoid}, (UInt, ), size) +end +function _jlfree(p::Union{DenseVecOrMat{T}, Ptr{T}, Ref{T}}) where {T} + ccall(:jl_free, Cvoid, (Ptr{T}, ), p isa DenseVecOrMat ? pointer(p) : p) +end + +function _copytorawptr(A::DenseVecOrMat{T}) where {T} + sz = sizeof(A) + ptr = _jlmalloc(sz) + ptr = Ptr{T}(ptr) + unsafe_copyto!(ptr, pointer(A), length(A)) + return ptr +end + +_copytoraw(A::DenseVecOrMat) = unsafe_wrap(Array, _copytorawptr(A), size(A)) \ No newline at end of file diff --git a/src/options.jl b/src/options.jl index 7d42f9a1..10ce31c4 100644 --- a/src/options.jl +++ b/src/options.jl @@ -121,10 +121,12 @@ function gbget(A::AbstractGBArray, option) return GxB_Matrix_Option_get(A, option) end -function format(A::GBVecOrMat) - t = gbget(A, SPARSITY_STATUS) - f = gbget(A, FORMAT) - return (GBSparsity(t), GBFormat(f)) +function sparsitystatus(A::AbstractGBArray) + t = GBSparsity(gbget(A, SPARSITY_STATUS)) + return consttoshape(t) +end +function format(A::AbstractGBArray) + return (sparsitystatus(A), storageorder(A)) end const HYPER_SWITCH = LibGraphBLAS.GxB_HYPER_SWITCH @@ -160,6 +162,9 @@ function option_toconst(sym::Symbol) sym === :hypersparse && return GBHYPER end +function option_toconst(sparsity::AbstractSparsity) + return shapetoconst(sparsity) +end """ Sparsity options for GraphBLAS. values can be summed to produce additional options. diff --git a/src/pack.jl b/src/pack.jl index 233eb9cc..dcaed5f5 100644 --- a/src/pack.jl +++ b/src/pack.jl @@ -1,13 +1,38 @@ -function _packdensematrix!(A::AbstractGBArray{T}, M::DenseVecOrMat; desc = nothing) where {T} +function _packdensematrix!(A::AbstractGBArray{T}, M::VecOrMat{T}; desc = nothing) where {T} desc = _handledescriptor(desc) Csize = length(A) * sizeof(T) - values = Ref{Ptr{Cvoid}}(pointer(M)) - isuniform = false + ptr = pointer(M) + # lock(memlock) + # try + # PTRTOJL[Ptr{Cvoid}(ptr)] = M + # finally + # unlock(memlock) + # end @wraperror LibGraphBLAS.GxB_Matrix_pack_FullC( gbpointer(A), - values, + Ref{Ptr{Cvoid}}(ptr), Csize, - isuniform, + false, #isuniform + desc + ) + return A +end + +function _packdensematrixR!(A::AbstractGBArray{T}, M::VecOrMat{T}; desc = nothing) where {T} + desc = _handledescriptor(desc) + Csize = length(A) * sizeof(T) + ptr = pointer(M) + # lock(memlock) + # try + # PTRTOJL[Ptr{Cvoid}(ptr)] = M + # finally + # unlock(memlock) + # end + @wraperror LibGraphBLAS.GxB_Matrix_pack_FullR( + gbpointer(A), + Ref{Ptr{Cvoid}}(ptr), + Csize, + false, #isuniform desc ) return A @@ -22,12 +47,23 @@ function _packcscmatrix!( colptrsize = length(colptr) * sizeof(LibGraphBLAS.GrB_Index), rowidxsize = length(rowidx) * sizeof(LibGraphBLAS.GrB_Index), valsize = length(values) * sizeof(T), - rebaseindices = true + decrementindices = true ) where {T, Ti} - if rebaseindices - decrement!(colptr) - decrement!(rowidx) - end + decrementindices && decrement!(colptr) + decrementindices && decrement!(rowidx) + + # colpointer = pointer(colptr) + # rowpointer = pointer(rowidx) + # valpointer = pointer(values) + # lock(memlock) + # try + # PTRTOJL[Ptr{Cvoid}(colpointer)] = colptr + # PTRTOJL[Ptr{Cvoid}(rowpointer)] = rowidx + # PTRTOJL[Ptr{Cvoid}(valpointer)] = values + # finally + # unlock(memlock) + # end + colptr = Ref{Ptr{LibGraphBLAS.GrB_Index}}(pointer(colptr)) rowidx = Ref{Ptr{LibGraphBLAS.GrB_Index}}(pointer(rowidx)) values = Ref{Ptr{Cvoid}}(pointer(values)) @@ -57,18 +93,30 @@ function _packcsrmatrix!( rowptrsize = length(rowptr) * sizeof(LibGraphBLAS.GrB_Index), colidxsize = length(colidx) * sizeof(LibGraphBLAS.GrB_Index), valsize = length(values) * sizeof(T), - rebaseindices = true + decrementindices = true ) where {T, Ti} - if rebaseindices - decrement!(rowptr) - decrement!(colidx) - end + + decrementindices && decrement!(rowptr) + decrementindices && decrement!(colidx) + + # rowpointer = pointer(rowptr) + # colpointer = pointer(colidx) + # valpointer = pointer(values) + # lock(memlock) + # try + # PTRTOJL[Ptr{Cvoid}(rowpointer)] = rowptr + # PTRTOJL[Ptr{Cvoid}(colpointer)] = colidx + # PTRTOJL[Ptr{Cvoid}(valpointer)] = values + # finally + # unlock(memlock) + # end + rowptr = Ref{Ptr{LibGraphBLAS.GrB_Index}}(pointer(rowptr)) colidx = Ref{Ptr{LibGraphBLAS.GrB_Index}}(pointer(colidx)) values = Ref{Ptr{Cvoid}}(pointer(values)) desc = _handledescriptor(desc) - @wraperror LibGraphBLAS.GxB_Matrix_pack_CSC( + @wraperror LibGraphBLAS.GxB_Matrix_pack_CSR( gbpointer(A), rowptr, colidx, @@ -85,4 +133,49 @@ end function _makeshallow!(A::AbstractGBArray) ccall((:GB_make_shallow, libgraphblas), Cvoid, (LibGraphBLAS.GrB_Matrix,), gbpointer(A)) -end \ No newline at end of file +end + +function pack!(A::AbstractGBArray, M::VecOrMat; order = ColMajor(), copytoraw = true) + M = copytoraw ? _copytoraw(M) : M + if order === ColMajor() + _packdensematrix!(A, M) + else + _packdensematrixR!(A, M) + end + return A +end + +function pack!( + A::AbstractGBArray, ptr, idx, values; + order = ColMajor(), decrementindices = true, copytoraw = true +) + ptr2 = copytoraw ? _copytoraw(ptr) : ptr + idx2 = copytoraw ? _copytoraw(idx) : idx + values2 = copytoraw ? _copytoraw(values) : values + if order === ColMajor() + _packcscmatrix!(A, ptr2, idx2, values2; decrementindices) + else + _packcsrmatrix!(A, ptr2, idx2, values2; decrementindices) + end + return A +end + +function pack!(A::AbstractGBMatrix, S::SparseMatrixCSC; copytoraw = true) + pack!(A, getcolptr(S), rowvals(S), nonzeros(S); copytoraw) +end + +function pack!(A::AbstractGBArray, s::SparseVector; copytoraw = true) + pack!(A, [1, length(s.nzind) + 1], rowvals(s), nonzeros(s); copytoraw) +end + +function pack!( + ::Type{GT}, A::AbstractArray{T}; + fill = nothing, order = ColMajor(), copytoraw = true +) where {GT<:AbstractGBArray, T} + if GT <: AbstractGBVector + G = GT{T}(size(A, 1); fill) + else + G = GT{T}(size(A, 1), size(A, 2); fill) + end + return pack!(G, A; order, copytoraw) +end diff --git a/src/types.jl b/src/types.jl index fc450f0c..54ae2f85 100644 --- a/src/types.jl +++ b/src/types.jl @@ -276,4 +276,22 @@ gbpointer(A::AbstractGBArray) = A.p[] # We need to do this at runtime. This should perhaps be `RuntimeOrder`, but that trait should likely be removed. # This should ideally work out fine. a GBMatrix or GBVector won't have StorageOrders.storageorder(A::AbstractGBMatrix) = gbget(A, :format) == Integer(BYCOL) ? StorageOrders.ColMajor() : StorageOrders.RowMajor() -StorageOrders.storageorder(A::AbstractGBVector) = ColMajor() \ No newline at end of file +StorageOrders.storageorder(A::AbstractGBVector) = ColMajor() + +abstract type AbstractSparsity end +struct Dense <: AbstractSparsity end +struct Bitmap <: AbstractSparsity end +struct Sparse <: AbstractSparsity end +struct Hypersparse <: AbstractSparsity end + +shapetoconst(::Dense) = GBDENSE +shapetoconst(::Bitmap) = GBBITMAP +shapetoconst(::Sparse) = GBSPARSE +shapetoconst(::Hypersparse) = GBHYPER + +function consttoshape(c) + c == GBDENSE && (return Dense()) + c == GBBITMAP && (return Bitmap()) + c == GBSPARSE && (return Sparse()) + c == GBHYPER && (return Hypersparse()) +end \ No newline at end of file diff --git a/src/unpack.jl b/src/unpack.jl index e9df35cc..b443dcd1 100644 --- a/src/unpack.jl +++ b/src/unpack.jl @@ -1,4 +1,5 @@ function _unpackdensematrix!(A::AbstractGBArray{T}; desc = nothing) where {T} + szA = size(A) desc = _handledescriptor(desc) Csize = Ref{LibGraphBLAS.GrB_Index}(length(A) * sizeof(T)) values = Ref{Ptr{Cvoid}}(Ptr{T}()) @@ -10,10 +11,40 @@ function _unpackdensematrix!(A::AbstractGBArray{T}; desc = nothing) where {T} isiso, desc ) - return unsafe_wrap(Array{T}, Ptr{T}(values[]), size(A)) + return unsafe_wrap(Array, Ptr{T}(values[]), szA) + # lock(memlock) + # M = try + # pop!(PTRTOJL, values[]) + # finally + # unlock(memlock) + # end + # return size(A, 2) == 1 ? reshape(M, :) : reshape(M, szA) end -function _unpackcscmatrix!(A::AbstractGBArray{T}; desc = nothing, rebaseindices = true) where {T} +function _unpackdensematrixR!(A::AbstractGBArray{T}; desc = nothing) where {T} + szA = size(A) + desc = _handledescriptor(desc) + Csize = Ref{LibGraphBLAS.GrB_Index}(length(A) * sizeof(T)) + values = Ref{Ptr{Cvoid}}(Ptr{T}()) + isiso = Ref{Bool}(false) + @wraperror LibGraphBLAS.GxB_Matrix_unpack_FullR( + gbpointer(A), + values, + Csize, + isiso, + desc + ) + return unsafe_wrap(Array, values[], szA) + # lock(memlock) + # M = try + # pop!(PTRTOJL, values[]) + # finally + # unlock(memlock) + # end + # return size(A, 2) == 1 ? reshape(M, :) : reshape(M, szA) +end + +function _unpackcscmatrix!(A::AbstractGBArray{T}; desc = nothing, incrementindices = true) where {T} desc = _handledescriptor(desc) colptr = Ref{Ptr{LibGraphBLAS.GrB_Index}}() rowidx = Ref{Ptr{LibGraphBLAS.GrB_Index}}() @@ -36,43 +67,53 @@ function _unpackcscmatrix!(A::AbstractGBArray{T}; desc = nothing, rebaseindices isjumbled, desc ) - colptr = unsafe_wrap(Array{LibGraphBLAS.GrB_Index}, colptr[], size(A, 2) + 1) - rowidx = unsafe_wrap(Array{LibGraphBLAS.GrB_Index}, rowidx[], nnonzeros) - + # lock(memlock) + # colptr, rowidx = try + # (pop!(PTRTOJL, colptr[]), pop!(PTRTOJL, rowidx[])) + # finally + # unlock(memlock) + # end + # lock(memlock) + # vals = try + # pop!(PTROJL, values[]) + # finally + # unlock(memlock) + # end + colptr = unsafe_wrap(Array{Int64}, colptr[], size(A, 2) + 1) + rowidx = unsafe_wrap(Array{Int64}, rowidx[], nnonzeros) + + # if isiso[] + # vals = fill(vals[1], nnonzeros) + # end if isiso[] val = unsafe_wrap(Array{T}, Ptr{T}(values[]), 1)[1] vals = ccall(:jl_realloc, Ptr{Cvoid}, (Ptr{T}, Int64), Ptr{T}(values[]), nnonzeros * sizeof(T)) vals = unsafe_wrap(Array{T}, Ptr{T}(vals), nnonzeros) vals .= val - valsize = nnonzeros * sizeof(T) else vals = unsafe_wrap(Array{T}, Ptr{T}(values[]), nnonzeros) - valsize = valsize[] end - if rebaseindices + if incrementindices increment!(colptr) increment!(rowidx) end return colptr, - colptrsize[], rowidx, - rowidxsize[], - vals, - valsize + vals end -function _unpackcsrmatrix!(A::GBVecOrMat{T}; desc = nothing, rebaseindices = true) where {T} +function _unpackcsrmatrix!(A::AbstractGBArray{T}; desc = nothing, incrementindices = true) where {T} desc = _handledescriptor(desc) rowptr = Ref{Ptr{LibGraphBLAS.GrB_Index}}() colidx = Ref{Ptr{LibGraphBLAS.GrB_Index}}() values = Ref{Ptr{Cvoid}}(Ptr{T}()) - colidxsize = Ref{LibGraphBLAS.GrB_Index}() rowptrsize = Ref{LibGraphBLAS.GrB_Index}() + colidxsize = Ref{LibGraphBLAS.GrB_Index}() valsize = Ref{LibGraphBLAS.GrB_Index}() isiso = Ref{Bool}(false) isjumbled = C_NULL nnonzeros = nnz(A) - @wraperror LibGraphBLAS.GxB_Matrix_unpack_CSR( + @wraperror LibGraphBLAS.GxB_Matrix_unpack_CSC( gbpointer(A), rowptr, colidx, @@ -84,8 +125,24 @@ function _unpackcsrmatrix!(A::GBVecOrMat{T}; desc = nothing, rebaseindices = tru isjumbled, desc ) - rowptr = unsafe_wrap(Array{LibGraphBLAS.GrB_Index}, rowptr[],size(A, 1) + 1) - colidx = unsafe_wrap(Array{LibGraphBLAS.GrB_Index}, colidx[], nnonzeros) + # lock(memlock) + # rowptr, colidx = try + # (pop!(PTRTOJL, rowptr[]), pop!(PTRTOJL, colidx[])) + # finally + # unlock(memlock) + # end + # lock(memlock) + # vals = try + # pop!(PTROJL, values[]) + # finally + # unlock(memlock) + # end + # if isiso[] + # vals = fill(vals[1], nnonzeros) + # end + + rowptr = unsafe_wrap(Array{Int64}, rowptr[], size(A, 1) + 1) + colidx = unsafe_wrap(Array{Int64}, colidx[], nnonzeros) if isiso[] val = unsafe_wrap(Array{T}, Ptr{T}(values[]), 1)[1] @@ -97,15 +154,68 @@ function _unpackcsrmatrix!(A::GBVecOrMat{T}; desc = nothing, rebaseindices = tru vals = unsafe_wrap(Array{T}, Ptr{T}(values[]), nnonzeros) valsize = valsize[] end - if rebaseindices + + if incrementindices increment!(rowptr) increment!(colidx) end - return rowptr, - rowptrsize[], colidx, - colidxsize[], - vals, - valsize + vals +end + +function unpack!(A::AbstractGBArray{T, N, F}, ::Dense; order = ColMajor()) where {T, N, F} + if sparsitystatus(A) !== Dense() + X = similar(A) + if T === F + filler = A.fill + else + filler = zero(T) + end + if X isa GBVector + X[:] = zero(T) + else + X[:,:] = zero(T) + end + eadd!(A, X, A; mask=A, desc = Descriptor(complement_mask=true, structural_mask=true)) + gbset(A, :sparsity_control, Dense()) + end + wait(A) + if order === ColMajor() + return _unpackdensematrix!(A) + else + return _unpackdensematrixR!(A) + end end + +function unpack!(A::AbstractGBVector, ::Type{Vector}) + unpack!(A, Dense()) +end +unpack!(A::AbstractGBMatrix, ::Type{Matrix}) = unpack!(A, Dense()) + +function unpack!(A::AbstractGBArray, ::Sparse; order = ColMajor(), incrementindices = true) + wait(A) + if order === ColMajor() + return _unpackcscmatrix!(A; incrementindices) + else + return _unpackcsrmatrix!(A; incrementindices) + end +end +unpack!(A::AbstractGBArray, ::Type{SparseMatrixCSC}) = SparseMatrixCSC(size(A)..., unpack!(A, Sparse())...) + +# remove colptr for this, colptr doesn't really exist anyway, it should just be [0] (or [1] in 1-based). +function unpack!(A::AbstractGBVector, ::Type{SparseVector}) + colptr, rowidx, vals = unpack!(A, Sparse()) + _jlfree(colptr) # We need to free this dangling [0]/[1] otherwise it will leak when we repack. + # TODO: remove this when we switch to cheatmalloc. + return SparseVector(size(A)..., rowidx, vals) +end + +function unpack!(A::AbstractGBArray) + sparsity, order = format(A) + return unpack!(A, sparsity; order) +end + + +# TODO: BITMAP && HYPER +# TODO: A repack! api? \ No newline at end of file diff --git a/src/vector.jl b/src/vector.jl index fc307478..aa6e2c26 100644 --- a/src/vector.jl +++ b/src/vector.jl @@ -60,7 +60,20 @@ function GBVector(n::Integer, x::T; fill = nothing) where {T} end GBVector{T, F}(::Number) where {T, F} = throw(ArgumentError("The F parameter is implicit and determined by the `fill` keyword argument to constructors. Users must not specify this manually.")) +function GBVector(v::AbstractVector{T}; fill::F = nothing) where {T, F} + needcopy = true + if v isa AbstractVector && !(v isa Vector) + v = collect(v) + needcopy = false + end + A = GBVector{T}(size(v, 1); fill) + return pack!(A, v) # needcopy ? copy(v) : v. Currently copies within pack! +end +function GBVector(v::SparseVector{T}; fill::F = nothing) where {T, F} + A = GBVector{T}(size(v, 1); fill) + return pack!(A, v) # currently copies within pack! +end # Some Base and basic SparseArrays/LinearAlgebra functions: ########################################################### @@ -69,7 +82,7 @@ Base.unsafe_convert(::Type{LibGraphBLAS.GrB_Matrix}, v::GBVector) = v.p[] function Base.copy(A::GBVector{T, F}) where {T, F} C = Ref{LibGraphBLAS.GrB_Matrix}() LibGraphBLAS.GrB_Matrix_dup(C, gbpointer(A)) - return GBVector{T, F}(C[], A.fill) + return GBVector{T, F}(C, A.fill) end diff --git a/test/asjulia.jl b/test/asjulia.jl deleted file mode 100644 index e41ce795..00000000 --- a/test/asjulia.jl +++ /dev/null @@ -1,40 +0,0 @@ -@testset "asjulia" begin - A = [[1,2] [3,4]] - B = GBMatrix(A) - @test (A .== A) == SuiteSparseGraphBLAS.as((x) -> x .== A, Matrix, B) - SuiteSparseGraphBLAS.as(Matrix, B; dropzeros=true) do mat - mat[2, 2] = zero(eltype(mat)) - return nothing - end - - u = [1,3,5,7,9] - v = GBVector(u) - @test 25 == SuiteSparseGraphBLAS.as(Vector, v) do vec - sum(vec) - end - - A = spdiagm([1,3,5,7,9]) - B = GBMatrix(A) - @test SparseMatrixCSC(B) == A - @test 25 == SuiteSparseGraphBLAS.as(SparseMatrixCSC, B, freeunpacked=true) do mat - x = 0 - for i ∈ 1:5 - x += mat[i, i] - end - return x - end - - u = sparsevec([1,3,5,7,9], [1,2,3,4,5]) - v = GBVector(u) - @test SparseVector(v) == u - SuiteSparseGraphBLAS.as(SparseVector, v) do vec - for i ∈ 1:2:9 - vec[i] = vec[i] * 10 - end - return nothing - end - @test sum(v) == 150 - @test u .* 10 == SuiteSparseGraphBLAS.as(SparseVector, v; freeunpacked=true) do vec - copy(vec) - end -end \ No newline at end of file diff --git a/test/runtests.jl b/test/runtests.jl index 7f28bf96..99499b9f 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -71,8 +71,6 @@ println("Testing SuiteSparseGraphBLAS.jl") println("$(SuiteSparseGraphBLAS.get_lib())") @testset "SuiteSparseGraphBLAS" begin - - include_test("asjulia.jl") include_test("libutils.jl") include_test("operatorutils.jl") include_test("ops.jl") From e7cd2b87d27bf3977d7da0c9734c65da4e7a04e0 Mon Sep 17 00:00:00 2001 From: Wimmerer Date: Thu, 30 Jun 2022 14:52:25 -0400 Subject: [PATCH 2/8] fix a few unpack/pack bugs --- src/pack.jl | 10 +++++----- src/unpack.jl | 10 +++++----- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/src/pack.jl b/src/pack.jl index dcaed5f5..ba43db2e 100644 --- a/src/pack.jl +++ b/src/pack.jl @@ -149,13 +149,13 @@ function pack!( A::AbstractGBArray, ptr, idx, values; order = ColMajor(), decrementindices = true, copytoraw = true ) - ptr2 = copytoraw ? _copytoraw(ptr) : ptr - idx2 = copytoraw ? _copytoraw(idx) : idx - values2 = copytoraw ? _copytoraw(values) : values + ptr = copytoraw ? _copytoraw(ptr) : ptr + idx = copytoraw ? _copytoraw(idx) : idx + values = copytoraw ? _copytoraw(values) : values if order === ColMajor() - _packcscmatrix!(A, ptr2, idx2, values2; decrementindices) + _packcscmatrix!(A, ptr, idx, values; decrementindices) else - _packcsrmatrix!(A, ptr2, idx2, values2; decrementindices) + _packcsrmatrix!(A, ptr, idx, values; decrementindices) end return A end diff --git a/src/unpack.jl b/src/unpack.jl index b443dcd1..c1fd01bd 100644 --- a/src/unpack.jl +++ b/src/unpack.jl @@ -79,8 +79,8 @@ function _unpackcscmatrix!(A::AbstractGBArray{T}; desc = nothing, incrementindic # finally # unlock(memlock) # end - colptr = unsafe_wrap(Array{Int64}, colptr[], size(A, 2) + 1) - rowidx = unsafe_wrap(Array{Int64}, rowidx[], nnonzeros) + colptr = unsafe_wrap(Array{Int64}, Ptr{Int64}(colptr[]), size(A, 2) + 1) + rowidx = unsafe_wrap(Array{Int64}, Ptr{Int64}(rowidx[]), nnonzeros) # if isiso[] # vals = fill(vals[1], nnonzeros) @@ -113,7 +113,7 @@ function _unpackcsrmatrix!(A::AbstractGBArray{T}; desc = nothing, incrementindic isiso = Ref{Bool}(false) isjumbled = C_NULL nnonzeros = nnz(A) - @wraperror LibGraphBLAS.GxB_Matrix_unpack_CSC( + @wraperror LibGraphBLAS.GxB_Matrix_unpack_CSR( gbpointer(A), rowptr, colidx, @@ -141,8 +141,8 @@ function _unpackcsrmatrix!(A::AbstractGBArray{T}; desc = nothing, incrementindic # vals = fill(vals[1], nnonzeros) # end - rowptr = unsafe_wrap(Array{Int64}, rowptr[], size(A, 1) + 1) - colidx = unsafe_wrap(Array{Int64}, colidx[], nnonzeros) + rowptr = unsafe_wrap(Array{Int64}, Ptr{Int64}(rowptr[]), size(A, 1) + 1) + colidx = unsafe_wrap(Array{Int64}, Ptr{Int64}(colidx[]), nnonzeros) if isiso[] val = unsafe_wrap(Array{T}, Ptr{T}(values[]), 1)[1] From 1de532cc0d38096de64ac075578812e1684fcd78 Mon Sep 17 00:00:00 2001 From: Wimmerer Date: Thu, 30 Jun 2022 21:23:56 -0400 Subject: [PATCH 3/8] generate for 7.1 --- Project.toml | 2 +- src/lib/LibGraphBLAS_gen.jl | 234 +++++++++++++++++++++++++++++++++--- src/lib/Project.toml | 3 + src/lib/generator.jl | 1 + src/lib/generator.toml | 34 +++++- 5 files changed, 254 insertions(+), 20 deletions(-) diff --git a/Project.toml b/Project.toml index 709307bb..d6f7354e 100644 --- a/Project.toml +++ b/Project.toml @@ -24,7 +24,7 @@ ChainRulesCore = "1" HyperSparseMatrices = "0.2" MacroTools = "0.5" Preferences = "1" -SSGraphBLAS_jll = "6.2.1" +SSGraphBLAS_jll = "7.1.0" SpecialFunctions = "2" StorageOrders = "0.2" julia = "1.6" diff --git a/src/lib/LibGraphBLAS_gen.jl b/src/lib/LibGraphBLAS_gen.jl index ff518f03..a9c10362 100644 --- a/src/lib/LibGraphBLAS_gen.jl +++ b/src/lib/LibGraphBLAS_gen.jl @@ -1,6 +1,11 @@ module LibGraphBLAS -import ..libgraphblas -const GxB_FC64_t = ComplexF64 + +to_c_type(t::Type) = t +to_c_type_pairs(va_list) = map(enumerate(to_c_type.(va_list))) do (ind, type) + :(va_list[$ind]::$type) +end + +const GxB_FC64_t = ComplexF32 const GxB_FC32_t = ComplexF32 @@ -106,6 +111,11 @@ function GrB_Matrix_extractElement_Scalar(x, A, i, j) ccall((:GrB_Matrix_extractElement_Scalar, libgraphblas), GrB_Info, (GrB_Scalar, GrB_Matrix, GrB_Index, GrB_Index), x, A, i, j) end +# automatic type deduction for variadic arguments may not be what you want, please use with caution +@generated function GxB_Global_Option_set(field, va_list...) + :(@ccall(libgraphblas.GxB_Global_Option_set(field::GxB_Option_Field; $(to_c_type_pairs(va_list)...))::GrB_Info)) + end + @enum GxB_Option_Field::UInt32 begin GxB_HYPER_SWITCH = 0 GxB_BITMAP_SWITCH = 34 @@ -139,10 +149,45 @@ end GxB_GLOBAL_GPU_CHUNK = 22 end +# automatic type deduction for variadic arguments may not be what you want, please use with caution +@generated function GxB_Vector_Option_set(A, field, va_list...) + :(@ccall(libgraphblas.GxB_Vector_Option_set(A::GrB_Vector, field::GxB_Option_Field; $(to_c_type_pairs(va_list)...))::GrB_Info)) + end + +# automatic type deduction for variadic arguments may not be what you want, please use with caution +@generated function GxB_Matrix_Option_set(A, field, va_list...) + :(@ccall(libgraphblas.GxB_Matrix_Option_set(A::GrB_Matrix, field::GxB_Option_Field; $(to_c_type_pairs(va_list)...))::GrB_Info)) + end + mutable struct GB_Descriptor_opaque end const GrB_Descriptor = Ptr{GB_Descriptor_opaque} +# automatic type deduction for variadic arguments may not be what you want, please use with caution +@generated function GxB_Desc_set(desc, field, va_list...) + :(@ccall(libgraphblas.GxB_Desc_set(desc::GrB_Descriptor, field::GrB_Desc_Field; $(to_c_type_pairs(va_list)...))::GrB_Info)) + end + +# automatic type deduction for variadic arguments may not be what you want, please use with caution +@generated function GxB_Global_Option_get(field, va_list...) + :(@ccall(libgraphblas.GxB_Global_Option_get(field::GxB_Option_Field; $(to_c_type_pairs(va_list)...))::GrB_Info)) + end + +# automatic type deduction for variadic arguments may not be what you want, please use with caution +@generated function GxB_Vector_Option_get(A, field, va_list...) + :(@ccall(libgraphblas.GxB_Vector_Option_get(A::GrB_Vector, field::GxB_Option_Field; $(to_c_type_pairs(va_list)...))::GrB_Info)) + end + +# automatic type deduction for variadic arguments may not be what you want, please use with caution +@generated function GxB_Matrix_Option_get(A, field, va_list...) + :(@ccall(libgraphblas.GxB_Matrix_Option_get(A::GrB_Matrix, field::GxB_Option_Field; $(to_c_type_pairs(va_list)...))::GrB_Info)) + end + +# automatic type deduction for variadic arguments may not be what you want, please use with caution +@generated function GxB_Desc_get(desc, field, va_list...) + :(@ccall(libgraphblas.GxB_Desc_get(desc::GrB_Descriptor, field::GrB_Desc_Field; $(to_c_type_pairs(va_list)...))::GrB_Info)) + end + function GrB_Type_free(type) ccall((:GrB_Type_free, libgraphblas), GrB_Info, (Ptr{GrB_Type},), type) end @@ -562,13 +607,15 @@ function GB_Iterator_rc_seek(iterator, j, jth_vector) ccall((:GB_Iterator_rc_seek, libgraphblas), GrB_Info, (GxB_Iterator, GrB_Index, Bool), iterator, j, jth_vector) end -function GB_Vector_Iterator_bitmap_seek(iterator, p) - ccall((:GB_Vector_Iterator_bitmap_seek, libgraphblas), GrB_Info, (GxB_Iterator, GrB_Index), iterator, p) +function GB_Vector_Iterator_bitmap_seek(iterator, unused) + ccall((:GB_Vector_Iterator_bitmap_seek, libgraphblas), GrB_Info, (GxB_Iterator, GrB_Index), iterator, unused) end @enum GrB_Mode::UInt32 begin GrB_NONBLOCKING = 0 GrB_BLOCKING = 1 + GxB_NONBLOCKING_GPU = 2 + GxB_BLOCKING_GPU = 3 end function GrB_init(mode) @@ -1315,6 +1362,10 @@ function GrB_Vector_extractElement_UDT(x, v, i) ccall((:GrB_Vector_extractElement_UDT, libgraphblas), GrB_Info, (Ptr{Cvoid}, GrB_Vector, GrB_Index), x, v, i) end +function GxB_Vector_isStoredElement(v, i) + ccall((:GxB_Vector_isStoredElement, libgraphblas), GrB_Info, (GrB_Vector, GrB_Index), v, i) +end + function GrB_Vector_removeElement(v, i) ccall((:GrB_Vector_removeElement, libgraphblas), GrB_Info, (GrB_Vector, GrB_Index), v, i) end @@ -1587,6 +1638,10 @@ function GrB_Matrix_extractElement_UDT(x, A, i, j) ccall((:GrB_Matrix_extractElement_UDT, libgraphblas), GrB_Info, (Ptr{Cvoid}, GrB_Matrix, GrB_Index, GrB_Index), x, A, i, j) end +function GxB_Matrix_isStoredElement(A, i, j) + ccall((:GxB_Matrix_isStoredElement, libgraphblas), GrB_Info, (GrB_Matrix, GrB_Index, GrB_Index), A, i, j) +end + function GrB_Matrix_removeElement(C, i, j) ccall((:GrB_Matrix_removeElement, libgraphblas), GrB_Info, (GrB_Matrix, GrB_Index, GrB_Index), C, i, j) end @@ -1655,12 +1710,12 @@ function GxB_Matrix_split(Tiles, m, n, Tile_nrows, Tile_ncols, A, desc) ccall((:GxB_Matrix_split, libgraphblas), GrB_Info, (Ptr{GrB_Matrix}, GrB_Index, GrB_Index, Ptr{GrB_Index}, Ptr{GrB_Index}, GrB_Matrix, GrB_Descriptor), Tiles, m, n, Tile_nrows, Tile_ncols, A, desc) end -function GxB_Matrix_diag(C, v, k, desc) - ccall((:GxB_Matrix_diag, libgraphblas), GrB_Info, (GrB_Matrix, GrB_Vector, Int64, GrB_Descriptor), C, v, k, desc) +function GrB_Matrix_diag(C, v, k) + ccall((:GrB_Matrix_diag, libgraphblas), GrB_Info, (Ptr{GrB_Matrix}, GrB_Vector, Int64), C, v, k) end -function GrB_Matrix_diag(C, v, k) - ccall((:GrB_Matrix_diag, libgraphblas), GrB_Info, (GrB_Matrix, GrB_Vector, Int64), C, v, k) +function GxB_Matrix_diag(C, v, k, desc) + ccall((:GxB_Matrix_diag, libgraphblas), GrB_Info, (GrB_Matrix, GrB_Vector, Int64, GrB_Descriptor), C, v, k, desc) end function GxB_Vector_diag(v, A, k, desc) @@ -2909,21 +2964,60 @@ function GxB_Vector_Iterator_attach(iterator, v, desc) ccall((:GxB_Vector_Iterator_attach, libgraphblas), GrB_Info, (GxB_Iterator, GrB_Vector, GrB_Descriptor), iterator, v, desc) end +@enum RMM_MODE::UInt32 begin + rmm_wrap_host = 0 + rmm_wrap_host_pinned = 1 + rmm_wrap_device = 2 + rmm_wrap_managed = 3 +end + +function rmm_wrap_finalize() + ccall((:rmm_wrap_finalize, libgraphblas), Cvoid, ()) +end + +function rmm_wrap_initialize(mode, init_pool_size, max_pool_size) + ccall((:rmm_wrap_initialize, libgraphblas), Cint, (RMM_MODE, Csize_t, Csize_t), mode, init_pool_size, max_pool_size) +end + +function rmm_wrap_allocate(size) + ccall((:rmm_wrap_allocate, libgraphblas), Ptr{Cvoid}, (Ptr{Csize_t},), size) +end + +function rmm_wrap_deallocate(p, size) + ccall((:rmm_wrap_deallocate, libgraphblas), Cvoid, (Ptr{Cvoid}, Csize_t), p, size) +end + +function rmm_wrap_malloc(size) + ccall((:rmm_wrap_malloc, libgraphblas), Ptr{Cvoid}, (Csize_t,), size) +end + +function rmm_wrap_calloc(n, size) + ccall((:rmm_wrap_calloc, libgraphblas), Ptr{Cvoid}, (Csize_t, Csize_t), n, size) +end + +function rmm_wrap_realloc(p, newsize) + ccall((:rmm_wrap_realloc, libgraphblas), Ptr{Cvoid}, (Ptr{Cvoid}, Csize_t), p, newsize) +end + +function rmm_wrap_free(p) + ccall((:rmm_wrap_free, libgraphblas), Cvoid, (Ptr{Cvoid},), p) +end + # Skipping MacroDefinition: GB_PUBLIC extern -# const GxB_STDC_VERSION = __STDC_VERSION__ +const GxB_STDC_VERSION = __STDC_VERSION__ -# const GB_restrict = restrict +const GB_restrict = restrict const GxB_IMPLEMENTATION_NAME = "SuiteSparse:GraphBLAS" -const GxB_IMPLEMENTATION_DATE = "Feb 16, 2022" +const GxB_IMPLEMENTATION_DATE = "May 20, 2022" -const GxB_IMPLEMENTATION_MAJOR = 6 +const GxB_IMPLEMENTATION_MAJOR = 7 -const GxB_IMPLEMENTATION_MINOR = 2 +const GxB_IMPLEMENTATION_MINOR = 1 -const GxB_IMPLEMENTATION_SUB = 1 +const GxB_IMPLEMENTATION_SUB = 0 const GxB_SPEC_DATE = "Nov 15, 2021" @@ -2963,9 +3057,9 @@ const GRB_SUBVERSION = GxB_SPEC_MINOR #"Mathematics by Jeremy Kepner. See also 'Graph Algorithms in the Language\n" \ #"of Linear Algebra,' edited by J. Kepner and J. Gilbert, SIAM, 2011.\n" -const GrB_INDEX_MAX = GrB_Index(Culonglong(1) << 60) * (-1) +# const GrB_INDEX_MAX = (GrB_Index(Culonglong(1) << 60))(-1) -const GxB_INDEX_MAX = GrB_Index(Culonglong(1) << 60) +# const GxB_INDEX_MAX = GrB_Index(Culonglong(1) << 60) const GxB_NTHREADS = 5 @@ -3021,4 +3115,112 @@ const GxB_COMPRESSION_LZ4HC = 2000 const GxB_COMPRESSION_INTEL = 1000000 +# Skipping MacroDefinition: GB_Iterator_rc_knext ( iterator ) \ +#( /* move to the next vector, and check if iterator is exhausted */ ( ++ ( iterator -> k ) >= iterator -> anvec ) ? ( /* iterator is at the end of the matrix */ iterator -> pstart = 0 , iterator -> pend = 0 , iterator -> p = 0 , iterator -> k = iterator -> anvec , GxB_EXHAUSTED ) : ( /* find first entry in vector, and pstart/pend for this vector */ ( iterator -> A_sparsity <= GxB_SPARSE ) ? ( /* matrix is sparse or hypersparse */ iterator -> pstart = iterator -> Ap [ iterator -> k ] , iterator -> pend = iterator -> Ap [ iterator -> k + 1 ] , iterator -> p = iterator -> pstart , ( ( iterator -> p >= iterator -> pend ) ? GrB_NO_VALUE : GrB_SUCCESS ) ) : ( /* matrix is bitmap or full */ iterator -> pstart += iterator -> avlen , iterator -> pend += iterator -> avlen , iterator -> p = iterator -> pstart , ( iterator -> A_sparsity <= GxB_BITMAP ) ? ( /* matrix is bitmap */ GB_Iterator_rc_bitmap_next ( iterator ) ) : ( /* matrix is full */ ( ( iterator -> p >= iterator -> pend ) ? GrB_NO_VALUE : GrB_SUCCESS ) ) ) ) \ +#) + +# Skipping MacroDefinition: GB_Iterator_rc_inext ( iterator ) \ +#( /* move to the next entry in the vector */ ( ++ ( iterator -> p ) >= iterator -> pend ) ? ( /* no more entries in the current vector */ GrB_NO_VALUE ) : ( ( iterator -> A_sparsity == GxB_BITMAP ) ? ( /* the matrix is in bitmap form */ GB_Iterator_rc_bitmap_next ( iterator ) ) : ( GrB_SUCCESS ) ) \ +#) + +# Skipping MacroDefinition: GB_Iterator_rc_getj ( iterator ) \ +#( ( iterator -> k >= iterator -> anvec ) ? ( /* iterator is past the end of the matrix */ iterator -> avdim ) : ( ( iterator -> A_sparsity == GxB_HYPERSPARSE ) ? ( /* return the name of kth vector: j = Ah [k] if it appears */ iterator -> Ah [ iterator -> k ] ) : ( /* return the kth vector: j = k */ iterator -> k ) ) \ +#) + +# Skipping MacroDefinition: GB_Iterator_rc_geti ( iterator ) \ +#( ( iterator -> Ai != NULL ) ? ( iterator -> Ai [ iterator -> p ] ) : ( ( iterator -> p - iterator -> pstart ) ) \ +#) + +# Skipping MacroDefinition: GxB_rowIterator_attach ( iterator , A , desc ) \ +#( GB_Iterator_attach ( iterator , A , GxB_BY_ROW , desc ) \ +#) + +# Skipping MacroDefinition: GxB_rowIterator_kount ( iterator ) \ +#( ( iterator ) -> anvec \ +#) + +# Skipping MacroDefinition: GxB_rowIterator_seekRow ( iterator , row ) \ +#( GB_Iterator_rc_seek ( iterator , row , false ) \ +#) + +# Skipping MacroDefinition: GxB_rowIterator_kseek ( iterator , k ) \ +#( GB_Iterator_rc_seek ( iterator , k , true ) \ +#) + +# Skipping MacroDefinition: GxB_rowIterator_nextRow ( iterator ) \ +#( GB_Iterator_rc_knext ( iterator ) \ +#) + +# Skipping MacroDefinition: GxB_rowIterator_nextCol ( iterator ) \ +#( GB_Iterator_rc_inext ( ( iterator ) ) \ +#) + +# Skipping MacroDefinition: GxB_rowIterator_getRowIndex ( iterator ) \ +#( GB_Iterator_rc_getj ( ( iterator ) ) \ +#) + +# Skipping MacroDefinition: GxB_rowIterator_getColIndex ( iterator ) \ +#( GB_Iterator_rc_geti ( ( iterator ) ) \ +#) + +# Skipping MacroDefinition: GxB_colIterator_attach ( iterator , A , desc ) \ +#( GB_Iterator_attach ( iterator , A , GxB_BY_COL , desc ) \ +#) + +# Skipping MacroDefinition: GxB_colIterator_kount ( iterator ) \ +#( ( iterator ) -> anvec \ +#) + +# Skipping MacroDefinition: GxB_colIterator_seekCol ( iterator , col ) \ +#( GB_Iterator_rc_seek ( iterator , col , false ) \ +#) + +# Skipping MacroDefinition: GxB_colIterator_kseek ( iterator , k ) \ +#( GB_Iterator_rc_seek ( iterator , k , true ) \ +#) + +# Skipping MacroDefinition: GxB_colIterator_nextCol ( iterator ) \ +#( GB_Iterator_rc_knext ( ( iterator ) ) \ +#) + +# Skipping MacroDefinition: GxB_colIterator_nextRow ( iterator ) \ +#( GB_Iterator_rc_inext ( ( iterator ) ) \ +#) + +# Skipping MacroDefinition: GxB_colIterator_getColIndex ( iterator ) \ +#( GB_Iterator_rc_getj ( ( iterator ) ) \ +#) + +# Skipping MacroDefinition: GxB_colIterator_getRowIndex ( iterator ) \ +#( GB_Iterator_rc_geti ( ( iterator ) ) \ +#) + +# Skipping MacroDefinition: GxB_Vector_Iterator_getpmax ( iterator ) \ +#( ( iterator -> pmax ) \ +#) + +# Skipping MacroDefinition: GB_Vector_Iterator_seek ( iterator , q ) \ +#( ( q >= iterator -> pmax ) ? ( /* the iterator is exhausted */ iterator -> p = iterator -> pmax , GxB_EXHAUSTED ) : ( /* seek to an arbitrary position in the vector */ iterator -> p = q , ( iterator -> A_sparsity == GxB_BITMAP ) ? ( GB_Vector_Iterator_bitmap_seek ( iterator , 0 ) ) : ( GrB_SUCCESS ) ) \ +#) + +# Skipping MacroDefinition: GxB_Vector_Iterator_seek ( iterator , p ) \ +#( GB_Vector_Iterator_seek ( iterator , p ) \ +#) + +# Skipping MacroDefinition: GB_Vector_Iterator_next ( iterator ) \ +#( /* move to the next entry */ ( ++ ( iterator -> p ) >= iterator -> pmax ) ? ( /* the iterator is exhausted */ iterator -> p = iterator -> pmax , GxB_EXHAUSTED ) : ( ( iterator -> A_sparsity == GxB_BITMAP ) ? ( /* bitmap: seek to the next entry present in the bitmap */ GB_Vector_Iterator_bitmap_seek ( iterator , 0 ) ) : ( /* other formats: already at the next entry */ GrB_SUCCESS ) ) \ +#) + +# Skipping MacroDefinition: GxB_Vector_Iterator_next ( iterator ) \ +#( GB_Vector_Iterator_next ( iterator ) \ +#) + +# Skipping MacroDefinition: GxB_Vector_Iterator_getp ( iterator ) \ +#( ( iterator -> p ) \ +#) + +# Skipping MacroDefinition: GxB_Vector_Iterator_getIndex ( iterator ) \ +#( ( ( iterator -> Ai != NULL ) ? iterator -> Ai [ iterator -> p ] : iterator -> p ) \ +#) + end # module diff --git a/src/lib/Project.toml b/src/lib/Project.toml index 72a96b23..aab5c176 100644 --- a/src/lib/Project.toml +++ b/src/lib/Project.toml @@ -1,3 +1,6 @@ [deps] Clang = "40e3b903-d033-50b4-a0cc-940c62c95e31" SSGraphBLAS_jll = "7ed9a814-9cab-54e9-8e9e-d9e95b4d61b1" + +[compat] +SSGraphBLAS_jll = "7.1.0" \ No newline at end of file diff --git a/src/lib/generator.jl b/src/lib/generator.jl index 80b6e97b..d3ee6350 100644 --- a/src/lib/generator.jl +++ b/src/lib/generator.jl @@ -10,6 +10,7 @@ headers = [GRAPHBLAS] options = load_options(joinpath(@__DIR__, "generator.toml")) args = get_default_args() +push!(args, "-fparse-all-comments") push!(args, "-I$HEADER_BASE") ctx = create_context(headers, args, options) diff --git a/src/lib/generator.toml b/src/lib/generator.toml index 2424b358..d7d95165 100644 --- a/src/lib/generator.toml +++ b/src/lib/generator.toml @@ -1,12 +1,40 @@ [general] library_name = "libgraphblas" module_name = "LibGraphBLAS" -#prologue_file_path = "./prologue.jl" output_file_path = "./LibGraphBLAS_gen.jl" -#epilogue_file_path = "./epilogue.jl" use_julia_native_enum_type = true [codegen] opaque_as_mutable_struct = true +wrap_variadic_function = true [codegen.macro] -macro_mode = "basic" \ No newline at end of file +macro_mode = "basic" +functionlike_macro_includelist = [ + "GB_Iterator_rc_knext", + "GB_Iterator_rc_inext", + "GB_Iterator_rc_getj", + "GB_Iterator_rc_geti", + "GxB_rowIterator_attach", + "GxB_rowIterator_kount", + "GxB_rowIterator_seekRow", + "GxB_rowIterator_kseek", + "GxB_rowIterator_nextRow", + "GxB_rowIterator_nextCol", + "GxB_rowIterator_getRowIndex", + "GxB_rowIterator_getColIndex", + "GxB_colIterator_attach", + "GxB_colIterator_kount", + "GxB_colIterator_seekCol", + "GxB_colIterator_kseek", + "GxB_colIterator_nextCol", + "GxB_colIterator_nextRow", + "GxB_colIterator_getColIndex", + "GxB_colIterator_getRowIndex", + "GxB_Vector_Iterator_getpmax", + "GB_Vector_Iterator_seek", + "GxB_Vector_Iterator_seek", + "GB_Vector_Iterator_next", + "GxB_Vector_Iterator_next", + "GxB_Vector_Iterator_getp", + "GxB_Vector_Iterator_getIndex", +] \ No newline at end of file From f6a8ef58adac0fa170fd80e198ca461a20ee6f8e Mon Sep 17 00:00:00 2001 From: Wimmerer Date: Thu, 30 Jun 2022 21:30:48 -0400 Subject: [PATCH 4/8] rm macros --- src/lib/LibGraphBLAS_gen.jl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/lib/LibGraphBLAS_gen.jl b/src/lib/LibGraphBLAS_gen.jl index a9c10362..9fbff13e 100644 --- a/src/lib/LibGraphBLAS_gen.jl +++ b/src/lib/LibGraphBLAS_gen.jl @@ -3005,9 +3005,9 @@ end # Skipping MacroDefinition: GB_PUBLIC extern -const GxB_STDC_VERSION = __STDC_VERSION__ +# const GxB_STDC_VERSION = __STDC_VERSION__ -const GB_restrict = restrict +# const GB_restrict = restrict const GxB_IMPLEMENTATION_NAME = "SuiteSparse:GraphBLAS" From 9dca60817f70ab3dc24d2724a2e702e54c283cc9 Mon Sep 17 00:00:00 2001 From: Wimmerer Date: Thu, 30 Jun 2022 21:32:54 -0400 Subject: [PATCH 5/8] libgraphblas missing --- src/lib/LibGraphBLAS_gen.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lib/LibGraphBLAS_gen.jl b/src/lib/LibGraphBLAS_gen.jl index 9fbff13e..4653cf08 100644 --- a/src/lib/LibGraphBLAS_gen.jl +++ b/src/lib/LibGraphBLAS_gen.jl @@ -1,5 +1,5 @@ module LibGraphBLAS - +using ..libgraphblas to_c_type(t::Type) = t to_c_type_pairs(va_list) = map(enumerate(to_c_type.(va_list))) do (ind, type) :(va_list[$ind]::$type) From 7cd7f47eb29b6d36c9aebfed4ada3a8c43da9399 Mon Sep 17 00:00:00 2001 From: Wimmerer Date: Thu, 30 Jun 2022 21:35:20 -0400 Subject: [PATCH 6/8] import rather than using --- src/lib/LibGraphBLAS_gen.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lib/LibGraphBLAS_gen.jl b/src/lib/LibGraphBLAS_gen.jl index 4653cf08..62f337f5 100644 --- a/src/lib/LibGraphBLAS_gen.jl +++ b/src/lib/LibGraphBLAS_gen.jl @@ -1,5 +1,5 @@ module LibGraphBLAS -using ..libgraphblas +import ..libgraphblas to_c_type(t::Type) = t to_c_type_pairs(va_list) = map(enumerate(to_c_type.(va_list))) do (ind, type) :(va_list[$ind]::$type) From 51e04b0d9157eb039ceb74e275902a6402cdb417 Mon Sep 17 00:00:00 2001 From: Wimmerer Date: Thu, 30 Jun 2022 23:07:25 -0400 Subject: [PATCH 7/8] fix extra copy and leak --- src/abstractgbarray.jl | 55 ++++++++++++++++++------------------------ src/mem.jl | 8 +++--- 2 files changed, 28 insertions(+), 35 deletions(-) diff --git a/src/abstractgbarray.jl b/src/abstractgbarray.jl index 7c8f2ad9..8292331e 100644 --- a/src/abstractgbarray.jl +++ b/src/abstractgbarray.jl @@ -23,7 +23,7 @@ function Base.Matrix(A::AbstractGBMatrix) T = sparsity === Dense() ? A : copy(A) # If A is not dense we need to copy to avoid densifying x = unpack!(T, Dense()) C = copy(x) - pack!(T, x) + pack!(T, x; copytoraw = false) return C end @@ -32,7 +32,7 @@ function Base.Vector(v::AbstractGBVector) T = sparsity === Dense() ? v : copy(v) # If A is not dense we need to copy to avoid densifying x = unpack!(T, Dense()) C = copy(x) - pack!(T, x) + pack!(T, x; copytoraw = false) return C end @@ -41,7 +41,7 @@ function SparseArrays.SparseMatrixCSC(A::AbstractGBArray) T = sparsity === Sparse() ? A : copy(A) x = unpack!(T, SparseMatrixCSC) C = copy(x) - pack!(T, x) + pack!(T, x; copytoraw = false) return C end @@ -276,21 +276,16 @@ for T ∈ valid_vec return x end end - # TODO: Update when upstream. - # this is less than ideal. But required for isstored. - # a new version of graphBLAS will replace this with Matrix_extractElement_Structural - func = Symbol(prefix, :_Matrix_extractElement_, suffix(T)) - @eval begin - function Base.isstored(A::AbstractGBMatrix{$T}, i::Int, j::Int) - result = LibGraphBLAS.$func(Ref{$T}(), gbpointer(A), decrement!(i), decrement!(j)) - if result == LibGraphBLAS.GrB_SUCCESS - true - elseif result == LibGraphBLAS.GrB_NO_VALUE - false - else - @wraperror result - end - end +end + +function Base.isstored(A::AbstractGBMatrix, i::Int, j::Int) + result = LibGraphBLAS.GxB_Matrix_isStoredElement(gbpointer(A), decrement!(i), decrement!(j)) + if result == LibGraphBLAS.GrB_SUCCESS + true + elseif result == LibGraphBLAS.GrB_NO_VALUE + false + else + @wraperror result end end @@ -305,19 +300,6 @@ function _assign(C::AbstractGBMatrix{T}, x::T, I, ni, J, nj, mask, accum, desc) @wraperror LibGraphBLAS.GrB_Matrix_assign_UDT(C, mask, accum, in, I, ni, J, nj, desc) return x end -# TODO: Update when upstream. -# this is less than ideal. But required for isstored. -# a new version of graphBLAS will replace this with Matrix_extractElement_Structural -function Base.isstored(A::AbstractGBMatrix{T}, i::Int, j::Int) where {T} - result = LibGraphBLAS.GrB_Matrix_extractElement_UDT(Ref{T}(), gbpointer(A), decrement!(i), decrement!(j)) - if result == LibGraphBLAS.GrB_SUCCESS - true - elseif result == LibGraphBLAS.GrB_NO_VALUE - false - else - @wraperror result - end -end # subassign fallback for Matrix <- Matrix, and Matrix <- Vector @@ -591,6 +573,17 @@ for T ∈ valid_vec end end +function Base.isstored(v::AbstractGBVector, i::Int) + result = LibGraphBLAS.GxB_Matrix_isStoredElement(gbpointer(v), decrement!(i), 0) + if result == LibGraphBLAS.GrB_SUCCESS + true + elseif result == LibGraphBLAS.GrB_NO_VALUE + false + else + @wraperror result + end +end + # UDT versions of Vector functions, which just require one def of each. function build(v::AbstractGBVector{T}, I::Vector{<:Integer}, X::Vector{T}; combine = +) where {T} diff --git a/src/mem.jl b/src/mem.jl index 7c40ce5c..3cde918c 100644 --- a/src/mem.jl +++ b/src/mem.jl @@ -1,5 +1,5 @@ -function _jlmalloc(size) - return ccall(:jl_malloc, Ptr{Cvoid}, (UInt, ), size) +function _jlmalloc(size, ::Type{T}) where {T} + return ccall(:jl_malloc, Ptr{T}, (UInt, ), size) end function _jlfree(p::Union{DenseVecOrMat{T}, Ptr{T}, Ref{T}}) where {T} ccall(:jl_free, Cvoid, (Ptr{T}, ), p isa DenseVecOrMat ? pointer(p) : p) @@ -7,8 +7,8 @@ end function _copytorawptr(A::DenseVecOrMat{T}) where {T} sz = sizeof(A) - ptr = _jlmalloc(sz) - ptr = Ptr{T}(ptr) + ptr = _jlmalloc(sz, T) + ptr = ptr unsafe_copyto!(ptr, pointer(A), length(A)) return ptr end From 2844a671caea0231f0e850382bd5cdf1d0b4dd03 Mon Sep 17 00:00:00 2001 From: Wimmerer Date: Sat, 2 Jul 2022 02:36:27 -0400 Subject: [PATCH 8/8] missing vector constructor --- src/abstractgbarray.jl | 8 ++++++++ src/pack.jl | 2 +- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/src/abstractgbarray.jl b/src/abstractgbarray.jl index 8292331e..70a4e097 100644 --- a/src/abstractgbarray.jl +++ b/src/abstractgbarray.jl @@ -45,6 +45,14 @@ function SparseArrays.SparseMatrixCSC(A::AbstractGBArray) return C end +function SparseArrays.SparseVector(v::AbstractGBVector) + sparsity = sparsitystatus(v) + T = sparsity === Sparse() ? A : copy(A) + x = unpack!(T, SparseVector) + C = copy(x) + pack!(T, x; copytoraw = false) + return C +end # AbstractGBMatrix functions: ############################# diff --git a/src/pack.jl b/src/pack.jl index ba43db2e..715636aa 100644 --- a/src/pack.jl +++ b/src/pack.jl @@ -169,7 +169,7 @@ function pack!(A::AbstractGBArray, s::SparseVector; copytoraw = true) end function pack!( - ::Type{GT}, A::AbstractArray{T}; + ::Type{GT}, A::AbstractArray{T}; fill = nothing, order = ColMajor(), copytoraw = true ) where {GT<:AbstractGBArray, T} if GT <: AbstractGBVector