Verbosity Presets

Presets provide convenient, predefined verbosity configurations that cover common use cases. Instead of manually setting each message category, users can choose from standard presets that automatically configure appropriate message levels. SciMLLogging provides the AbstractVerbosityPreset type, along with five subtypes meant to represent different verbosity levels. It is up to the implementer of the AbstractVerbositySpecifier to ensure that the verbosity presets are able to be used.

General Idea of Preset Levels

Definition of the Preset Levels

The general idea behind the preset levels is as follows. Each lower level keeps everything enabled from the level above it, and adds the additional information:

  • None makes it easy to turn off all printing/logging to ensure 0 overhead and 0 noise.
  • Minimal turns on only the fatal errors, for example solvers exiting early due to instability, which the user must react to in order to appropriately compute correctly.
  • Standard turns on non-fatal but critical warnings, for example major performance warnings or deprecations which have been flagged that the user almost certaintly should respond to. While the program is still running correctly if these are firing, this is the level on by default to signal to the wider userbase issues which should be handled in order to have "normal" running code.
  • Detailed turns on additional information as part of the run which can be helpful for in-depth debugging. This includes information about critical quantities at each step of the calculation, behaviors of the solver that are chosen behind the scenes, and critical numerical issues which are detected. This level should be detailed, but it should be something that does not necessarily overflow the standard REPL output and should not introduce major performance overhead.
  • All turns on all logging available in the system. This can include detailed printing that happens in every iteration (i.e. overflowing the terminal output maximum lines), expensive calculations of critical quantities like condition numbers which can be more expensive than the standard solver but serve as good diagnostics to understand the numerical quantities better, and other verbose output which could be found interesting to package developers looking for obscure issues. It is generally recommended that All output is redirected to a file as it likely will need to be parsed to be human understandable.

Preset Level Examples

  • In the ODE solver, if dt<dtmin the solver needs to exit. Almost all users should be notified of this behavior in order to understand why the solver did not go to the final time. This should be set as a WarnLevel in the Minimal preset.
  • In LinearSolve.jl's default methods, it has the ability to swap from using an LU factorization to a column-pivoted QR factorization behind the scenes if a singular matrix is detected. Since LinearSolve.jl automatically recovers from any error here, most users do not need to know if this has happened, thus it is a solver behavoir that should be logged at the Detailed level because it's non-verbose and no extra cost to know, but can be a critical debugging information.
  • In SciMLSensitivity.jl's default vjp method, it has to run through a bunch of different potential reverse-mode AD methods to see which is compatible with the user's f. If none of the AD methods are compatible, it needs to fallback to FiniteDiffVJP, which is finite differencing and thus changes the J'v calcuation from O(n) matrix-free to O(n^2) building J. This is a massive difference in computational cost which most users should know about, as it should generally be considered incorrect behavior to require finite differencing here and the user should be notified by default about this fallback. Thus it should be given WarnLevel in the Standard preset, since it's not critical so it's not Minimal. In the Detailed preset, the vjp choice should additionally be shared every time even if it's not finite differencing.
  • In LinearSolve.jl, it can be very useful to know cond(A) in order to know how ill-conditioned the numerical problem is at every step. This can help for understanding why Newton-Krylov methods aren't converging well, or whether ODE solves should have difficulties handling a given step. However, cond(A) is a very expensive calculation, sometimes more expensive than the solver itself, and thus it should only be enabled when maximum information is needed. Thus this printing would only be enabled when All is chosen.
  • The default ODE solver has the ability to automatically swap between solvers based on certain qualities of the ODE that are detected, essentially estimating condition number. While this behavior is not necessary for most users to know, it can help a lot while debugging to know exactly when the swaps occured. Since they don't occur often, this information should be included in the Detailed output, along with some information about why the trigger occurred.
  • Error estimate values of adaptive ODE solvers, eigenvalue estimates in stabilized RK (RKC) methods, and other per-step estimators can be really useful for debugging ODE solvers in order to know what specific term is likely making the solver drop the dt to be smaller, but it's very noisy to print tons of information at every step. Thus this information can be setup to have standard printers which are only turned on by demand or in the All preset.

Abstract Base Type

SciMLLogging.AbstractVerbosityPresetType
AbstractVerbosityPreset

Abstract base type for predefined verbosity configurations.

Presets provide convenient ways for users to configure verbosity without needing to specify individual message categories. Concrete subtypes include:

  • None: Disable all verbosity
  • Minimal: Only essential messages
  • Standard: Balanced verbosity for typical use
  • Detailed: Comprehensive verbosity for debugging
  • All: Enable all message categories
source

Available Presets

SciMLLogging.NoneType
None <: AbstractVerbosityPreset

Preset that disables all verbosity. All message categories should be set to to Silent().

source
SciMLLogging.MinimalType
Minimal <: AbstractVerbosityPreset

Preset that shows only essential messages. Typically includes only warnings, errors, and critical status information while suppressing routine progress and debugging messages.

This verbosity preset should set messages related to critical failures and errors that stop computation to ErrorLevel. Messages related to fatal issues (e.g., convergence problems, solver exiting, etc.) should be set to WarnLevel(). All other messages should be set to Silent().

source
SciMLLogging.StandardType
Standard <: AbstractVerbosityPreset

Preset that provides balanced verbosity suitable for typical usage. Shows important progress and status information without overwhelming the user with details.

This verbosity preset should include the settings from Minimal, while also setting messages such as non-fatal deprecations and critical warnings that require handling to InfoLevel.

source
SciMLLogging.DetailedType
Detailed <: AbstractVerbosityPreset

Preset that provides comprehensive verbosity for debugging and detailed analysis. Shows most or all available message categories to help with troubleshooting and understanding program behavior.

This verbosity preset should include the settings from Standard, plus progress updates (e.g., iteration counters, intermediate state), performance metrics (e.g., timing information, memory usage), detailed diagnostics, and internal state information. The only messages that should be Silent() at this preset are very small details that would clutter output even during debugging, and information that would be expensive to calculate.

source
SciMLLogging.AllType
All <: AbstractVerbosityPreset

Preset that enables maximum verbosity. All message categories are typically set to show informational messages or their appropriate levels.

This verbosity preset should include the settings from Detailed, plus even more details. At this preset, no messages should be Silent().

source

Custom Presets

Packages can define their own preset types for specialized use cases:

# Package-specific preset
struct DebuggingPreset <: AbstractVerbosityPreset end

function MyPackageVerbosity(::DebuggingPreset)
    MyPackageVerbosity{true}(
        initialization = InfoLevel(),
        progress = DebugLevel(),  # Extra detailed progress
        convergence = InfoLevel(),
        warnings = WarnLevel(),
        errors = ErrorLevel()
    )
end

Using Presets

Presets are typically used as constructor arguments for verbosity specifiers:

using SciMLLogging

# Assuming a package defines MyPackageVerbosity
quiet_config = MyPackageVerbosity(None())      # No output
default_config = MyPackageVerbosity(Standard()) # Balanced output
debug_config = MyPackageVerbosity(All())       # Maximum output

How Presets Work

When you pass a preset to a verbosity specifier constructor, the package implementation maps the preset to appropriate message levels for each category. For example:

# This preset usage...
verbosity = SolverVerbosity(Standard())

# ...might be equivalent to this manual configuration:
verbosity = SolverVerbosity(
    initialization = InfoLevel(),
    progress = Silent(),
    convergence = InfoLevel(),
    diagnostics = WarnLevel(),
    performance = InfoLevel()
)