Skip to content

Refactor options manager - #39

Merged
connorjward merged 12 commits into
mainfrom
connorjward/auto-options
Aug 26, 2026
Merged

connorjward merged 12 commits into
mainfrom
connorjward/auto-options

Conversation

@connorjward

@connorjward connorjward commented Jun 17, 2026

Copy link
Copy Markdown
Collaborator

Key changes:

  • Allow users to set command line options for autogenerated prefixes, this logs a warning because it isn't a safe thing to do but some users want it.
  • Don't overwrite options set on the command line, and don't drop them after first use.

Closes #37

The MFE in the issue is fixed by this:

from firedrake import *
import pytest


@pytest.mark.parametrize("options_prefix", (None, "", "pippo_"))
def test_change_command_line(options_prefix):
    mesh = UnitSquareMesh(2, 2)
    V = FunctionSpace(mesh, "CG", 1)

    u = Function(V)
    v = TestFunction(V)

    F = inner(u, v) * dx - conj(v) * dx

    problem = NonlinearVariationalProblem(F, u)
    
    # suppose users pass options by command line or via environment variable
    # here we mimic this by inserting the option directly in PETSc database
    # PETSc behavior: -some_option_whatever equivalent to -some_option_<n>_whatever for all n integers
    opts = PETSc.Options(options_prefix if options_prefix is not None else "firedrake_")
    opts["ksp_type"] = "minres"
    solver = NonlinearVariationalSolver(problem, solver_parameters={"ksp_type": "cg"}, options_prefix=options_prefix)
    opts_not_removed = "ksp_type" in opts and opts["ksp_type"] == "minres"
    # remove our option so that it won't conflict with all other tests
    del opts["ksp_type"]
    assert solver.snes.ksp.getType() == "minres" and opts_not_removed

@connorjward

Copy link
Copy Markdown
Collaborator Author

@JHopeCollins this is only a rough first attempt but I want to check with you on the approach. The main thing I'm doing is moving the options logic into the inserted_options context manager/method instead of __init__. I think that this makes sense because users should be allowed to noodle with PETSc.Options() themselves. Currently the options are baked in when we construct the OptionsManager.

@connorjward
connorjward force-pushed the connorjward/auto-options branch from 0b9e714 to a0fd39a Compare June 19, 2026 14:46
@connorjward

Copy link
Copy Markdown
Collaborator Author

Here's an example demonstrating what I believe to be quite unintuitive behaviour. I totally get why this isn't recommended practice, but I also think that we should always try and do the intuitive thing.

@pytest.mark.skipnopetsc4py
@pytest.mark.parametrize("options_prefix", (None, "", "custom_"))
def test_commandline_options_change(caplog, options_prefix):
    from petsc4py import PETSc

    options = PETSc.Options()
    om = petsctools.OptionsManager(
        {"opt1": "value1"}, options_prefix=options_prefix
    )

    with om.inserted_options():
        assert options[f"{om.options_prefix}opt1"] == "value1"

    # Put some options in the database after the options manager is created
    options[f"{om.options_prefix}opt1"] = "value2"

    with om.inserted_options():
        # NOTE: not 'value2' because we use the frozen value from when we first
        # made the options manager
        assert options[f"{om.options_prefix}opt1"] == "value1"

    # the original option should be put back (currently it's dropped)
    assert options[f"{om.options_prefix}opt1"] == "value2"

Comment thread petsctools/options.py Outdated
@connorjward
connorjward marked this pull request as ready for review August 25, 2026 13:44
Comment thread tests/test_options.py
Comment thread petsctools/options.py Outdated
Comment thread tests/test_options.py Outdated
Comment thread tests/test_options.py
Comment thread petsctools/options.py Outdated
Comment thread petsctools/options.py Outdated

@JHopeCollins JHopeCollins left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Generally good, this looks like it deals with the original problem and also provides more information to users.

  1. We will no longer interfere with the global options dictionary or attempt to hide any entries from the auto-prefixed solver.
  2. We will warn you if you do use the auto-generated prefix that this is unstable, where previously we would confusingly just silently ignore some options.

I had some small requests then I'm happy to approve. The biggest one is actually fixing a bug from my DefaultOptionsSet PR!

Comment thread tests/test_options.py
Co-authored-by: Josh Hope-Collins <joshua.hope-collins13@imperial.ac.uk>
@connorjward
connorjward enabled auto-merge (squash) August 26, 2026 10:29
@connorjward
connorjward merged commit 9883f21 into main Aug 26, 2026
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Raise a warning when trying to pass options to an autogenerated prefix.

2 participants