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.LibPETSc.PetscLibType — Method
PetscLibType(library_path::String; PetscScalar=Float64, PetscInt=Int64)Create a custom PETSc library instance from a user-specified shared library path.
Replaces v0.4's set_petsclib, which mutated nothing despite its name and so was never a set_*! (docs/src/man/naming.md §7): it builds and returns a library handle, which is what a constructor does.
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 ofFloat64,Float32,Complex{Float64},Complex{Float32}. Default:Float64PetscInt::Type: Integer type the library was built with.Int32orInt64. Default:Int64
Returns
A PetscLibType instance for use with initialize, finalize, and all PETSc.jl functions.
Environment-variable alternative
Instead of calling this constructor, 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 # Int32With 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.LibPETSc.PetscLibType("/path/to/libpetsc.so";
PetscScalar=Float64, PetscInt=Int64)
PETSc.initialize(petsclib)
# ... your code ...
PETSc.finalize(petsclib)
# Single-precision complex, 32-bit indices
petsclib = PETSc.LibPETSc.PetscLibType("/opt/petsc/lib/libpetsc.so";
PetscScalar=Complex{Float32}, PetscInt=Int32)See Also
initialize: Initialize a PETSc libraryfinalize: Finalize a PETSc library
PETSc.LibraryInfo — Type
LibraryInfoThe shape of the NamedTuple library_info returns, and the type its show method is written for.
PETSc.PetscNotInitialized — Type
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.
PETSc.check_initialized — Method
check_initialized(petsclib)Throw PetscNotInitialized unless petsclib is initialized.
PETSc.check_wrappers_version — Function
check_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: optionalPetscLibTypeor path string. Ifnothing, the first availablePETSc.petsclibs[1]is used.
Returns a named tuple: (:wrappers_version, :installed_version, :match). match is true when versions are equal, false when they differ, and nothing if either side could not be determined.
PETSc.finalize — Method
finalize(petsclib)
Finalize the petsclib, if no petsclib is given then all PETSc.petsclibs will be finalized.
External Links
- PETSc Manual:
Sys/PetscFinalize
PETSc.initialize — Method
initialize([petsclib]; log_view = false, options = String[])Initialize the petsclib. If no petsclib is given, all PETSc.petsclibs will be initialized.
Additionally:
This will initialize MPI if it has not already been initialized.
It will disable the PETSc signal handler (via
Sys/PetscPopSignalHandlerAdd an
atexithook to callPETSc.finalize.
Arguments
log_view::Bool = false: Enable PETSc's-log_viewperformance logging. When enabled, PETSc will output performance statistics at finalization.options::Vector{String} = String[]: Additional PETSc command-line options, handed toPetscInitializeas its command line. They override thePETSC_OPTIONSenvironment variable.
BLAS threads
PETSc's BLAS calls run in Julia's OpenBLAS thread pool, the one LinearAlgebra.BLAS.set_num_threads sizes, for every library in petsclibs. -blas_num_threads n, given in options or in PETSC_OPTIONS, sets that pool to n threads.
Without that option, when several MPI ranks share a node, initialize sets the pool to one thread. Each rank owns a pool, and its busy-waiting threads would otherwise compete with the ranks for cores: a solve can run many times slower with the right answer. A set OPENBLAS_NUM_THREADS or OMP_NUM_THREADS also leaves the pool as it is. Serial runs, and runs with one rank per node, are unaffected. This changes Julia's process-wide BLAS setting, which finalize does not restore. initialize sets the pool only once, so a later BLAS.set_num_threads(n) takes effect as usual.
Examples
# Basic initialization
PETSc.initialize(petsclib)
# Enable performance logging to stdout
PETSc.initialize(petsclib; log_view = true)
# Write log to a file. PETSc reads `:file:format`, so on Windows give a path
# without a drive letter, such as a relative one
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"])
# Four BLAS threads per rank, overriding the one-thread default for ranks sharing a node
PETSc.initialize(petsclib; options = ["-blas_num_threads", "4"])External Links
- PETSc Manual:
Sys/PetscInitialize
PETSc.inttype — Method
inttype(petsclib::PetscLibType)return the int type for the associated petsclib
PETSc.isdestroyable — Method
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.
PETSc.isfinalized — Method
PETSc.isinitialized — Method
isinitialized(petsclib)
Check if petsclib is initialized
External Links
- PETSc Manual:
Sys/PetscInitialized
PETSc.library_info — Method
library_info()Report the PETSc library configuration as a NamedTuple (§12).
| Field | Meaning |
|---|---|
source | :preferences if LocalPreferences.toml names a library, :jll for the bundled PETSc_jll binaries |
path | the library path in use |
scalar | PetscScalar of the preferred library |
int | PetscInt of the preferred library |
real | PetscReal of the preferred library |
The preferred library is petsclibs[1]: the configured one when a preference is set, and the first of the bundled builds otherwise.
v0.4 printed a report and returned nothing, so the name promised data it never handed back. The report is unchanged — it is now the show method — and the values are reachable from code.
info = library_info()
info.scalar # Float64See Also
set_library!: configure a custom library persistentlyunset_library!: revert toPETSc_jll
PETSc.owns — Method
owns(obj)Whether destroy! on obj destroys the PETSc object it holds, which is the wrapper's own field.
A constructor returns an owning wrapper. A reader returns a borrowed one: the object belongs to whatever it was read from, and destroy! on the borrowed wrapper does nothing and leaves it usable. That covers the high-level readers (pc(ksp), snes(ts), dm(ksp), solution(ksp) and the rest), every LibPETSc function with Get in its name except the few that hand out a new reference (MatGetFactor, DMLabelGetStratumIS, ...: their manual pages say the caller destroys the result), and the objects a callback receives.
PETSc.scalartype — Method
scalartype(petsclib::PetscLibType)return the scalar type for the associated petsclib
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:Float64PetscInt: integer type the library was built with (Int64orInt32). 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
unset_library!: remove the preference and revert toPETSc_jllPetscLibType(path): load a custom library for the current session only
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. PETSc.petsclibs then holds the four scalar variants of that width.
Takes effect on the next Julia session (Preferences.jl recompilation). Has no effect when a custom library is configured via set_library!.
PETSc.set_type! — Function
set_type!(obj, type::Symbol)Set the PETSc implementation obj uses, for example set_type!(ksp, :gmres).
Defined for PetscVec, PetscMat, KSP, PC, SNES, TS and AbstractPetscDM. The Symbol is converted to a String at the C boundary (§3.1).
set_type!(obj, "gmres") still works in v0.5 and warns; it is a MethodError in v0.6.
PETSc.tao_usable_after_reinitialize — Method
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).
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.
Options
PETSc uses an options database to configure solvers and other objects at runtime. These functions provide access to the options system.
PETSc.LibPETSc.PetscOptions — Method
PetscOptions(petsclib; kwargs...)Create a PETSc options database for the given petsclib.
Replaces v0.4's Options factory: construction goes through the type (docs/src/man/naming.md §5.1).
Keyword arguments are converted to PETSc options:
- Options with value
nothingortrueare set without a value (flags) - Options with value
falseare not set - Other values are converted to strings
Examples
julia> using PETSc
julia> petsclib = PETSc.petsclibs[1];
julia> PETSc.initialize(petsclib)
julia> opt = PETSc.PetscOptions(
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 foundExternal Links
- PETSc Manual:
Sys/PetscOptionsCreate
PETSc.destroy! — Method
destroy!(opts::AbstractPetscOptions)Free the options database opts holds, if this process is still allowed to.
Does nothing when the library has been finalized or re-initialized, or when opts was already destroyed: see isdestroyable. Does nothing on a borrowed handle either: see owns.
PETSc.options_prefix — Function
options_prefix(obj)The prefix obj, a KSP, SNES, TS or PC, reads its options under, or "" when it has none. A solver PETSc builds inside another inherits the outer prefix: the KSP of a SNES prefixed "outer_" reads -outer_ksp_type.
External Links
- PETSc Manual:
KSP/KSPGetOptionsPrefix
- PETSc Manual:
SNES/SNESGetOptionsPrefix
- PETSc Manual:
TS/TSGetOptionsPrefix
- PETSc Manual:
PC/PCGetOptionsPrefix
PETSc.parse_option — Method
parse_option(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> parse_option(opt, :int, 7)
4
julia> parse_option(opt, :bad_key, 7)
7
julia> parse_option(opt, :tup, (1, 1, 1))
(1, 2, 3)
julia> parse_option(opt, :string_tup, (1, 1, 1))
tokens = SubString{String}["1", "2", "3"]
(1, 2, 3)
julia> parse_option(opt, :string_int, (1, 1, 1))
tokens = SubString{String}["4"]
(4, 4, 4)
julia> parse_option(opt, :int, (1, 1, 1))
(4, 4, 4)
julia> parse_option(opt, :int, (1., 1., 1.))
(4.0, 4.0, 4.0)PETSc.parse_options — Method
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=1PETSc.set_from_options! — Function
set_from_options!(obj)Apply PETSc's options to the KSP, SNES or TS obj: those given to its constructor, then the global database, so a command-line option given for the object's prefix (see set_options_prefix!) is read too. Returns obj.
solve! does this itself; call it to configure obj earlier, for example a nested solver before its first use.
External Links
- PETSc Manual:
KSP/KSPSetFromOptions
- PETSc Manual:
SNES/SNESSetFromOptions
- PETSc Manual:
TS/TSSetFromOptions
PETSc.set_options_prefix! — Function
set_options_prefix!(obj, prefix::AbstractString)Make obj, a KSP, SNES, TS or PC, read its options under prefix: with "inner_", a KSP reads -inner_ksp_type. This is how two solvers in one program are configured apart. Returns obj.
External Links
- PETSc Manual:
KSP/KSPSetOptionsPrefix
- PETSc Manual:
SNES/SNESSetOptionsPrefix
- PETSc Manual:
TS/TSSetOptionsPrefix
- PETSc Manual:
PC/PCSetOptionsPrefix
System Utilities
General system-level utilities for working with PETSc objects.
PETSc.comm — Method
comm = function comm(
obj::Union{
PetscVec{PetscLib},
PetscMat{PetscLib},
KSP{PetscLib},
#SNES{PetscLib},
#PetscDM{PetscLib},
},
) where {PetscLib}Gets the MPI communicator for any of the objects above
Code Auditing
The audit utilities help identify potential memory leaks by tracking PETSc object creation and destruction.
PETSc.audit_argnames — Method
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.
PETSc.audit_callee — Method
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.
PETSc.audit_creator — Method
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.
PETSc.audit_destroyer — Method
audit_destroyer(name::Symbol) -> BoolWhether name releases a PETSc object. Covers the names in AUDIT_DESTROYER_NAMES 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.
PETSc.audit_file — Method
audit_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 (global_vec, local_vec, DMCreateMatrix, …), through either PETSc or LibPETSc. Releases are destroy! and the low-level VecDestroy-style routines.
Returns a NamedTuple:
created:(line, var, kind)for each creation,var === nothingwhen the result is not assigneddestroyed:(line, var)for each releasefinalized:(line, var)for eachfinalizecallleaked: 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_file("examples/ex1.jl");
julia> isempty(report.leaked)
truePETSc.audit_hasparseerror — Method
audit_hasparseerror(ex) -> BoolWhether 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.
PETSc.audit_isbroadcast — Method
audit_isbroadcast(ex) -> BoolWhether 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.
PETSc.audit_report — Method
audit_report(created, destroyed, finalized, leaked)Print the human-readable form of an audit_file result.
PETSc.audit_targets — Method
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.
PETSc.audit_walk — Function
audit_walk(f, ex, line = 0) -> IntApply f(expr, line) to every Expr in ex, tracking the source line from the LineNumberNodes the parser emits. Returns the last line seen.
PETSc.AUDIT_DESTROYER_NAMES — Constant
AUDIT_DESTROYER_NAMESNames that release a PETSc object. finalizer counts: it hands the release to the garbage collector rather than performing it, but the object is accounted for.
PETSc.AUDIT_NAMED_CREATORS — Constant
AUDIT_NAMED_CREATORSCreators whose name carries no Create/Duplicate marker for audit_creator to recognise by shape.
PETSc.AUDIT_TYPE_CREATORS — Constant
AUDIT_TYPE_CREATORSType constructors whose name is also the kind of object they create.