SuiteSparseGraphBLAS.jl and Krylov.jl #670
Replies: 2 comments
-
We could reuse the following script for the benchmarks. It uses real life matrices from the SuiteSparseMatrixCollection. using BenchmarkTools, SuiteSparseMatrixCollection, MatrixMarket
using SparseArrays, LinearAlgebra, Printf, JLD, Base.Threads
ssmc = ssmc_db(verbose=false)
dataset = ssmc[(ssmc.binary .== false) .& (10000 .≤ ssmc.nrows .≤ 20000) .& (ssmc.numerical_symmetry .== 1.0), :]
# dataset = ssmc[(ssmc.binary .== false) .& (1000 .≤ ssmc.nrows .≤ 10000), :]
paths = fetch_ssmc(dataset, format="MM")
names = dataset[!,:name]
function threaded_mul!(y::Vector{T}, A::SparseMatrixCSC{T}, x::Vector{T}) where T <: Number
A.m == A.n || error("A is not a square matrix!")
@threads for i = 1 : A.n
tmp = zero(T)
@inbounds for j = A.colptr[i] : (A.colptr[i+1] - 1)
tmp += A.nzval[j] * x[A.rowval[j]]
end
@inbounds y[i] = tmp
end
return y
end
# nb_pbs = length(paths) # 796 matrices...
nb_pbs = 15
benchmark_sparse = true
benchmark_mkl = true
benchmark_julia = true
time_sparse = zeros(nb_pbs)
time_mkl = zeros(nb_pbs)
time_julia = zeros(nb_pbs)
if benchmark_sparse
for i = 1 : nb_pbs
name = dataset[!,:name][i]
path = paths[i]
@printf("SparseArrays -- %3d / %3d -- %s\n", i, nb_pbs, name)
A = Float64.(MatrixMarket.mmread(path * "/$name.mtx"))
n, m = size(A)
x = rand(m)
y = rand(n)
time_sparse[i] = @belapsed for k in 1:1000 mul!($y, $A, $x) end
end
save("time_sparse.jld", "time_sparse", time_sparse)
else
time_sparse = load("time_sparse.jld", "time_sparse")
end
using MKLSparse
if benchmark_mkl
for i = 1 : nb_pbs
name = names[i]
path = paths[i]
@printf("MKLSparse -- %3d / %3d -- %s\n", i, nb_pbs, name)
A = MatrixMarket.mmread(path * "/$name.mtx")
n, m = size(A)
x = rand(m)
y = rand(n)
time_mkl[i] = @belapsed for k in 1:1000 mul!($y, $A, $x) end
end
save("time_mkl.jld", "time_mkl", time_mkl)
else
time_mkl = load("time_mkl.jld", "time_mkl")
end
if benchmark_julia
for i = 1 : nb_pbs
name = dataset[!,:name][i]
path = paths[i]
@printf("Julia -- %3d / %3d -- %s\n", i, nb_pbs, name)
A = Float64.(MatrixMarket.mmread(path * "/$name.mtx"))
n, m = size(A)
x = rand(m)
y = rand(n)
time_julia[i] = @belapsed for k in 1:1000 threaded_mul!($y, $A, $x) end
end
save("time_julia.jld", "time_julia", time_julia)
else
time_julia = load("time_julia.jld", "time_julia")
end
using PlotlyJS
p = plot([
bar(name="mul! SparseArrays", x=names[1:nb_pbs], y=time_sparse),
bar(name="mul! MKLSparse", x=names[1:nb_pbs], y=time_mkl),
bar(name="threaded_mul!", x=names[1:nb_pbs], y=time_julia),
],
)
relayout!(p, barmode="group")
savefig(p, "julia_vs_mkl_eps", format="eps")
savefig(p, "julia_vs_mkl_svg", format="svg") |
Beta Was this translation helpful? Give feedback.
-
I'll work on benchmarking. I definitely have Let me run some stability tests and check with Tim Davis though. I may be able to "cheat" here a bit and tell SuiteSparse:GraphBLAS that the output vector is not "shallow". This would be doable, but slightly dangerous. If we pass an accumulator (effectively (For clarity, GraphBLAS is very particular about the patterns of vectors and matrices. If |
Beta Was this translation helpful? Give feedback.
-
SuiteSparseGraphBLAS.jl could provide efficient sparse matrix - dense vector products for Krylov.jl but we can't easily use it here for the following reasons:
KrylovSolver
must be a subtype ofDenseVector
andGBVector
is anAbstractSparseVector
(even if GBVector is dense vector internally);dot
,axpy!
,axpby!
,norm
, etc...) are not all supported by theGBVector
type.However, I don't think that it's relevant to store variables inside the Krylov workspaces with
GBVector
.We want to use it because
mul!(y, GBMatrix, x)
is only working ifx
andy
areGBVector
.Is it possible to make it working with
x::Vector
andy::Vector
or not?If it's not possible, we could just define an operator that take as input a SparseMatrixCSC and create a structure with a
GBMatrix
and two auxiliaryGBVector
such that we can do:In the documentation, I did some benchmarks with
MKLSparse
, the defaultmul!
ofSparseArrays
and a multhreadedmul!
implemented julia.It will be great to add some benchmarks with
SuiteSparseGraphBLAS.jl
and how to use it in Krylov.jl if we solve the previous problems.@wimmerer
Beta Was this translation helpful? Give feedback.
All reactions