|
| 1 | +using BenchmarkTools, Random, VectorizationBase |
| 2 | +using LinearAlgebra, SparseArrays, LinearSolve, Sparspak |
| 3 | +import Pardiso |
| 4 | +using Plots |
| 5 | + |
| 6 | +BenchmarkTools.DEFAULT_PARAMETERS.seconds = 0.5 |
| 7 | + |
| 8 | +# Why do I need to set this ? |
| 9 | +BenchmarkTools.DEFAULT_PARAMETERS.samples = 10 |
| 10 | + |
| 11 | +# Sparse matrix generation on a n-dimensional rectangular grid. After |
| 12 | +# https://discourse.julialang.org/t/seven-lines-of-julia-examples-sought/50416/135 |
| 13 | +# by A. Braunstein. |
| 14 | + |
| 15 | +A ⊕ B = kron(I(size(B, 1)), A) + kron(B, I(size(A, 1))) |
| 16 | + |
| 17 | +function lattice(n; Tv = Float64) |
| 18 | + d = fill(2 * one(Tv), n) |
| 19 | + d[1] = one(Tv) |
| 20 | + d[end] = one(Tv) |
| 21 | + spdiagm(1 => -ones(Tv, n - 1), 0 => d, -1 => -ones(Tv, n - 1)) |
| 22 | +end |
| 23 | + |
| 24 | +lattice(L...; Tv = Float64) = lattice(L[1]; Tv) ⊕ lattice(L[2:end]...; Tv) |
| 25 | + |
| 26 | +# |
| 27 | +# Create a matrix similar to that of a finite difference discretization in a `dim`-dimensional |
| 28 | +# unit cube of ``-Δu + δu`` with approximately N unknowns. It is strictly diagonally dominant. |
| 29 | +# |
| 30 | +function fdmatrix(N; dim = 2, Tv = Float64, δ = 1.0e-2) |
| 31 | + n = N^(1 / dim) |> ceil |> Int |
| 32 | + lattice([n for i in 1:dim]...; Tv) + Tv(δ) * I |
| 33 | +end |
| 34 | + |
| 35 | +algs = [ |
| 36 | + UMFPACKFactorization(), |
| 37 | + KLUFactorization(), |
| 38 | + MKLPardisoFactorize(), |
| 39 | + SparspakFactorization(), |
| 40 | +] |
| 41 | +cols = [:red, :blue, :green, :magenta, :turqoise] # one color per alg |
| 42 | +lst = [:dash, :solid, :dashdot] # one line style per dim |
| 43 | + |
| 44 | +__parameterless_type(T) = Base.typename(T).wrapper |
| 45 | +parameterless_type(x) = __parameterless_type(typeof(x)) |
| 46 | +parameterless_type(::Type{T}) where {T} = __parameterless_type(T) |
| 47 | + |
| 48 | +# |
| 49 | +# kmax=12 gives ≈ 40_000 unknowns max, can be watched in real time |
| 50 | +# kmax=15 gives ≈ 328_000 unknows, you can go make a coffee. |
| 51 | +# Main culprit is KLU factorization in 3D. |
| 52 | +# |
| 53 | +function run_and_plot(; dims = [1, 2, 3], kmax = 12) |
| 54 | + ns = [10 * 2^k for k in 0:kmax] |
| 55 | + |
| 56 | + res = [[Float64[] for i in 1:length(algs)] for dim in dims] |
| 57 | + |
| 58 | + for dim in dims |
| 59 | + for i in 1:length(ns) |
| 60 | + rng = MersenneTwister(123) |
| 61 | + A = fdmatrix(ns[i]; dim) |
| 62 | + n = size(A, 1) |
| 63 | + @info "dim=$(dim): $n × $n" |
| 64 | + b = rand(rng, n) |
| 65 | + u0 = rand(rng, n) |
| 66 | + |
| 67 | + for j in 1:length(algs) |
| 68 | + bt = @belapsed solve(prob, $(algs[j])).u setup=(prob = LinearProblem(copy($A), |
| 69 | + copy($b); |
| 70 | + u0 = copy($u0), |
| 71 | + alias_A = true, |
| 72 | + alias_b = true)) |
| 73 | + push!(res[dim][j], bt) |
| 74 | + end |
| 75 | + end |
| 76 | + end |
| 77 | + |
| 78 | + p = plot(; |
| 79 | + ylabel = "Time/s", |
| 80 | + xlabel = "N", |
| 81 | + yscale = :log10, |
| 82 | + xscale = :log10, |
| 83 | + title = "Time for NxN sparse LU Factorization", |
| 84 | + label = string(Symbol(parameterless_type(algs[1]))), |
| 85 | + legend = :outertopright) |
| 86 | + |
| 87 | + for dim in dims |
| 88 | + for i in 1:length(algs) |
| 89 | + plot!(p, ns, res[dim][i]; |
| 90 | + linecolor = cols[i], |
| 91 | + linestyle = lst[dim], |
| 92 | + label = "$(string(Symbol(parameterless_type(algs[i])))) $(dim)D") |
| 93 | + end |
| 94 | + end |
| 95 | + savefig("sparselubench.png") |
| 96 | + savefig("sparselubench.pdf") |
| 97 | +end |
0 commit comments