garbage collection different between petsc4py 3.17.4 and 3.18.3
petsc4py
3.18.3 does not garbage collect as effectively as 3.17.4.
This plot shows memory usage when repeatedly creating and solving a matrix:
This has been observed on macOS, Debian, and Ubuntu.
In both cases, petsc4py was obtained from conda-forge.
This plot was generated by running mprof
on the following script in serial (adapted from demo/kspsolve):
from petsc4py import PETSc
def mat_and_vec():
# grid size and spacing
m, n = 32, 32
hx = 1.0/(m-1)
hy = 1.0/(n-1)
# create sparse matrix
A = PETSc.Mat()
A.create(PETSc.COMM_WORLD)
A.setSizes([m*n, m*n])
A.setType('aij') # sparse
A.setPreallocationNNZ(5)
# precompute values for setting
# diagonal and non-diagonal entries
diagv = 2.0/hx**2 + 2.0/hy**2
offdx = -1.0/hx**2
offdy = -1.0/hy**2
# loop over owned block of rows on this
# processor and insert entry values
Istart, Iend = A.getOwnershipRange()
for I in range(Istart, Iend) :
A[I,I] = diagv
i = I//n # map row number to
j = I - i*n # grid coordinates
if i> 0 : J = I-n; A[I,J] = offdx
if i< m-1: J = I+n; A[I,J] = offdx
if j> 0 : J = I-1; A[I,J] = offdy
if j< n-1: J = I+1; A[I,J] = offdy
# communicate off-processor values
# and setup internal data structures
# for performing parallel operations
A.assemblyBegin()
A.assemblyEnd()
# obtain sol & rhs vectors
x, b = A.createVecs()
x.set(0)
b.set(1)
return A, x, b
def solve(A, x, b):
# create linear solver
ksp = PETSc.KSP()
ksp.create(PETSc.COMM_WORLD)
# use conjugate gradients
ksp.setType('cg')
# and incomplete Cholesky
ksp.getPC().setType('icc')
# and next solve
ksp.setOperators(A)
ksp.setFromOptions()
ksp.solve(b, x)
for sweep in range(50000):
solve(*mat_and_vec())
Notes
- I am aware that it would be more efficient to retain and repopulate the matrix and vectors, but repeatedly destroying and creating them used to work.
- Manually calling
ksp.destroy()
,A.destroy()
,x.destroy()
, andb.destroy()
at the end ofsolve()
also resolves the issue, but automatic garbage collection used to work when these variables went out of scope. - Manually calling
PETSc.garbage_cleanup()
at each iteration also resolves the issue, but automatic garbage collection used to work. -
-malloc_dump
and-malloc_view
indicate no leak with either version. - #1291 may be related.