Linear Verbosity Specifiers#1049
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.
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.
This should live in LinearSolve
| mutable struct LinearPerformanceVerbosity | ||
| no_right_preconditioning::Verbosity.Type | ||
|
|
||
| function LinearPerformanceVerbosity(; | ||
| no_right_preconditioning = linear_defaults[:no_right_preconditioning]) | ||
| new(no_right_preconditioning) | ||
| end | ||
|
|
||
| function LinearPerformanceVerbosity(verbose::Verbosity.Type) | ||
| @match verbose begin | ||
| Verbosity.None() => new(fill( | ||
| Verbosity.None(), length(fieldnames(LinearPerformanceVerbosity)))...) | ||
|
|
||
| Verbosity.Info() => new(fill( | ||
| Verbosity.Info(), length(fieldnames(LinearPerformanceVerbosity)))...) | ||
|
|
||
| Verbosity.Warn() => new(fill( | ||
| Verbosity.Warn(), length(fieldnames(LinearPerformanceVerbosity)))...) | ||
|
|
||
| Verbosity.Error() => new(fill( | ||
| Verbosity.Error(), length(fieldnames(LinearPerformanceVerbosity)))...) | ||
|
|
||
| Verbosity.Default() => LinearPerformanceVerbosity() | ||
|
|
||
| Verbosity.Edge() => LinearPerformanceVerbosity() | ||
|
|
||
| _ => @error "Not a valid choice for verbosity." | ||
| end | ||
| end | ||
|
|
||
| end | ||
|
|
||
| mutable struct LinearNumericalVerbosity | ||
| using_IterativeSolvers::Verbosity.Type | ||
| IterativeSolvers_iterations::Verbosity.Type | ||
| KrylovKit_verbosity::Verbosity.Type | ||
| KrylovJL_verbosity::Verbosity.Type | ||
|
|
||
| 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.
All of this should go to linearsolve since it will be edited alongside the code
| group = getproperty(verbose, group) | ||
| opt_level = getproperty(group, option) |
There was a problem hiding this comment.
Does this mean every AbstractVerbositySpecifier has to have exactly 2 levels of nesting?
There was a problem hiding this comment.
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.
What if we don't type this as ::Function, so that any callable can go here?
There was a problem hiding this comment.
Yeah that makes sense.
| level = message_level( | ||
| verbose, option, group) | ||
| if !isnothing(level) | ||
| message = f() |
There was a problem hiding this comment.
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.
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.
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.
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 🙂
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.
LinearVerbosityholds aLinearErrorControlVerbosity, aLinearPerformanceVerbosity, and aLinearNumericalVerbosity. The@SciMLMessagemacro 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.