How to know which PETSc solver methods are available?

dolfinx uses PETSc for solving the matrices of the system. PETSc can be built with many options, including external solvers like MUMPS, SuperLU and SuperLU-Dist.

The petsc4py interface will tell you if a given external package is available, via PETSc.Sys()hasExternalPackage("mumps"). But that requires you to know the registered name of the package to enquire about.

In legacy dolfin there were functions like list_linear_solver_methods() to list PETSc’s available solvers, but these utility functions are removed from dolfinx.

Is there a function I missed in dolfinx or in petsc4py.PETSc to list which solvers are available at runtime?

You can use:

from mpi4py import MPI

from petsc4py import PETSc

opts = PETSc.Options()
opts["help"] = None
ksp = PETSc.KSP().create()
ksp.setFromOptions()
----------------------------------------
Preconditioner (PC) options:
  -pc_type <now (null) : formerly (null)>: Preconditioner (one of) nn hypre hmg tfs spai composite ksp lu icc patch bjacobi eisenstat smg deflation pfmg vpbjacobi redistribute sor mg pbjacobi syspfmg cholesky python mat qr svd fieldsplit bddc mpi kaczmarz jacobi telescope redundant cp shell galerkin ilu exotic gasm gamg none lmvm asm lsc (PCSetType)
  -pc_use_amat: <now FALSE : formerly FALSE> use Amat (instead of Pmat) to define preconditioner in nested inner solves (PCSetUseAmat)
----------------------------------------
Krylov Method (KSP) options:
  -ksp_type <now gmres : formerly gmres>: Krylov method (one of) fetidp pipefgmres stcg tsirm tcqmr groppcg nash fcg symmlq lcd minres cgs preonly lgmres pipecgrr fbcgs pipeprcg pipecg ibcgs fgmres qcg gcr cgne pipefcg pipecr pipebcgs bcgsl pipecg2 pipelcg gltr cg tfqmr pgmres lsqr pipegcr bicg cgls bcgs cr python dgmres none qmrcgs gmres richardson chebyshev fbcgsr (KSPSetType)
  -ksp_monitor_cancel: <now FALSE : formerly FALSE> Remove any hardwired monitor routines (KSPMonitorCancel)
----------------------------------------

Similarly for Matrices/Vectors:

opts = PETSc.Options()
opts["help"] = None
mat = PETSc.Mat().create()
mat.setFromOptions()

As for linear solvers for lu factorization, I struggle with figuring out the right way of extracting those options

2 Likes

Thanks dokken. At least that gives us some of the options!

@dparsons
I thought about this for a bit longer, and here is a solution:

from petsc4py import PETSc
import inspect


def check_petsc_packages():
    st = PETSc.Mat.SolverType

    # Get all attributes of the SolverType class
    rs = inspect.getmembers(st, lambda a: not inspect.isroutine(a))
    # Remove all dunder methods
    rs = [r for r in rs if not (r[0].startswith("__") and r[0].endswith("__"))]
    for r in rs:
        name = r[0]
        is_available = PETSc.Sys().hasExternalPackage(name)
        print(f"Package {name}: {'Available' if is_available else 'Not Available'}")


check_petsc_packages()

yields:

Package BAS: Not Available
Package CHOLMOD: Available
Package CUDA: Not Available
Package CUSPARSE: Not Available
Package ELEMENTAL: Not Available
Package ESSL: Not Available
Package KLU: Available
Package LUSOL: Not Available
Package MATLAB: Not Available
Package MKL_CPARDISO: Not Available
Package MKL_PARDISO: Not Available
Package MUMPS: Available
Package PASTIX: Not Available
Package PETSC: Not Available
Package SCALAPACK: Available
Package SPQR: Available
Package STRUMPACK: Not Available
Package SUPERLU: Available
Package SUPERLU_DIST: Available
Package UMFPACK: Available

It is not perfect, as for instance PETSC should always be available, but it is not an external package.

The complete list of LU decomposition packages can be found at: Summary of Sparse Linear Solvers Available In PETSc — PETSc 3.24.1 documentation

2 Likes

Nice. Could always add

        if name == "PETSC":
             continue

to tidy up that rough edge.