[petsc-dev] Why do we use void* instead of PetscObject in PETSc?
Hapla Vaclav
vaclav.hapla at erdw.ethz.ch
Mon Mar 4 08:00:20 CST 2019
Something related are functions like
https://www.mcs.anl.gov/petsc/petsc-current/docs/manualpages/SNES/SNESSetConvergenceTest.html
https://www.mcs.anl.gov/petsc/petsc-current/docs/manualpages/KSP/KSPMonitorSet.html
which even have 3 parameters - the "evaluation" function, the context, and destroying function.
I have never liked this design. I think they are pretending to be "simple" for users instead of "bothering" them with having to implement a type of SNESConvergenceTest/KSPMonitor (imaginary classes at the moment). But at the end one spends much more time by finding a bug such as passing ctx instead of &ctx or something like that.
And the API is uglier, error-prone, harder to remember, etc. It splits e.g. the notion of "convergence test" into 3 complicated arguments. Compare
SNESSetConvergenceTest(SNES snes,PetscErrorCode (*SNESConvergenceTestFunction)(SNES,PetscInt,PetscReal,PetscReal,PetscReal,SNESConvergedReason*,void*),void *cctx,PetscErrorCode (*destroy)(void*))
vs
SNESSetConvergenceTest(SNES snes, SNESConvergenceTest test)
I think if E in PETSc means extensible, we should encourage users to create their own types or classes. If that is documented and there are some examples, people will just copy-paste and alter them as before but will have less problems and nicer code eventually. And they would be better prepared to implement e.g. a whole new PC.
Thanks
Vaclav
> On 2 Mar 2019, at 17:19, Dave May via petsc-dev <petsc-dev at mcs.anl.gov> wrote:
>
> I think there would be a lot of merit (in the long run) if user contexts, such as given to KSPSetComputeOperators(), SNESSetJacobian() etc were changed to be of type PetscObject rather than void*.
>
> Some obvious benefits would be:
> [1] Type checking!
> [2] User contexts could be readily shared using PetscObjects reference counter (PetscObjectReferenece()).
> [3] User contexts would have a communicator.
> [4] User contexts could have textual names associated with them (PetscObjectSetName()).
> [5] Internal to PETSc (e.g. within KSPComputeOperators_SNES) the header of the context could be checked to ensure the type of the PetscObject is valid (SNES in this example).
>
> If this change was adopted, the user could readily change their code to use a PetscContainer. Such a change avoids the user having to recreate their own object model / class to deal with simple issues associated with sharing a context, or having to manage communicators within their own contexts.
>
> I see the point that the context is "the users problem". Many PETSc examples simply use a pointer to typedef'd struct as the context. Users tend to copy examples, and really, a simple struct with a bunch of parameters is not a good object model to be followed. Would it be so horrible to require users to put "their problem" (e.g. context) inside a PetscObject?
>
> Besides the huge volume of work required to change internal PETSc code and more over, the code of all users, are there genuinely compelling reasons to keep using void* everywhere? I cannot think of one, but I would like to hear others thoughts on this. (Maybe there are concerns with Fortran compatibility?).
>
>
> Thanks
> Dave
>
>
>
More information about the petsc-dev
mailing list