[petsc-users] petsc4py snes behavior

Nicola Creati ncreati at inogs.it
Mon Feb 8 02:41:35 CST 2016

```Hello,
I'm trying to convert some PETSc examples from C to Python. I noted a
strange behavior of the snes solver. It seems that the same example in
Python and C are characterized by a different number of function
evaluations. I converted ex25.c example in the "
snes/examples/tutorials" folder.  The number of function evaluations is
always bigger in Python and increases with the number of grid nodes. The
increased number of function evaluations affects the performance and in
other examples can drastically increase the execution time (for example
in ex30.c " Steady-state 2D subduction...").
This is my Python version of the simple ex25.c:

## # SNES/Tutorials/ex25
import sys
import petsc4py
petsc4py.init(sys.argv)
from petsc4py import PETSc
import numpy as np

class UserContext(object):
def __init__(self, da):
self.da = da
self.localX = da.createLocalVec()

def formFunction(self, snes, X, F):

self.da.globalToLocal(X, self.localX)
x = self.da.getVecArray(self.localX)
f = self.da.getVecArray(F)

(x0, x1), (y0, y1)= self.da.getRanges()
hx = 1/float(x1-1)
hy = 1/float(y1-1)

for j in range(y0, y1):
for i in range(x0, x1):
if i == 0 or i == (x1-1) or j == 0 or j == (y1-1 ):
f[j,i] = x[j,i] - (1.0 - (2.0 * hx * i - 1.0) *
(2.0 * hx * i -1.0))
else:
gradup    = (x[j+1, i] -x[j, i])/hy
graddown  = (x[j, i]   -x[j-1, i])/hy
gradright = (x[j, i+1] -x[j, i])/hx
gradleft  = (x[j, i]   -x[j, i-1])/hx

gradx = 0.5 * (x[j, i+1] - x[j, i-1])/hx
grady = 0.5 * (x[j+1, i] - x[j-1, i])/hy

coeffright = 1.0/np.sqrt(1.0 + gradright *

* hx + (coeffright * gradright - coeffleft * gradleft) * hy

snes = PETSc.SNES().create()
da = PETSc.DMDA().create(dim=(-5, -5),
stencil_type = PETSc.DMDA.StencilType.STAR,
stencil_width =1,
setup=False)
da.setFromOptions()
da.setUp()

snes.setDM(da)

ctx = UserContext(da)
da.setAppCtx(ctx)

F = da.createGlobalVec()
snes.setFunction(ctx.formFunction, F)

snes.setFromOptions()

x = da.createGlobalVector()

snes.solve(None, x)
its = snes.getIterationNumber()
lits = snes.getLinearSolveIterations()

print "Number of SNES iterations = %d" % its
print "Number of Linear iterations = %d" % lits

litspit = lits/float(its)
print "Average Linear its / SNES = %e" % float(litspit)

#####################################

I executed the code with the following options:

python ex25.py -snes_view -snes_monitor -da_grid_x 50 -da_grid_y 50

This is the output from Python:

Konsole output
0 SNES Function norm 7.229568285876e+00
1 SNES Function norm 1.970854029907e-02
2 SNES Function norm 5.721344031051e-03
3 SNES Function norm 1.179738644817e-03
4 SNES Function norm 1.028879149924e-04
5 SNES Function norm 7.472012969660e-07
6 SNES Function norm 4.744184684658e-11
SNES Object: 1 MPI processes
type: newtonls
maximum iterations=50, maximum function evaluations=10000
tolerances: relative=1e-08, absolute=1e-50, solution=1e-08
total number of linear solver iterations=223
total number of function evaluations=37
norm schedule ALWAYS
SNESLineSearch Object:   1 MPI processes
type: bt
interpolation: cubic
alpha=1.000000e-04
maxstep=1.000000e+08, minlambda=1.000000e-12
tolerances: relative=1.000000e-08, absolute=1.000000e-15,
lambda=1.000000e-08
maximum iterations=40
KSP Object:   1 MPI processes
type: gmres
GMRES: restart=30, using Classical (unmodified) Gram-Schmidt
Orthogonalization with no iterative refinement
GMRES: happy breakdown tolerance 1e-30
maximum iterations=10000, initial guess is zero
tolerances:  relative=1e-05, absolute=1e-50, divergence=10000
left preconditioning
using PRECONDITIONED norm type for convergence test
PC Object:   1 MPI processes
type: ilu
ILU: out-of-place factorization
0 levels of fill
tolerance for zero pivot 2.22045e-14
matrix ordering: natural
factor fill ratio given 1, needed 1
Factored matrix follows:
Mat Object:           1 MPI processes
type: seqaij
rows=2500, cols=2500
package used to perform factorization: petsc
total: nonzeros=12300, allocated nonzeros=12300
total number of mallocs used during MatSetValues calls =0
not using I-node routines
linear system matrix = precond matrix:
Mat Object:     1 MPI processes
type: seqaij
rows=2500, cols=2500
total: nonzeros=12300, allocated nonzeros=12300
total number of mallocs used during MatSetValues calls =0
not using I-node routines
Number of SNES iterations = 6
Number of Linear iterations = 223
Average Linear its / SNES = 3.716667e+01

This the output from the original C code with the same options (./ex25
-snes_view -snes_monitor -da_grid_x 50 -da_grid_y 50):

Konsole output
0 SNES Function norm 7.229568285876e+00
1 SNES Function norm 1.970854029907e-02
2 SNES Function norm 5.721344035538e-03
3 SNES Function norm 1.179738636852e-03
4 SNES Function norm 1.028879138425e-04
5 SNES Function norm 7.472012249912e-07
6 SNES Function norm 4.743884624164e-11
SNES Object: 1 MPI processes
type: newtonls
maximum iterations=50, maximum function evaluations=10000
tolerances: relative=1e-08, absolute=1e-50, solution=1e-08
total number of linear solver iterations=223
total number of function evaluations=7
norm schedule ALWAYS
SNESLineSearch Object:   1 MPI processes
type: bt
interpolation: cubic
alpha=1.000000e-04
maxstep=1.000000e+08, minlambda=1.000000e-12
tolerances: relative=1.000000e-08, absolute=1.000000e-15,
lambda=1.000000e-08
maximum iterations=40
KSP Object:   1 MPI processes
type: gmres
GMRES: restart=30, using Classical (unmodified) Gram-Schmidt
Orthogonalization with no iterative refinement
GMRES: happy breakdown tolerance 1e-30
maximum iterations=10000, initial guess is zero
tolerances:  relative=1e-05, absolute=1e-50, divergence=10000
left preconditioning
using PRECONDITIONED norm type for convergence test
PC Object:   1 MPI processes
type: ilu
ILU: out-of-place factorization
0 levels of fill
tolerance for zero pivot 2.22045e-14
matrix ordering: natural
factor fill ratio given 1, needed 1
Factored matrix follows:
Mat Object:           1 MPI processes
type: seqaij
rows=2500, cols=2500
package used to perform factorization: petsc
total: nonzeros=12300, allocated nonzeros=12300
total number of mallocs used during MatSetValues calls =0
not using I-node routines
linear system matrix = precond matrix:
Mat Object:     1 MPI processes
type: seqaij
rows=2500, cols=2500
total: nonzeros=12300, allocated nonzeros=12300
total number of mallocs used during MatSetValues calls =0
not using I-node routines
Number of SNES iterations = 6
Number of Linear iterations = 223
Average Linear its / SNES = 3.716667e+01

Why the number of function evaluations is so different?
I'm using last version of PETSc and petsc4py.
Thank you.

Nicola

--
_____________________________________________________________________
Nicola Creati
Istituto Nazionale di Oceanografia e di Geofisica Sperimentale - OGS
IRI (Ricerca Teconologica e Infrastrutture) Department
B.go Grotta Gigante - Brisciki 42/c
34010 Sgonico - Zgonik (TS) - Italy
Tel. +39-0402140213
Fax  +39-040327307

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.mcs.anl.gov/pipermail/petsc-users/attachments/20160208/b54ffcb1/attachment.html>
```