diff --git a/Project.toml b/Project.toml index 6a968e50..a0db0464 100644 --- a/Project.toml +++ b/Project.toml @@ -5,7 +5,6 @@ version = "0.5.0" [deps] ChainRulesCore = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4" -FiniteDifferences = "26cc04aa-876d-5657-8c51-4c34ba976000" Libdl = "8f399da3-3557-5675-b5ff-fb832c97cbdb" LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e" MacroTools = "1914dd2f-81c6-5fcd-8719-6d5c9610ff09" @@ -18,9 +17,8 @@ SuiteSparse = "4607b0f0-06f3-5cda-b6b1-a6196a1729e9" [compat] ChainRulesCore = "1" -FiniteDifferences = "0.12" MacroTools = "0.5" Preferences = "1" -SSGraphBLAS_jll = "6.0" +SSGraphBLAS_jll = "6.2.1" SpecialFunctions = "2" julia = "1.6" diff --git a/src/SuiteSparseGraphBLAS.jl b/src/SuiteSparseGraphBLAS.jl index 5218cc36..3a57f42c 100644 --- a/src/SuiteSparseGraphBLAS.jl +++ b/src/SuiteSparseGraphBLAS.jl @@ -23,15 +23,15 @@ using SpecialFunctions: lgamma, gamma, erf, erfc using Base.Broadcast include("abstracts.jl") include("libutils.jl") -include("lib/LibGraphBLAS.jl") -using .libgb -include("operators/libgbops.jl") -# Globals +include("lib/LibGraphBLAS_gen.jl") +using .LibGraphBLAS +include("operators/libgbops.jl") -include("types.jl") include("gbtypes.jl") +include("types.jl") + include("constants.jl") @@ -88,7 +88,7 @@ include("asjulia.jl") include("spmgb/sparsemat.jl") export SparseArrayCompat -export libgb +export LibGraphBLAS export UnaryOps, BinaryOps, Monoids, Semirings #Submodules export UnaryOp, BinaryOp, Monoid, Semiring #UDFs export Descriptor #Types @@ -124,19 +124,19 @@ function __init__() #The artifact does dlopen for us. libgraphblas_handle[] = SSGraphBLAS_jll.libgraphblas_handle end - _load_globaltypes() # We initialize GraphBLAS by giving it Julia's GC wrapped memory management functions. # In the future this should hopefully allow us to do no-copy passing of arrays between Julia and SS:GrB. # In the meantime it helps Julia respond to memory pressure from SS:GrB and finalize things in a timely fashion. - libgb.GxB_init(libgb.GrB_NONBLOCKING, cglobal(:jl_malloc), cglobal(:jl_calloc), cglobal(:jl_realloc), cglobal(:jl_free)) + @wraperror LibGraphBLAS.GxB_init(LibGraphBLAS.GrB_NONBLOCKING, cglobal(:jl_malloc), cglobal(:jl_calloc), cglobal(:jl_realloc), cglobal(:jl_free)) gbset(:nthreads, Sys.CPU_THREADS ÷ 2) # Eagerly load selectops constants. _loadselectops() + ALL.p = load_global("GrB_ALL", LibGraphBLAS.GrB_Index) # Set printing done by SuiteSparse:GraphBLAS to base-1 rather than base-0. gbset(BASE1, 1) atexit() do # Finalize the lib, for now only frees a small internal memory pool. - libgb.GrB_finalize() + @wraperror LibGraphBLAS.GrB_finalize() @static if artifact_or_path != "default" dlclose(libgraphblas_handle[]) end diff --git a/src/asjulia.jl b/src/asjulia.jl index 201f919f..9e4bfb09 100644 --- a/src/asjulia.jl +++ b/src/asjulia.jl @@ -33,13 +33,11 @@ function asCSCVectors(f::Function, A::GBMatrix{T}; freeunpacked=false) where {T} result = try f(colptr, rowidx, values, A) finally - println("I'm finally") if freeunpacked - ccall(:jl_free, Cvoid, (Ptr{libgb.GrB_Index},), pointer(colptr)) - ccall(:jl_free, Cvoid, (Ptr{libgb.GrB_Index},), pointer(rowidx)) + 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 - println("I repacked!") _packcscmatrix!(A, colptr, rowidx, values) end end @@ -52,8 +50,8 @@ function asCSRVectors(f::Function, A::GBMatrix{T}; freeunpacked=false) where {T} f(rowptr, colidx, values, A) finally if freeunpacked - ccall(:jl_free, Cvoid, (Ptr{libgb.GrB_Index},), pointer(rowptr)) - ccall(:jl_free, Cvoid, (Ptr{libgb.GrB_Index},), pointer(colidx)) + ccall(:jl_free, Cvoid, (Ptr{LibGraphBLAS.GrB_Index},), pointer(rowptr)) + ccall(:jl_free, Cvoid, (Ptr{LibGraphBLAS.GrB_Index},), pointer(colidx)) ccall(:jl_free, Cvoid, (Ptr{T},), pointer(values)) else _packcsrmatrix!(A, rowptr, colidx, values) @@ -64,13 +62,13 @@ end function asSparseMatrixCSC(f::Function, A::GBMatrix{T}; freeunpacked=false) where {T} colptr, rowidx, values = _unpackcscmatrix!(A) - array = SparseMatrixCSC{T, libgb.GrB_Index}(size(A, 1), size(A, 2), colptr, rowidx, values) + array = SparseMatrixCSC{T, LibGraphBLAS.GrB_Index}(size(A, 1), size(A, 2), colptr, rowidx, values) result = try f(array, A) finally if freeunpacked - ccall(:jl_free, Cvoid, (Ptr{libgb.GrB_Index},), pointer(colptr)) - ccall(:jl_free, Cvoid, (Ptr{libgb.GrB_Index},), pointer(rowidx)) + 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) @@ -81,13 +79,13 @@ end function asSparseVector(f::Function, A::GBVector{T}; freeunpacked=false) where {T} colptr, rowidx, values = _unpackcscmatrix!(A) - vector = SparseVector{T, libgb.GrB_Index}(size(A, 1), rowidx, values) + vector = SparseVector{T, LibGraphBLAS.GrB_Index}(size(A, 1), rowidx, values) result = try f(vector, A) finally if freeunpacked - ccall(:jl_free, Cvoid, (Ptr{libgb.GrB_Index},), pointer(colptr)) - ccall(:jl_free, Cvoid, (Ptr{libgb.GrB_Index},), pointer(rowidx)) + 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) diff --git a/src/chainrules/chainruleutils.jl b/src/chainrules/chainruleutils.jl index ff2ac056..cb71c792 100644 --- a/src/chainrules/chainruleutils.jl +++ b/src/chainrules/chainruleutils.jl @@ -1,27 +1,7 @@ -using FiniteDifferences import LinearAlgebra import ChainRulesCore: frule, rrule using ChainRulesCore const RealOrComplex = Union{Real, Complex} -#Required for ChainRulesTestUtils -function FiniteDifferences.to_vec(M::GBMatrix) - x, back = FiniteDifferences.to_vec(Matrix(M)) - function backtomat(xvec) - M2 = GBMatrix(back(xvec)) - return mask(M2, M; structural=true) - end - return x, backtomat -end - -function FiniteDifferences.to_vec(v::GBVector) - x, back = FiniteDifferences.to_vec(Vector(v)) - function backtovec(xvec) - v2 = GBVector(back(xvec)) - return mask(v2, v; structural=true) - end - return x, backtovec -end - # LinearAlgebra.norm doesn't like the nothings. LinearAlgebra.norm(A::GBArray, p::Real=2) = norm(nonzeros(A), p) diff --git a/src/constants.jl b/src/constants.jl index 63d62907..59555ea0 100644 --- a/src/constants.jl +++ b/src/constants.jl @@ -2,14 +2,14 @@ const GBVecOrMat{T} = Union{GBVector{T}, GBMatrix{T}} const GBMatOrTranspose{T} = Union{GBMatrix{T}, Transpose{T, GBMatrix{T}}} const GBVecOrTranspose{T} = Union{GBVector{T}, Transpose{T, GBVector{T}}} const GBArray{T} = Union{GBVecOrTranspose{T}, GBMatOrTranspose{T}} -const ptrtogbtype = Dict{Ptr, AbstractGBType}() +const ptrtogbtype = IdDict{Ptr, GBType}() const GrBOp = Union{ - libgb.GrB_Monoid, - libgb.GrB_UnaryOp, - libgb.GrB_Semiring, - libgb.GrB_BinaryOp, - libgb.GxB_SelectOp + LibGraphBLAS.GrB_Monoid, + LibGraphBLAS.GrB_UnaryOp, + LibGraphBLAS.GrB_Semiring, + LibGraphBLAS.GrB_BinaryOp, + LibGraphBLAS.GxB_SelectOp } const TypedOp = Union{ @@ -32,3 +32,5 @@ const OperatorUnion = Union{ AbstractOp, GrBOp } + +const ALL = GBAllType(C_NULL) \ No newline at end of file diff --git a/src/descriptors.jl b/src/descriptors.jl index 427f0fca..640e6480 100644 --- a/src/descriptors.jl +++ b/src/descriptors.jl @@ -14,83 +14,140 @@ a function, defaults to avoid hyperthreading, which is typically most performant """ mutable struct Descriptor <: AbstractDescriptor name::String - p::libgb.GrB_Descriptor - function Descriptor(name, p::libgb.GrB_Descriptor) + p::LibGraphBLAS.GrB_Descriptor + function Descriptor(name, p::LibGraphBLAS.GrB_Descriptor) d = new(name, p) function f(descriptor) - libgb.GrB_Descriptor_free(Ref(descriptor.p)) + LibGraphBLAS.GrB_Descriptor_free(Ref(descriptor.p)) end return finalizer(f, d) end end function Descriptor(;kwargs...) - desc = Descriptor("", libgb.GrB_Descriptor_new()) + d = Ref{LibGraphBLAS.GrB_Descriptor}() + @wraperror LibGraphBLAS.GrB_Descriptor_new(d) + desc = Descriptor("", d[]) for (s, x) in kwargs setproperty!(desc, s, x) end return desc end -Base.unsafe_convert(::Type{libgb.GrB_Descriptor}, d::Descriptor) = d.p +Base.unsafe_convert(::Type{LibGraphBLAS.GrB_Descriptor}, d::Descriptor) = d.p + +# Todo: improve these. They can't be wrapped by ccall because they're "generic"? +# Or at least not wrapped by Clang.jl +function GxB_Desc_get(desc, field) + if field ∈ [LibGraphBLAS.GrB_OUTP, LibGraphBLAS.GrB_MASK, LibGraphBLAS.GrB_INP0, LibGraphBLAS.GrB_INP1] + T = LibGraphBLAS.GrB_Desc_Value + elseif field ∈ [LibGraphBLAS.GxB_DESCRIPTOR_NTHREADS, LibGraphBLAS.GxB_AxB_METHOD, LibGraphBLAS.GxB_SORT] + T = Cint + elseif field ∈ [LibGraphBLAS.GxB_DESCRIPTOR_CHUNK] + T = Cdouble + else + error("Not a valid Descriptor option.") + end + v = Ref{T}() + @wraperror ccall( + (:GxB_Desc_get, libgraphblas), + LibGraphBLAS.GrB_Info, + (LibGraphBLAS.GrB_Descriptor, UInt32, Ptr{Cvoid}), + desc, + field, + v + ) + return v[] +end + +function GxB_Desc_set(d, field, value) + if field ∈ [LibGraphBLAS.GrB_OUTP, LibGraphBLAS.GrB_MASK, LibGraphBLAS.GrB_INP0, LibGraphBLAS.GrB_INP1] + @wraperror ccall( + (:GxB_Desc_set, libgraphblas), + LibGraphBLAS.GrB_Info, + (LibGraphBLAS.GrB_Descriptor, LibGraphBLAS.GrB_Desc_Field, LibGraphBLAS.GrB_Desc_Value), + d, + field, + value + ) + elseif field ∈ [LibGraphBLAS.GxB_DESCRIPTOR_NTHREADS, LibGraphBLAS.GxB_AxB_METHOD, LibGraphBLAS.GxB_SORT] + @wraperror ccall( + (:GxB_Desc_set, libgraphblas), + LibGraphBLAS.GrB_Info, + (LibGraphBLAS.GrB_Descriptor, LibGraphBLAS.GrB_Desc_Field, Cint), + d, + field, + value + ) + elseif field ∈ [LibGraphBLAS.GxB_DESCRIPTOR_CHUNK] + @wraperror ccall( + (:GxB_Desc_set, libgraphblas), + LibGraphBLAS.GrB_Info, + (LibGraphBLAS.GrB_Descriptor, LibGraphBLAS.GrB_Desc_Field, Cdouble), + d, + field, + value + ) + end +end function Base.getproperty(d::Descriptor, s::Symbol) if s === :p return getfield(d, s) elseif s === :replace_output - x = libgb.GxB_Desc_get(d, libgb.GrB_OUTP) - if x == libgb.GrB_REPLACE + x = GxB_Desc_get(d, LibGraphBLAS.GrB_OUTP) + if x == LibGraphBLAS.GrB_REPLACE return true else return false end elseif s === :complement_mask - x = libgb.GxB_Desc_get(d, libgb.libgb.GrB_MASK) - if x == libgb.GrB_COMP || x == libgb.GrB_STRUCT_COMP + x = GxB_Desc_get(d, LibGraphBLAS.GrB_MASK) + if x == LibGraphBLAS.GrB_COMP || x == LibGraphBLAS.GrB_STRUCT_COMP return true else return false end elseif s === :structural_mask - x = libgb.GxB_Desc_get(d, libgb.GrB_MASK) - if x == libgb.GrB_STRUCTURE || x == libgb.GrB_STRUCT_COMP + x = GxB_Desc_get(d, LibGraphBLAS.GrB_MASK) + if x == LibGraphBLAS.GrB_STRUCTURE || x == LibGraphBLAS.GrB_STRUCT_COMP return true else return false end elseif s === :transpose_input1 - x = libgb.GxB_Desc_get(d, libgb.GrB_INP0) - if x == libgb.GrB_TRAN + x = GxB_Desc_get(d, LibGraphBLAS.GrB_INP0) + if x == LibGraphBLAS.GrB_TRAN return true else return false end elseif s === :transpose_input2 - x = libgb.GxB_Desc_get(d, libgb.GrB_INP1) - if x == libgb.GrB_TRAN + x = GxB_Desc_get(d, LibGraphBLAS.GrB_INP1) + if x == LibGraphBLAS.GrB_TRAN return true else return false end elseif s === :nthreads - return libgb.GxB_Desc_get(d, libgb.GxB_DESCRIPTOR_NTHREADS) + return GxB_Desc_get(d, LibGraphBLAS.GxB_DESCRIPTOR_NTHREADS) elseif s === :chunk - return libgb.GxB_Desc_get(d, libgb.GxB_DESCRIPTOR_CHUNK) + return GxB_Desc_get(d, LibGraphBLAS.GxB_DESCRIPTOR_CHUNK) elseif s === :sort - if libgb.GxB_Desc_get(d, libgb.GxB_SORT) == libgb.GxB_DEFAULT + if GxB_Desc_get(d, LibGraphBLAS.GxB_SORT) == LibGraphBLAS.GxB_DEFAULT return false else return true end elseif s === :axb_method - x = libgb.GxB_Desc_get(d, libgb.GxB_AxB_METHOD) - if x == libgb.GxB_AxB_GUSTAVSON + x = GxB_Desc_get(d, LibGraphBLAS.GxB_AxB_METHOD) + if x == LibGraphBLAS.GxB_AxB_GUSTAVSON return :gustavson - elseif x == libgb.GxB_AxB_DOT + elseif x == LibGraphBLAS.GxB_AxB_DOT return :dot - elseif x == libgb.AxB_HASH + elseif x == LibGraphBLAS.AxB_HASH return :hash - elseif x == libgb.GxB_AxB_SAXPY + elseif x == LibGraphBLAS.GxB_AxB_SAXPY return :saxpy else return :default @@ -105,38 +162,38 @@ function Base.setproperty!(d::Descriptor, s::Symbol, x) setfield!(d, s, x) return nothing elseif s === :replace_output - x ? (y = libgb.GrB_REPLACE) : (y = libgb.GxB_DEFAULT) - libgb.GxB_Desc_set(d, libgb.GrB_OUTP, y) + x ? (y = LibGraphBLAS.GrB_REPLACE) : (y = LibGraphBLAS.GxB_DEFAULT) + GxB_Desc_set(d, LibGraphBLAS.GrB_OUTP, y) elseif s === :complement_mask if x == false if d.structural_mask - libgb.GxB_Desc_set(d, libgb.GrB_MASK, libgb.GrB_STRUCTURE) + GxB_Desc_set(d, LibGraphBLAS.GrB_MASK, LibGraphBLAS.GrB_STRUCTURE) else - libgb.GxB_Desc_set(d, libgb.GrB_MASK, libgb.GxB_DEFAULT) + GxB_Desc_set(d, LibGraphBLAS.GrB_MASK, LibGraphBLAS.GxB_DEFAULT) end else - libgb.GxB_Desc_set(d, libgb.GrB_MASK, libgb.GrB_COMP) + GxB_Desc_set(d, LibGraphBLAS.GrB_MASK, LibGraphBLAS.GrB_COMP) end elseif s === :structural_mask if x == false if d.complement_mask - libgb.GxB_Desc_set(d, libgb.GrB_MASK, libgb.GrB_COMP) + GxB_Desc_set(d, LibGraphBLAS.GrB_MASK, LibGraphBLAS.GrB_COMP) else - libgb.GxB_Desc_set(d, libgb.GrB_MASK, libgb.GxB_DEFAULT) + GxB_Desc_set(d, LibGraphBLAS.GrB_MASK, LibGraphBLAS.GxB_DEFAULT) end else - libgb.GxB_Desc_set(d, libgb.GrB_MASK, libgb.GrB_STRUCTURE) + GxB_Desc_set(d, LibGraphBLAS.GrB_MASK, LibGraphBLAS.GrB_STRUCTURE) end elseif s === :transpose_input1 - libgb.GxB_Desc_set(d, libgb.GrB_INP0, x ? libgb.GrB_TRAN : libgb.GxB_DEFAULT) + GxB_Desc_set(d, LibGraphBLAS.GrB_INP0, x ? LibGraphBLAS.GrB_TRAN : LibGraphBLAS.GxB_DEFAULT) elseif s === :transpose_input2 - libgb.GxB_Desc_set(d, libgb.GrB_INP1, x ? libgb.GrB_TRAN : libgb.GxB_DEFAULT) + GxB_Desc_set(d, LibGraphBLAS.GrB_INP1, x ? LibGraphBLAS.GrB_TRAN : LibGraphBLAS.GxB_DEFAULT) elseif s === :nthreads - libgb.GxB_Desc_set(d, libgb.GxB_DESCRIPTOR_NTHREADS, x) + GxB_Desc_set(d, LibGraphBLAS.GxB_DESCRIPTOR_NTHREADS, x) elseif s === :chunk - libgb.GxB_Desc_set(d, libgb.GxB_DESCRIPTOR_CHUNK, x) + GxB_Desc_set(d, LibGraphBLAS.GxB_DESCRIPTOR_CHUNK, x) elseif s === :sort - libgb.GxB_Desc_set(d, libgb.GxB_SORT, x ? 3 : 0) + GxB_Desc_set(d, LibGraphBLAS.GxB_SORT, x ? 3 : 0) end end function Base.propertynames(::Descriptor) diff --git a/src/export.jl b/src/export.jl index 21f7aec8..898d713e 100644 --- a/src/export.jl +++ b/src/export.jl @@ -4,14 +4,14 @@ function _exportdensematrix!( desc = nothing ) where {T} desc = _handledescriptor(desc) - nrows = Ref{libgb.GrB_Index}(size(A,1)) - ncols = Ref{libgb.GrB_Index}(size(A,2)) - Csize = Ref{libgb.GrB_Index}(length(A) * sizeof(T)) + 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) - libgb.GxB_Matrix_export_FullC( + @wraperror LibGraphBLAS.GxB_Matrix_export_FullC( Ref(A.p), - Ref(toGBType(T).p), + Ref(gbtype(T).p), nrows, ncols, values, @@ -32,19 +32,19 @@ function _exportcscmatrix!( desc = nothing ) where {T} desc = _handledescriptor(desc) - nrows = Ref{libgb.GrB_Index}(size(A, 1)) - ncols = Ref{libgb.GrB_Index}(size(A, 2)) - t = Ref{libgb.GrB_Type}(toGBType(T).p) - colptr = Ref{Ptr{libgb.GrB_Index}}() - rowidx = Ref{Ptr{libgb.GrB_Index}}() + 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{libgb.GrB_Index}() - rowidxsize = Ref{libgb.GrB_Index}() - Axsize = Ref{libgb.GrB_Index}() + colptrsize = Ref{LibGraphBLAS.GrB_Index}() + rowidxsize = Ref{LibGraphBLAS.GrB_Index}() + Axsize = Ref{LibGraphBLAS.GrB_Index}() isuniform = Ref{Bool}(false) isjumbled = C_NULL - libgb.GxB_Matrix_export_CSC( + @wraperror LibGraphBLAS.GxB_Matrix_export_CSC( Ref(A.p), t, nrows, @@ -71,13 +71,13 @@ 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{libgb.GrB_Index}(undef, Int(colptrsize ÷ sizeof(libgb.GrB_Index))) -# row = Vector{libgb.GrB_Index}(undef, Int(rowidxsize ÷ sizeof(libgb.GrB_Index))) +# 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{libgb.GrB_Index}(colptr), length(col)) -# unsafe_copyto!(pointer(row), Ptr{libgb.GrB_Index}(rowidx), length(row)) -# ccall(:jl_free, Cvoid, (Ptr{libgb.GrB_Index},), colptr) -# ccall(:jl_free, Cvoid, (Ptr{libgb.GrB_Index},), rowidx) +# 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 @@ -94,13 +94,13 @@ function _exportdensevec!( desc = nothing ) where {T} desc = _handledescriptor(desc) - n = Ref{libgb.GrB_Index}(size(v,1)) - vsize = Ref{libgb.GrB_Index}(length(v) * sizeof(T)) + 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) - libgb.GxB_Vector_export_Full( + @wraperror LibGraphBLAS.GxB_Vector_export_Full( Ref(v.p), - Ref(toGBType(T).p), + Ref(gbtype(T).p), n, values, vsize, diff --git a/src/gbtypes.jl b/src/gbtypes.jl index 37885935..75fc1a22 100644 --- a/src/gbtypes.jl +++ b/src/gbtypes.jl @@ -32,103 +32,95 @@ const valid_vec = [ const gxb_union = Union{ComplexF32, ComplexF64} const gxb_vec = [ComplexF32, ComplexF64] -struct GBType{T} <: AbstractGBType - p::libgb.GrB_Type +mutable struct GBType{T} <: AbstractGBType + builtin::Bool + loaded::Bool + p::LibGraphBLAS.GrB_Type + typestr::String + function GBType{T}(builtin, loaded, p, typestr) where {T} + type = new{T}(builtin, loaded, p, typestr) + return finalizer(type) do t + @wraperror LibGraphBLAS.GrB_Type_free(Ref(t.p)) + end + end end -Base.unsafe_convert(::Type{libgb.GrB_Type}, s::AbstractGBType) = s.p +""" + gbtype(x) + +Determine the GBType equivalent of a Julia primitive type. + +See also: [`juliatype`](@ref) +""" +function gbtype end + +macro gbtype(expr...) -GBType{T}(name::AbstractString) where {T<:valid_union} = GBType{T}(load_global(name)) + jtype = expr[1] + if length(expr) == 2 + namestr = string(expr[2]) + else + namestr = uppercase(string(jtype)) + end + builtin = isGxB(namestr) || isGrB(namestr) + namesym = Symbol(builtin ? namestr[5:end] : namestr) + return quote + const $(esc(namesym)) = GBType{$(esc(jtype))}($builtin, false, LibGraphBLAS.GrB_Type(), $namestr) + $(esc(:(SuiteSparseGraphBLAS.gbtype)))(::Type{$(esc(jtype))}) = $(esc(namesym)) + end +end + +function Base.unsafe_convert(::Type{LibGraphBLAS.GrB_Type}, s::GBType{T}) where {T} + if !s.loaded + if s.builtin + s.p = load_global(s.typestr, LibGraphBLAS.GrB_Type) + else + typeref = Ref{LibGraphBLAS.GrB_Type}() + @wraperror LibGraphBLAS.GxB_Type_new(typeref, sizeof(T), string(T), "") + s.p = typeref[] + end + s.loaded = true + ptrtogbtype[s.p] = s + end + if !s.loaded + error("This type could not be loaded, and is invalid.") + else + return s.p + end +end function Base.show(io::IO, ::MIME"text/plain", t::GBType{T}) where T print(io, "GBType(" * string(T) * "): ") gxbprint(io, t) end -struct GBAllType <: AbstractGBType - p::Ptr{libgb.GrB_Index} +mutable struct GBAllType <: AbstractGBType + p::Ptr{LibGraphBLAS.GrB_Index} end Base.show(io::IO, ::MIME"text/plain", t::GBAllType) = print(io, "GraphBLAS type: GrB_ALL") -Base.unsafe_convert(::Type{Ptr{libgb.GrB_Index}}, s::GBAllType) = s.p +Base.unsafe_convert(::Type{Ptr{LibGraphBLAS.GrB_Index}}, s::GBAllType) = s.p Base.length(::GBAllType) = 0 #Allow indexing with ALL -function _load_globaltypes() - global BOOL = GBType{Bool}("GrB_BOOL") - ptrtogbtype[BOOL.p] = BOOL - global INT8 = GBType{Int8}("GrB_INT8") - ptrtogbtype[INT8.p] = INT8 - global UINT8 = GBType{UInt8}("GrB_UINT8") - ptrtogbtype[UINT8.p] = UINT8 - global INT16 = GBType{Int16}("GrB_INT16") - ptrtogbtype[INT16.p] = INT16 - global UINT16 = GBType{UInt16}("GrB_UINT16") - ptrtogbtype[UINT16.p] = UINT16 - global INT32 = GBType{Int32}("GrB_INT32") - ptrtogbtype[INT32.p] = INT32 - global UINT32 = GBType{UInt32}("GrB_UINT32") - ptrtogbtype[UINT32.p] = UINT32 - global INT64 = GBType{Int64}("GrB_INT64") - ptrtogbtype[INT64.p] = INT64 - global UINT64 = GBType{UInt64}("GrB_UINT64") - ptrtogbtype[UINT64.p] = UINT64 - global FP32 = GBType{Float32}("GrB_FP32") - ptrtogbtype[FP32.p] = FP32 - global FP64 = GBType{Float64}("GrB_FP64") - ptrtogbtype[FP64.p] = FP64 - global FC32 = GBType{ComplexF32}("GxB_FC32") - ptrtogbtype[FC32.p] = FC32 - global FC64 = GBType{ComplexF32}("GxB_FC64") - ptrtogbtype[FC64.p] = FC64 - global NULL = GBType{Nothing}(C_NULL) - ptrtogbtype[NULL.p] = NULL - global ALL = GBAllType(load_global("GrB_ALL", libgb.GrB_Index)) - ptrtogbtype[ALL.p] = ALL -end - """ tojuliatype(x::GBType) Determine the Julia equivalent of a GBType. -See also: [`toGBType`](@ref) +See also: [`gbtype`](@ref) """ -tojuliatype(::GBType{T}) where {T} = T +juliatype(::GBType{T}) where {T} = T -""" - toGBType(x) +@gbtype Bool GrB_BOOL +@gbtype Int8 GrB_INT8 +@gbtype UInt8 GrB_UINT8 +@gbtype Int16 GrB_INT16 +@gbtype UInt16 GrB_UINT16 +@gbtype Int32 GrB_INT32 +@gbtype UInt32 GrB_UINT32 +@gbtype Int64 GrB_INT64 +@gbtype UInt64 GrB_UINT64 +@gbtype Float32 GrB_FP32 +@gbtype Float64 GrB_FP64 +@gbtype ComplexF32 GxB_FC32 +@gbtype ComplexF64 GxB_FC64 -Determine the GBType equivalent of a Julia primitive type. - -See also: [`juliatype`](@ref) -""" -function toGBType(x) - if x == Bool - return BOOL - elseif x == Int8 - return INT8 - elseif x == UInt8 - return UINT8 - elseif x == Int16 - return INT16 - elseif x == UInt16 - return UINT16 - elseif x == Int32 - return INT32 - elseif x == UInt32 - return UINT32 - elseif x == Int64 - return INT64 - elseif x == UInt64 - return UINT64 - elseif x == Float32 - return FP32 - elseif x == Float64 - return FP64 - elseif x == ComplexF32 - return FC32 - elseif x == ComplexF64 - return FC64 - else - throw(ArgumentError("Not a valid GrB data type")) - end -end diff --git a/src/import.jl b/src/import.jl index 1d2c6b30..7110b065 100644 --- a/src/import.jl +++ b/src/import.jl @@ -11,17 +11,17 @@ function _importcscmat( desc = nothing, iso = false ) where {T} - A = Ref{libgb.GrB_Matrix}() #Pointer to new GBMatrix - m = libgb.GrB_Index(m) #nrows - n = libgb.GrB_Index(n) #ncols + A = Ref{LibGraphBLAS.GrB_Matrix}() #Pointer to new GBMatrix + m = LibGraphBLAS.GrB_Index(m) #nrows + n = LibGraphBLAS.GrB_Index(n) #ncols desc = _handledescriptor(desc) - libgb.GxB_Matrix_import_CSC( + @wraperror LibGraphBLAS.GxB_Matrix_import_CSC( A, - toGBType(T), + gbtype(T), m, n, - Ref{Ptr{libgb.GrB_Index}}(colptr), - Ref{Ptr{libgb.GrB_Index}}(rowindices), + Ref{Ptr{LibGraphBLAS.GrB_Index}}(colptr), + Ref{Ptr{LibGraphBLAS.GrB_Index}}(rowindices), Ref{Ptr{Cvoid}}(values), colsize, rowsize, @@ -47,12 +47,12 @@ function _importcscmat( # 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. - colsize = libgb.GrB_Index(sizeof(colptr)) #Size of colptr vector - rowsize = libgb.GrB_Index(sizeof(rowindices)) #Size of rowindex vector - valsize = libgb.GrB_Index(sizeof(values)) #Size of nzval vector - col = ccall(:jl_malloc, Ptr{libgb.GrB_Index}, (UInt, ), colsize) + 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(colptr .- 1)), length(colptr)) - row = ccall(:jl_malloc, Ptr{libgb.GrB_Index}, (UInt, ), rowsize) + row = ccall(:jl_malloc, Ptr{LibGraphBLAS.GrB_Index}, (UInt, ), rowsize) unsafe_copyto!(row, Ptr{UInt64}(pointer(rowindices .- 1)), length(rowindices)) val = ccall(:jl_malloc, Ptr{T}, (UInt, ), valsize) unsafe_copyto!(val, pointer(values), length(values)) @@ -89,14 +89,14 @@ function _importcscvec( n::Integer, vi::Ptr{UInt64}, vi_size, vx::Ptr{T}, vx_size, nnz; jumbled::Bool = false, desc = nothing, iso = false ) where {T} - v = Ref{libgb.GrB_Vector}() - n = libgb.GrB_Index(n) + v = Ref{LibGraphBLAS.GrB_Vector}() + n = LibGraphBLAS.GrB_Index(n) desc = _handledescriptor(desc) - libgb.GxB_Vector_import_CSC( + @wraperror LibGraphBLAS.GxB_Vector_import_CSC( v, - toGBType(T), + gbtype(T), n, - Ref{Ptr{libgb.GrB_Index}}(vi), + Ref{Ptr{LibGraphBLAS.GrB_Index}}(vi), Ref{Ptr{Cvoid}}(vx), vi_size, vx_size, @@ -112,9 +112,9 @@ function _importcscvec( n::Integer, vi::Vector{U}, vx::Vector{T}, nnz; jumbled::Bool = false, desc = nothing, iso = false ) where {U,T} - vi_size = libgb.GrB_Index(sizeof(vi)) - vx_size = libgb.GrB_Index(sizeof(vx)) - indices = ccall(:jl_malloc, Ptr{libgb.GrB_Index}, (UInt, ), vi_size) + vi_size = LibGraphBLAS.GrB_Index(sizeof(vi)) + vx_size = LibGraphBLAS.GrB_Index(sizeof(vx)) + indices = ccall(:jl_malloc, Ptr{LibGraphBLAS.GrB_Index}, (UInt, ), vi_size) unsafe_copyto!(indices, Ptr{UInt64}(pointer(vi .- 1)), length(vi)) values = ccall(:jl_malloc, Ptr{T}, (UInt, ), vx_size) unsafe_copyto!(values, pointer(vx), length(vx)) @@ -134,17 +134,17 @@ function _importcsrmat( desc = nothing, iso = false ) where {U, T} - A = Ref{libgb.GrB_Matrix}() #Pointer to new GBMatrix - m = libgb.GrB_Index(m) #nrows - n = libgb.GrB_Index(n) #ncols + A = Ref{LibGraphBLAS.GrB_Matrix}() #Pointer to new GBMatrix + m = LibGraphBLAS.GrB_Index(m) #nrows + n = LibGraphBLAS.GrB_Index(n) #ncols desc = _handledescriptor(desc) - libgb.GxB_Matrix_import_CSR( + @wraperror LibGraphBLAS.GxB_Matrix_import_CSR( A, - toGBType(T), + gbtype(T), m, n, - Ref{Ptr{libgb.GrB_Index}}(rowptr), - Ref{Ptr{libgb.GrB_Index}}(colindices), + Ref{Ptr{LibGraphBLAS.GrB_Index}}(rowptr), + Ref{Ptr{LibGraphBLAS.GrB_Index}}(colindices), Ref{Ptr{Cvoid}}(values), rowsize, colsize, @@ -166,9 +166,9 @@ function _importcsrmat( desc = nothing, iso = false ) where {T} - rowsize = libgb.GrB_Index(sizeof(rowptr)) #Size of colptr vector - colsize = libgb.GrB_Index(sizeof(colindices)) #Size of rowindex vector - valsize = libgb.GrB_Index(sizeof(values)) #Size of nzval vector + 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. @@ -176,9 +176,9 @@ function _importcsrmat( # 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{libgb.GrB_Index}, (UInt, ), rowsize) + 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{libgb.GrB_Index}, (UInt, ), colsize) + 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)) @@ -190,13 +190,13 @@ function _importdensematrix( m::Integer, n::Integer, A::Ptr{T}, Asize; desc = nothing, iso = false ) where {T} - C = Ref{libgb.GrB_Matrix}() - m = libgb.GrB_Index(m) - n = libgb.GrB_Index(n) + C = Ref{LibGraphBLAS.GrB_Matrix}() + m = LibGraphBLAS.GrB_Index(m) + n = LibGraphBLAS.GrB_Index(n) desc = _handledescriptor(desc) - libgb.GxB_Matrix_import_FullC( + @wraperror LibGraphBLAS.GxB_Matrix_import_FullC( C, - toGBType(T), + gbtype(T), m, n, Ref{Ptr{Cvoid}}(A), @@ -211,9 +211,9 @@ function _importdensematrix( m::Integer, n::Integer, A::VecOrMat{T}; desc = nothing, iso = false ) where {T} - m = libgb.GrB_Index(m) - n = libgb.GrB_Index(n) - Asize = libgb.GrB_Index(sizeof(A)) + 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) @@ -250,12 +250,12 @@ function _importdensevec( n::Integer, v::Ptr{T}, vsize; desc = nothing, iso = false ) where {T} - w = Ref{libgb.GrB_Vector}() - n = libgb.GrB_Index(n) + w = Ref{LibGraphBLAS.GrB_Vector}() + n = LibGraphBLAS.GrB_Index(n) desc = _handledescriptor(desc) - libgb.GxB_Vector_import_Full( + @wraperror LibGraphBLAS.GxB_Vector_import_Full( w, - toGBType(T), + gbtype(T), n, Ref{Ptr{Cvoid}}(v), vsize, @@ -270,8 +270,8 @@ function _importdensevec( n::Integer, v::Vector{T}; desc = nothing, iso = false ) where {T} - n = libgb.GrB_Index(n) - vsize = libgb.GrB_Index(sizeof(v)) + n = LibGraphBLAS.GrB_Index(n) + vsize = LibGraphBLAS.GrB_Index(sizeof(v)) # We have to do this instead of Libc.malloc because GraphBLAS will use :jl_free, not Libc.free vx = ccall(:jl_malloc, Ptr{T}, (UInt, ), vsize) unsafe_copyto!(vx, pointer(v), length(v)) diff --git a/src/indexutils.jl b/src/indexutils.jl index cc5b2338..53bddbc3 100644 --- a/src/indexutils.jl +++ b/src/indexutils.jl @@ -9,17 +9,17 @@ function idx(I) if I == ALL return I, 0 #ni doesn't matter if I=ALL elseif I isa UnitRange - return [I.start, I.stop], libgb.GxB_RANGE #Simple ranges + return [I.start, I.stop], LibGraphBLAS.GxB_RANGE #Simple ranges elseif I isa StepRange #The step must survive tozerobased(I), so we add 1 to it. if I.step > 0 - return [I.start, I.stop, I.step + 1], libgb.GxB_STRIDE #Normal stried ranges + return [I.start, I.stop, I.step + 1], LibGraphBLAS.GxB_STRIDE #Normal stried ranges elseif I.step < 0 #Strided ranges with negative increment - return [I.start, I.stop, -I.step + 1], libgb.GxB_BACKWARDS + return [I.start, I.stop, -I.step + 1], LibGraphBLAS.GxB_BACKWARDS end elseif I isa Vector - return Vector{libgb.GrB_Index}(I), length(I) #Assume ni = length(I) otherwise + return Vector{LibGraphBLAS.GrB_Index}(I), length(I) #Assume ni = length(I) otherwise elseif I isa Integer return [UInt64(I)], 1 elseif I isa CartesianIndex{1} diff --git a/src/lib/LibGraphBLAS.jl b/src/lib/LibGraphBLAS.jl index 975f5c42..6ce7f77c 100644 --- a/src/lib/LibGraphBLAS.jl +++ b/src/lib/LibGraphBLAS.jl @@ -56,39 +56,6 @@ macro wraperror(code) end end -macro check(code) - MacroTools.@q begin - info = $(esc(code)) - if info == GrB_UNINITIALIZED_OBJECT - throw(UninitializedObjectError) - elseif info == GrB_INVALID_OBJECT - throw(InvalidObjectError) - elseif info == GrB_NULL_POINTER - throw(NullPointerError) - elseif info == GrB_INVALID_VALUE - throw(InvalidValueError) - elseif info == GrB_INVALID_INDEX - throw(InvalidIndexError) - elseif info == GrB_DOMAIN_MISMATCH - throw(DomainError(nothing, "GraphBLAS Domain Mismatch")) - elseif info == GrB_DIMENSION_MISMATCH - throw(DimensionMismatch()) - elseif info == GrB_OUTPUT_NOT_EMPTY - throw(OutputNotEmptyError) - elseif info == GrB_OUT_OF_MEMORY - throw(OutOfMemoryError()) - elseif info == GrB_INSUFFICIENT_SPACE - throw(InsufficientSpaceError) - elseif info == GrB_INDEX_OUT_OF_BOUNDS - throw(BoundsError()) - elseif info == GrB_PANIC - throw(PANIC) - else - throw(ErrorException("Unreachable Reached.")) - end - end -end - function tozerobased(I) I isa Vector && (return I .- 1) I isa Integer && (return I - 1) @@ -2723,191 +2690,6 @@ function GxB_cuda_free(p) ccall((:GxB_cuda_free, libgraphblas), Cvoid, (Ptr{Cvoid},), p) end -function GxB_Desc_get(desc, field) - if field ∈ [GrB_OUTP, GrB_MASK, GrB_INP0, GrB_INP1] - T = GrB_Desc_Value - elseif field ∈ [GxB_DESCRIPTOR_NTHREADS, GxB_AxB_METHOD, GxB_SORT] - T = Cint - elseif field ∈ [GxB_DESCRIPTOR_CHUNK] - T = Cdouble - else - error("Not a valid Descriptor option.") - end - v = Ref{T}() - ccall( - (:GxB_Desc_get, libgraphblas), - GrB_Info, - (GrB_Descriptor, UInt32, Ptr{Cvoid}), - desc, - field, - v - ) - return v[] -end - -function GxB_Desc_set(d, field, value) - if field ∈ [GrB_OUTP, GrB_MASK, GrB_INP0, GrB_INP1] - ccall( - (:GxB_Desc_set, libgraphblas), - GrB_Info, - (GrB_Descriptor, GrB_Desc_Field, GrB_Desc_Value), - d, - field, - value - ) - elseif field ∈ [GxB_DESCRIPTOR_NTHREADS, GxB_AxB_METHOD, GxB_SORT] - ccall( - (:GxB_Desc_set, libgraphblas), - GrB_Info, - (GrB_Descriptor, GrB_Desc_Field, Cint), - d, - field, - value - ) - elseif field ∈ [GxB_DESCRIPTOR_CHUNK] - ccall( - (:GxB_Desc_set, libgraphblas), - GrB_Info, - (GrB_Descriptor, GrB_Desc_Field, Cdouble), - d, - field, - value - ) - end -end - -function GxB_Global_Option_get(field) - if field ∈ [GxB_HYPER_SWITCH, GxB_BITMAP_SWITCH] - T = Cdouble - elseif field ∈ [GxB_FORMAT] - T = UInt32 - elseif field ∈ [GxB_GLOBAL_NTHREADS, GxB_GLOBAL_CHUNK] - T = Cint - elseif field ∈ [GxB_BURBLE] - T = Bool - end - v = Ref{T}() - ccall( - (:GxB_Global_Option_get, libgraphblas), - Cvoid, - (UInt32, Ptr{Cvoid}), - field, - v - ) - return v[] -end - -function GxB_Global_Option_set(field, value) - if field ∈ [GxB_HYPER_SWITCH, GxB_BITMAP_SWITCH, GxB_GLOBAL_CHUNK] - ccall( - (:GxB_Global_Option_set, libgraphblas), - Cvoid, - (UInt32, Cdouble), - field, - value - ) - elseif field ∈ [GxB_GLOBAL_NTHREADS, GxB_BURBLE, GxB_PRINT_1BASED, GxB_FORMAT] - ccall( - (:GxB_Global_Option_set, libgraphblas), - Cvoid, - (UInt32, Cint), - field, - value - ) - end -end - -function GxB_Matrix_Option_get(A, field) - if field ∈ [GxB_HYPER_SWITCH, GxB_BITMAP_SWITCH] - T = Cdouble - elseif field ∈ [GxB_FORMAT, GxB_SPARSITY_STATUS, GxB_SPARSITY_CONTROL] - T = Cint - end - v = Ref{T}() - ccall( - (:GxB_Matrix_Option_get, libgraphblas), - Cvoid, - (GrB_Matrix, UInt32, Ptr{Cvoid}), - A, - field, - v - ) - return v[] -end - -function GxB_Matrix_Option_set(A, field, value) - if field ∈ [GxB_HYPER_SWITCH, GxB_BITMAP_SWITCH] - ccall( - (:GxB_Matrix_Option_set, libgraphblas), - Cvoid, - (GrB_Matrix, UInt32, Cdouble), - A, - field, - value - ) - elseif field ∈ [GxB_FORMAT, GxB_SPARSITY_CONTROL] - ccall( - (:GxB_Matrix_Option_set, libgraphblas), - Cvoid, - (GrB_Matrix, UInt32, UInt32), - A, - field, - value - ) - end -end - -function GxB_Vector_Option_get(A, field) - if field ∈ [GxB_HYPER_SWITCH, GxB_BITMAP_SWITCH] - T = Cdouble - elseif field ∈ [GxB_FORMAT] - T = UInt32 - elseif field ∈ [GxB_SPARSITY_STATUS, GxB_SPARSITY_CONTROL] - T = Cint - end - v = Ref{T}() - ccall( - (:GxB_Vector_Option_get, libgraphblas), - Cvoid, - (GrB_Vector, UInt32, Ptr{Cvoid}), - A, - field, - v - ) - return v[] -end - -function GxB_Vector_Option_set(A, field, value) - if field ∈ [GxB_HYPER_SWITCH, GxB_BITMAP_SWITCH] - ccall( - (:GxB_Vector_Option_set, libgraphblas), - Cvoid, - (GrB_Vector, UInt32, Cdouble), - A, - field, - value - ) - elseif field ∈ [GxB_FORMAT] - ccall( - (:GxB_Vector_Option_set, libgraphblas), - Cvoid, - (GrB_Vector, UInt32, UInt32), - A, - field, - value - ) - elseif field ∈ [GxB_SPARSITY_CONTROL] - ccall( - (:GxB_Vector_Option_set, libgraphblas), - Cvoid, - (GrB_Vector, UInt32, Cint), - A, - field, - value - ) - end -end - # Skipping MacroDefinition: GB_PUBLIC extern diff --git a/src/lib/LibGraphBLAS_gen.jl b/src/lib/LibGraphBLAS_gen.jl index 5510b5c1..11172280 100644 --- a/src/lib/LibGraphBLAS_gen.jl +++ b/src/lib/LibGraphBLAS_gen.jl @@ -1,5 +1,5 @@ module LibGraphBLAS - +import ..libgraphblas const GxB_FC64_t = ComplexF32 const GxB_FC32_t = ComplexF32 @@ -2911,9 +2911,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" @@ -2937,7 +2937,7 @@ const GRB_VERSION = GxB_SPEC_MAJOR const GRB_SUBVERSION = GxB_SPEC_MINOR -const GxB_IMPLEMENTATION = GxB_VERSION(GxB_IMPLEMENTATION_MAJOR, GxB_IMPLEMENTATION_MINOR, GxB_IMPLEMENTATION_SUB) +# const GxB_IMPLEMENTATION = GxB_VERSION(GxB_IMPLEMENTATION_MAJOR, GxB_IMPLEMENTATION_MINOR, GxB_IMPLEMENTATION_SUB) # Skipping MacroDefinition: GxB_IMPLEMENTATION_ABOUT \ #"SuiteSparse:GraphBLAS, Timothy A. Davis, (c) 2017-2022, All Rights Reserved." \ @@ -2955,7 +2955,7 @@ const GxB_IMPLEMENTATION = GxB_VERSION(GxB_IMPLEMENTATION_MAJOR, GxB_IMPLEMENTAT #"See the License for the specific language governing permissions and\n" \ #"limitations under the License.\n" -const GxB_SPEC_VERSION = GxB_VERSION(GxB_SPEC_MAJOR, GxB_SPEC_MINOR, GxB_SPEC_SUB) +# const GxB_SPEC_VERSION = GxB_VERSION(GxB_SPEC_MAJOR, GxB_SPEC_MINOR, GxB_SPEC_SUB) # Skipping MacroDefinition: GxB_SPEC_ABOUT \ #"GraphBLAS C API, by Aydin Buluc, Timothy Mattson, Scott McMillan,\n" \ @@ -2963,7 +2963,7 @@ const GxB_SPEC_VERSION = GxB_VERSION(GxB_SPEC_MAJOR, GxB_SPEC_MINOR, GxB_SPEC_SU #"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) @@ -2995,15 +2995,15 @@ const GxB_ANY_SPARSITY = GxB_HYPERSPARSE + GxB_SPARSE + GxB_BITMAP + GxB_FULL const GxB_AUTO_SPARSITY = GxB_ANY_SPARSITY -const GrB_NULL = NULL +const GrB_NULL = C_NULL -const GrB_INVALID_HANDLE = NULL +const GrB_INVALID_HANDLE = C_NULL -const GxB_RANGE = INT64_MAX +const GxB_RANGE = typemax(Int64) -const GxB_STRIDE = INT64_MAX - 1 +const GxB_STRIDE = typemax(Int64) - 1 -const GxB_BACKWARDS = INT64_MAX - 2 +const GxB_BACKWARDS = typemax(Int64) - 2 const GxB_BEGIN = 0 diff --git a/src/libutils.jl b/src/libutils.jl index b48237eb..315a91f0 100644 --- a/src/libutils.jl +++ b/src/libutils.jl @@ -1,4 +1,78 @@ +# exceptions: + +struct UninitializedObjectError <: Exception end +struct InvalidObjectError <: Exception end +struct NullPointerError <: Exception end +struct InvalidValueError <: Exception end +struct InvalidIndexError <: Exception end +struct OutputNotEmptyError <: Exception end +struct InsufficientSpaceError <: Exception end +struct PANIC <: Exception end + +macro wraperror(code) + MacroTools.@q begin + info = $(esc(code)) + if info == LibGraphBLAS.GrB_SUCCESS + # We do GrB_NO_VALUE manually to ensure inference is happy, and avoid an extra branch. + else + if info == LibGraphBLAS.GrB_UNINITIALIZED_OBJECT + throw(UninitializedObjectError) + elseif info == LibGraphBLAS.GrB_INVALID_OBJECT + throw(InvalidObjectError) + elseif info == LibGraphBLAS.GrB_NULL_POINTER + throw(NullPointerError) + elseif info == LibGraphBLAS.GrB_INVALID_VALUE + throw(InvalidValueError) + elseif info == LibGraphBLAS.GrB_INVALID_INDEX + throw(InvalidIndexError) + elseif info == LibGraphBLAS.GrB_DOMAIN_MISMATCH + throw(DomainError(nothing, "GraphBLAS Domain Mismatch")) + elseif info == LibGraphBLAS.GrB_DIMENSION_MISMATCH + throw(DimensionMismatch()) + elseif info == LibGraphBLAS.GrB_OUTPUT_NOT_EMPTY + throw(OutputNotEmptyError) + elseif info == LibGraphBLAS.GrB_OUT_OF_MEMORY + throw(OutOfMemoryError()) + elseif info == LibGraphBLAS.GrB_INSUFFICIENT_SPACE + throw(InsufficientSpaceError) + elseif info == LibGraphBLAS.GrB_INDEX_OUT_OF_BOUNDS + throw(BoundsError()) + elseif info == LibGraphBLAS.GrB_PANIC + throw(PANIC) + else + throw(ErrorException("Unreachable Reached.")) + end + end + end +end + +function decrement(I) + I isa Vector && (return I .- 1) +end + +@inline function decrement(I::Integer) + return I - 1 +end + +function increment(I) + I isa Vector && (return I .+ 1) +end + +@inline function increment(I::Integer) + return I + 1 +end + +@inline function decrement!(I) + I isa Vector && (return I .-= 1) + I isa Number && (return I - 1) + return I # don't need to modify here, likely an AllType. +end +@inline function increment!(I) + I isa Vector && (return I .+= 1) + I isa Number && (return I + 1) + return I # don't need to modify here, likely an AllType. +end function suffix(T::Symbol) if T === :Bool diff --git a/src/matrix.jl b/src/matrix.jl index b9d27210..876241b0 100644 --- a/src/matrix.jl +++ b/src/matrix.jl @@ -1,12 +1,14 @@ # Constructors: ############### """ - GBMatrix{T}(nrows = libgb.GxB_INDEX_MAX, ncols = libgb.GxB_INDEX_MAX) + GBMatrix{T}(nrows = LibGraphBLAS.GxB_INDEX_MAX, ncols = LibGraphBLAS.GxB_INDEX_MAX) Create a GBMatrix of the specified size, defaulting to the maximum on each dimension, 2^60. """ -function GBMatrix{T}(nrows = libgb.GxB_INDEX_MAX, ncols = libgb.GxB_INDEX_MAX) where {T} - GBMatrix{T}(libgb.GrB_Matrix_new(toGBType(T),nrows, ncols)) +function GBMatrix{T}(nrows = LibGraphBLAS.GxB_INDEX_MAX, ncols = LibGraphBLAS.GxB_INDEX_MAX) where {T} + m = Ref{LibGraphBLAS.GrB_Matrix}() + @wraperror LibGraphBLAS.GrB_Matrix_new(m, gbtype(T), nrows, ncols) + return GBMatrix{T}(m[]) end GBMatrix{T}(dims::Dims{2}) where {T} = GBMatrix{T}(dims...) @@ -62,17 +64,19 @@ function GBMatrix(v::GBVector) end function build(A::GBMatrix{T}, I::AbstractVector, J::AbstractVector, x::T) where {T} - nnz(A) == 0 || throw(libgb.OutputNotEmptyError("Cannot build matrix with existing elements")) + nnz(A) == 0 || throw(OutputNotEmptyError("Cannot build matrix with existing elements")) length(I) == length(J) || DimensionMismatch("I, J and X must have the same length") x = GBScalar(x) - libgb.GxB_Matrix_build_Scalar( + @wraperror LibGraphBLAS.GxB_Matrix_build_Scalar( A, - Vector{libgb.GrB_Index}(I), - Vector{libgb.GrB_Index}(J), + Vector{LibGraphBLAS.GrB_Index}(decrement!(I)), + Vector{LibGraphBLAS.GrB_Index}(decrement!(J)), x, length(I) ) + increment!(I) + increment!(J) return A end @@ -80,10 +84,12 @@ end # Some Base and basic SparseArrays/LinearAlgebra functions: ########################################################### -Base.unsafe_convert(::Type{libgb.GrB_Matrix}, A::GBMatrix) = A.p +Base.unsafe_convert(::Type{LibGraphBLAS.GrB_Matrix}, A::GBMatrix) = A.p function Base.copy(A::GBMatrix{T}) where {T} - return GBMatrix{T}(libgb.GrB_Matrix_dup(A)) + C = Ref{LibGraphBLAS.GrB_Matrix}() + LibGraphBLAS.GrB_Matrix_dup(C, A) + return GBMatrix{T}(C[]) end """ @@ -93,13 +99,22 @@ end Clear all the entries from the GBArray. Does not modify the type or dimensions. """ -clear!(A::GBArray) = libgb.GrB_Matrix_clear(parent(A)) +clear!(A::GBArray) = @wraperror LibGraphBLAS.GrB_Matrix_clear(parent(A)); return nothing function Base.size(A::GBMatrix) - return (Int64(libgb.GrB_Matrix_nrows(A)), Int64(libgb.GrB_Matrix_ncols(A))) + nrows = Ref{LibGraphBLAS.GrB_Index}() + ncols = Ref{LibGraphBLAS.GrB_Index}() + @wraperror LibGraphBLAS.GrB_Matrix_nrows(nrows, A) + @wraperror LibGraphBLAS.GrB_Matrix_ncols(ncols, A) + return (Int64(nrows[]), Int64(ncols[])) +end + +function SparseArrays.nnz(A::GBArray) + nvals = Ref{LibGraphBLAS.GrB_Index}() + @wraperror LibGraphBLAS.GrB_Matrix_nvals(nvals, parent(A)) + return Int64(nvals[]) end -SparseArrays.nnz(A::GBArray) = Int64(libgb.GrB_Matrix_nvals(parent(A))) Base.eltype(::Type{GBMatrix{T}}) where{T} = T function Base.similar( @@ -110,12 +125,12 @@ function Base.similar( end function Base.deleteat!(A::GBMatrix, i, j) - libgb.GrB_Matrix_removeElement(A, i, j) + @wraperror LibGraphBLAS.GrB_Matrix_removeElement(A, decrement!(i), decrement!(j)) return A end function Base.resize!(A::GBMatrix, nrows_new, ncols_new) - libgb.GrB_Matrix_resize(A, nrows_new, ncols_new) + @wraperror LibGraphBLAS.GrB_Matrix_resize(A, nrows_new, ncols_new) return A end # This does not conform to the normal definition with a lazy wrapper. @@ -123,14 +138,16 @@ function LinearAlgebra.Diagonal(v::GBVector, k::Integer=0; desc = nothing) s = size(v, 1) C = GBMatrix{eltype(v)}(s, s) desc = _handledescriptor(desc) - libgb.GxB_Matrix_diag(C, Ptr{libgb.GrB_Vector}(v.p), k, desc) + # Switch ptr to a Vector to trick GraphBLAS. + # This is allowed since GrB_Vector is a GrB_Matrix internally. + @wraperror LibGraphBLAS.GxB_Matrix_diag(C, Ptr{LibGraphBLAS.GrB_Vector}(v.p), k, desc) return C end -function LinearAlgebra.diagm(v::GBVector, k::Integer=0; desc = nothing) - return Diagonal(v, k; desc) -end - +# TODO: FIXME +# function LinearAlgebra.diagm(v::GBVector, k::Integer=0; desc = nothing) +# return Diagonal(v, k; desc) +# end # Type dependent functions build, setindex, getindex, and findnz: for T ∈ valid_vec @@ -152,17 +169,21 @@ for T ∈ valid_vec if !(J isa Vector) J = Vector(J) end - nnz(A) == 0 || throw(libgb.OutputNotEmptyError("Cannot build matrix with existing elements")) + nnz(A) == 0 || throw(OutputNotEmptyError("Cannot build matrix with existing elements")) length(X) == length(I) == length(J) || DimensionMismatch("I, J and X must have the same length") - libgb.$func( + decrement!(I) + decrement!(J) + @wraperror LibGraphBLAS.$func( A, - Vector{libgb.GrB_Index}(I) .- 1, - Vector{libgb.GrB_Index}(J) .- 1, + Vector{LibGraphBLAS.GrB_Index}(I), + Vector{LibGraphBLAS.GrB_Index}(J), X, length(X), dup ) + increment!(I) + increment!(J) end end # Setindex functions @@ -170,7 +191,8 @@ for T ∈ valid_vec @eval begin function Base.setindex!(A::GBMatrix{$T}, x, i::Integer, j::Integer) x = convert($T, x) - return libgb.$func(A, x, libgb.GrB_Index(i) - 1, libgb.GrB_Index(j) - 1) + @wraperror LibGraphBLAS.$func(A, x, LibGraphBLAS.GrB_Index(decrement!(i)), LibGraphBLAS.GrB_Index(decrement!(j))) + return x end end # Getindex functions @@ -178,13 +200,13 @@ for T ∈ valid_vec @eval begin function Base.getindex(A::GBMatrix{$T}, i::Int, j::Int) x = Ref{$T}() - result = libgb.$func(x, A, i - 1, j - 1) - if result == libgb.GrB_SUCCESS + result = LibGraphBLAS.$func(x, A, decrement!(i), decrement!(j)) + if result == LibGraphBLAS.GrB_SUCCESS return x[] - elseif result == libgb.GrB_NO_VALUE + elseif result == LibGraphBLAS.GrB_NO_VALUE return nothing else - throw(ErrorException("Invalid extractElement return value")) + @wraperror result end end # Fix ambiguity @@ -196,29 +218,29 @@ for T ∈ valid_vec func = Symbol(prefix, :_Matrix_extractTuples_, suffix(T)) @eval begin function SparseArrays.findnz(A::GBMatrix{$T}) - nvals = Ref{libgb.GrB_Index}(nnz(A)) - I = Vector{libgb.GrB_Index}(undef, nvals[]) - J = Vector{libgb.GrB_Index}(undef, nvals[]) + nvals = Ref{LibGraphBLAS.GrB_Index}(nnz(A)) + I = Vector{LibGraphBLAS.GrB_Index}(undef, nvals[]) + J = Vector{LibGraphBLAS.GrB_Index}(undef, nvals[]) X = Vector{$T}(undef, nvals[]) - libgb.$func(I, J, X, nvals, A) + @wraperror LibGraphBLAS.$func(I, J, X, nvals, A) nvals[] == length(I) == length(J) == length(X) || throw(DimensionMismatch("length(I) != length(X)")) - return I .+ 1, J .+ 1, X + return increment!(I), increment!(J), X end function SparseArrays.nonzeros(A::GBMatrix{$T}) - nvals = Ref{libgb.GrB_Index}(nnz(A)) + nvals = Ref{LibGraphBLAS.GrB_Index}(nnz(A)) X = Vector{$T}(undef, nvals[]) - libgb.$func(C_NULL, C_NULL, X, nvals, A) + @wraperror LibGraphBLAS.$func(C_NULL, C_NULL, X, nvals, A) nvals[] == length(X) || throw(DimensionMismatch("")) return X end function SparseArrays.nonzeroinds(A::GBMatrix{$T}) - nvals = Ref{libgb.GrB_Index}(nnz(A)) - I = Vector{libgb.GrB_Index}(undef, nvals[]) - J = Vector{libgb.GrB_Index}(undef, nvals[]) + nvals = Ref{LibGraphBLAS.GrB_Index}(nnz(A)) + I = Vector{LibGraphBLAS.GrB_Index}(undef, nvals[]) + J = Vector{LibGraphBLAS.GrB_Index}(undef, nvals[]) wait(A) - libgb.$func(I, J, C_NULL, nvals, A) + @wraperror LibGraphBLAS.$func(I, J, C_NULL, nvals, A) nvals[] == length(I) == length(J) || throw(DimensionMismatch("")) - return I .+ 1, J .+ 1 + return increment!(I), increment!(J) end end end @@ -279,10 +301,33 @@ Assign a submatrix of `A` to `C`. Equivalent to [`assign!`](@ref) except that # Throws - `GrB_DIMENSION_MISMATCH`: If `size(A) != (max(I), max(J))` or `size(A) != size(mask)`. """ + +for T ∈ valid_vec + func = Symbol(:GxB_Matrix_subassign_, suffix(T)) + @eval begin + function _subassign(C::GBMatrix{$T}, x, I, ni, J, nj, mask, accum, desc) + @wraperror LibGraphBLAS.$func(C, mask, accum, x, I, ni, J, nj, desc) + return x + end + end + if T ∈ gxb_vec + prefix = :GxB + else + prefix = :GrB + end + func = Symbol(prefix, :_Matrix_assign_, suffix(T)) + @eval begin + function _assign(C::GBMatrix{$T}, x, I, ni, J, nj, mask, accum, desc) + @wraperror LibGraphBLAS.$func(C, mask, accum, x, I, ni, J, nj, desc) + return x + end + end +end function subassign!( C::GBMatrix, A, I, J; mask = nothing, accum = nothing, desc = nothing ) + A1 = A I, ni = idx(I) J, nj = idx(J) if A isa GBArray @@ -292,14 +337,18 @@ function subassign!( A = GBMatrix(A) end mask === nothing && (mask = C_NULL) + I = decrement!(I) + J = decrement!(J) if A isa GBArray desc = _handledescriptor(desc; in1 = A) - libgb.GxB_Matrix_subassign(C, mask, getaccum(accum, eltype(C)), parent(A), I, ni, J, nj, desc) + @wraperror LibGraphBLAS.GxB_Matrix_subassign(C, mask, getaccum(accum, eltype(C)), parent(A), I, ni, J, nj, desc) else desc = _handledescriptor(desc) - libgb.scalarmatsubassign[eltype(A)](C, mask, getaccum(accum, eltype(C)), A, I, ni, J, nj, desc) + _subassign(C, A, I, ni, J, nj, mask, getaccum(accum, eltype(C)), desc) end - return A + increment!(I) + increment!(J) + return A1 end """ @@ -338,14 +387,18 @@ function assign!( elseif A isa AbstractMatrix A = GBMatrix(A) end + I = decrement!(I) + J = decrement!(J) mask === nothing && (mask = C_NULL) if A isa GBArray desc = _handledescriptor(desc; in1 = A) - libgb.GrB_Matrix_assign(C, mask, getaccum(accum, eltype(C)), parent(A), I, ni, J, nj, desc) + @wraperror LibGraphBLAS.GrB_Matrix_assign(C, mask, getaccum(accum, eltype(C)), parent(A), I, ni, J, nj, desc) else desc = _handledescriptor(desc) - libgb.scalarmatassign[eltype(A)](C, mask, getaccum(accum, eltype(C)), A, I, ni, J, nj, desc) + _assign(C, A, I, ni, J, nj, mask, getaccum(accum, eltype(C)), desc) end + increment!(I) + increment!(J) return A end diff --git a/src/operations/concat.jl b/src/operations/concat.jl index 869cabf6..6df0d957 100644 --- a/src/operations/concat.jl +++ b/src/operations/concat.jl @@ -1,5 +1,5 @@ function hvcat!(C, Tiles) - libgb.GxB_Matrix_concat(C, Tiles, size(Tiles,1), size(Tiles,2), C_NULL) + @wraperror LibGraphBLAS.GxB_Matrix_concat(C, Tiles, size(Tiles,1), size(Tiles,2), C_NULL) return C end diff --git a/src/operations/ewise.jl b/src/operations/ewise.jl index 5ec26d6b..7af2adae 100644 --- a/src/operations/ewise.jl +++ b/src/operations/ewise.jl @@ -36,13 +36,13 @@ function emul!( op = BinaryOp(op)(eltype(A), eltype(B)) accum = getaccum(accum, eltype(C)) if op isa TypedSemiring - libgb.GrB_Matrix_eWiseMult_Semiring(C, mask, accum, op, parent(A), parent(B), desc) + @wraperror LibGraphBLAS.GrB_Matrix_eWiseMult_Semiring(C, mask, accum, op, parent(A), parent(B), desc) return C elseif op isa TypedMonoid - libgb.GrB_Matrix_eWiseMult_Monoid(C, mask, accum, op, parent(A), parent(B), desc) + @wraperror LibGraphBLAS.GrB_Matrix_eWiseMult_Monoid(C, mask, accum, op, parent(A), parent(B), desc) return C elseif op isa TypedBinaryOperator - libgb.GrB_Matrix_eWiseMult_BinaryOp(C, mask, accum, op, parent(A), parent(B), desc) + @wraperror LibGraphBLAS.GrB_Matrix_eWiseMult_BinaryOp(C, mask, accum, op, parent(A), parent(B), desc) return C else throw(ArgumentError("$op is not a valid monoid binary op or semiring.")) @@ -131,13 +131,13 @@ function eadd!( op = BinaryOp(op)(eltype(A), eltype(B)) accum = getaccum(accum, eltype(C)) if op isa TypedSemiring - libgb.GrB_Matrix_eWiseAdd_Semiring(C, mask, accum, op, parent(A), parent(B), desc) + @wraperror LibGraphBLAS.GrB_Matrix_eWiseAdd_Semiring(C, mask, accum, op, parent(A), parent(B), desc) return C elseif op isa TypedMonoid - libgb.GrB_Matrix_eWiseAdd_Monoid(C, mask, accum, op, parent(A), parent(B), desc) + @wraperror LibGraphBLAS.GrB_Matrix_eWiseAdd_Monoid(C, mask, accum, op, parent(A), parent(B), desc) return C elseif op isa TypedBinaryOperator - libgb.GrB_Matrix_eWiseAdd_BinaryOp(C, mask, accum, op, parent(A), parent(B), desc) + @wraperror LibGraphBLAS.GrB_Matrix_eWiseAdd_BinaryOp(C, mask, accum, op, parent(A), parent(B), desc) return C else throw(ArgumentError("$op is not a valid monoid binary op or semiring.")) @@ -226,7 +226,7 @@ function eunion!( op = BinaryOp(op)(eltype(A), eltype(B)) accum = getaccum(accum, eltype(C)) if op isa TypedBinaryOperator - libgb.GxB_Matrix_eWiseUnion(C, mask, accum, op, parent(A), GBScalar(α), parent(B), GBScalar(β), desc) + @wraperror LibGraphBLAS.GxB_Matrix_eWiseUnion(C, mask, accum, op, parent(A), GBScalar(α), parent(B), GBScalar(β), desc) return C else throw(ArgumentError("$op is not a valid binary op.")) diff --git a/src/operations/extract.jl b/src/operations/extract.jl index 320ffd5f..823a79a8 100644 --- a/src/operations/extract.jl +++ b/src/operations/extract.jl @@ -63,7 +63,11 @@ function extract!( J isa Number && (J = UInt64[J]) mask === nothing && (mask = C_NULL) desc = _handledescriptor(desc; in1 = A) - libgb.GrB_Matrix_extract(C, mask, getaccum(accum, eltype(C)), parent(A), I, ni, J, nj, desc) + I = decrement!(I) + J = decrement!(J) + @wraperror LibGraphBLAS.GrB_Matrix_extract(C, mask, getaccum(accum, eltype(C)), parent(A), I, ni, J, nj, desc) + I isa Vector && increment!(I) + J isa Vector && increment!(J) return C end @@ -155,9 +159,11 @@ function extract!( mask = nothing, accum = nothing, desc = nothing ) I, ni = idx(I) + I = decrement!(I) desc = _handledescriptor(desc) mask === nothing && (mask = C_NULL) - libgb.GrB_Matrix_extract(w, mask, getaccum(accum, eltype(w)), u, I, ni, UInt64[1], 1, desc) + @wraperror LibGraphBLAS.GrB_Matrix_extract(w, mask, getaccum(accum, eltype(w)), u, I, ni, UInt64[1], 1, desc) + I isa Vector && increment!(I) return w end diff --git a/src/operations/kronecker.jl b/src/operations/kronecker.jl index 3576a2df..4b656ea8 100644 --- a/src/operations/kronecker.jl +++ b/src/operations/kronecker.jl @@ -17,11 +17,11 @@ function LinearAlgebra.kron!( op = BinaryOp(op)(eltype(A), eltype(B)) accum = getaccum(accum, eltype(C)) if op isa TypedBinaryOperator - libgb.GxB_kron(C, mask, accum, op, parent(A), parent(B), desc) + @wraperror LibGraphBLAS.GxB_kron(C, mask, accum, op, parent(A), parent(B), desc) elseif op isa TypedMonoid - libgb.GrB_Matrix_kronecker_Monoid(C, mask, accum, op, parent(A), parent(B), desc) + @wraperror LibGraphBLAS.GrB_Matrix_kronecker_Monoid(C, mask, accum, op, parent(A), parent(B), desc) elseif op isa TypedSemiring - libgb.GrB_Matrix_kronecker_Semiring(C, mask, accum, op, parent(A), parent(B), desc) + @wraperror LibGraphBLAS.GrB_Matrix_kronecker_Semiring(C, mask, accum, op, parent(A), parent(B), desc) else throw(ArgumentError("$op is not a valid monoid binary op or semiring.")) end diff --git a/src/operations/map.jl b/src/operations/map.jl index eacf791f..451c573d 100644 --- a/src/operations/map.jl +++ b/src/operations/map.jl @@ -8,7 +8,7 @@ function Base.map!( desc = _handledescriptor(desc; in1=A) op = UnaryOp(op)(eltype(A)) accum = getaccum(accum, eltype(C)) - libgb.GrB_Matrix_apply(C, mask, accum, op, parent(A), desc) + @wraperror LibGraphBLAS.GrB_Matrix_apply(C, mask, accum, op, parent(A), desc) return C end @@ -57,7 +57,7 @@ function Base.map!( desc = _handledescriptor(desc; in2=A) op = BinaryOp(op)(eltype(A), typeof(x)) accum = getaccum(accum, eltype(C)) - libgb.scalarmatapply1st[optype(typeof(x), eltype(A))](C, mask, accum, op, x, parent(A), desc) + @wraperror LibGraphBLAS.GxB_Matrix_apply_BinaryOp1st(C, mask, accum, op, GBScalar(x), parent(A), desc) return C end @@ -84,7 +84,7 @@ function Base.map!( desc = _handledescriptor(desc; in1=A) op = BinaryOp(op)(eltype(A), typeof(x)) accum = getaccum(accum, eltype(C)) - libgb.scalarmatapply2nd[optype(typeof(x), eltype(A))](C, mask, accum, op, parent(A), x, desc) + @wraperror LibGraphBLAS.GxB_Matrix_apply_BinaryOp2nd(C, mask, accum, op, parent(A), GBScalar(x), desc) return C end diff --git a/src/operations/mul.jl b/src/operations/mul.jl index 4045ee07..875127ce 100644 --- a/src/operations/mul.jl +++ b/src/operations/mul.jl @@ -15,7 +15,7 @@ function LinearAlgebra.mul!( op = Semiring(op)(eltype(A), eltype(B)) accum = getaccum(accum, eltype(C)) op isa TypedSemiring || throw(ArgumentError("$op is not a valid TypedSemiring")) - libgb.GrB_mxm(C, mask, accum, op, parent(A), parent(B), desc) + @wraperror LibGraphBLAS.GrB_mxm(C, mask, accum, op, parent(A), parent(B), desc) return C end diff --git a/src/operations/reduce.jl b/src/operations/reduce.jl index 1d4df0b8..1319f446 100644 --- a/src/operations/reduce.jl +++ b/src/operations/reduce.jl @@ -6,7 +6,7 @@ function reduce!( desc = _handledescriptor(desc; in1=A) op = Monoid(op)(eltype(w)) accum = getaccum(accum, eltype(w)) - libgb.GrB_Matrix_reduce_Monoid(Ptr{libgb.GrB_Vector}(w.p), mask, accum, op, parent(A), desc) + @wraperror LibGraphBLAS.GrB_Matrix_reduce_Monoid(Ptr{LibGraphBLAS.GrB_Vector}(w.p), mask, accum, op, parent(A), desc) return w end @@ -36,16 +36,16 @@ function Base.reduce( return w elseif dims == (1,2) || dims == Colon() || A isa GBVecOrTranspose if init === nothing - c = Ref{typeout}() + c = GBScalar{typeout}() typec = typeout else - c = Ref(init) + GBScalar{typeout}(init) typec = typeof(init) end op = Monoid(op)(typec) desc = _handledescriptor(desc; in1=A) accum = getaccum(accum, typec) - libgb.scalarmatreduce[typeout](c, accum, op, parent(A), desc) + @wraperror LibGraphBLAS.GrB_Matrix_reduce_Monoid_Scalar(c, accum, op, parent(A), desc) return c[] end end diff --git a/src/operations/resize.jl b/src/operations/resize.jl index a5d06a5d..06caf203 100644 --- a/src/operations/resize.jl +++ b/src/operations/resize.jl @@ -1,9 +1,9 @@ function Base.resize!(A::GBMatrix, nrows::Integer, ncols::Integer) - libgb.GrB_Matrix_resize(A, libgb.GrB_Index(nrows), libgb.GrB_Index(ncols)) + @wraperror LibGraphBLAS.GrB_Matrix_resize(A, LibGraphBLAS.GrB_Index(nrows), LibGraphBLAS.GrB_Index(ncols)) return A end function Base.resize!(v::GBVector, nrows::Integer) - libgb.GrB_Matrix_resize(v, libgb.GrB_Index(nrows), 1) + @wraperror LibGraphBLAS.GrB_Matrix_resize(v, LibGraphBLAS.GrB_Index(nrows), 1) return v end diff --git a/src/operations/select.jl b/src/operations/select.jl index c8c7dc34..b076d0ce 100644 --- a/src/operations/select.jl +++ b/src/operations/select.jl @@ -15,7 +15,7 @@ function select!( if thunk isa Number thunk = GBScalar(thunk) end - libgb.GxB_Matrix_select(C, mask, accum, op, parent(A), thunk, desc) + @wraperror LibGraphBLAS.GxB_Matrix_select(C, mask, accum, op, parent(A), thunk, desc) return C end diff --git a/src/operations/transpose.jl b/src/operations/transpose.jl index ce7e9bf8..d4704522 100644 --- a/src/operations/transpose.jl +++ b/src/operations/transpose.jl @@ -21,7 +21,7 @@ function gbtranspose!( mask, accum = _handlenothings(mask, accum) desc = _handledescriptor(desc; in1=A) accum = getaccum(accum, eltype(C)) - libgb.GrB_transpose(C, mask, accum, parent(A), desc) + @wraperror LibGraphBLAS.GrB_transpose(C, mask, accum, parent(A), desc) return C end diff --git a/src/operators/binaryops.jl b/src/operators/binaryops.jl index 713cc3d5..fc8cc1aa 100644 --- a/src/operators/binaryops.jl +++ b/src/operators/binaryops.jl @@ -1,9 +1,9 @@ module BinaryOps import ..SuiteSparseGraphBLAS using ..SuiteSparseGraphBLAS: isGxB, isGrB, TypedBinaryOperator, AbstractBinaryOp, GBType, - valid_vec, juliaop, toGBType, symtotype, Itypes, Ftypes, Ztypes, FZtypes, Rtypes, optype, + valid_vec, juliaop, gbtype, symtotype, Itypes, Ftypes, Ztypes, FZtypes, Rtypes, optype, Ntypes, Ttypes, suffix, valid_union -using ..libgb +using ..LibGraphBLAS export BinaryOp, @binop export second, rminus, iseq, isne, isgt, islt, isge, isle, ∨, ∧, lxor, xnor, fmod, @@ -46,7 +46,7 @@ function typedbinopconstexpr(jlfunc, builtin, namestr, xtype, ytype, outtype) ysym = Symbol(ytype) outsym = Symbol(outtype) if builtin - constquote = :(const $(esc(namesym)) = TypedBinaryOperator{$(esc(:typeof))($(esc(jlfunc))), $(esc(xsym)), $(esc(ysym)), $(esc(outsym))}(true, false, $namestr, libgb.GrB_BinaryOp(), $(esc(jlfunc)))) + constquote = :(const $(esc(namesym)) = TypedBinaryOperator{$(esc(:typeof))($(esc(jlfunc))), $(esc(xsym)), $(esc(ysym)), $(esc(outsym))}(true, false, $namestr, LibGraphBLAS.GrB_BinaryOp(), $(esc(jlfunc)))) else constquote = :(const $(esc(namesym)) = TypedBinaryOperator($(esc(jlfunc)), $(esc(xsym)), $(esc(ysym)), $(esc(outsym)))) end @@ -108,7 +108,6 @@ macro binop(expr...) ytypes = xtypes end outtypes = symtotype(types.args[3]) - println(outtypes) constquote = typedbinopexprs(jlfunc, builtin, name, xtypes, ytypes, outtypes) dispatchquote = Base.remove_linenums!(quote $newfunc diff --git a/src/operators/libgbops.jl b/src/operators/libgbops.jl index 0f7946e1..64a266be 100644 --- a/src/operators/libgbops.jl +++ b/src/operators/libgbops.jl @@ -1,22 +1,22 @@ -ztype(op::libgb.GrB_UnaryOp) = tojuliatype(ptrtogbtype[libgb.GxB_UnaryOp_ztype(op)]) -xtype(op::libgb.GrB_UnaryOp) = tojuliatype(ptrtogbtype[libgb.GxB_UnaryOp_xtype(op)]) -Base.show(io::IO, ::MIME"text/plain", u::libgb.GrB_UnaryOp) = gxbprint(io, u) +ztype(op::LibGraphBLAS.GrB_UnaryOp) = juliatype(ptrtogbtype[LibGraphBLAS.GxB_UnaryOp_ztype(op)]) +xtype(op::LibGraphBLAS.GrB_UnaryOp) = juliatype(ptrtogbtype[LibGraphBLAS.GxB_UnaryOp_xtype(op)]) +Base.show(io::IO, ::MIME"text/plain", u::LibGraphBLAS.GrB_UnaryOp) = gxbprint(io, u) -xtype(op::libgb.GrB_BinaryOp) = tojuliatype(ptrtogbtype[libgb.GxB_BinaryOp_xtype(op)]) -ytype(op::libgb.GrB_BinaryOp) = tojuliatype(ptrtogbtype[libgb.GxB_BinaryOp_ytype(op)]) -ztype(op::libgb.GrB_BinaryOp) = tojuliatype(ptrtogbtype[libgb.GxB_BinaryOp_ztype(op)]) -Base.show(io::IO, ::MIME"text/plain", u::libgb.GrB_BinaryOp) = gxbprint(io, u) +xtype(op::LibGraphBLAS.GrB_BinaryOp) = juliatype(ptrtogbtype[LibGraphBLAS.GxB_BinaryOp_xtype(op)]) +ytype(op::LibGraphBLAS.GrB_BinaryOp) = juliatype(ptrtogbtype[LibGraphBLAS.GxB_BinaryOp_ytype(op)]) +ztype(op::LibGraphBLAS.GrB_BinaryOp) = juliatype(ptrtogbtype[LibGraphBLAS.GxB_BinaryOp_ztype(op)]) +Base.show(io::IO, ::MIME"text/plain", u::LibGraphBLAS.GrB_BinaryOp) = gxbprint(io, u) -operator(monoid::libgb.GrB_Monoid) = libgb.GxB_Monoid_operator(monoid) -xtype(monoid::libgb.GrB_Monoid) = xtype(operator(monoid)) -ytype(monoid::libgb.GrB_Monoid) = ytype(operator(monoid)) -ztype(monoid::libgb.GrB_Monoid) = ztype(operator(monoid)) -Base.show(io::IO, ::MIME"text/plain", m::libgb.GrB_Monoid) = gxbprint(io, m) +operator(monoid::LibGraphBLAS.GrB_Monoid) = LibGraphBLAS.GxB_Monoid_operator(monoid) +xtype(monoid::LibGraphBLAS.GrB_Monoid) = xtype(operator(monoid)) +ytype(monoid::LibGraphBLAS.GrB_Monoid) = ytype(operator(monoid)) +ztype(monoid::LibGraphBLAS.GrB_Monoid) = ztype(operator(monoid)) +Base.show(io::IO, ::MIME"text/plain", m::LibGraphBLAS.GrB_Monoid) = gxbprint(io, m) -mulop(rig::libgb.GrB_Semiring) = libgb.GxB_Semiring_multiply(rig) -addop(rig::libgb.GrB_Semiring) = libgb.GxB_Semiring_add(rig) -xtype(rig::libgb.GrB_Semiring) = xtype(mulop(rig)) -ytype(rig::libgb.GrB_Semiring) = ytype(mulop(rig)) -ztype(rig::libgb.GrB_Semiring) = ztype(addop(rig)) -Base.show(io::IO, ::MIME"text/plain", s::libgb.GrB_Semiring) = gxbprint(io, s) +mulop(rig::LibGraphBLAS.GrB_Semiring) = LibGraphBLAS.GxB_Semiring_multiply(rig) +addop(rig::LibGraphBLAS.GrB_Semiring) = LibGraphBLAS.GxB_Semiring_add(rig) +xtype(rig::LibGraphBLAS.GrB_Semiring) = xtype(mulop(rig)) +ytype(rig::LibGraphBLAS.GrB_Semiring) = ytype(mulop(rig)) +ztype(rig::LibGraphBLAS.GrB_Semiring) = ztype(addop(rig)) +Base.show(io::IO, ::MIME"text/plain", s::LibGraphBLAS.GrB_Semiring) = gxbprint(io, s) diff --git a/src/operators/monoids.jl b/src/operators/monoids.jl index b674aa6e..54497822 100644 --- a/src/operators/monoids.jl +++ b/src/operators/monoids.jl @@ -2,8 +2,8 @@ module Monoids import ..SuiteSparseGraphBLAS using ..SuiteSparseGraphBLAS: isGxB, isGrB, TypedMonoid, AbstractMonoid, GBType, - valid_vec, juliaop, toGBType, symtotype, Itypes, Ftypes, Ztypes, FZtypes, Rtypes, Ntypes, Ttypes, suffix, BinaryOps.BinaryOp, _builtinMonoid, BinaryOps.∨, BinaryOps.∧, BinaryOps.lxor, BinaryOps.xnor, BinaryOps.bxnor -using ..libgb + valid_vec, juliaop, gbtype, symtotype, Itypes, Ftypes, Ztypes, FZtypes, Rtypes, Ntypes, Ttypes, suffix, BinaryOps.BinaryOp, _builtinMonoid, BinaryOps.∨, BinaryOps.∧, BinaryOps.lxor, BinaryOps.xnor, BinaryOps.bxnor +using ..LibGraphBLAS export Monoid, @monoid struct Monoid{F} <: AbstractMonoid diff --git a/src/operators/selectops.jl b/src/operators/selectops.jl index 06d005cf..13dac5d6 100644 --- a/src/operators/selectops.jl +++ b/src/operators/selectops.jl @@ -1,23 +1,23 @@ mutable struct SelectOp <: AbstractSelectOp name::String - p::libgb.GxB_SelectOp + p::LibGraphBLAS.GxB_SelectOp juliaop::Union{Function, Nothing} - function SelectOp(name, p::libgb.GxB_SelectOp, juliaop) + function SelectOp(name, p::LibGraphBLAS.GxB_SelectOp, juliaop) d = new(name, p, juliaop) function f(selectop) - libgb.GxB_SelectOp_free(Ref(selectop.p)) + @wraperror LibGraphBLAS.GxB_SelectOp_free(Ref(selectop.p)) end return finalizer(f, d) end end -const SelectUnion = Union{AbstractSelectOp, libgb.GxB_SelectOp} +const SelectUnion = Union{AbstractSelectOp, LibGraphBLAS.GxB_SelectOp} -Base.unsafe_convert(::Type{libgb.GxB_SelectOp}, selectop::SelectOp) = selectop.p +Base.unsafe_convert(::Type{LibGraphBLAS.GxB_SelectOp}, selectop::SelectOp) = selectop.p -const TRIL = SelectOp("GxB_TRIL", libgb.GxB_SelectOp(C_NULL), LinearAlgebra.tril) -const TRIU = SelectOp("GxB_TRIU", libgb.GxB_SelectOp(C_NULL), LinearAlgebra.triu) -const DIAG = SelectOp("GxB_DIAG", libgb.GxB_SelectOp(C_NULL), LinearAlgebra.diag) +const TRIL = SelectOp("GxB_TRIL", LibGraphBLAS.GxB_SelectOp(), LinearAlgebra.tril) +const TRIU = SelectOp("GxB_TRIU", LibGraphBLAS.GxB_SelectOp(), LinearAlgebra.triu) +const DIAG = SelectOp("GxB_DIAG", LibGraphBLAS.GxB_SelectOp(), LinearAlgebra.diag) """ offdiag(A::GBArray, k=0) @@ -25,47 +25,47 @@ const DIAG = SelectOp("GxB_DIAG", libgb.GxB_SelectOp(C_NULL), LinearAlgebra.diag Select the entries **not** on the `k`th diagonal of A. """ function offdiag end #I don't know of a function which does this already. -const OFFDIAG = SelectOp("GxB_OFFDIAG", libgb.GxB_SelectOp(C_NULL), offdiag) +const OFFDIAG = SelectOp("GxB_OFFDIAG", LibGraphBLAS.GxB_SelectOp(), offdiag) offdiag(A::GBArray, k=0) = select(offdiag, A, k) -const NONZERO = SelectOp("GxB_NONZERO", libgb.GxB_SelectOp(C_NULL), nonzeros) -const EQ_ZERO = SelectOp("GxB_EQ_ZERO", libgb.GxB_SelectOp(C_NULL), nothing) -const GT_ZERO = SelectOp("GxB_GT_ZERO", libgb.GxB_SelectOp(C_NULL), nothing) -const GE_ZERO = SelectOp("GxB_GE_ZERO", libgb.GxB_SelectOp(C_NULL), nothing) -const LT_ZERO = SelectOp("GxB_LT_ZERO", libgb.GxB_SelectOp(C_NULL), nothing) -const LE_ZERO = SelectOp("GxB_LE_ZERO", libgb.GxB_SelectOp(C_NULL), nothing) -const NE = SelectOp("GxB_NE_THUNK", libgb.GxB_SelectOp(C_NULL), !=) -const EQ = SelectOp("GxB_EQ_THUNK", libgb.GxB_SelectOp(C_NULL), ==) -const GT = SelectOp("GxB_GT_THUNK", libgb.GxB_SelectOp(C_NULL), >) -const GE = SelectOp("GxB_GE_THUNK", libgb.GxB_SelectOp(C_NULL), >=) -const LT = SelectOp("GxB_LT_THUNK", libgb.GxB_SelectOp(C_NULL), <) -const LE = SelectOp("GxB_LE_THUNK", libgb.GxB_SelectOp(C_NULL), <=) +const NONZERO = SelectOp("GxB_NONZERO", LibGraphBLAS.GxB_SelectOp(), nonzeros) +const EQ_ZERO = SelectOp("GxB_EQ_ZERO", LibGraphBLAS.GxB_SelectOp(), nothing) +const GT_ZERO = SelectOp("GxB_GT_ZERO", LibGraphBLAS.GxB_SelectOp(), nothing) +const GE_ZERO = SelectOp("GxB_GE_ZERO", LibGraphBLAS.GxB_SelectOp(), nothing) +const LT_ZERO = SelectOp("GxB_LT_ZERO", LibGraphBLAS.GxB_SelectOp(), nothing) +const LE_ZERO = SelectOp("GxB_LE_ZERO", LibGraphBLAS.GxB_SelectOp(), nothing) +const NE = SelectOp("GxB_NE_THUNK", LibGraphBLAS.GxB_SelectOp(), !=) +const EQ = SelectOp("GxB_EQ_THUNK", LibGraphBLAS.GxB_SelectOp(), ==) +const GT = SelectOp("GxB_GT_THUNK", LibGraphBLAS.GxB_SelectOp(), >) +const GE = SelectOp("GxB_GE_THUNK", LibGraphBLAS.GxB_SelectOp(), >=) +const LT = SelectOp("GxB_LT_THUNK", LibGraphBLAS.GxB_SelectOp(), <) +const LE = SelectOp("GxB_LE_THUNK", LibGraphBLAS.GxB_SelectOp(), <=) function SelectOp(name) simple = Symbol(replace(string(name[5:end]), "_THUNK" => "")) constquote = quote - const $simple = SelectOp($name, libgb.GxB_SelectOp(C_NULL)) + const $simple = SelectOp($name, LibGraphBLAS.GxB_SelectOp()) end @eval($constquote) end function _loadselectops() - TRIL.p = load_global("GxB_TRIL", libgb.GxB_SelectOp) - TRIU.p = load_global("GxB_TRIU", libgb.GxB_SelectOp) - DIAG.p = load_global("GxB_DIAG", libgb.GxB_SelectOp) - OFFDIAG.p = load_global("GxB_OFFDIAG", libgb.GxB_SelectOp) - NONZERO.p = load_global("GxB_NONZERO", libgb.GxB_SelectOp) - EQ_ZERO.p = load_global("GxB_EQ_ZERO", libgb.GxB_SelectOp) - GT_ZERO.p = load_global("GxB_GT_ZERO", libgb.GxB_SelectOp) - GE_ZERO.p = load_global("GxB_GE_ZERO", libgb.GxB_SelectOp) - LT_ZERO.p = load_global("GxB_LT_ZERO", libgb.GxB_SelectOp) - LE_ZERO.p = load_global("GxB_LE_ZERO", libgb.GxB_SelectOp) - NE.p = load_global("GxB_NE_THUNK", libgb.GxB_SelectOp) - EQ.p = load_global("GxB_EQ_THUNK", libgb.GxB_SelectOp) - GT.p = load_global("GxB_GT_THUNK", libgb.GxB_SelectOp) - GE.p = load_global("GxB_GE_THUNK", libgb.GxB_SelectOp) - LT.p = load_global("GxB_LT_THUNK", libgb.GxB_SelectOp) - LE.p = load_global("GxB_LE_THUNK", libgb.GxB_SelectOp) + TRIL.p = load_global("GxB_TRIL", LibGraphBLAS.GxB_SelectOp) + TRIU.p = load_global("GxB_TRIU", LibGraphBLAS.GxB_SelectOp) + DIAG.p = load_global("GxB_DIAG", LibGraphBLAS.GxB_SelectOp) + OFFDIAG.p = load_global("GxB_OFFDIAG", LibGraphBLAS.GxB_SelectOp) + NONZERO.p = load_global("GxB_NONZERO", LibGraphBLAS.GxB_SelectOp) + EQ_ZERO.p = load_global("GxB_EQ_ZERO", LibGraphBLAS.GxB_SelectOp) + GT_ZERO.p = load_global("GxB_GT_ZERO", LibGraphBLAS.GxB_SelectOp) + GE_ZERO.p = load_global("GxB_GE_ZERO", LibGraphBLAS.GxB_SelectOp) + LT_ZERO.p = load_global("GxB_LT_ZERO", LibGraphBLAS.GxB_SelectOp) + LE_ZERO.p = load_global("GxB_LE_ZERO", LibGraphBLAS.GxB_SelectOp) + NE.p = load_global("GxB_NE_THUNK", LibGraphBLAS.GxB_SelectOp) + EQ.p = load_global("GxB_EQ_THUNK", LibGraphBLAS.GxB_SelectOp) + GT.p = load_global("GxB_GT_THUNK", LibGraphBLAS.GxB_SelectOp) + GE.p = load_global("GxB_GE_THUNK", LibGraphBLAS.GxB_SelectOp) + LT.p = load_global("GxB_LT_THUNK", LibGraphBLAS.GxB_SelectOp) + LE.p = load_global("GxB_LE_THUNK", LibGraphBLAS.GxB_SelectOp) end diff --git a/src/operators/semirings.jl b/src/operators/semirings.jl index c7ee84fc..520b39fb 100644 --- a/src/operators/semirings.jl +++ b/src/operators/semirings.jl @@ -1,13 +1,13 @@ module Semirings import ..SuiteSparseGraphBLAS using ..SuiteSparseGraphBLAS: isGxB, isGrB, TypedSemiring, AbstractSemiring, GBType, - valid_vec, juliaop, toGBType, symtotype, Itypes, Ftypes, Ztypes, FZtypes, + valid_vec, juliaop, gbtype, symtotype, Itypes, Ftypes, Ztypes, FZtypes, Rtypes, Ntypes, Ttypes, suffix, BinaryOps.BinaryOp, Monoids.Monoid, BinaryOps.second, BinaryOps.rminus, BinaryOps.iseq, BinaryOps.isne, BinaryOps.isgt, BinaryOps.islt, BinaryOps.isge, BinaryOps.isle, BinaryOps.∨, BinaryOps.∧, BinaryOps.lxor, BinaryOps.xnor, BinaryOps.fmod, BinaryOps.bxnor, BinaryOps.bget, BinaryOps.bset, BinaryOps.bclr, BinaryOps.firsti0, BinaryOps.firsti, BinaryOps.firstj0, BinaryOps.firstj, BinaryOps.secondi0, BinaryOps.secondi, BinaryOps.secondj0, BinaryOps.secondj, xtype, ytype, ztype -using ..libgb +using ..LibGraphBLAS export Semiring, @rig struct Semiring{FM, FA} <: AbstractSemiring @@ -49,7 +49,7 @@ function typedrigconstexpr(addfunc, mulfunc, builtin, namestr, xtype, ytype, out :((::$(esc(:Semiring)){$(esc(:typeof))($(esc(addfunc))), $(esc(:typeof))($(esc(mulfunc)))})(::Type{$xsym}, ::Type{$ysym}) = $(esc(namesym))) end return quote - const $(esc(namesym)) = TypedSemiring($builtin, false, $namestr, libgb.GrB_Semiring(), Monoid($(esc(addfunc)))($(esc(outsym))), BinaryOp($(esc(mulfunc)))($(esc(xsym)), $(esc(ysym)))) + const $(esc(namesym)) = TypedSemiring($builtin, false, $namestr, LibGraphBLAS.GrB_Semiring(), Monoid($(esc(addfunc)))($(esc(outsym))), BinaryOp($(esc(mulfunc)))($(esc(xsym)), $(esc(ysym)))) $(dispatchquote) end end diff --git a/src/operators/unaryops.jl b/src/operators/unaryops.jl index c666deea..20943a03 100644 --- a/src/operators/unaryops.jl +++ b/src/operators/unaryops.jl @@ -2,8 +2,8 @@ module UnaryOps import ..SuiteSparseGraphBLAS using ..SuiteSparseGraphBLAS: isGxB, isGrB, TypedUnaryOperator, AbstractUnaryOp, GBType, - valid_vec, juliaop, toGBType, symtotype, Itypes, Ftypes, Ztypes, FZtypes, Rtypes, Ntypes, Ttypes, suffix -using ..libgb + valid_vec, juliaop, gbtype, symtotype, Itypes, Ftypes, Ztypes, FZtypes, Rtypes, Ntypes, Ttypes, suffix +using ..LibGraphBLAS export UnaryOp, @unop export positioni, positionj, frexpx, frexpe @@ -42,7 +42,7 @@ function typedunopconstexpr(jlfunc, builtin, namestr, intype, outtype) insym = Symbol(intype) outsym = Symbol(outtype) if builtin - constquote = :(const $(esc(namesym)) = TypedUnaryOperator{$(esc(:typeof))($(esc(jlfunc))), $(esc(insym)), $(esc(outsym))}(true, false, $namestr, libgb.GrB_UnaryOp(), $(esc(jlfunc)))) + constquote = :(const $(esc(namesym)) = TypedUnaryOperator{$(esc(:typeof))($(esc(jlfunc))), $(esc(insym)), $(esc(outsym))}(true, false, $namestr, LibGraphBLAS.GrB_UnaryOp(), $(esc(jlfunc)))) else constquote = :(const $(esc(namesym)) = TypedUnaryOperator($(esc(jlfunc)), $(esc(insym)), $(esc(outsym)))) end diff --git a/src/options.jl b/src/options.jl index fab9d7b2..2a49b691 100644 --- a/src/options.jl +++ b/src/options.jl @@ -11,41 +11,177 @@ Set an option either for a specific GBArray, or globally. The commonly used opti single GBArray. """ gbset +using .LibGraphBLAS: GrB_Descriptor, GrB_Info, GrB_Desc_Field, GrB_Desc_Value, GrB_OUTP, GrB_MASK, GrB_INP0, GrB_INP1, +GxB_DESCRIPTOR_NTHREADS, GxB_AxB_METHOD, GxB_SORT, GxB_DESCRIPTOR_CHUNK, GxB_HYPER_SWITCH, GxB_BITMAP_SWITCH, +GxB_GLOBAL_CHUNK, GxB_BURBLE, GxB_PRINT_1BASED, GxB_FORMAT, GxB_SPARSITY_STATUS, GxB_SPARSITY_CONTROL, GxB_GLOBAL_NTHREADS +# manually wrapping these. They use `...` so aren't picked up by Clang. + +function GxB_Global_Option_get(field) + if field ∈ [GxB_HYPER_SWITCH, GxB_BITMAP_SWITCH] + T = Cdouble + elseif field ∈ [GxB_FORMAT] + T = UInt32 + elseif field ∈ [GxB_GLOBAL_NTHREADS, GxB_GLOBAL_CHUNK] + T = Cint + elseif field ∈ [GxB_BURBLE] + T = Bool + end + v = Ref{T}() + ccall( + (:GxB_Global_Option_get, libgraphblas), + Cvoid, + (UInt32, Ptr{Cvoid}), + field, + v + ) + return v[] +end + +function GxB_Global_Option_set(field, value) + if field ∈ [GxB_HYPER_SWITCH, GxB_BITMAP_SWITCH, GxB_GLOBAL_CHUNK] + ccall( + (:GxB_Global_Option_set, libgraphblas), + Cvoid, + (UInt32, Cdouble), + field, + value + ) + elseif field ∈ [GxB_GLOBAL_NTHREADS, GxB_BURBLE, GxB_PRINT_1BASED, GxB_FORMAT] + ccall( + (:GxB_Global_Option_set, libgraphblas), + Cvoid, + (UInt32, Cint), + field, + value + ) + end +end + +function GxB_Matrix_Option_get(A, field) + if field ∈ [GxB_HYPER_SWITCH, GxB_BITMAP_SWITCH] + T = Cdouble + elseif field ∈ [GxB_FORMAT, GxB_SPARSITY_STATUS, GxB_SPARSITY_CONTROL] + T = Cint + end + v = Ref{T}() + ccall( + (:GxB_Matrix_Option_get, libgraphblas), + Cvoid, + (LibGraphBLAS.GrB_Matrix, UInt32, Ptr{Cvoid}), + A, + field, + v + ) + return v[] +end + +function GxB_Matrix_Option_set(A, field, value) + if field ∈ [GxB_HYPER_SWITCH, GxB_BITMAP_SWITCH] + ccall( + (:GxB_Matrix_Option_set, libgraphblas), + Cvoid, + (LibGraphBLAS.GrB_Matrix, UInt32, Cdouble), + A, + field, + value + ) + elseif field ∈ [GxB_FORMAT, GxB_SPARSITY_CONTROL] + ccall( + (:GxB_Matrix_Option_set, libgraphblas), + Cvoid, + (LibGraphBLAS.GrB_Matrix, UInt32, UInt32), + A, + field, + value + ) + end +end + +function GxB_Vector_Option_get(A, field) + if field ∈ [GxB_HYPER_SWITCH, GxB_BITMAP_SWITCH] + T = Cdouble + elseif field ∈ [GxB_FORMAT] + T = UInt32 + elseif field ∈ [GxB_SPARSITY_STATUS, GxB_SPARSITY_CONTROL] + T = Cint + end + v = Ref{T}() + ccall( + (:GxB_Vector_Option_get, libgraphblas), + Cvoid, + (LibGraphBLAS.GrB_Vector, UInt32, Ptr{Cvoid}), + A, + field, + v + ) + return v[] +end + +function GxB_Vector_Option_set(A, field, value) + if field ∈ [GxB_HYPER_SWITCH, GxB_BITMAP_SWITCH] + ccall( + (:GxB_Vector_Option_set, libgraphblas), + Cvoid, + (LibGraphBLAS.GrB_Vector, UInt32, Cdouble), + A, + field, + value + ) + elseif field ∈ [GxB_FORMAT] + ccall( + (:GxB_Vector_Option_set, libgraphblas), + Cvoid, + (LibGraphBLAS.GrB_Vector, UInt32, UInt32), + A, + field, + value + ) + elseif field ∈ [GxB_SPARSITY_CONTROL] + ccall( + (:GxB_Vector_Option_set, libgraphblas), + Cvoid, + (LibGraphBLAS.GrB_Vector, UInt32, Cint), + A, + field, + value + ) + end +end function gbset(option, value) option = option_toconst(option) value = option_toconst(value) - libgb.GxB_Global_Option_set(option, value) + GxB_Global_Option_set(option, value) return nothing end function gbget(option) option = option_toconst(option) - return libgb.GxB_Global_Option_get(option) + return GxB_Global_Option_get(option) end function gbset(A::GBMatrix, option, value) option = option_toconst(option) value = option_toconst(value) - libgb.GxB_Matrix_Option_set(A, option, value) + GxB_Matrix_Option_set(A, option, value) return nothing end function gbget(A::GBMatrix, option) option = option_toconst(option) - return libgb.GxB_Matrix_Option_get(A, option) + return GxB_Matrix_Option_get(A, option) end function gbset(A::GBVector, option, value) option = option_toconst(option) value = option_toconst(value) - libgb.GxB_Matrix_Option_set(A, option, value) + GxB_Matrix_Option_set(A.p, option, value) return nothing end function gbget(A::GBVector, option) option = option_toconst(option) - return libgb.GxB_Matrix_Option_get(A, option) + return GxB_Matrix_Option_get(A.p, option) end function format(A::GBVecOrMat) @@ -54,17 +190,17 @@ function format(A::GBVecOrMat) return (GBSparsity(t), GBFormat(f)) end -const HYPER_SWITCH = libgb.GxB_HYPER_SWITCH -const BITMAP_SWITCH = libgb.GxB_BITMAP_SWITCH -const FORMAT = libgb.GxB_FORMAT -const SPARSITY_STATUS = libgb.GxB_SPARSITY_STATUS -const SPARSITY_CONTROL = libgb.GxB_SPARSITY_CONTROL -const BASE1 = libgb.GxB_PRINT_1BASED -const NTHREADS = libgb.GxB_GLOBAL_NTHREADS -const BURBLE = libgb.GxB_BURBLE +const HYPER_SWITCH = LibGraphBLAS.GxB_HYPER_SWITCH +const BITMAP_SWITCH = LibGraphBLAS.GxB_BITMAP_SWITCH +const FORMAT = LibGraphBLAS.GxB_FORMAT +const SPARSITY_STATUS = LibGraphBLAS.GxB_SPARSITY_STATUS +const SPARSITY_CONTROL = LibGraphBLAS.GxB_SPARSITY_CONTROL +const BASE1 = LibGraphBLAS.GxB_PRINT_1BASED +const NTHREADS = LibGraphBLAS.GxB_GLOBAL_NTHREADS +const BURBLE = LibGraphBLAS.GxB_BURBLE -const BYROW = libgb.GxB_BY_ROW -const BYCOL = libgb.GxB_BY_COL +const BYROW = LibGraphBLAS.GxB_BY_ROW +const BYCOL = LibGraphBLAS.GxB_BY_COL #only translate if it's a symbol option_toconst(option) = option @@ -87,12 +223,12 @@ end Sparsity options for GraphBLAS. values can be summed to produce additional options. """ @enum GBSparsity::Int32 begin - GBDENSE = 8 #libgb.GxB_FULL - GBBITMAP = 4 #libgb.GxB_BITMAP - GBSPARSE = 2 #libgb.GxB_SPARSE - GBHYPER = 1 #libgb.GxB_HYPERSPARSE - GBANYSPARSITY = 15 #libgb.GxB_ANY_SPARSITY - GBDENSE_OR_BITMAP = 12 #libgb.GxB_FULL + libgb.GXB_BITMAP - GBSPARSE_OR_HYPER = 3 #libgb.GxB_SPARSE + libgb.GXB_HYPERSPARSE + GBDENSE = 8 #LibGraphBLAS.GxB_FULL + GBBITMAP = 4 #LibGraphBLAS.GxB_BITMAP + GBSPARSE = 2 #LibGraphBLAS.GxB_SPARSE + GBHYPER = 1 #LibGraphBLAS.GxB_HYPERSPARSE + GBANYSPARSITY = 15 #LibGraphBLAS.GxB_ANY_SPARSITY + GBDENSE_OR_BITMAP = 12 #LibGraphBLAS.GxB_FULL + LibGraphBLAS.GXB_BITMAP + GBSPARSE_OR_HYPER = 3 #LibGraphBLAS.GxB_SPARSE + LibGraphBLAS.GXB_HYPERSPARSE #... Probably don't need others end diff --git a/src/pack.jl b/src/pack.jl index 243a2ae7..3a51fbe8 100644 --- a/src/pack.jl +++ b/src/pack.jl @@ -3,7 +3,7 @@ function _packdensematrix!(A::GBVecOrMat{T}, M::DenseVecOrMat; desc = nothing) w Csize = length(A) * sizeof(T) values = Ref{Ptr{Cvoid}}(pointer(M)) isuniform = false - libgb.GxB_Matrix_pack_FullC( + @wraperror LibGraphBLAS.GxB_Matrix_pack_FullC( A.p, values, Csize, @@ -22,15 +22,15 @@ function _packcscmatrix!( ) where {T, Ti} colptr .-= 1 rowidx .-= 1 - colptrsize = length(colptr) * sizeof(libgb.GrB_Index) - rowidxsize = length(rowidx) * sizeof(libgb.GrB_Index) + colptrsize = length(colptr) * sizeof(LibGraphBLAS.GrB_Index) + rowidxsize = length(rowidx) * sizeof(LibGraphBLAS.GrB_Index) valsize = length(values) * sizeof(T) - colptr = Ref{Ptr{libgb.GrB_Index}}(pointer(colptr)) - rowidx = Ref{Ptr{libgb.GrB_Index}}(pointer(rowidx)) + colptr = Ref{Ptr{LibGraphBLAS.GrB_Index}}(pointer(colptr)) + rowidx = Ref{Ptr{LibGraphBLAS.GrB_Index}}(pointer(rowidx)) values = Ref{Ptr{Cvoid}}(pointer(values)) desc = _handledescriptor(desc) - x = libgb.GxB_Matrix_pack_CSC( + @wraperror LibGraphBLAS.GxB_Matrix_pack_CSC( A, colptr, rowidx, @@ -54,15 +54,15 @@ function _packcsrmatrix!( ) where {T, Ti} rowptr .-= 1 colidx .-= 1 - rowptrsize = length(rowptr) * sizeof(libgb.GrB_Index) - colidxsize = length(colidx) * sizeof(libgb.GrB_Index) + rowptrsize = length(rowptr) * sizeof(LibGraphBLAS.GrB_Index) + colidxsize = length(colidx) * sizeof(LibGraphBLAS.GrB_Index) valsize = length(values) * sizeof(T) - rowptr = Ref{Ptr{libgb.GrB_Index}}(pointer(rowptr)) - colidx = Ref{Ptr{libgb.GrB_Index}}(pointer(colidx)) + 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) - libgb.GxB_Matrix_pack_CSC( + @wraperror LibGraphBLAS.GxB_Matrix_pack_CSC( A, rowptr, colidx, @@ -78,5 +78,5 @@ function _packcsrmatrix!( end function _makeshallow!(A::GBVecOrMat) - ccall((:GB_make_shallow, libgraphblas), Cvoid, (libgb.GrB_Matrix,), A) + ccall((:GB_make_shallow, libgraphblas), Cvoid, (LibGraphBLAS.GrB_Matrix,), A) end \ No newline at end of file diff --git a/src/print.jl b/src/print.jl index f2d7ccea..63d648bd 100644 --- a/src/print.jl +++ b/src/print.jl @@ -1,38 +1,38 @@ -function gxbprint(io::IO, x, name = "", level::libgb.GxB_Print_Level = libgb.GxB_SUMMARY) +function gxbprint(io::IO, x, name = "", level::LibGraphBLAS.GxB_Print_Level = LibGraphBLAS.GxB_SUMMARY) print(io, gxbstring(x, name, level)) end -function gxbstring(x, name = "", level::libgb.GxB_Print_Level = libgb.GxB_SUMMARY) +function gxbstring(x, name = "", level::LibGraphBLAS.GxB_Print_Level = LibGraphBLAS.GxB_SUMMARY) str = mktemp() do _, f cf = Libc.FILE(f) if x isa AbstractGBType - libgb.GxB_Type_fprint(x, name, level, cf) - elseif x isa libgb.GrB_UnaryOp - libgb.GxB_UnaryOp_fprint(x, name, level, cf) - elseif x isa libgb.GrB_BinaryOp - libgb.GxB_BinaryOp_fprint(x, name, level, cf) - elseif x isa libgb.GrB_Monoid - libgb.GxB_Monoid_fprint(x, name, level, cf) + @wraperror LibGraphBLAS.GxB_Type_fprint(x, name, level, cf) + elseif x isa LibGraphBLAS.GrB_UnaryOp + @wraperror LibGraphBLAS.GxB_UnaryOp_fprint(x, name, level, cf) + elseif x isa LibGraphBLAS.GrB_BinaryOp + @wraperror LibGraphBLAS.GxB_BinaryOp_fprint(x, name, level, cf) + elseif x isa LibGraphBLAS.GrB_Monoid + @wraperror LibGraphBLAS.GxB_Monoid_fprint(x, name, level, cf) elseif x isa SelectUnion - libgb.GxB_SelectOp_fprint(x, name, level, cf) - elseif x isa libgb.GrB_Semiring - libgb.GxB_Semiring_fprint(x, name, level, cf) + @wraperror LibGraphBLAS.GxB_SelectOp_fprint(x, name, level, cf) + elseif x isa LibGraphBLAS.GrB_Semiring + @wraperror LibGraphBLAS.GxB_Semiring_fprint(x, name, level, cf) elseif x isa AbstractDescriptor - libgb.GxB_Descriptor_fprint(x, name, level, cf) + @wraperror LibGraphBLAS.GxB_Descriptor_fprint(x, name, level, cf) elseif x isa GBVector - if level == libgb.GxB_SUMMARY - libgb.GxB_Matrix_fprint(x, name, libgb.GxB_SHORT, cf) + if level == LibGraphBLAS.GxB_SUMMARY + @wraperror LibGraphBLAS.GxB_Matrix_fprint(x, name, LibGraphBLAS.GxB_SHORT, cf) else - libgb.GxB_Matrix_fprint(x, name, level, cf) + @wraperror LibGraphBLAS.GxB_Matrix_fprint(x, name, level, cf) end elseif x isa GBMatrix - if level == libgb.GxB_SUMMARY - libgb.GxB_Matrix_fprint(x, name, libgb.GxB_SHORT, cf) + if level == LibGraphBLAS.GxB_SUMMARY + @wraperror LibGraphBLAS.GxB_Matrix_fprint(x, name, LibGraphBLAS.GxB_SHORT, cf) else - libgb.GxB_Vector_fprint(x, name, level, cf) + @wraperror LibGraphBLAS.GxB_Vector_fprint(x, name, level, cf) end elseif x isa GBScalar - libgb.GxB_Scalar_fprint(x, name, libgb.GxB_SHORT, cf) + @wraperror LibGraphBLAS.GxB_Scalar_fprint(x, name, LibGraphBLAS.GxB_SHORT, cf) end flush(f) seekstart(f) diff --git a/src/scalar.jl b/src/scalar.jl index d9e47339..be8c52a0 100644 --- a/src/scalar.jl +++ b/src/scalar.jl @@ -1,8 +1,12 @@ # Constructors: ############### -GBScalar{T}() where {T} = GBScalar{T}(libgb.GxB_Scalar_new(toGBType(T))) +function GBScalar{T}() where {T} + s = Ref{LibGraphBLAS.GxB_Scalar}() + @wraperror LibGraphBLAS.GxB_Scalar_new(s, gbtype(T)) + return GBScalar{T}(s[]) +end -function GBScalar(v::T) where {T <: valid_union} +function GBScalar(v::T) where {T} x = GBScalar{T}() x[] = v return x @@ -10,26 +14,33 @@ end # Some Base and basic SparseArrays/LinearAlgebra functions: ########################################################### -Base.unsafe_convert(::Type{libgb.GxB_Scalar}, s::GBScalar) = s.p +Base.unsafe_convert(::Type{LibGraphBLAS.GxB_Scalar}, s::GBScalar) = s.p function Base.copy(s::GBScalar{T}) where {T} - return GBScalar{T}(libgb.GxB_Scalar_dup(s)) + s2 = Ref{LibGraphBLAS.GxB_Scalar}() + @wraperror LibGraphBLAS.GxB_Scalar_dup(s2, s) + return GBScalar{T}(s2[]) end -clear!(s::GBScalar) = libgb.GxB_Scalar_clear(s) +function clear!(s::GBScalar) + @wraperror LibGraphBLAS.GxB_Scalar_clear(s) +end # Type dependent functions setindex and getindex: for T ∈ valid_vec func = Symbol(:GxB_Scalar_setElement_, suffix(T)) @eval begin function Base.setindex!(value::GBScalar{$T}, s::$T) - libgb.$func(value, s) + @wraperror LibGraphBLAS.$func(value, s) + return s end end func = Symbol(:GxB_Scalar_extractElement_, suffix(T)) @eval begin function Base.getindex(value::GBScalar{$T}) - libgb.$func(value) + x = Ref{$T}() + @wraperror LibGraphBLAS.$func(x, value) + return x[] end end end @@ -40,4 +51,8 @@ function Base.show(io::IO, ::MIME"text/plain", s::GBScalar) gxbprint(io, s) end -SparseArrays.nnz(v::GBScalar) = Int64(libgb.GrB_Scalar_nvals(v)) +function SparseArrays.nnz(v::GBScalar) + n = Ref{LibGraphBLAS.GrB_Index}() + @wraperror LibGraphBLAS.GrB_Scalar_nvals(n, v) + return n[] +end diff --git a/src/types.jl b/src/types.jl index fd16e84c..a957df56 100644 --- a/src/types.jl +++ b/src/types.jl @@ -2,26 +2,26 @@ mutable struct TypedUnaryOperator{F, X, Z} <: AbstractTypedOp{Z} builtin::Bool loaded::Bool typestr::String # If a built-in this is something like GxB_AINV_FP64, if not it's just some user defined string. - p::libgb.GrB_UnaryOp + p::LibGraphBLAS.GrB_UnaryOp fn::F function TypedUnaryOperator{F, X, Z}(builtin, loaded, typestr, p, fn) where {F, X, Z} unop = new(builtin, loaded, typestr, p, fn) return finalizer(unop) do op - libgb.GrB_UnaryOp_free(Ref(op.p)) + @wraperror LibGraphBLAS.GrB_UnaryOp_free(Ref(op.p)) end end end function TypedUnaryOperator(fn::F, ::Type{X}, ::Type{Z}) where {F, X, Z} - return TypedUnaryOperator{F, X, Z}(false, false, string(fn), libgb.GrB_UnaryOp(), fn) + return TypedUnaryOperator{F, X, Z}(false, false, string(fn), LibGraphBLAS.GrB_UnaryOp(), fn) end -function Base.unsafe_convert(::Type{libgb.GrB_UnaryOp}, op::TypedUnaryOperator{F, X, Z}) where {F, X, Z} +function Base.unsafe_convert(::Type{LibGraphBLAS.GrB_UnaryOp}, op::TypedUnaryOperator{F, X, Z}) where {F, X, Z} # We can lazily load the built-ins since they are already constants. # Could potentially do this with UDFs, but probably not worth the effort. if !op.loaded if op.builtin - op.p = load_global(op.typestr, libgb.GrB_UnaryOp) + op.p = load_global(op.typestr, LibGraphBLAS.GrB_UnaryOp) else fn = op.fn @@ -29,9 +29,10 @@ function Base.unsafe_convert(::Type{libgb.GrB_UnaryOp}, op::TypedUnaryOperator{F unsafe_store!(z, fn(x)) return nothing end - opref = Ref{libgb.GrB_UnaryOp}() + opref = Ref{LibGraphBLAS.GrB_UnaryOp}() unaryopfn_C = @cfunction($unaryopfn, Cvoid, (Ptr{Z}, Ref{X})) - libgb.GB_UnaryOp_new(opref, unaryopfn_C, toGBType(Z), toGBType(X), string(fn)) + # the "" below is a placeholder for C code in the future for JIT'ing. (And maybe compiled code as a ptr :pray:?) + LibGraphBLAS.GxB_UnaryOp_new(opref, unaryopfn_C, gbtype(Z), gbtype(X), string(fn), "") op.p = opref[] end op.loaded = true @@ -47,32 +48,32 @@ mutable struct TypedBinaryOperator{F, X, Y, Z} <: AbstractTypedOp{Z} builtin::Bool loaded::Bool typestr::String # If a built-in this is something like GxB_AINV_FP64, if not it's just some user defined string. - p::libgb.GrB_BinaryOp + p::LibGraphBLAS.GrB_BinaryOp fn::F function TypedBinaryOperator{F, X, Y, Z}(builtin, loaded, typestr, p, fn::F) where {F, X, Y, Z} binop = new(builtin, loaded, typestr, p, fn) return finalizer(binop) do op - libgb.GrB_BinaryOp_free(Ref(op.p)) + @wraperror LibGraphBLAS.GrB_BinaryOp_free(Ref(op.p)) end end end function TypedBinaryOperator(fn::F, ::Type{X}, ::Type{Y}, ::Type{Z}) where {F, X, Y, Z} - return TypedBinaryOperator{F, X, Y, Z}(false, false, string(fn), libgb.GrB_BinaryOp(), fn) + return TypedBinaryOperator{F, X, Y, Z}(false, false, string(fn), LibGraphBLAS.GrB_BinaryOp(), fn) end -function Base.unsafe_convert(::Type{libgb.GrB_BinaryOp}, op::TypedBinaryOperator{F, X, Y, Z}) where {F, X, Y, Z} +function Base.unsafe_convert(::Type{LibGraphBLAS.GrB_BinaryOp}, op::TypedBinaryOperator{F, X, Y, Z}) where {F, X, Y, Z} if !op.loaded if op.builtin - op.p = load_global(op.typestr, libgb.GrB_UnaryOp) + op.p = load_global(op.typestr, LibGraphBLAS.GrB_UnaryOp) else fn = op.fn function binaryopfn(z, x, y) unsafe_store!(z, fn(x, y)) return nothing end - opref = Ref{libgb.GrB_BinaryOp}() + opref = Ref{LibGraphBLAS.GrB_BinaryOp}() binaryopfn_C = @cfunction($binaryopfn, Cvoid, (Ptr{Z}, Ref{X}, Ref{Y})) - libgb.GB_BinaryOp_new(opref, binaryopfn_C, toGBType(Z), toGBType(X), toGBType(Y), string(fn)) + @wraperror LibGraphBLAS.GB_BinaryOp_new(opref, binaryopfn_C, gbtype(Z), gbtype(X), gbtype(Y), string(fn)) op.p = opref[] end op.loaded = true @@ -88,39 +89,54 @@ mutable struct TypedMonoid{F, Z, T} <: AbstractTypedOp{Z} builtin::Bool loaded::Bool typestr::String # If a built-in this is something like GrB_PLUS_FP64, if not it's just some user defined string. - p::libgb.GrB_Monoid + p::LibGraphBLAS.GrB_Monoid binaryop::TypedBinaryOperator{F, Z, Z, Z} identity::Z terminal::T function TypedMonoid(builtin, loaded, typestr, p, binaryop::TypedBinaryOperator{F, Z, Z, Z}, identity::Z, terminal::T) where {F, Z, T<:Union{Z, Nothing}} monoid = new{F, Z, T}(builtin, loaded, typestr, p, binaryop, identity, terminal) return finalizer(monoid) do op - libgb.GrB_Monoid_free(Ref(op.p)) + @wraperror LibGraphBLAS.GrB_Monoid_free(Ref(op.p)) end end end -function Base.unsafe_convert(::Type{libgb.GrB_Monoid}, op::TypedMonoid{Z, T}) where {Z, T} - if !op.loaded - if op.builtin - op.p = load_global(op.typestr, libgb.GrB_Monoid) - else - opref = Ref{libgb.GrB_Monoid}() +for Z ∈ valid_vec + if Z ∈ gxb_vec + prefix = :GxB + else + prefix = :GrB + end + # Build functions + func = Symbol(prefix, :_Monoid_new_, suffix(Z)) + functerm = Symbol(:GxB_Monoid_terminal_new_, suffix(Z)) + @eval begin + function _monoidnew!(op::TypedMonoid{F, $Z, T}) where {F, T} + opref = Ref{LibGraphBLAS.GrB_Monoid}() if op.terminal === nothing if Z ∈ valid_union - libgb.monoididnew[Z](opref, op.binop, op.identity) + @wraperror LibGraphBLAS.$func(opref, op.binop, op.identity) else - libgb.monoididnew[Any](opref, op.binop, Ref(op.identity)) + @wraperror LibGraphBLAS.GrB_Monoid_new_UDT(opref, op.binop, Ref(op.identity)) end else if Z ∈ valid_union - libgb.monoidtermnew[Z](opref, op.binop, op.identity, op.terminal) + @wraperror LibGraphBLAS.$functerm(opref, op.binop, op.identity, op.terminal) else - libgb.monoidtermnew[Any](opref, op.binop, Ref(op.identity), Ref(op.terminal)) + @wraperror LibGraphBLAS.GrB_Monoid_terminal_new_UDT(opref, op.binop, Ref(op.identity), Ref(op.terminal)) end end op.p = opref[] end + end +end +function Base.unsafe_convert(::Type{LibGraphBLAS.GrB_Monoid}, op::TypedMonoid{F, Z, T}) where {F, Z, T} + if !op.loaded + if op.builtin + op.p = load_global(op.typestr, LibGraphBLAS.GrB_Monoid) + else + _monoidnew!(op) + end op.loaded = true end if !op.loaded @@ -131,11 +147,11 @@ function Base.unsafe_convert(::Type{libgb.GrB_Monoid}, op::TypedMonoid{Z, T}) wh end function _builtinMonoid(typestr, binaryop::TypedBinaryOperator{F, Z, Z, Z}, identity, terminal::T) where {F, Z, T} - return TypedMonoid(true, false, typestr, libgb.GrB_Monoid(), binaryop, identity, terminal) + return TypedMonoid(true, false, typestr, LibGraphBLAS.GrB_Monoid(), binaryop, identity, terminal) end function TypedMonoid(binop::TypedBinaryOperator{F, Z, Z, Z}, identity::Z, terminal::T) where {F, Z, T} - return TypedMonoid(false, false, string(fn), libgb.GrB_Monoid(), binop, identity, terminal) + return TypedMonoid(false, false, string(fn), LibGraphBLAS.GrB_Monoid(), binop, identity, terminal) end #Enable use of functions for determining identity and terminal values. Could likely be pared down to 2 functions somehow. @@ -154,24 +170,24 @@ mutable struct TypedSemiring{FA, FM, X, Y, Z, T} <: AbstractTypedOp{Z} builtin::Bool loaded::Bool typestr::String - p::libgb.GrB_Semiring + p::LibGraphBLAS.GrB_Semiring addop::TypedMonoid{FA, Z, T} mulop::TypedBinaryOperator{FM, X, Y, Z} function TypedSemiring(builtin, loaded, typestr, p, addop::TypedMonoid{FA, Z, T}, mulop::TypedBinaryOperator{FM, X, Y, Z}) where {FA, FM, X, Y, Z, T} semiring = new{FA, FM, X, Y, Z, T}(builtin, loaded, typestr, p, addop, mulop) return finalizer(semiring) do rig - libgb.GrB_Semiring_free(Ref(rig.p)) + @wraperror LibGraphBLAS.GrB_Semiring_free(Ref(rig.p)) end end end -function Base.unsafe_convert(::Type{libgb.GrB_Semiring}, op::TypedSemiring) +function Base.unsafe_convert(::Type{LibGraphBLAS.GrB_Semiring}, op::TypedSemiring) if !op.loaded if op.builtin - op.p = load_global(op.typestr, libgb.GrB_Semiring) + op.p = load_global(op.typestr, LibGraphBLAS.GrB_Semiring) else - opref = Ref{libgb.GrB_Semiring}() - libgb.GrB_Semiring_new(opref, op.addop, op.mulop) + opref = Ref{LibGraphBLAS.GrB_Semiring}() + @wraperror LibGraphBLAS.GrB_Semiring_new(opref, op.addop, op.mulop) op.p = opref[] end op.loaded = true @@ -183,16 +199,16 @@ function Base.unsafe_convert(::Type{libgb.GrB_Semiring}, op::TypedSemiring) end end -TypedSemiring(addop, mulop) = TypedSemiring(false, false, "", libgb.GrB_Semiring(), addop, mulop) +TypedSemiring(addop, mulop) = TypedSemiring(false, false, "", LibGraphBLAS.GrB_Semiring(), addop, mulop) """ """ mutable struct GBScalar{T} - p::libgb.GxB_Scalar - function GBScalar{T}(p::libgb.GxB_Scalar) where {T} + p::LibGraphBLAS.GxB_Scalar + function GBScalar{T}(p::LibGraphBLAS.GxB_Scalar) where {T} s = new(p) function f(scalar) - libgb.GxB_Scalar_free(Ref(scalar.p)) + @wraperror LibGraphBLAS.GxB_Scalar_free(Ref(scalar.p)) end return finalizer(f, s) end @@ -208,13 +224,17 @@ compressed sparse vector. See also: [`GBMatrix`](@ref). """ mutable struct GBVector{T} <: AbstractSparseArray{T, UInt64, 1} - p::libgb.GrB_Matrix - function GBVector{T}(p::libgb.GrB_Matrix) where {T} + p::LibGraphBLAS.GrB_Matrix + function GBVector{T}(p::LibGraphBLAS.GrB_Matrix; aliased=false) where {T} v = new(p) function f(vector) - libgb.GrB_Matrix_free(Ref(vector.p)) + @wraperror LibGraphBLAS.GrB_Matrix_free(Ref(vector.p)) + end + if aliased + return v + else + return finalizer(f, v) end - return finalizer(f, v) end end @@ -233,12 +253,16 @@ row or column orientation: The storage type is automatically determined by the library. """ mutable struct GBMatrix{T} <: AbstractSparseArray{T, UInt64, 2} - p::libgb.GrB_Matrix - function GBMatrix{T}(p::libgb.GrB_Matrix) where {T} + p::LibGraphBLAS.GrB_Matrix + function GBMatrix{T}(p::LibGraphBLAS.GrB_Matrix; aliased=false) where {T} A = new(p) function f(matrix) - libgb.GrB_Matrix_free(Ref(matrix.p)) + @wraperror LibGraphBLAS.GrB_Matrix_free(Ref(matrix.p)) + end + if aliased + return A + else + return finalizer(f, A) end - return finalizer(f, A) end end diff --git a/src/unpack.jl b/src/unpack.jl index 05f0f76b..89c119dd 100644 --- a/src/unpack.jl +++ b/src/unpack.jl @@ -1,9 +1,9 @@ function _unpackdensematrix!(A::GBVecOrMat{T}; desc = nothing) where {T} desc = _handledescriptor(desc) - Csize = Ref{libgb.GrB_Index}(length(A) * sizeof(T)) + Csize = Ref{LibGraphBLAS.GrB_Index}(length(A) * sizeof(T)) values = Ref{Ptr{Cvoid}}(Ptr{T}()) isiso = Ref{Bool}(false) - libgb.GxB_Matrix_unpack_FullC( + @wraperror LibGraphBLAS.GxB_Matrix_unpack_FullC( A.p, values, Csize, @@ -15,15 +15,15 @@ end function _unpackcscmatrix!(A::GBVecOrMat{T}; desc = nothing) where {T} desc = _handledescriptor(desc) - colptr = Ref{Ptr{libgb.GrB_Index}}() - rowidx = Ref{Ptr{libgb.GrB_Index}}() + colptr = Ref{Ptr{LibGraphBLAS.GrB_Index}}() + rowidx = Ref{Ptr{LibGraphBLAS.GrB_Index}}() values = Ref{Ptr{Cvoid}}(Ptr{T}()) - colptrsize = Ref{libgb.GrB_Index}() - rowidxsize = Ref{libgb.GrB_Index}() - valsize = Ref{libgb.GrB_Index}() + colptrsize = Ref{LibGraphBLAS.GrB_Index}() + rowidxsize = Ref{LibGraphBLAS.GrB_Index}() + valsize = Ref{LibGraphBLAS.GrB_Index}() isiso = Ref{Bool}(false) isjumbled = Ref{Bool}(false) - libgb.GxB_Matrix_unpack_CSC( + @wraperror LibGraphBLAS.GxB_Matrix_unpack_CSC( A.p, colptr, rowidx, @@ -35,8 +35,8 @@ function _unpackcscmatrix!(A::GBVecOrMat{T}; desc = nothing) where {T} isjumbled, desc ) - colptr = unsafe_wrap(Array{libgb.GrB_Index}, colptr[], colptrsize[] ÷ sizeof(libgb.GrB_Index)) - rowidx = unsafe_wrap(Array{libgb.GrB_Index}, rowidx[], rowidxsize[] ÷ sizeof(libgb.GrB_Index)) + colptr = unsafe_wrap(Array{LibGraphBLAS.GrB_Index}, colptr[], colptrsize[] ÷ sizeof(LibGraphBLAS.GrB_Index)) + rowidx = unsafe_wrap(Array{LibGraphBLAS.GrB_Index}, rowidx[], rowidxsize[] ÷ sizeof(LibGraphBLAS.GrB_Index)) colptr .+= 1 rowidx .+= 1 return colptr, @@ -46,15 +46,15 @@ end function _unpackcsrmatrix!(A::GBVecOrMat{T}; desc = nothing) where {T} desc = _handledescriptor(desc) - rowptr = Ref{Ptr{libgb.GrB_Index}}() - colidx = Ref{Ptr{libgb.GrB_Index}}() + rowptr = Ref{Ptr{LibGraphBLAS.GrB_Index}}() + colidx = Ref{Ptr{LibGraphBLAS.GrB_Index}}() values = Ref{Ptr{Cvoid}}(Ptr{T}()) - colidxsize = Ref{libgb.GrB_Index}() - rowptrsize = Ref{libgb.GrB_Index}() - valsize = Ref{libgb.GrB_Index}() + colidxsize = Ref{LibGraphBLAS.GrB_Index}() + rowptrsize = Ref{LibGraphBLAS.GrB_Index}() + valsize = Ref{LibGraphBLAS.GrB_Index}() isiso = Ref{Bool}(false) isjumbled = Ref{Bool}(false) - libgb.GxB_Matrix_unpack_CSR( + @wraperror LibGraphBLAS.GxB_Matrix_unpack_CSR( A.p, rowptr, colidx, @@ -66,8 +66,8 @@ function _unpackcsrmatrix!(A::GBVecOrMat{T}; desc = nothing) where {T} isjumbled, desc ) - rowptr = unsafe_wrap(Array{libgb.GrB_Index}, rowptr[], rowptrsize[] ÷ sizeof(libgb.GrB_Index)) - colidx = unsafe_wrap(Array{libgb.GrB_Index}, colidx[], colidxsize[] ÷ sizeof(libgb.GrB_Index)) + rowptr = unsafe_wrap(Array{LibGraphBLAS.GrB_Index}, rowptr[], rowptrsize[] ÷ sizeof(LibGraphBLAS.GrB_Index)) + colidx = unsafe_wrap(Array{LibGraphBLAS.GrB_Index}, colidx[], colidxsize[] ÷ sizeof(LibGraphBLAS.GrB_Index)) rowptr .+= 1 colidx .+= 1 return rowptr, diff --git a/src/vector.jl b/src/vector.jl index 1b29ea90..a595a790 100644 --- a/src/vector.jl +++ b/src/vector.jl @@ -1,10 +1,12 @@ # Constructors: ############### """ - GBVector{T}(n = libgb.GxB_INDEX_MAX) + GBVector{T}(n = LibGraphBLAS.GxB_INDEX_MAX) """ -function GBVector{T}(n = libgb.GxB_INDEX_MAX) where {T} - v = GBVector{T}(libgb.GrB_Matrix_new(toGBType(T),n, 1)) +function GBVector{T}(n = LibGraphBLAS.GxB_INDEX_MAX) where {T} + m = Ref{LibGraphBLAS.GrB_Matrix}() + @wraperror LibGraphBLAS.GrB_Matrix_new(m, gbtype(T), n, 1) + v = GBVector{T}(m[]) gbset(v, FORMAT, BYCOL) return v end @@ -55,14 +57,18 @@ end # Some Base and basic SparseArrays/LinearAlgebra functions: ########################################################### -Base.unsafe_convert(::Type{libgb.GrB_Matrix}, v::GBVector) = v.p +Base.unsafe_convert(::Type{LibGraphBLAS.GrB_Matrix}, v::GBVector) = v.p -function Base.copy(v::GBVector{T}) where {T} - return GBVector{T}(libgb.GrB_Matrix_dup(v)) +function Base.copy(A::GBVector{T}) where {T} + C = Ref{LibGraphBLAS.GrB_Matrix}() + LibGraphBLAS.GrB_Matrix_dup(C, A) + return GBVector{T}(C[]) end function Base.size(v::GBVector) - return (Int64(libgb.GrB_Matrix_nrows(v)),) + nrows = Ref{LibGraphBLAS.GrB_Index}() + @wraperror LibGraphBLAS.GrB_Matrix_nrows(nrows, v) + return (Int64(nrows[]),) end Base.eltype(::Type{GBVector{T}}) where{T} = T @@ -82,12 +88,12 @@ function Base.similar( end function Base.deleteat!(v::GBVector, i) - libgb.GrB_Matrix_removeElement(v, i, 1) + @wraperror LibGraphBLAS.GrB_Matrix_removeElement(v, decrement!(i), 1) return v end function Base.resize!(v::GBVector, n) - libgb.GrB_Matrix_resize(v, n, 1) + @wraperror LibGraphBLAS.GrB_Matrix_resize(v, n, 1) return v end @@ -105,7 +111,7 @@ function LinearAlgebra.diag(A::GBMatOrTranspose{T}, k::Integer = 0; desc = nothi if A isa Transpose k = -k end - GBVector{T}(libgb.GxB_Vector_diag(libgb.GrB_Vector(v.p), parent(A), k, desc)) + @wraperror LibGraphBLAS.GxB_Vector_diag(LibGraphBLAS.GrB_Vector(v.p), parent(A), k, desc) return v end @@ -134,10 +140,19 @@ for T ∈ valid_vec func = Symbol(prefix, :_Matrix_build_, suffix(T)) @eval begin function build(v::GBVector{$T}, I::Vector, X::Vector{$T}; dup = +) - nnz(v) == 0 || throw(libgb.OutputNotEmptyError("Cannot build vector with existing elements")) + nnz(v) == 0 || throw(OutputNotEmptyError("Cannot build vector with existing elements")) length(X) == length(I) || DimensionMismatch("I and X must have the same length") dup = BinaryOp(dup)($T) - libgb.$func(Ptr{libgb.GrB_Vector}(v.p), Vector{libgb.GrB_Index}(I) .- 1, zeros(libgb.GrB_Index, length(I)), X, length(X), dup) + decrement!(I) + @wraperror LibGraphBLAS.$func( + Ptr{LibGraphBLAS.GrB_Vector}(v.p), + Vector{LibGraphBLAS.GrB_Index}(I), + zeros(LibGraphBLAS.GrB_Index, length(I)), + X, + length(X), + dup + ) + increment!(I) end end # Setindex functions @@ -145,7 +160,7 @@ for T ∈ valid_vec @eval begin function Base.setindex!(v::GBVector{$T}, x, i::Integer) x = convert($T, x) - return libgb.$func(v, x, libgb.GrB_Index(i) - 1, 0) + return LibGraphBLAS.$func(v, x, LibGraphBLAS.GrB_Index(decrement!(i)), 0) end end # Getindex functions @@ -153,13 +168,13 @@ for T ∈ valid_vec @eval begin function Base.getindex(v::GBVector{$T}, i::Integer) x = Ref{$T}() - result = libgb.$func(x, v, libgb.GrB_Index(i) - 1, 0) - if result == libgb.GrB_SUCCESS + result = LibGraphBLAS.$func(x, v, LibGraphBLAS.GrB_Index(decrement!(i)), 0) + if result == LibGraphBLAS.GrB_SUCCESS return x[] - elseif result == libgb.GrB_NO_VALUE + elseif result == LibGraphBLAS.GrB_NO_VALUE return nothing else - throw(ErrorException("Invalid extractElement return value.")) + @wraperror result end end end @@ -167,41 +182,44 @@ for T ∈ valid_vec func = Symbol(prefix, :_Matrix_extractTuples_, suffix(T)) @eval begin function SparseArrays.findnz(v::GBVector{$T}) - nvals = Ref{libgb.GrB_Index}(nnz(v)) - I = Vector{libgb.GrB_Index}(undef, nvals[]) + nvals = Ref{LibGraphBLAS.GrB_Index}(nnz(v)) + I = Vector{LibGraphBLAS.GrB_Index}(undef, nvals[]) X = Vector{$T}(undef, nvals[]) - libgb.$func(I, C_NULL, X, nvals, v) + @wraperror LibGraphBLAS.$func(I, C_NULL, X, nvals, v) nvals[] == length(I) == length(X) || throw(DimensionMismatch("length(I) != length(X)")) - return I .+ 1, X + return increment!(I), X end function SparseArrays.nonzeros(v::GBVector{$T}) - nvals = Ref{libgb.GrB_Index}(nnz(v)) + nvals = Ref{LibGraphBLAS.GrB_Index}(nnz(v)) X = Vector{$T}(undef, nvals[]) - libgb.$func(C_NULL, C_NULL, X, nvals, v) + @wraperror LibGraphBLAS.$func(C_NULL, C_NULL, X, nvals, v) nvals[] == length(X) || throw(DimensionMismatch("")) return X end function SparseArrays.nonzeroinds(v::GBVector{$T}) - nvals = Ref{libgb.GrB_Index}(nnz(v)) - I = Vector{libgb.GrB_Index}(undef, nvals[]) + nvals = Ref{LibGraphBLAS.GrB_Index}(nnz(v)) + I = Vector{LibGraphBLAS.GrB_Index}(undef, nvals[]) wait(v) - libgb.$func(I, C_NULL, C_NULL, nvals, v) + @wraperror LibGraphBLAS.$func(I, C_NULL, C_NULL, nvals, v) nvals[] == length(I) || throw(DimensionMismatch("")) - return I .+ 1 + return increment!(I) end end end function build(v::GBVector{T}, I::Vector, x::T) where {T} - nnz(v) == 0 || throw(libgb.OutputNotEmptyError("Cannot build vector with existing elements")) + nnz(v) == 0 || throw(OutputNotEmptyError("Cannot build vector with existing elements")) x = GBScalar(x) - return libgb.GxB_Matrix_build_Scalar( + decrement!(I) + @wraperror LibGraphBLAS.GxB_Matrix_build_Scalar( v, - Vector{libgb.GrB_Index}(I), - zeros(libgb.GrB_Index, length(I)), + Vector{LibGraphBLAS.GrB_Index}(I), + zeros(LibGraphBLAS.GrB_Index, length(I)), x, length(I) ) + increment!(I) + return v end # Indexing functions: @@ -230,20 +248,8 @@ end Assign a subvector of `w` to `u`. Return `u`. Equivalent to the matrix definition. """ -function subassign!( - w::GBVector, u, I; - mask = nothing, accum = nothing, desc = nothing -) - desc = _handledescriptor(desc) - I, ni = idx(I) - u isa Vector && (u = GBVector(u)) - mask === nothing && (mask = C_NULL) - if u isa GBVector - libgb.GxB_Matrix_subassign(w, mask, getaccum(accum, eltype(w)), u, I, ni, UInt64[1], 1, desc) - else - libgb.scalarmatsubassign[eltype(u)](w, mask, getaccum(accum, eltype(w)), u, I, ni, UInt64[1], 1, desc) - end - return nothing +function subassign!(w::GBVector{T}, u, I; mask = nothing, accum = nothing, desc = nothing) where {T} + return subassign!(GBMatrix{T}(w.p; aliased=true), u, I, UInt64[1]; mask, accum, desc) end """ @@ -251,20 +257,8 @@ end Assign a subvector of `w` to `u`. Return `u`. Equivalent to the matrix definition. """ -function assign!( - w::GBVector, u, I; - mask = nothing, accum = nothing, desc = nothing -) - desc = _handledescriptor(desc) - I, ni = idx(I) - u isa Vector && (u = GBVector(u)) - mask === nothing && (mask = C_NULL) - if u isa GBVector - libgb.GrB_Matrix_assign(w, mask, getaccum(accum, eltype(w)), u, I, ni, UInt64[1], 1, desc) - else - libgb.scalarmatassign[eltype(u)](w, mask, getaccum(accum, eltype(w)), u, I, ni, UInt64[1], 1, desc) - end - return nothing +function assign!(w::GBVector{T}, u, I; mask = nothing, accum = nothing, desc = nothing) where {T} + return assign!(GBMatrix{T}(w.p; aliased=true), u, I, UInt64[1]; mask, accum, desc) end function Base.setindex!( diff --git a/src/wait.jl b/src/wait.jl index eef9043f..763c2dd3 100644 --- a/src/wait.jl +++ b/src/wait.jl @@ -1,47 +1,47 @@ -function wait(A::GBArray) - waitmode = libgb.GrB_MATERIALIZE - libgb.GrB_Matrix_wait(A, waitmode) +function Base.wait(A::GBArray) + waitmode = LibGraphBLAS.GrB_MATERIALIZE + @wraperror LibGraphBLAS.GrB_Matrix_wait(A, waitmode) return nothing end -function wait(A::libgb.GrB_UnaryOp) - waitmode = libgb.GrB_MATERIALIZE - libgb.GrB_UnaryOp_wait(A, waitmode) +function Base.wait(A::LibGraphBLAS.GrB_UnaryOp) + waitmode = LibGraphBLAS.GrB_MATERIALIZE + @wraperror LibGraphBLAS.GrB_UnaryOp_wait(A, waitmode) return nothing end -function wait(A::libgb.GrB_BinaryOp) - waitmode = libgb.GrB_MATERIALIZE - libgb.GrB_BinaryOp_wait(A, waitmode) +function Base.wait(A::LibGraphBLAS.GrB_BinaryOp) + waitmode = LibGraphBLAS.GrB_MATERIALIZE + @wraperror LibGraphBLAS.GrB_BinaryOp_wait(A, waitmode) return nothing end -function wait(A::libgb.GxB_SelectOp) - waitmode = libgb.GrB_MATERIALIZE - libgb.GrB_SelectOp_wait(A, waitmode) +function Base.wait(A::LibGraphBLAS.GxB_SelectOp) + waitmode = LibGraphBLAS.GrB_MATERIALIZE + @wraperror LibGraphBLAS.GrB_SelectOp_wait(A, waitmode) return nothing end -function wait(A::libgb.GrB_IndexUnaryOp) - waitmode = libgb.GrB_MATERIALIZE - libgb.GrB_IndexUnaryOp_wait(A, waitmode) +function Base.wait(A::LibGraphBLAS.GrB_IndexUnaryOp) + waitmode = LibGraphBLAS.GrB_MATERIALIZE + @wraperror LibGraphBLAS.GrB_IndexUnaryOp_wait(A, waitmode) return nothing end -function wait(A::libgb.GrB_Monoid) - waitmode = libgb.GrB_MATERIALIZE - libgb.GrB_Monoid_wait(A, waitmode) +function Base.wait(A::LibGraphBLAS.GrB_Monoid) + waitmode = LibGraphBLAS.GrB_MATERIALIZE + @wraperror LibGraphBLAS.GrB_Monoid_wait(A, waitmode) return nothing end -function wait(A::libgb.GrB_Semiring) - waitmode = libgb.GrB_MATERIALIZE - libgb.GrB_Semiring_wait(A, waitmode) +function Base.wait(A::LibGraphBLAS.GrB_Semiring) + waitmode = LibGraphBLAS.GrB_MATERIALIZE + @wraperror LibGraphBLAS.GrB_Semiring_wait(A, waitmode) return nothing end -function wait(A::GBScalar) - waitmode = libgb.GrB_MATERIALIZE - libgb.GrB_Scalar_wait(A, waitmode) +function Base.wait(A::GBScalar) + waitmode = LibGraphBLAS.GrB_MATERIALIZE + @wraperror LibGraphBLAS.GrB_Scalar_wait(A, waitmode) return nothing end \ No newline at end of file diff --git a/test/chainrules/chainrulesutils.jl b/test/chainrules/chainrulesutils.jl index 9f9c3780..c60de0b7 100644 --- a/test/chainrules/chainrulesutils.jl +++ b/test/chainrules/chainrulesutils.jl @@ -1,3 +1,22 @@ +#Required for ChainRulesTestUtils +function FiniteDifferences.to_vec(M::GBMatrix) + x, back = FiniteDifferences.to_vec(Matrix(M)) + function backtomat(xvec) + M2 = GBMatrix(back(xvec)) + return mask(M2, M; structural=true) + end + return x, backtomat +end + +function FiniteDifferences.to_vec(v::GBVector) + x, back = FiniteDifferences.to_vec(Vector(v)) + function backtovec(xvec) + v2 = GBVector(back(xvec)) + return mask(v2, v; structural=true) + end + return x, backtovec +end + function test_to_vec(x::T; check_inferred=true) where {T} check_inferred && @inferred FiniteDifferences.to_vec(x) x_vec, back = FiniteDifferences.to_vec(x) diff --git a/test/operations.jl b/test/operations.jl deleted file mode 100644 index e1e218d6..00000000 --- a/test/operations.jl +++ /dev/null @@ -1,10 +0,0 @@ -@testset "Operations" begin - include("operations/ewise.jl") - include("operations/kron.jl") - include("operations/map.jl") - include("operations/mul.jl") - include("operations/reduce.jl") - include("operations/select.jl") - include("operations/transpose.jl") - include("operations/broadcasting.jl") -end diff --git a/test/runtests.jl b/test/runtests.jl index b3e154c5..5baa0a12 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -65,8 +65,17 @@ ChainRulesTestUtils.rand_tangent(::AbstractRNG, ::SuiteSparseGraphBLAS.AbstractO println("Testing SuiteSparseGraphBLAS.jl") @testset "SuiteSparseGraphBLAS" begin + + include_test("gbarray.jl") - include_test("operations.jl") + include_test("operations/ewise.jl") + include_test("operations/kron.jl") + include_test("operations/map.jl") + include_test("operations/mul.jl") + include_test("operations/reduce.jl") + include_test("operations/select.jl") + include_test("operations/transpose.jl") + include_test("operations/broadcasting.jl") include_test("chainrules/chainrulesutils.jl") include_test("chainrules/mulrules.jl") include_test("chainrules/ewiserules.jl")