|
| 1 | +using Ferrite |
| 2 | +using SparseMatricesCSR: SparseMatrixCSR |
| 3 | +using SparseArrays: SparseMatrixCSC |
| 4 | +using DataFrames |
| 5 | +using Ferrite: FastSparsityPattern |
| 6 | + |
| 7 | +function dh_scalar(grid) |
| 8 | + CT = getcelltype(grid) |
| 9 | + RS = getrefshape(CT) |
| 10 | + return close!(add!(DofHandler(grid), :u, Lagrange{RS, 1}())) |
| 11 | +end |
| 12 | + |
| 13 | +function dh_complex(grid::Grid{sdim}) where {sdim} |
| 14 | + CT = getcelltype(grid) |
| 15 | + RS = getrefshape(CT) |
| 16 | + dh = DofHandler(grid) |
| 17 | + add!(dh, :u, Lagrange{RS, 2}()) |
| 18 | + add!(dh, :v, Lagrange{RS, 1}()^sdim) |
| 19 | + return close!(dh) |
| 20 | +end |
| 21 | + |
| 22 | +create_sp(dh) = add_sparsity_entries!(init_sparsity_pattern(dh), dh) |
| 23 | +create_fsp(dh) = FastSparsityPattern(dh) |
| 24 | + |
| 25 | +grid_2d = generate_grid(Triangle, 1000 .* (1, 1)) |
| 26 | +grid_3d = generate_grid(Hexahedron, 80 .* (1, 1, 1)) |
| 27 | + |
| 28 | +dofhandlers = [ |
| 29 | + "dh_2d_scalar" => dh_scalar(grid_2d), |
| 30 | + "dh_3d_scalar" => dh_scalar(grid_3d), |
| 31 | + "dh_2d_complex" => dh_complex(grid_2d), |
| 32 | + "dh_3d_complex" => dh_complex(grid_3d), |
| 33 | +] |
| 34 | + |
| 35 | +function timef(f::F, ::Type{MatrixType}, args...; kwargs...) where {F, MatrixType} |
| 36 | + sp0 = f(args...; kwargs...) # Compile |
| 37 | + allocate_matrix(MatrixType, sp0) # Compile |
| 38 | + GC.gc() |
| 39 | + sp_allocs = @allocations (sp_runtime = @elapsed (sp = f(args...; kwargs...))) |
| 40 | + m_allocs = @allocations (m_runtime = @elapsed allocate_matrix(MatrixType, sp)) |
| 41 | + return (; sp_t = sp_runtime, sp_a = sp_allocs, m_t = m_runtime, m_a = m_allocs) |
| 42 | +end |
| 43 | + |
| 44 | +function fmt_time(t::Number; digits = 2) |
| 45 | + units = ["ns", "μs", "ms", "s", "min", "h"] |
| 46 | + values = [1.0e-9, 1.0e-6, 1.0e-3, 1.0, 60.0, 3600] |
| 47 | + idx = findfirst(v -> v > t, values) |
| 48 | + i = max(idx === nothing ? length(values) : idx - 1, 1) |
| 49 | + return string(round(t / values[i]; digits)) * " " * units[i] |
| 50 | +end |
| 51 | + |
| 52 | +function fmt_count(n::Integer; digits = 2) |
| 53 | + units = ["k", "M", "G"] |
| 54 | + values = [1.0e3, 1.0e6, 1.0e9] |
| 55 | + n < 1000 && return string(n) |
| 56 | + i = findlast(v -> v ≤ n, values) |
| 57 | + return string(round(n / values[i]; digits)) * units[i] |
| 58 | +end |
| 59 | + |
| 60 | +function make_timings(MatrixType) |
| 61 | + return map([create_sp, create_fsp]) do f |
| 62 | + [key => timef(f, MatrixType, dh) for (key, dh) in dofhandlers] |
| 63 | + end |
| 64 | +end |
| 65 | + |
| 66 | +function make_df(timings) |
| 67 | + _getdata(v, k) = getindex.(last.(v), k) |
| 68 | + return DataFrame( |
| 69 | + "case" => first.(dofhandlers), |
| 70 | + "t (sp) [s]" => fmt_time.(_getdata(timings[1], :sp_t)), |
| 71 | + "t (fsp) [s]" => fmt_time.(_getdata(timings[2], :sp_t)), |
| 72 | + "allocs (sp)" => fmt_count.(_getdata(timings[1], :sp_a)), |
| 73 | + "allocs (fsp)" => fmt_count.(_getdata(timings[2], :sp_a)), |
| 74 | + "t (K,sp) [s]" => fmt_time.(_getdata(timings[1], :m_t)), |
| 75 | + "t (K,fsp) [s]" => fmt_time.(_getdata(timings[2], :m_t)), |
| 76 | + "allocs (K,sp)" => fmt_count.(_getdata(timings[1], :m_a)), |
| 77 | + "allocs (K,fsp)" => fmt_count.(_getdata(timings[2], :m_a)) |
| 78 | + ) |
| 79 | +end |
| 80 | + |
| 81 | +display(make_df(make_timings(SparseMatrixCSC{Float64, Int}))) |
| 82 | +# display(make_df(make_timings(SparseMatrixCSR))) |
0 commit comments