Skip to content

Commit 40af13b

Browse files
committed
storageorders/oriented integration
1 parent d1f226e commit 40af13b

File tree

6 files changed

+164
-35
lines changed

6 files changed

+164
-35
lines changed

src/SuiteSparseGraphBLAS.jl

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@ using Random: randsubseq, default_rng, AbstractRNG, GLOBAL_RNG
2222
using SpecialFunctions: lgamma, gamma, erf, erfc
2323
using Base.Broadcast
2424
using Serialization
25+
using StorageOrders
26+
using HyperSparseMatrices
2527
include("abstracts.jl")
2628
include("libutils.jl")
2729

@@ -86,13 +88,15 @@ include("chainrules/reducerules.jl")
8688
include("chainrules/selectrules.jl")
8789
include("chainrules/constructorrules.jl")
8890

91+
include("serialization.jl")
92+
8993
#EXPERIMENTAL
9094
include("misc.jl")
9195
include("asjulia.jl")
9296
# include("spmgb/sparsemat.jl")
9397
include("mmread.jl")
9498
include("iterator.jl")
95-
include("serialization.jl")
99+
include("oriented.jl")
96100

97101
export SparseArrayCompat
98102
export LibGraphBLAS

src/abstractgbarray.jl

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -524,4 +524,28 @@ function Base.setindex!(
524524
)
525525
subassign!(u, x, I; mask, accum, desc)
526526
return nothing
527+
end
528+
529+
function Base.show(io::IO, ::MIME"text/plain", A::AbstractGBArray) #fallback printing
530+
gxbprint(io, A)
531+
end
532+
533+
function Base.getindex(
534+
A::AbstractGBMatrix, i, ::Colon;
535+
mask = nothing, accum = nothing, desc = nothing
536+
)
537+
return extract(A, i, ALL; mask, accum, desc)
538+
end
539+
function Base.getindex(
540+
A::AbstractGBMatrix, ::Colon, ::Colon;
541+
mask = nothing, accum = nothing, desc = nothing
542+
)
543+
return extract(A, ALL, ALL; mask, accum, desc)
544+
end
545+
546+
function Base.getindex(
547+
A::AbstractGBMatrix, i::Union{Vector, UnitRange, StepRange, Number}, j::Union{Vector, UnitRange, StepRange, Number};
548+
mask = nothing, accum = nothing, desc = nothing
549+
)
550+
return extract(A, i, j; mask, accum, desc)
527551
end

src/matrix.jl

Lines changed: 2 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -60,14 +60,9 @@ end
6060

6161
GBMatrix(nrows, ncols, x::T; fill::F = nothing) where {T, F} = GBMatrix((nrows, ncols), x; fill)
6262

63-
# TODO, switch to pointer fudging.
6463
function GBMatrix(v::GBVector)
65-
A = GBMatrix{eltype(v)}(size(v, 1), size(v, 2))
66-
nz = findnz(v)
67-
for i 1:length(nz[1])
68-
A[nz[1][i], 1] = nz[2][i]
69-
end
70-
return A
64+
# this copies, I think that's ideal, and I can implement @view or something at a later date.
65+
return copy(GBMatrix{eltype(v), typeof(v.fill)}(v.p, v.fill))
7166
end
7267

7368
# Some Base and basic SparseArrays/LinearAlgebra functions:
@@ -131,33 +126,9 @@ end
131126
# return Diagonal(v, k; desc)
132127
# end
133128

134-
function Base.show(io::IO, ::MIME"text/plain", A::GBMatrix)
135-
gxbprint(io, A)
136-
end
137-
138129
# Indexing functions
139130
####################
140131

141-
function Base.getindex(
142-
A::GBMatOrTranspose, i, ::Colon;
143-
mask = nothing, accum = nothing, desc = nothing
144-
)
145-
return extract(A, i, ALL; mask, accum, desc)
146-
end
147-
function Base.getindex(
148-
A::GBMatOrTranspose, ::Colon, ::Colon;
149-
mask = nothing, accum = nothing, desc = nothing
150-
)
151-
return extract(A, ALL, ALL; mask, accum, desc)
152-
end
153-
154-
function Base.getindex(
155-
A::GBMatOrTranspose, i::Union{Vector, UnitRange, StepRange, Number}, j::Union{Vector, UnitRange, StepRange, Number};
156-
mask = nothing, accum = nothing, desc = nothing
157-
)
158-
return extract(A, i, j; mask, accum, desc)
159-
end
160-
161132
# Linear indexing
162133
function Base.getindex(A::GBMatOrTranspose, v::AbstractVector)
163134
throw("Not implemented")

