[petsc-dev] SNESSetKSP and SNESDestroy
Pierre Jolivet
pierre.jolivet at enseeiht.fr
Thu May 30 16:05:24 CDT 2019
> On 30 May 2019, at 10:51 PM, Stefano Zampini <stefano.zampini at gmail.com> wrote:
>
>
>
>>>
>>>
>>
>> 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
Oops, didn’t check my inbox before sending the previous message.
This does get the job done in a much cleaner way.
Thanks!
Pierre
> 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/
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.mcs.anl.gov/pipermail/petsc-dev/attachments/20190530/56dd212e/attachment-0001.html>
More information about the petsc-dev
mailing list