Utilities

This page documents utility functions for initialization, options handling, system information, and code auditing.

Initialization

The initialization functions manage PETSc's lifecycle, including MPI initialization and cleanup.

PETSc.PetscNotInitializedType
PetscNotInitialized(petsclib)

Thrown when a PETSc object is built or used before its library is initialized.

Call initialize on the library first. Every PETSc call needs the library up, so this is reported as its own type rather than as an ArgumentError, which lets callers catch it specifically.

source
PETSc.check_petsc_wrappers_versionFunction
check_petsc_wrappers_version(petsclib=nothing)

Load the generated petsc_wrappers_version.jl (if present) and compare the declared wrapper version PETSC_WRAPPERS_VERSION with the installed PETSc version obtained from LibPETSc.PetscGetVersionNumber for petsclib.

Arguments

  • petsclib: optional PetscLibType or path string. If nothing, the first available PETSc.petsclibs[1] is used.

Returns a named tuple: (:wrappers_version, :installed_version, :match). match is true when the library is one of [SUPPORTED_PETSC_VERSIONS], false when it is not, and nothing if the library version could not be determined.

source
PETSc.initializeMethod
initialize([petsclib]; log_view = false, options = String[])

Initialize the petsclib. If no petsclib is given, all PETSc.petsclibs will be initialized.

Additionally:

Arguments

  • log_view::Bool = false: Enable PETSc's -log_view performance logging. When enabled, PETSc will output performance statistics at finalization.
  • options::Vector{String} = String[]: Additional PETSc command-line options. These are passed via the PETSC_OPTIONS environment variable.

Examples

# Basic initialization
PETSc.initialize(petsclib)

# Enable performance logging to stdout
PETSc.initialize(petsclib; log_view = true)

# Write log to a file
PETSc.initialize(petsclib; log_view = true, options = [":logfile.txt"])

# Enable memory logging
PETSc.initialize(petsclib; log_view = true, options = [":logfile.txt", "-log_view_memory"])

# Pass custom PETSc options without logging
PETSc.initialize(petsclib; options = ["-malloc_debug", "-on_error_abort"])

External Links

source
PETSc.inttypeMethod
inttype(petsclib::PetscLibType)

return the int type for the associated petsclib

source
PETSc.isdestroyableMethod
isdestroyable(obj, ::Type{PetscLib})

Whether obj still refers to a PETSc object this process is allowed to destroy.

It is not destroyable when the library is finalized, when the pointer is already null, or when the object predates the current initialize/finalize cycle. initialize and finalize both bump petsclib.age, and every object records the age it was created under. PetscFinalize frees everything it owns, including the inner communicator, so calling xxxDestroy on an object from an earlier cycle reaches a communicator that no longer exists and aborts inside MPI with "Invalid communicator". That happens from a GC finalizer, so it surfaces at an arbitrary later point rather than where the object was dropped.

source
PETSc.library_infoMethod
library_info()

Print the current PETSc library configuration: which library is in use, how it was configured (preference or default JLL), and the scalar/integer types.

source
PETSc.scalartypeMethod
scalartype(petsclib::PetscLibType)

return the scalar type for the associated petsclib

source
PETSc.set_library!Method
set_library!(path; PetscScalar=Float64, PetscInt=Int64)

Persistently configure PETSc.jl to use a custom PETSc shared library.

The path and type configuration are stored in LocalPreferences.toml (per-project, git-ignorable) and take effect on the next Julia session. Recompilation is triggered automatically — no environment variables are needed.

To revert to the default PETSc_jll libraries, call unset_library!.

Arguments

  • path: path to the PETSc shared library (e.g. "/path/to/libpetsc.so")
  • PetscScalar: scalar type the library was built with (Float64, Float32, Complex{Float64}, Complex{Float32}). Default: Float64
  • PetscInt: integer type the library was built with (Int64 or Int32). Default: Int64

Examples

PETSc.set_library!(
    "/project/petsc/lib/libpetsc.so";
    PetscScalar = Float64,
    PetscInt    = Int64,
)
# Restart Julia — the new library is used automatically from here on.

See Also

source
PETSc.set_petscint!Method
set_petscint!(::Type{T}) where {T<:Union{Int32,Int64}}

Persistently select which PetscInt width of the PETSc_jll libraries is loaded (default: Int64). Only one width is registered per process: the Int64 and Int32 library variants link external packages (hypre, SuperLU_DIST) that export identical symbols with different integer ABIs, so mixing both widths in one process is unsafe on platforms with a flat dynamic-linker namespace.

Takes effect on the next Julia session (standard Preferences.jl recompilation). Has no effect when a custom library is configured via set_library!.

