[petsc-dev] SNESSetKSP and SNESDestroy

Stefano Zampini stefano.zampini at gmail.com
Thu May 30 15:51:29 CDT 2019



>> 
>> 
> 
> Yeah… about that hack…
> Before my first message, I tried something like:
> 
> 	SNESCreate(&snes);
> 	KSP backup;
> 	SNESGetKSP(snes, &backup);
> 	SNESSetKSP(snes, &ksp);
> 	SNESSolve(snes);
> 	SNESSetKSP(snes, &backup);
> 	SNESDestroy(&snes);
> 
> And this is bailing out ([1]PETSC ERROR: SNESSetKSP() Wrong type of object: Parameter # 2), which I find quite ironing since I’m getting the KSP from SNESGetKSP.
> 

Pierre,

I assume you meant

SNESGetKSP(snes,&backup);
SNESSetKSP(snes,ksp);
SNESSolve(snes);
SNESSetKSP(snes,backup);

The issue here is that the getter SNESGetKSP does not increase reference count on backup.
So, when you do SNESSetKSP(snes,ksp) the object pointed to by backup is actually destroyed.
This is why you got the error.

This is the correct code

SNESGetKSP(snes,&backup);
PetscObjectReference((PetscObject)backup); // increase reference count
SNESSetKSP(snes,ksp); // calls KSPdestroy on backup -> decrease reference count
SNESSolve(snes);
SNESSetKSP(snes,backup); // backup still points to a valid object
KSPDestroy(&backup); // decrease reference count to backup (or destroy if it goes to zero)


> SNESGetKSP(snes, &backup);

> 	KSP backup;
> 	
> 	SNESSetKSP(snes, &ksp);
> SNESSolve(snes);

> SNESSetKSP(snes, &backup);

> As I’m typing this email I just tried something and the following fixes the hack: just add an extra KSPCreate on backup before the SNESDestroy.
> 
> Thanks,
> Pierre
> 
>>>> 
>>   KSP dummy;
>>   KSPCreate(...,&dummy);
>>>> KSP ksp;
>>>> KSPSetUp(ksp);
>>>> while(cond) {
>>>>       SNES snes;
>>>>       SNESCreate(&snes);
>>>>       SNESSetKSP(snes, &ksp);
>>>>       SNESSolve(snes);
>>           SNESSetKSP(snes,dummy);
>>>>       SNESDestroy(&snes);
>>>> }
>> It should work even if you don't setup dummy. But perhaps it is picky and you may need to add a matrix to dummy etc (don't worry it doesn't copy the matrix).
>> 
>> Barry
>> 
>> 
>> 
>> 
>>> On May 30, 2019, at 9:51 AM, Stefano Zampini via petsc-dev <petsc-dev at mcs.anl.gov> wrote:
>>> 
>>> I meant SNESDestroy should call KSPDestroy
>>> 
>>> The reason for having the XXXReset methods called by the XXXDestroy is mostly code reuse, and it may lead to troubles.
>>> The Reset concept is not uniform throughout the library.
>>> 
>>>> On May 30, 2019, at 3:59 PM, Stefano Zampini <stefano.zampini at gmail.com> wrote:
>>>> 
>>>> I think snes reset should call ksp destroy. I don't see the case for which this can lead to troubles 
>>>> 
>>>> Il Gio 30 Mag 2019, 15:43 Matthew Knepley via petsc-dev <petsc-dev at mcs.anl.gov> ha scritto:
>>>> On Thu, May 30, 2019 at 6:08 AM Pierre Jolivet via petsc-dev <petsc-dev at mcs.anl.gov> wrote:
>>>> Hello,
>>>> I’m doing a continuation loop with something like:
>>>> KSP ksp;
>>>> KSPSetUp(ksp);
>>>> while(cond) {
>>>>       SNES snes;
>>>>       SNESCreate(&snes);
>>>>       SNESSetKSP(snes, &ksp);
>>>>       SNESSolve(snes);
>>>>       SNESDestroy(&snes);
>>>> }
>>>> 
>>>> For the first iteration, everything is OK.
>>>> After that, it looks like SNESDestroy is messing up with my outer-defined KSP(*), i.e., for the code to work I need to comment out the SNESDestroy.
>>>> Is this the expected behavior? (if not, I’ll provide a MWE)
>>>> How to fix this properly, without having leaks by not destroying the inner-defined SNESes?
>>>> 
>>>> Thanks in advance,
>>>> Pierre
>>>> 
>>>> (*) to the outer-defined KSP is attached a PCFIELDSPLIT, first SNESSolve, everything OK:
>>>> PC Object: 1 MPI processes
>>>> type: fieldsplit
>>>>   FieldSplit with MULTIPLICATIVE composition: total splits = 2
>>>> 
>>>> Second SNESSolve:
>>>> [0]PETSC ERROR: PCFieldSplitSetDefaults() Unhandled case, must have at least two fields, not 1
>>>> 
>>>> I believe SNESDestroy() calls SNESReset(), which calls KSPReset(), which is wiping out your information.
>>>> 
>>>> This pattern is in a lot of places. Destroy calls Reset because it is natural to reuse the code which tears down
>>>> the internal structures. Reset calls reset on subobjects because we also want to tear down their internal structures (usually).
>>>> Reset wouldn't do what we want on resizing if we left subobjects unreset. However, this chain is causing subobjects to
>>>> be wiped clean on Destroy, so that we cannot reuse subobjects.
>>>> 
>>>> It would not even work if you change the Destroy to Reset in the continuation loop. However, I think you can hoist all
>>>> the SNES setup outside the loop. If you are changing sizes, then the KSP needs to be wiped out anyway. If not, then
>>>> you do not need to wipe out the SNES.
>>>> 
>>>> Thanks,
>>>> 
>>>>    Matt
>>>> 
>>>> -- 
>>>> What most experimenters take for granted before they begin their experiments is infinitely more interesting than any results to which their experiments lead.
>>>> -- Norbert Wiener
>>>> 
>>>> https://www.cse.buffalo.edu/~knepley/
>>> 
>> 
> 



More information about the petsc-dev mailing list