src/oriented.jl

Lines changed: 127 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,127 @@
1+
mutable struct OrientedGBMatrix{T, F, O} <: AbstractGBMatrix{T, F}
2+
p::Ref{LibGraphBLAS.GrB_Matrix}
3+
fill::F
4+
end
5+
6+
const GBMatrixC{T, F} = OrientedGBMatrix{T, F, StorageOrders.ColMajor()}
7+
const GBMatrixR{T, F} = OrientedGBMatrix{T, F, StorageOrders.RowMajor()}
8+
StorageOrders.storageorder(::OrientedGBMatrix{T, F, O}) where {T, F, O} = O
9+
10+
# Constructors:
11+
###############
12+
"""
13+
GBMatrix{T}(nrows, ncols; fill = nothing)
14+
15+
Create a GBMatrix of the specified size, defaulting to the maximum on each dimension, 2^60.
16+
"""
17+
function OrientedGBMatrix{T, O}(nrows::Integer, ncols::Integer; fill::F = nothing) where {T, F, O}
18+
m = Ref{LibGraphBLAS.GrB_Matrix}()
19+
@wraperror LibGraphBLAS.GrB_Matrix_new(m, gbtype(T), nrows, ncols)
20+
A = GBMatrix{T, F}(finalizer(m) do ref
21+
@wraperror LibGraphBLAS.GrB_Matrix_free(ref)
22+
end, fill)
23+
gbset(A, :format, O === StorageOrders.ColMajor() ? :bycol : :byrow)
24+
end
25+
26+
OrientedGBMatrix{T, O}(dims::Dims{2}; fill = nothing) where {T, O} = OrientedGBMatrix{T, O}(dims...; fill)
27+
OrientedGBMatrix{T, O}(dims::Tuple{<:Integer}; fill = nothing) where {T, O} = OrientedGBMatrix{T, O}(dims...; fill)
28+
OrientedGBMatrix{T, O}(size::Tuple{Base.OneTo, Base.OneTo}; fill = nothing) where {T, O} =
29+
OrientedGBMatrix{T, O}(size[1].stop, size[2].stop; fill)
30+
31+
"""
32+
GBMatrix(I, J, X; combine = +, nrows = maximum(I), ncols = maximum(J))
33+
34+
Create an nrows x ncols GBMatrix M such that M[I[k], J[k]] = X[k]. The combine function defaults
35+
to `|` for booleans and `+` for nonbooleans.
36+
"""
37+
function OrientedGBMatrix{O}(
38+
I::AbstractVector, J::AbstractVector, X::AbstractVector{T};
39+
combine = +, nrows = maximum(I), ncols = maximum(J), fill = nothing
40+
) where {T, O}
41+
I isa Vector || (I = collect(I))
42+
J isa Vector || (J = collect(J))
43+
X isa Vector || (X = collect(X))
44+
A = OrientedGBMatrix{T, O}(nrows, ncols; fill)
45+
build(A, I, J, X; combine)
46+
return A
47+
end
48+
49+
#iso constructors
50+
"""
51+
GBMatrix(I, J, x; nrows = maximum(I), ncols = maximum(J))
52+
53+
Create an nrows x ncols GBMatrix M such that M[I[k], J[k]] = x.
54+
The resulting matrix is "iso-valued" such that it only stores `x` once rather than once for
55+
each index.
56+
"""
57+
function OrientedGBMatrix{O}(I::AbstractVector, J::AbstractVector, x::T;
58+
nrows = maximum(I), ncols = maximum(J), fill = nothing) where {T, O}
59+
A = OrientedGBMatrix{T, O}(nrows, ncols; fill)
60+
build(A, I, J, x)
61+
return A
62+
end
63+
64+
65+
function OrientedGBMatrix{O}(dims::Dims{2}, x::T; fill = nothing) where {T, O}
66+
A = OrientedGBMatrix{T, O}(dims; fill)
67+
A[:, :] = x
68+
return A
69+
end
70+
71+
OrientedGBMatrix{O}(nrows, ncols, x::T; fill::F = nothing) where {T, F, O} = OrientedGBMatrix{O}((nrows, ncols), x; fill)
72+
function OrientedGBMatrix{O}(v::GBVector) where {O}
73+
# this copies, I think that's ideal, and I can implement @view or something at a later date.
74+
return copy(OrientedGBMatrix{eltype(v), typeof(v.fill), O}(v.p, v.fill))
75+
end
76+
77+
Base.unsafe_convert(::Type{LibGraphBLAS.GrB_Matrix}, A::OrientedGBMatrix) = A.p[]
78+
79+
function Base.copy(A::OrientedGBMatrix{T, F, O}) where {T, F, O}
80+
C = Ref{LibGraphBLAS.GrB_Matrix}()
81+
LibGraphBLAS.GrB_Matrix_dup(C, gbpointer(A))
82+
return OrientedGBMatrix{T, F, O}(C, A.fill) # This should automatically be the same orientation.
83+
end
84+
85+
# because of the fill kwarg we have to redo a lot of the Base.similar dispatch stack.
86+
function Base.similar(
87+
A::OrientedGBMatrix{T, F, O}, ::Type{TNew} = T,
88+
dims::Tuple{Int64, Vararg{Int64, N}} = size(A); fill = parent(A).fill
89+
) where {T, TNew, N, F, O}
90+
if dims isa Dims{1}
91+
return GBVector{TNew}(dims...; fill)
92+
else
93+
A = OrientedGBMatrix{TNew, O}(dims...; fill)
94+
end
95+
end
96+
97+
function Base.similar(A::OrientedGBMatrix{T}, dims::Tuple; fill = parent(A).fill) where {T}
98+
return similar(A, T, dims; fill)
99+
end
100+
101+
function Base.similar(
102+
A::OrientedGBMatrix{T}, ::Type{TNew},
103+
dims::Integer; fill = parent(A).fill
104+
) where {T, TNew}
105+
return similar(A, TNew, (dims,); fill)
106+
end
107+
108+
function Base.similar(
109+
A::OrientedGBMatrix{T}, ::Type{TNew},
110+
dim1::Integer, dim2::Integer; fill = parent(A).fill
111+
) where {T, TNew}
112+
return similar(A, TNew, (dim1, dim2); fill)
113+
end
114+
115+
function Base.similar(
116+
A::OrientedGBMatrix{T},
117+
dims::Integer; fill = parent(A).fill
118+
) where {T}
119+
return similar(A, (dims,); fill)
120+
end
121+
122+
function Base.similar(
123+
A::OrientedGBMatrix{T},
124+
dim1::Integer, dim2::Integer; fill = parent(A).fill
125+
) where {T}
126+
return similar(A, (dim1, dim2); fill)
127+
end