source
PETSc.set_petsclibMethod
set_petsclib(library_path::String; PetscScalar=Float64, PetscInt=Int64)

Create a custom PETSc library instance from a user-specified shared library path.

This function allows you to use a custom-compiled PETSc library instead of the pre-built libraries provided by PETSc_jll. The custom library must be compiled as a shared/dynamic library (not static), built with the matching scalar type and integer size, and linked against the same MPI installation that MPI.jl uses.

On HPC systems, set JULIA_PETSC_SKIP_JLL=1 before starting Julia to prevent PETSc_jll from being precompiled (its MPI stack is typically incompatible with cluster MPI). Then call this function in your script to load the cluster library.

Arguments

  • library_path::String: Path to the PETSc shared library (e.g. "/path/to/libpetsc.so")
  • PetscScalar::Type: Scalar type the library was built with. One of Float64, Float32, Complex{Float64}, Complex{Float32}. Default: Float64
  • PetscInt::Type: Integer type the library was built with. Int32 or Int64. Default: Int64

Returns

A PetscLibType instance for use with initialize, finalize, and all PETSc.jl functions.

Environment-variable alternative

Instead of calling set_petsclib, you can configure everything before Julia starts:

JULIA_PETSC_LIBRARY=/path/to/libpetsc.so   # also suppresses PETSc_jll
JULIA_PETSC_SCALAR=Float64                  # Float32 | ComplexFloat64 | ComplexFloat32
JULIA_PETSC_INT=Int64                       # Int32

With these set, PETSc.getlib(; PetscScalar=Float64, PetscInt=Int64) returns the custom library directly.

Examples

# Double-precision real, 64-bit indices (typical HPC build)
petsclib = PETSc.set_petsclib("/path/to/libpetsc.so";
                              PetscScalar=Float64, PetscInt=Int64)
PETSc.initialize(petsclib)
# ... your code ...
PETSc.finalize(petsclib)

# Single-precision complex, 32-bit indices
petsclib = PETSc.set_petsclib("/opt/petsc/lib/libpetsc.so";
                              PetscScalar=Complex{Float32}, PetscInt=Int32)

See Also

source
PETSc.tao_usable_after_reinitializeMethod
tao_usable_after_reinitialize()

Whether Tao objects can be created after finalize followed by initialize with the current PETSc binaries (false on Windows with PETSc 3.25.x, see _reset_stale_register_flags).

source
PETSc.unset_library!Method
unset_library!()

Remove the persistent custom-library preference set by set_library!, reverting to the default PETSc_jll binaries on the next Julia session.

source

Options

PETSc uses an options database to configure solvers and other objects at runtime. These functions provide access to the options system.

PETSc.OptionsMethod
Options(petsclib; kwargs...)

Create a PETSc options database for the given petsclib.

Keyword arguments are converted to PETSc options:

  • Options with value nothing or true are set without a value (flags)
  • Options with value false are not set
  • Other values are converted to strings

Examples

julia> using PETSc

julia> petsclib = PETSc.petsclibs[1];

julia> PETSc.initialize(petsclib)

julia> opt = PETSc.Options(
                         petsclib,
                         ksp_monitor = nothing,
                         ksp_view = true,
                         pc_type = "mg",
                         pc_mg_levels = 1,
                         false_opt = false,
                     )
#PETSc Option Table entries:
-ksp_monitor
-ksp_view
-pc_mg_levels 1
-pc_type mg
#End of PETSc Option Table entries


julia> opt["ksp_monitor"]
""

julia> opt["pc_type"]
"mg"

julia> opt["pc_type"] = "ilu"
"ilu"

julia> opt["pc_type"]
"ilu"

julia> opt["false_opt"]
ERROR: KeyError: key "bad_key" not found

julia> opt["bad_key"]
ERROR: KeyError: key "bad_key" not found

External Links

source
PETSc.parse_optionsMethod
parse_options(args::Vector{String})

Parse the args vector into a NamedTuple that can be used as the options for the PETSc solvers.

julia --project file.jl -ksp_monitor -pc_type mg -ksp_view -da_refine=1
source
PETSc.typedgetMethod
typedget(opt::NamedTuple, key::Symbol, default::T)

Parse opt similar to Base.get but ensures that the returned value is the same type as the default value. When T <: NTuple keys that result in a single value will be filled into an NTuple of the same length as T; in the case of strings it is parsed using Base.split with comma delimiter

Examples

julia> opt = (tup = (1, 2, 3), string_tup = "1,2,3", string_int = "4", int = 4)
(tup = (1, 2, 3), string_tup = "1,2,3", string_int = "4", int = 4)

