Skip to content

Commit d8e7aec

Browse files
committed
add linear verbosity stuff
1 parent cc3c3fe commit d8e7aec

File tree

1 file changed

+250
-0
lines changed

1 file changed

+250
-0
lines changed

src/verbosity.jl

Lines changed: 250 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,250 @@
1+
@data Verbosity begin
2+
None
3+
Info
4+
Warn
5+
Error
6+
Level(Int)
7+
Edge
8+
All
9+
Default
10+
end
11+
12+
# Linear Verbosity
13+
14+
linear_defaults = Dict(
15+
:default_lu_fallback => Verbosity.Warn()
16+
:using_iterative_solvers => Verbosity.Warn()
17+
)
18+
mutable struct LinearErrorControlVerbosity
19+
default_lu_fallback::Verbosity.Type
20+
21+
function LinearErrorControlVerbosity(;
22+
default_lu_fallback = linear_defaults[:default_lu_fallback])
23+
new(default_lu_fallback)
24+
end
25+
end
26+
27+
function LinearErrorControlVerbosity(verbose::Verbosity.Type)
28+
@match verbose begin
29+
Verbosity.None() => LinearErrorControlVerbosity(fill(
30+
Verbosity.None(), length(fieldnames(LinearErrorControlVerbosity)))...)
31+
32+
Verbosity.Info() => LinearErrorControlVerbosity(fill(
33+
Verbosity.Info(), length(fieldnames(LinearErrorControlVerbosity)))...)
34+
35+
Verbosity.Warn() => LinearErrorControlVerbosity(fill(
36+
Verbosity.Warn(), length(fieldnames(LinearErrorControlVerbosity)))...)
37+
38+
Verbosity.Error() => LinearErrorControlVerbosity(fill(
39+
Verbosity.Error(), length(fieldnames(LinearErrorControlVerbosity)))...)
40+
41+
Verbosity.Default() => LinearErrorControlVerbosity()
42+
43+
Verbosity.Edge() => LinearErrorControlVerbosity()
44+
45+
_ => @error "Not a valid choice for verbosity."
46+
end
47+
end
48+
49+
mutable struct LinearPerformanceVerbosity
50+
no_right_preconditioning::Verbosity.Type
51+
function LinearPerformanceVerbosity(;
52+
no_right_preconditioning = linear_defaults[:no_right_preconditioning])
53+
new(no_right_preconditioning)
54+
end
55+
end
56+
57+
function LinearPerformanceVerbosity(verbose::Verbosity.Type)
58+
@match verbose begin
59+
Verbosity.None() => LinearPerformanceVerbosity(fill(
60+
Verbosity.None(), length(fieldnames(LinearPerformanceVerbosity)))...)
61+
62+
Verbosity.Info() => LinearPerformanceVerbosity(fill(
63+
Verbosity.Info(), length(fieldnames(LinearPerformanceVerbosity)))...)
64+
65+
Verbosity.Warn() => LinearPerformanceVerbosity(fill(
66+
Verbosity.Warn(), length(fieldnames(LinearPerformanceVerbosity)))...)
67+
68+
Verbosity.Error() => LinearPerformanceVerbosity(fill(
69+
Verbosity.Error(), length(fieldnames(LinearPerformanceVerbosity)))...)
70+
71+
Verbosity.Default() => LinearPerformanceVerbosity()
72+
73+
Verbosity.Edge() => LinearPerformanceVerbosity()
74+
75+
_ => @error "Not a valid choice for verbosity."
76+
end
77+
end
78+
79+
mutable struct LinearNumericalVerbosity
80+
using_IterativeSolvers::Verbosity.Type
81+
IterativeSolvers_iterations::Verbosity.Type
82+
KrylovKit_verbosity::Verbosity.Type
83+
84+
function LinearNumericalVerbosity(;
85+
using_IterativeSolvers = linear_defaults[:using_IterativeSolvers],
86+
IterativeSolvers_iterations = linear_defaults[:IterativeSolvers_iterations],
87+
KrylovKit_verbosity = linear_defaults[:KrylovKit_verbosity])
88+
new(using_IterativeSolvers, IterativeSolvers_iterations, KrylovKit_verbosity)
89+
end
90+
end
91+
92+
function LinearNumericalVerbosity(verbose::Verbosity.Type)
93+
@match verbose begin
94+
Verbosity.None() => LinearNumericalVerbosity(fill(
95+
Verbosity.None(), length(fieldnames(LinearNumericalVerbosity)))...)
96+
97+
Verbosity.Info() => LinearNumericalVerbosity(fill(
98+
Verbosity.Info(), length(fieldnames(LinearNumericalVerbosity)))...)
99+
100+
Verbosity.Warn() => LinearNumericalVerbosity(fill(
101+
Verbosity.Warn(), length(fieldnames(LinearNumericalVerbosity)))...)
102+
103+
Verbosity.Error() => LinearNumericalVerbosity(fill(
104+
Verbosity.Error(), length(fieldnames(LinearNumericalVerbosity)))...)
105+
106+
Verbosity.Default() => LinearNumericalVerbosity()
107+
108+
Verbosity.Edge() => LinearNumericalVerbosity()
109+
110+
_ => @error "Not a valid choice for verbosity."
111+
end
112+
end
113+
114+
struct LinearVerbosity{T} <: AbstractVerbositySpecifier{T}
115+
error_control::LinearErrorControlVerbosity
116+
performance::LinearPerformanceVerbosity
117+
numerical::LinearNumericalVerbosity
118+
end
119+
120+
function LinearVerbosity(verbose::Verbosity.Type)
121+
@match verbose begin
122+
Verbosity.Default() => LinearVerbosity{true}(
123+
LinearErrorControlVerbosity(Verbosity.Default()),
124+
LinearPerformanceVerbosity(Verbosity.Default()),
125+
LinearNumericalVerbosity(Verbosity.Default())
126+
)
127+
128+
Verbosity.None() => LinearVerbosity{false}(
129+
LinearErrorControlVerbosity(Verbosity.None()),
130+
LinearPerformanceVerbosity(Verbosity.None()),
131+
LinearNumericalVerbosity(Verbosity.None()))
132+
133+
Verbosity.All() => LinearVerbosity{true}(
134+
LinearErrorControlVerbosity(Verbosity.Info()),
135+
LinearPerformanceVerbosity(Verbosity.Info()),
136+
LinearNumericalVerbosity(Verbosity.Info())
137+
)
138+
139+
_ => @error "Not a valid choice for verbosity."
140+
end
141+
end
142+
143+
function LinearVerbosity(;
144+
error_control = Verbosity.Default(), performance = Verbosity.Default(),
145+
numerical = Verbosity.Default(), kwargs...)
146+
if error_control isa Verbosity.Type
147+
error_control_verbosity = LinearErrorControlVerbosity(error_control)
148+
else
149+
error_control_verbosity = error_control
150+
end
151+
152+
if performance isa Verbosity.Type
153+
performance_verbosity = LinearPerformanceVerbosity(performance)
154+
else
155+
performance_verbosity = performance
156+
end
157+
158+
if numerical isa Verbosity.Type
159+
numerical_verbosity = LinearNumericalVerbosity(numerical)
160+
else
161+
numerical_verbosity = numerical
162+
end
163+
164+
if !isempty(kwargs)
165+
for (key, value) in pairs(kwargs)
166+
if hasfield(LinearErrorControlVerbosity, key)
167+
setproperty!(error_control_verbosity, key, value)
168+
elseif hasfield(LinearPerformanceVerbosity, key)
169+
setproperty!(performance_verbosity, key, value)
170+
elseif hasfield(LinearNumericalVerbosity, key)
171+
setproperty!(numerical_verbosity, key, value)
172+
else
173+
error("$key is not a recognized verbosity toggle.")
174+
end
175+
end
176+
end
177+
178+
LinearVerbosity{true}(error_control_verbosity,
179+
performance_verbosity, numerical_verbosity)
180+
end
181+
182+
# Utilities
183+
184+
function message_level(verbose::AbstractVerbositySpecifier{true}, option, group)
185+
group = getproperty(verbose, group)
186+
opt_level = getproperty(group, option)
187+
188+
@match opt_level begin
189+
Verbosity.None() => nothing
190+
Verbosity.Info() => Logging.Info
191+
Verbosity.Warn() => Logging.Warn
192+
Verbosity.Error() => Logging.Error
193+
Verbosity.Level(i) => Logging.LogLevel(i)
194+
end
195+
end
196+
197+
function emit_message(
198+
f::Function, verbose::V, option, group, file, line,
199+
_module) where {V <: AbstractVerbositySpecifier{true}}
200+
level = message_level(
201+
verbose, option, group)
202+
if !isnothing(level)
203+
message = f()
204+
Base.@logmsg level message _file=file _line=line _module=_module
205+
end
206+
end
207+
208+
function emit_message(message::String, verbose::V,
209+
option, group, file, line, _module) where {V <: AbstractVerbositySpecifier{true}}
210+
level = message_level(verbose, option, group)
211+
212+
if !isnothing(level)
213+
Base.@logmsg level message _file=file _line=line _module=_module
214+
end
215+
end
216+
217+
function emit_message(
218+
f, verbose::AbstractVerbositySpecifier{false}, option, group, file, line, _module)
219+
end
220+
221+
@doc doc"""
222+
A macro that emits a log message based on the log level specified in the `option` and `group` of the `AbstractVerbositySpecifier` supplied.
223+
224+
`f_or_message` may be a message String, or a 0-argument function that returns a String.
225+
226+
## Usage
227+
To emit a simple string, `@SciMLMessage("message", verbosity, :option, :group)` will emit a log message with the LogLevel specified in `verbosity`, at the appropriate `option` and `group`.
228+
229+
`@SciMLMessage` can also be used to emit a log message coming from the evaluation of a 0-argument function. This function is resolved in the environment of the macro call.
230+
Therefore it can use variables from the surrounding environment. This may be useful if the log message writer wishes to carry out some calculations using existing variables
231+
and use them in the log message.
232+
233+
```julia
234+
x = 10
235+
y = 20
236+
237+
@SciMLMessage(verbosity, :option, :group) do
238+
z = x + y
239+
"Message is: x + y = \$z"
240+
end
241+
```
242+
"""
243+
macro SciMLMessage(f_or_message, verb, option, group)
244+
line = __source__.line
245+
file = string(__source__.file)
246+
_module = __module__
247+
return :(emit_message(
248+
$(esc(f_or_message)), $(esc(verb)), $option, $group, $file, $line, $_module))
249+
end
250+

0 commit comments

Comments
 (0)