Skip to content

Commit

Permalink
Clarify memory management of returned petsc4py objects. (#3329)
Browse files Browse the repository at this point in the history
* Clarify memory management of returned petsc4py objects.

* Clearer.

* Update text with Garth's suggestion

---------

Co-authored-by: Jørgen Schartum Dokken <dokken92@gmail.com>
Co-authored-by: Jørgen S. Dokken <dokken@simula.no>
  • Loading branch information
3 people committed Sep 10, 2024
1 parent fba67dd commit 6831fee
Show file tree
Hide file tree
Showing 2 changed files with 52 additions and 3 deletions.
36 changes: 36 additions & 0 deletions python/dolfinx/fem/petsc.py
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,12 @@ def create_vector(L: Form) -> PETSc.Vec:
def create_vector_block(L: list[Form]) -> PETSc.Vec:
"""Create a PETSc vector (blocked) that is compatible with a list of linear forms.
Note:
Due to subtle issues in the interaction between petsc4py memory management
and the Python garbage collector, it is recommended that the method ``PETSc.Vec.destroy()``
is called on the returned object once the object is no longer required. Note that
``PETSc.Vec.destroy()`` is collective over the object's MPI communicator.
Args:
L: List of linear forms.
Expand Down Expand Up @@ -148,6 +154,12 @@ def create_vector_nest(L: list[Form]) -> PETSc.Vec:
def create_matrix(a: Form, mat_type=None) -> PETSc.Mat:
"""Create a PETSc matrix that is compatible with a bilinear form.
Note:
Due to subtle issues in the interaction between petsc4py memory management
and the Python garbage collector, it is recommended that the method ``PETSc.Mat.destroy()``
is called on the returned object once the object is no longer required. Note that
``PETSc.Mat.destroy()`` is collective over the object's MPI communicator.
Args:
a: A bilinear form.
mat_type: The PETSc matrix type (``MatType``).
Expand All @@ -164,6 +176,12 @@ def create_matrix(a: Form, mat_type=None) -> PETSc.Mat:
def create_matrix_block(a: list[list[Form]]) -> PETSc.Mat:
"""Create a PETSc matrix that is compatible with a rectangular array of bilinear forms.
Note:
Due to subtle issues in the interaction between petsc4py memory management
and the Python garbage collector, it is recommended that the method ``PETSc.Mat.destroy()``
is called on the returned object once the object is no longer required. Note that
``PETSc.Mat.destroy()`` is collective over the object's MPI communicator.
Args:
a: Rectangular array of bilinear forms.
Expand All @@ -178,6 +196,12 @@ def create_matrix_block(a: list[list[Form]]) -> PETSc.Mat:
def create_matrix_nest(a: list[list[Form]]) -> PETSc.Mat:
"""Create a PETSc matrix (``MatNest``) that is compatible with an array of bilinear forms.
Note:
Due to subtle issues in the interaction between petsc4py memory management
and the Python garbage collector, it is recommended that the method ``PETSc.Mat.destroy()``
is called on the returned object once the object is no longer required. Note that
``PETSc.Mat.destroy()`` is collective over the object's MPI communicator.
Args:
a: Rectangular array of bilinear forms.
Expand Down Expand Up @@ -958,6 +982,12 @@ def discrete_gradient(space0: _FunctionSpace, space1: _FunctionSpace) -> PETSc.M
H1 space uses an identity map and the H(curl) space uses a covariant
Piola map.
Note:
Due to subtle issues in the interaction between petsc4py memory management
and the Python garbage collector, it is recommended that the method ``PETSc.Mat.destroy()``
is called on the returned object once the object is no longer required. Note that
``PETSc.Mat.destroy()`` is collective over the object's MPI communicator.
Args:
space0: H1 space to interpolate the gradient from.
space1: H(curl) space to interpolate into.
Expand All @@ -971,6 +1001,12 @@ def discrete_gradient(space0: _FunctionSpace, space1: _FunctionSpace) -> PETSc.M
def interpolation_matrix(space0: _FunctionSpace, space1: _FunctionSpace) -> PETSc.Mat:
"""Assemble an interpolation operator matrix.
Note:
Due to subtle issues in the interaction between petsc4py memory management
and the Python garbage collector, it is recommended that the method ``PETSc.Mat.destroy()``
is called on the returned object once the object is no longer required. Note that
``PETSc.Mat.destroy()`` is collective over the object's MPI communicator.
Args:
space0: Space to interpolate from.
space1: Space to interpolate into.
Expand Down
19 changes: 16 additions & 3 deletions python/dolfinx/la.py
Original file line number Diff line number Diff line change
Expand Up @@ -263,6 +263,10 @@ def petsc_vec(self):
Upon first call, this function creates a PETSc ``Vec`` object
that wraps the degree-of-freedom data. The ``Vec`` object is
cached and the cached ``Vec`` is returned upon subsequent calls.
Note:
When the object is destroyed it will destroy the underlying petsc4py
vector automatically.
"""
if self._petsc_x is None:
self._petsc_x = create_petsc_vector_wrap(self)
Expand Down Expand Up @@ -317,15 +321,18 @@ def vector(map, bs=1, dtype: npt.DTypeLike = np.float64) -> Vector:
def create_petsc_vector_wrap(x: Vector):
"""Wrap a distributed DOLFINx vector as a PETSc vector.
Note:
Due to subtle issues in the interaction between petsc4py memory management
and the Python garbage collector, it is recommended that the method ``PETSc.Vec.destroy()``
is called on the returned object once the object is no longer required. Note that
``PETSc.Vec.destroy()`` is collective over the object's MPI communicator.
Args:
x: The vector to wrap as a PETSc vector.
Returns:
A PETSc vector that shares data with ``x``.
Note:
The vector ``x`` must not be destroyed before the returned PETSc
object.
"""
from petsc4py import PETSc

Expand All @@ -339,6 +346,12 @@ def create_petsc_vector_wrap(x: Vector):
def create_petsc_vector(map, bs: int):
"""Create a distributed PETSc vector.
Note:
Due to subtle issues in the interaction between petsc4py memory management
and the Python garbage collector, it is recommended that the method ``PETSc.Vec.destroy()``
is called on the returned object once the object is no longer required. Note that
``PETSc.Vec.destroy()`` is collective over the object's MPI communicator.
Args:
map: Index map that describes the size and parallel layout of
the vector to create.
Expand Down

0 comments on commit 6831fee

Please sign in to comment.