julia> typedget(opt, :int, 7)
4

julia> typedget(opt, :bad_key, 7)
7

julia> typedget(opt, :tup, (1, 1, 1))
(1, 2, 3)

julia> typedget(opt, :string_tup, (1, 1, 1))
tokens = SubString{String}["1", "2", "3"]
(1, 2, 3)

julia> typedget(opt, :string_int, (1, 1, 1))
tokens = SubString{String}["4"]
(4, 4, 4)

julia> typedget(opt, :int, (1, 1, 1))
(4, 4, 4)

julia> typedget(opt, :int, (1., 1., 1.))
(4.0, 4.0, 4.0)
source

System Utilities

General system-level utilities for working with PETSc objects.

PETSc.getcommMethod
comm = function getcomm(
                        obj::Union{
                            PetscVec{PetscLib},
                            PetscMat{PetscLib},
                            PetscKSP{PetscLib},
                            #PetscSNES{PetscLib},
                            #PetscDM{PetscLib},
                        },
                    ) where {PetscLib}

Gets the MPI communicator for any of the objects above

source

Code Auditing

The audit utilities help identify potential memory leaks by tracking PETSc object creation and destruction.

PETSc.audit_argnamesMethod
audit_argnames(ex) -> Vector{Symbol}

The plain names a call passes, for either call form, looking through splats and one level of array or tuple literal. destroy!(v), destroy!(v...) and destroy!.([v, w]) all name the objects they release.

source
PETSc.audit_calleeMethod
audit_callee(ex) -> Union{Nothing, Symbol}

The bare name a call expression invokes, discarding any module qualification, so f(x), PETSc.f(x), PETSc.LibPETSc.f(x) and PETSc.f.(xs) all yield :f.

source
PETSc.audit_creatorMethod
audit_creator(name::Symbol) -> Union{Nothing, String}

The kind of object name creates, or nothing if it creates none. Covers the Vec/Mat families (VecCreateSeq, MatDuplicate, MatSeqAIJWithArrays, …) by shape rather than by listing every member.

source
PETSc.audit_destroyerMethod
audit_destroyer(name::Symbol) -> Bool

Whether name releases a PETSc object. Covers the high-level destroy/destroy! and the low-level VecDestroy, MatDestroy, DMDestroy and friends, which the previous text-matching version treated as leaks.

finalizer counts too. finalizer(destroy, v) hands the release to the garbage collector rather than performing it, but the object is accounted for and must not read as a leak. The package uses that idiom for sequential objects.

source
PETSc.audit_hasparseerrorMethod
audit_hasparseerror(ex) -> Bool

Whether the parsed tree contains an error or incomplete node, which happens when the file has a syntax error. Meta.parseall reports those in the tree rather than throwing.

source
PETSc.audit_isbroadcastMethod
audit_isbroadcast(ex) -> Bool

Whether ex is a dot-call such as destroy!.(vs). Those parse as Expr(:.) with a tuple of arguments, not as Expr(:call), so they need recognising separately. Plain field access a.b carries a QuoteNode instead and is not a call.

source
PETSc.audit_petsc_fileMethod
audit_petsc_file(path::AbstractString; verbose::Bool = true)

Scan a Julia source file for PETSc objects that are created but never destroyed.

Creations are calls to a type constructor (KSP, SNES, DMDA, DMStag, DMPlex), to a Vec/Mat creation routine (VecCreateSeq, MatDuplicate, MatSeqAIJWithArrays, …), or to one of the DM allocators (DMGlobalVec, DMLocalVec, DMCreateMatrix, …), through either PETSc or LibPETSc. Releases are destroy/destroy! and the low-level VecDestroy-style routines.

Returns a NamedTuple:

  • created: (line, var, kind) for each creation, var === nothing when the result is not assigned
  • destroyed: (line, var) for each release
  • finalized: (line, var) for each finalize call
  • leaked: variables that are created and never released

Pass verbose = false to suppress the printed report.

Notes

Heuristic: it does not follow control flow, scopes, or aliasing, and creations whose result is not assigned cannot be matched against a release.

Examples

julia> report = audit_petsc_file("examples/ex1.jl");

julia> isempty(report.leaked)
true
source
PETSc.audit_targetsMethod
audit_targets(lhs) -> Vector{Symbol}

The variables an assignment binds. Handles x = …, x, y = … and (x, y) = …, skipping anything that is not a plain name.

source
PETSc.audit_walkFunction
audit_walk(f, ex, line = 0) -> Int

Apply f(expr, line) to every Expr in ex, tracking the source line from the LineNumberNodes the parser emits. Returns the last line seen.

source