src/serialization.jl

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@ function _gbdeserialize(s::AbstractSerializer, ::Type{T}) where {T} # Only for i
1818
return refA[], fill
1919
end
2020

21-
2221
function Serialization.deserialize(s::AbstractSerializer, ::Type{GBMatrix{T, Tf}}) where {T, Tf}
2322
return GBMatrix{T, Tf}(_gbdeserialize(s, T)...)
2423
end
@@ -31,4 +30,3 @@ function serialize_sizehint(A::GBVecOrMat)
3130
@wraperror LibGraphBLAS.GrB_Matrix_serializeSize(sz, gbpointer(A))
3231
return sz[]
3332
end
34-

src/types.jl

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -284,4 +284,9 @@ end
284284
# Most likely this will be the case for all AbstractGBArray.
285285
# However, if one (for some reason) wraps another AbstractGBArray
286286
# this should be overloaded.
287-
gbpointer(A::AbstractGBArray) = A.p[]
287+
gbpointer(A::AbstractGBArray) = A.p[]
288+
289+
# We need to do this at runtime. This should perhaps be `RuntimeOrder`, but that trait should likely be removed.
290+
# This should ideally work out fine. a GBMatrix or GBVector won't have
291+
StorageOrders.storageorder(A::AbstractGBMatrix) = gbget(A, :format) == BYCOL ? StorageOrders.ColMajor() : StorageOrders.RowMajor()
292+
StorageOrders.storageorder(A::AbstractGBVector) = ColMajor()

0 commit comments

Comments
 (0)