Skip to content

Commit b8ce68a

Browse files
authored
using TimerOutputs for duration/allocation measurements (#61)
1 parent a1c70e3 commit b8ce68a

8 files changed

Lines changed: 165 additions & 140 deletions

File tree

CHANGELOG.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,14 @@
11
# CHANGES
22

3+
4+
## v1.2.0 May 28, 2025
5+
6+
### Changed
7+
- TimerOutputs for measuring/storing/showing runtime and allocations in solve, now also for separate operators
8+
9+
### Fixed
10+
- HomogeneousData/InterpolateBoundaryData operator fix when system matrix is of type GenericMTExtendableSparseMatrixCSC
11+
312
## v1.1.1 April 29, 2025
413

514
### Fixed

Project.toml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
name = "ExtendableFEM"
22
uuid = "a722555e-65e0-4074-a036-ca7ce79a4aed"
33
authors = ["Christian Merdon <merdon@wias-berlin.de>", "Patrick Jaap <patrick.jaap@wias-berlin.de>"]
4-
version = "1.1.1"
4+
version = "1.2"
55

66
[deps]
77
CommonSolve = "38540f10-b2f7-11e9-35d8-d573e4eb0ff2"
@@ -19,6 +19,7 @@ SciMLBase = "0bca4576-84f4-4d90-8ffe-ffa030f20462"
1919
SparseArrays = "2f01184e-e22b-5df5-ae63-d93ebab69eaf"
2020
SparseDiffTools = "47a9eef4-7e08-11e9-0b38-333d64bd3804"
2121
Symbolics = "0c5d862f-8b57-4792-8d23-62f2024744c7"
22+
TimerOutputs = "a759f4b9-e2f1-59dc-863e-4aeb61b1ea8f"
2223
UnicodePlots = "b8865327-cd53-5732-bb35-84acbb429228"
2324

2425
[compat]
@@ -48,6 +49,7 @@ StaticArrays = "1.9.13"
4849
Symbolics = "4.2,5,6"
4950
Test = "1"
5051
TetGen = "2.0.0"
52+
TimerOutputs = "0.5.29"
5153
Triangulate = "2.4.0"
5254
UnicodePlots = "3.6.5"
5355
julia = "1.9"

examples/Example103_BurgersEquation.jl

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -96,8 +96,9 @@ function main(;
9696
t = 0
9797
for it in 1:Int(floor(T / τ))
9898
t += τ
99-
ExtendableFEM.solve(PD, FES, SC; time = t)
99+
ExtendableFEM.solve(PD, FES, SC; time = t, verbosity = -1, timeroutputs = :hide)
100100
end
101+
show(timeroutputs(SC))
101102
end
102103

103104
## plot final state

examples/Example205_HeatEquation.jl

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,8 +79,9 @@ function main(;
7979
t = 0
8080
for it in 1:Int(floor(T / τ))
8181
t += τ
82-
ExtendableFEM.solve(PD, FES, SC; time = t)
82+
ExtendableFEM.solve(PD, FES, SC; time = t, verbosity = -1, timeroutputs = :hide)
8383
end
84+
@show timeroutputs(SC)
8485
end
8586

8687
## plot final state

src/ExtendableFEM.jl

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@ using SparseDiffTools: SparseDiffTools, ForwardColorJacCache,
7272
forwarddiff_color_jacobian!, matrix_colors
7373
using Symbolics: Symbolics
7474
using SciMLBase: SciMLBase
75+
using TimerOutputs: TimerOutput, print_timer, @timeit
7576
using UnicodePlots: UnicodePlots
7677

7778

@@ -145,6 +146,7 @@ export tensor_view
145146
include("solver_config.jl")
146147
export SolverConfiguration
147148
export residual
149+
export timeroutputs
148150

149151
include("solvers.jl")
150152
export solve

src/common_operators/combinedofs.jl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ mutable struct CombineDofs{UT, CT} <: AbstractOperator
1313
end
1414

1515
default_combop_kwargs() = Dict{Symbol, Tuple{Any, String}}(
16+
:name => ("CombineDofs", "name for operator used in printouts"),
1617
:penalty => (1.0e30, "penalty for fixed degrees of freedom"),
1718
:verbosity => (0, "verbosity level"),
1819
)

src/solver_config.jl

Lines changed: 48 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,8 @@
1-
default_statistics() = Dict{Symbol, Vector{Real}}(
2-
:assembly_times => [],
3-
:solver_times => [],
4-
:assembly_allocations => [],
5-
:solver_allocations => [],
6-
:linear_residuals => [],
7-
:nonlinear_residuals => [],
8-
:matrix_nnz => [],
9-
:total_times => [],
10-
:total_allocations => [],
1+
default_statistics(Tv = Float64, Ti = Int64) = Dict{Symbol, Any}(
2+
:timeroutputs => TimerOutput(),
3+
:linear_residuals => Tv[],
4+
:nonlinear_residuals => Tv[],
5+
:matrix_nnz => Ti[],
116
)
127

138
mutable struct SolverConfiguration{AT <: AbstractMatrix, bT, xT}
@@ -19,7 +14,7 @@ mutable struct SolverConfiguration{AT <: AbstractMatrix, bT, xT}
1914
res::xT
2015
freedofs::Vector{Int} ## stores indices of free dofs
2116
LP::LinearProblem
22-
statistics::Dict{Symbol, Vector{Real}}
17+
statistics::Dict{Symbol, Any}
2318
linsolver::Any
2419
unknown_ids_in_sol::Array{Int, 1}
2520
unknowns::Array{Unknown, 1}
@@ -28,17 +23,54 @@ mutable struct SolverConfiguration{AT <: AbstractMatrix, bT, xT}
2823
parameters::Dict{Symbol, Any} # dictionary with user parameters
2924
end
3025

26+
"""
27+
````
28+
residuals(S::SolverConfiguration)
29+
````
30+
31+
returns the vector with the residuals of all iterations
32+
"""
33+
residuals(S::SolverConfiguration) = S.statistics[:nonlinear_residuals]
34+
3135
"""
3236
````
3337
residual(S::SolverConfiguration)
3438
````
3539
3640
returns the residual of the last solve
37-
3841
"""
3942
residual(S::SolverConfiguration) = S.statistics[:nonlinear_residuals][end]
4043

4144

45+
"""
46+
````
47+
timeroutputs(S::SolverConfiguration)
48+
````
49+
50+
returns TimerOutputs object that contains detailed information on solving and assembly times
51+
"""
52+
timeroutputs(S::SolverConfiguration) = S.statistics[:timeroutputs]
53+
54+
55+
"""
56+
````
57+
lastmatrix(S::SolverConfiguration)
58+
````
59+
60+
returns the currently stored system matrix
61+
"""
62+
lastmatrix(S::SolverConfiguration) = S.A
63+
64+
"""
65+
````
66+
lastrhs(S::SolverConfiguration)
67+
````
68+
69+
returns the currently stored right-hand side
70+
"""
71+
lastrhs(S::SolverConfiguration) = S.b
72+
73+
4274
#
4375
# Default context information with help info.
4476
#
@@ -65,6 +97,7 @@ default_solver_kwargs() = Dict{Symbol, Tuple{Any, String}}(
6597
:constant_rhs => (false, "right-hand side is constant (skips reassembly)"),
6698
:method_linear => (UMFPACKFactorization(), "any solver or custom LinearSolveFunction compatible with LinearSolve.jl (default = UMFPACKFactorization())"),
6799
:precon_linear => (nothing, "function that computes preconditioner for method_linear in case an iterative solver is chosen"),
100+
:timeroutputs => (:full, "configures show of timeroutputs (choose between :hide, :full, :compact)"),
68101
:initialized => (false, "linear system in solver configuration is already assembled (turns true after first solve)"),
69102
:plot => (false, "plot all solved unknowns with a (very rough but fast) unicode plot"),
70103
)
@@ -83,8 +116,8 @@ end
83116

84117
"""
85118
````
86-
function iterate_until_stationarity(
87-
SolverConfiguration(Problem::ProblemDescription
119+
function SolverConfiguration(
120+
Problem::ProblemDescription
88121
[FES::Union{<:FESpace, Vector{<:FESpace}}];
89122
init = nothing,
90123
unknowns = Problem.unknowns,
@@ -170,5 +203,5 @@ function SolverConfiguration(Problem::ProblemDescription, unknowns::Array{Unknow
170203
else
171204
LP = LinearProblem(A.entries.cscmatrix, b.entries)
172205
end
173-
return SolverConfiguration{typeof(A), typeof(b), typeof(x)}(Problem, A, b, x, x_temp, res, freedofs, LP, default_statistics(), nothing, unknown_ids_in_sol, unknowns, copy(unknowns), offsets, parameters)
206+
return SolverConfiguration{typeof(A), typeof(b), typeof(x)}(Problem, A, b, x, x_temp, res, freedofs, LP, default_statistics(TvM, TiM), nothing, unknown_ids_in_sol, unknowns, copy(unknowns), offsets, parameters)
174207
end

0 commit comments

Comments
 (0)