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