-
-
Notifications
You must be signed in to change notification settings - Fork 105
Linear Verbosity Specifiers #1049
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Conversation
37a20d3
to
233818c
Compare
@ChrisRackauckas this is the PR with the types and constructors for |
@@ -0,0 +1,298 @@ | |||
@data Verbosity begin |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
what is this macro? It's not standard, namespace it.
linear_defaults = Dict( | ||
:default_lu_fallback => Verbosity.Warn(), | ||
:no_right_preconditioning => Verbosity.Warn(), | ||
:using_iterative_solvers => Verbosity.Warn(), | ||
:using_IterativeSolvers => Verbosity.Warn(), | ||
:IterativeSolvers_iterations => Verbosity.Warn(), | ||
:KrylovKit_verbosity => Verbosity.Warn(), | ||
:KrylovJL_verbosity => Verbosity.None() | ||
) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should live in LinearSolve
function LinearNumericalVerbosity(; | ||
using_IterativeSolvers = linear_defaults[:using_IterativeSolvers], | ||
IterativeSolvers_iterations = linear_defaults[:IterativeSolvers_iterations], | ||
KrylovKit_verbosity = linear_defaults[:KrylovKit_verbosity], | ||
KrylovJL_verbosity = linear_defaults[:KrylovJL_verbosity]) | ||
new(using_IterativeSolvers, IterativeSolvers_iterations, KrylovKit_verbosity, KrylovJL_verbosity) | ||
end | ||
|
||
function LinearNumericalVerbosity(verbose::Verbosity.Type) | ||
@match verbose begin | ||
Verbosity.None() => new(fill( | ||
Verbosity.None(), length(fieldnames(LinearNumericalVerbosity)))...) | ||
|
||
Verbosity.Info() => new(fill( | ||
Verbosity.Info(), length(fieldnames(LinearNumericalVerbosity)))...) | ||
|
||
Verbosity.Warn() => new(fill( | ||
Verbosity.Warn(), length(fieldnames(LinearNumericalVerbosity)))...) | ||
|
||
Verbosity.Error() => new(fill( | ||
Verbosity.Error(), length(fieldnames(LinearNumericalVerbosity)))...) | ||
|
||
Verbosity.Default() => LinearNumericalVerbosity() | ||
|
||
Verbosity.Edge() => LinearNumericalVerbosity() | ||
|
||
_ => @error "Not a valid choice for verbosity." | ||
end | ||
end | ||
end | ||
|
||
|
||
|
||
struct LinearVerbosity{T} <: AbstractVerbositySpecifier{T} | ||
error_control::LinearErrorControlVerbosity | ||
performance::LinearPerformanceVerbosity | ||
numerical::LinearNumericalVerbosity | ||
end | ||
|
||
function LinearVerbosity(verbose::Verbosity.Type) | ||
@match verbose begin | ||
Verbosity.Default() => LinearVerbosity{true}( | ||
LinearErrorControlVerbosity(Verbosity.Default()), | ||
LinearPerformanceVerbosity(Verbosity.Default()), | ||
LinearNumericalVerbosity(Verbosity.Default()) | ||
) | ||
|
||
Verbosity.None() => LinearVerbosity{false}( | ||
LinearErrorControlVerbosity(Verbosity.None()), | ||
LinearPerformanceVerbosity(Verbosity.None()), | ||
LinearNumericalVerbosity(Verbosity.None())) | ||
|
||
Verbosity.All() => LinearVerbosity{true}( | ||
LinearErrorControlVerbosity(Verbosity.Info()), | ||
LinearPerformanceVerbosity(Verbosity.Info()), | ||
LinearNumericalVerbosity(Verbosity.Info()) | ||
) | ||
|
||
_ => @error "Not a valid choice for LinearVerbosity. Available choices are `Default`, `None`, and `All`." | ||
end | ||
end | ||
|
||
function LinearVerbosity(; | ||
error_control = Verbosity.Default(), performance = Verbosity.Default(), | ||
numerical = Verbosity.Default(), kwargs...) | ||
if error_control isa Verbosity.Type | ||
error_control_verbosity = LinearErrorControlVerbosity(error_control) | ||
else | ||
error_control_verbosity = error_control | ||
end | ||
|
||
if performance isa Verbosity.Type | ||
performance_verbosity = LinearPerformanceVerbosity(performance) | ||
else | ||
performance_verbosity = performance | ||
end | ||
|
||
if numerical isa Verbosity.Type | ||
numerical_verbosity = LinearNumericalVerbosity(numerical) | ||
else | ||
numerical_verbosity = numerical | ||
end | ||
|
||
if !isempty(kwargs) | ||
for (key, value) in pairs(kwargs) | ||
if hasfield(LinearErrorControlVerbosity, key) | ||
setproperty!(error_control_verbosity, key, value) | ||
elseif hasfield(LinearPerformanceVerbosity, key) | ||
setproperty!(performance_verbosity, key, value) | ||
elseif hasfield(LinearNumericalVerbosity, key) | ||
setproperty!(numerical_verbosity, key, value) | ||
else | ||
error("$key is not a recognized verbosity toggle.") | ||
end | ||
end | ||
end | ||
|
||
LinearVerbosity{true}(error_control_verbosity, | ||
performance_verbosity, numerical_verbosity) | ||
end |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
All of this should go to linearsolve since it will be edited alongside the code
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It would be nice if this can be moved to something like SciMLVerbosity.jl
so
- packages not depending on SciMLBase can use this
- we can version it independently and break the API if we need to
I'd really like to use this in MTK and possibly Symbolics.
group = getproperty(verbose, group) | ||
opt_level = getproperty(group, option) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does this mean every AbstractVerbositySpecifier
has to have exactly 2 levels of nesting?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes but this can definitely be changed to be more flexible.
end | ||
|
||
function emit_message( | ||
f::Function, verbose::V, option, group, file, line, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What if we don't type this as ::Function
, so that any callable can go here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah that makes sense.
level = message_level( | ||
verbose, option, group) | ||
if !isnothing(level) | ||
message = f() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we pass the option and group here? This allows for the function to have side effects at specific locations. My main use case is hooking into Infiltrator.jl.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think what we could do is have a 'Code' verbosity type that holds a quote, and we can modify the '@SciMLMessage' macro to evaluate the quote when called. That way you can just set one of the toggles of the verbosity object to 'Code(:Main.@infiltrate)' and it will infiltrate whenever it hits the part of the code associated with the toggle.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm pretty sure runtime eval
doesn't have access to local function scope, which means @infiltrate
won't really do anything useful.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I probably used the wrong words, but I think if I write the macro correctly it should have the same access as surrounding code. Anyways the details can be worked out when I get back on Monday 🙂
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sure, sounds good.
Checklist
contributor guidelines, in particular the SciML Style Guide and
COLPRAC.
Additional context
#962
This contains just the things necessary to use the verbosity system with LinearSolve, so we can test things out and make sure that this meets the requirements for the verbosity system.
A Moshi.jl ADT is used for the base verbosity specifiers.
LinearVerbosity
holds aLinearErrorControlVerbosity
, aLinearPerformanceVerbosity
, and aLinearNumericalVerbosity
. The@SciMLMessage
macro takes a String or a function that returns a String, a verbosity object, a symbol representing the base toggle, and a symbol representing what group the message belongs to.