Dear all,
I want to compare various preconditioners for a Stokes problem in a single python script. The problem is set up once, then the different solvers are called. The solvers are defined with PETScOptions().set() commands.
Now the problem is that this sets the options globally, so each solver has to call PETScOptions().clear() again for all options afterwards to avoid conflicts. (Not to bad actually, just a loop.)
Another way is using queues of the multiprocessing module, but I've been experiencing some problems with hanging queues on the cluster I'm working on.
So, is there a way to simply restore the default values for the PETScOptions or to restrict PETScOptions().set() locally to the scope of a function?
Thanks!
David
MWE:
from dolfin import *
from petsc4py import PETSc
from multiprocessing import Process
def solve_petsc(petsc_opt, clear=False):
# this doesn't do anything and PETScOptions has no binding for clear() w/o argument
# if clear:
# PETSc.Options().clear()
for opt in petsc_opt:
PETScOptions().set(*opt)
ksp = PETSc.KSP().create()
ksp.setFromOptions()
PETSc.Options().view()
if clear:
for opt in petsc_opt:
PETScOptions().clear(opt[0])
def main():
petsc_configs = [
[['ksp_view'],
['ksp_converged_reason'],
['ksp_monitor_true_residual'],
['ksp_type', 'fgmres'],
['ksp_rtol', '1.0e-8'],
['pc_type', 'fieldsplit'],
['pc_fieldsplit_type', 'multiplicative'],
['pc_fieldsplit_detect_saddle_point'],
['fieldsplit_0_ksp_type', 'preonly'],
['fieldsplit_0_pc_type', 'ml'],
['fieldsplit_0_pc_ml_Threshold', '0.03'],
['fieldsplit_0_pc_ml_maxNlevels', '3'],
['fieldsplit_1_ksp_type', 'preonly'],
['fieldsplit_1_pc_type', 'jacobi']],
[['ksp_type', 'cg'], ['ksp_rtol', '1.0e-4']],
[['ksp_type', 'gmres'], ['ksp_atol', '1.0e-4']]
]
# 1: running solve_petsc in a separate process works
for petsc_opt in petsc_configs:
p = Process(target=solve_petsc, args=(petsc_opt, False))
p.start()
p.join()
print('\n')
# 2: clearing all set options works
for petsc_opt in petsc_configs:
solve_petsc(petsc_opt, clear=True)
print('\n')
# 3: petsc options 'accumulate'
for petsc_opt in petsc_configs:
solve_petsc(petsc_opt, clear=False)
main()
This uses 3 approaches to set the PETSc arguments for 3 solvers: one complex one and two very simple ones (for the sake of the argument).
Using multiprocesses to run the function which sets the options in separate processes works. Also, calling PETScOptions().clear(opt)
afterwards on all given options works, but strangely not for all given options (pc_ml_Threshold). Third, if nothing is done, the options accumulate over the loop.
The output is... rather long, I put it into the comments!
The problem with multiprocessing is, that in my parallel "real life" examples, it hangs a lot.. So nothing really works satisfactorily.