[petsc-dev] How to pass user data to a registered PC (PCRegister) ?

Matthew Knepley knepley at gmail.com
Sun Dec 31 10:10:19 CST 2017


On Sun, Dec 31, 2017 at 9:01 AM, Franck Houssen <franck.houssen at inria.fr>
wrote:

> Using PCSHELL means calling:
>  - PCShellSetSetUp, PCShellSetApply, PCShellSetDestroy to set callbacks.
>  - PCShellSetContext/PCShellGetContext to get/set context in callbacks.
>
> To go from PCSHELL to PCRegister, one need to:
>  - #include <petsc/private/pcimpl.h> // Access to PC data/struct.
>  - Set callbacks with pc->ops->...
>  - NO more use ANY shell methods (context, name), but, use pc->data
> instead.
>  - call PCRegister.
>
> Correct ? Did I miss something ?
>

Yes, I think that is right.


> Seems I get things to work (without compose function).
>

The purpose of Compose() is to avoid the dreaded downcast of C++ (this is
explained in https://arxiv.org/abs/1209.1711). Suppose you
have some PC and want to call

  PCJacobiSetRowMax()

In C++, you would first downcast your PC to PCJacobi, then check for NULL,
and finally call the function. This is ugly. In PETSc, you
can take any PC, for example PCSOR, and call

  PCJacobiSetRowMax(sor, ...);

and it will just silently do nothing rather than failing. This makes user
code much easier to write since you can write for all different PC
types without all the ugly checks.


> The last problem I have is in the options: options are passed to
> PetscInitialize but not found in the database (I mimic'ed the jacobi
> example). Is there specific related to this ?
>

Here is the control flow. You call PCSetFromOptions() on the pc, then it
looks up that function in pc->ops so make sure you set your
specific one there. That impl SetFromOptions gets called and customizes
your object. What is not working?

   Matt


> ----- Mail original -----
> > De: "Franck Houssen" <franck.houssen at inria.fr>
> > À: "Barry F. Smith" <bsmith at mcs.anl.gov>
> > Cc: "For users of the development version of PETSc" <
> petsc-dev at mcs.anl.gov>
> > Envoyé: Samedi 30 Décembre 2017 17:12:09
> > Objet: Re: [petsc-dev] How to pass user data to a registered PC
> (PCRegister) ?
> >
> > Don't get the link. I'll try first with independent function (no
> compose) and
> > see if this can work at least for a start.
> >
> > Franck
> >
> > ----- Mail original -----
> > > De: "Barry F. Smith" <bsmith at mcs.anl.gov>
> > > À: "Franck Houssen" <franck.houssen at inria.fr>
> > > Cc: "For users of the development version of PETSc" <
> petsc-dev at mcs.anl.gov>
> > > Envoyé: Vendredi 29 Décembre 2017 17:55:30
> > > Objet: Re: [petsc-dev] How to pass user data to a registered PC
> > > (PCRegister) ?
> > >
> > >
> > >
> > > > On Dec 29, 2017, at 9:03 AM, Franck Houssen <franck.houssen at inria.fr
> >
> > > > wrote:
> > > >
> > > > OK, on the highway now (bad ssh !), I'll try to check this out.
> > > >
> > > > ----- Mail original -----
> > > >> De: "Barry F. Smith" <bsmith at mcs.anl.gov>
> > > >> À: "Franck Houssen" <franck.houssen at inria.fr>
> > > >> Cc: "For users of the development version of PETSc"
> > > >> <petsc-dev at mcs.anl.gov>
> > > >> Envoyé: Jeudi 28 Décembre 2017 18:21:48
> > > >> Objet: Re: [petsc-dev] How to pass user data to a registered PC
> > > >> (PCRegister) ?
> > > >>
> > > >>
> > > >>
> > > >>> On Dec 28, 2017, at 10:34 AM, Franck Houssen <
> franck.houssen at inria.fr>
> > > >>> wrote:
> > > >>>
> > > >>> ----- Mail original -----
> > > >>>> De: "Barry F. Smith" <bsmith at mcs.anl.gov>
> > > >>>> À: "Franck Houssen" <franck.houssen at inria.fr>
> > > >>>> Cc: "For users of the development version of PETSc"
> > > >>>> <petsc-dev at mcs.anl.gov>
> > > >>>> Envoyé: Jeudi 28 Décembre 2017 16:43:16
> > > >>>> Objet: Re: [petsc-dev] How to pass user data to a registered PC
> > > >>>> (PCRegister) ?
> > > >>>>
> > > >>>>
> > > >>>>  The register is for a new type of PC of which can have many
> > > >>>>  instantiations
> > > >>>>  at the same time.
> > > >>>
> > > >>> OK, I didn't get that that way ! I was looking for a way to plug
> "my"
> > > >>> pc
> > > >>> at
> > > >>> the command line this way: -pc_type my_pc.
> > > >>> I already call PCSetType(pc, PCSHELL) and PCShellSetName(pc,
> "my_pc"):
> > > >>> maybe this already enables "-pc_type shell" or "-pc_type my_pc"...
> And
> > > >>> I
> > > >>> didn't know it ! :D I'll try that.
> > > >>>
> > > >>> I was looking for a way to integrate "my" (external) pc as any
> other
> > > >>> regular/existing petsc pc (bjacobi, ...) like a kind of plugin but
> > > >>> still
> > > >>> integrated to the cmd line: I believed PCRegister was meant for
> that.
> > > >>
> > > >>   Indeed it is exactly what it is meant for.  Please try to follow
> my
> > > >>   recipe
> > > >>   and let us know when you get stuck.
> > > >>
> > > >>
> > > >>> Not sure if this is actually possible/enabled by the API.
> > > >>>
> > > >>>> For example
> > > >>>>
> > > >>>>   PCRegister("mypctype",mypc_create);
> > > >>>>
> > > >>>>   KSPCreate(&ksp1);
> > > >>>>   KSPCreate(&ksp2);
> > > >>>>
> > > >>>>   KSPGetPC(ksp1,&pc1);
> > > >>>>   KSPGetPC(ksp2,&pc2);
> > > >>>>
> > > >>>>   You don't want pc1 and pc2 to have the same dof multiplicities,
> > > >>>>   domain
> > > >>>>   intersections etc since they are associated with completely
> > > >>>>   different
> > > >>>>   linear systems and presumably meshes etc.
> > > >>>>
> > > >>>>
> > > >>>>    Presumably you want each of pc1, pc2, to have their own
> version of
> > > >>>>    the
> > > >>>>    data so you need to stick it directly in the PC, for example
> > > >>>>
> > > >>>>  PCMypcSetDOFMultiplicities(pc1,stuff);
> > > >>>> PCMypcSetDOFMultiplicities(pc2,otherstuff);
> > > >>>>
> > > >
> > > > OK, I must provide/implement PCMypcSetDOFMultiplicities (add data to
> pc
> > > > context) besides mypc_create: sounds logical.
> > > > Is this OK if PCMypcSetDOFMultiplicities is independent from
> mypc_create
> > > > ?
> > > > I guess yes.
> > > >
> > > > From what I remember/understand, I got lost here: from the jacobi
> > > > example,
> > > > mypc_create looks to be supposed (?) to call some kind of
> > > > Petsc*ComposeFunction to associate PCMypcSetDOFMultiplicities to the
> pc
> > > > (correct ?)... But, in the jacobi example, PCJacobiGetUseAbs_Jacobi
> is
> > > > associated to PCJacobiGetUseAbs_C...
> > >
> > >   the _C name is a string name that is used by PETSc to "find" the
> correct
> > >   function pointer which is PCJacobiGetUseAbs_Jacobi. There is no
> > > _C function.
> >
> > ?!
> >
> > >
> > > > Which turns out not to be implemented according to git grep ?! Got
> lost
> > > > here (and looked for a way to pass user data directly to
> PCRegister): is
> > > > PCMypcSetDOFMultiplicities supposed to be "attached/composed" or
> > > > independent from the pc ?
> > >
> > >    composed.
> > >
> > > >
> > > >>> git grep PCJacobiGetUseAbs_C
> > > > src/ksp/pc/impls/jacobi/jacobi.c:  ierr =
> > > > PetscObjectComposeFunction((PetscObject)pc,"PCJacobiGetUseAbs_C",
> PCJacobiGetUseAbs_Jacobi);CHKERRQ(ierr);
> > > > src/ksp/pc/impls/jacobi/jacobi.c:  ierr =
> > > > PetscUseMethod(pc,"PCJacobiGetUseAbs_C",(PC,
> PetscBool*),(pc,flg));CHKERRQ(ierr);
> > > >
> > > > Sorry, for the short answer. Hope I succeeded to be clear enough.
> > >
> > >    Just copy jacobi.c and start converting it over to your names and
> needs
> > >    and you'll see it is actually really straightforward and not as
> > >    complicated as you think it is.
> > >
> > >    Barry
> > >
> > > >
> > > >>>> You write as many of these Set() functions as you need for your
> > > >>>> PCtype.
> > > >>>> You
> > > >>>> store the data inside the PC_Mypc data structure you create with
> > > >>>> mypc_create(). Look at PCCreate_Jacobi() and PCJacobiSetType for
> the
> > > >>>> pattern.
> > > >>>>
> > > >>>>  Barry
> > > >>>>
> > > >>>>
> > > >>>>> On Dec 28, 2017, at 9:34 AM, Franck Houssen <
> franck.houssen at inria.fr>
> > > >>>>> wrote:
> > > >>>>>
> > > >>>>> How to pass user data to a registered PC (PCRegister) ?
> > > >>>>>
> > > >>>>> At first, I expected the signature would be "PetscErrorCode
> > > >>>>> PCRegister(const char sname[],PetscErrorCode (*function)(PC, void
> > > >>>>> *))"
> > > >>>>> but
> > > >>>>> it turns out to be "PetscErrorCode PCRegister(const char
> > > >>>>> sname[],PetscErrorCode (*function)(PC))"
> > > >>>>>
> > > >>>>> I try to integrate a PC that needs A but also other informations
> (dof
> > > >>>>> multiplicities, domain intersections that the user must
> provide). I
> > > >>>>> guess
> > > >>>>> I can get A with PCGetOperators in the setup callback of the PC.
> But
> > > >>>>> still
> > > >>>>> not sure how to pass the other informations if I get to use
> > > >>>>> PCRegister.
> > > >>>>> I
> > > >>>>> looked a few examples in the bitbucket (jacobi:
> > > >>>>> src/ksp/ksp/examples/tutorials/ex12.c and
> > > >>>>> src/ksp/pc/impls/jacobi/jacobi.c
> > > >>>>> + SOR: src/ksp/pc/impls/sor/sor.c)... But didn't get any real
> > > >>>>> relevant
> > > >>>>> answer and feel a bit lost among the numerous pc !...
> > > >>>>>
> > > >>>>> The idea is: for now I use PCSetType(pc, PCSHELL) and
> > > >>>>> PCShellSetContext
> > > >>>>> with a context who knows the extra needed informations which is
> "not
> > > >>>>> so
> > > >>>>> handy" (that's OK as for now I am both the user and the PC
> provider).
> > > >>>>> I'd
> > > >>>>> like to package this in a more convenient way (a unique and
> "simple"
> > > >>>>> call
> > > >>>>> to PCRegister) to decouple the user from the PC machinery.
> > > >>>>>
> > > >>>>> Franck
> > >
> > >
> >
>



-- 
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/ <http://www.caam.rice.edu/~mk51/>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.mcs.anl.gov/pipermail/petsc-dev/attachments/20171231/0a90c4c7/attachment.html>


More information about the petsc-dev mailing list