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

Matthew Knepley knepley at gmail.com
Tue Jan 2 05:07:51 CST 2018


On Tue, Jan 2, 2018 at 6:04 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é: Dimanche 31 Décembre 2017 23:41:42
> > Objet: Re: [petsc-dev] How to pass user data to a registered PC
> (PCRegister) ?
> >
> >
> >
> > > On Dec 31, 2017, at 8:40 AM, Franck Houssen <franck.houssen at inria.fr>
> > > wrote:
> > >
> > > Seems finally, I got it to work.
> > > To get the options to work I had to call PetscOptionsBegin/End
> after/before
> > > PetscOptionsHead/Tail which is not what is done in the jacobi example:
> is
> > > this the right way to go ?
> >
> >   Something is wrong.
>
> I felt there was something wrong !...
>
> > PetscOptionsBegin/end are called in PCSetFromOptions()
> >   that is suppose to wrap YOUR PCSetFromOptions_mypc().
>
> OK, sounds logical, that's how I expected things to be done. That's why I
> was suspicious: what worked should not !...
>
> I believed maybe the problem was connected to the fact that I do NOT use
> compose function, but, according to Matt's explanation, I would say no: the
> use of PetscComposeFunction seems independent from the
> PCSetFromOptions_mypc problem.
>
> Note: in my case, I believe I do not really need PetscCompose, I just need
> one (regular) function to initialize specific stuffs needed in my_pc (at
> least for a start). I can go to PetscCompose later if it turns out to be
> relevant (that's how I understand this).
>
> > Perhaps you are
> >   calling PCSetFromOptions_mypc directly which you should never do.
>
> No, I don't call PCSetFromOptions_mypc directly.
>
> > Your PCCreate_mypc() should stick the function pointer for
> >   PCSetFromOptions_mypc into the ops table like it does PCApply_mypc etc.
> >   Then you just directly use PCSetFromOptions.
>
> create_mpc(PC pc) { // CB for PCRegister
>   ...
>   pcPC->ops->setfromoptions = setupfromoptions_mypc;
>   ...
> }
>
> static PetscErrorCode setupfromoptions_mypc(PetscOptionItems *
> PetscOptionsObject, PC pcPC) {
>   ...
>   PetscOptionsHead()
>   PetscOptionsBegin()
>   PetscOptionsStringArray("-mypc_opt", ..., flag)
>   cout << "debug " << flag << endl;
>   PetscOptionsEnd()
>   PetscOptionsTail()
> }
>
> I got called on setupfromoptions_mypc when I call PCSetUpFromOptions().
>
> If I let PetscOptionsBegin/End, it looks like I read in the "correct"
> option data base, I get (cout) : "debug 1" (-my_opt is read)
>
> If I comment PetscOptionsBegin/End, seems I read an incorrect (empty ?)
> option data base, I get (cout) : "debug 0"
>

Clearly something is being called with a wrong argument. I think Barry's
suggestion is best. You know that Jacobi works
and processes options correctly. Change that one step at a time into your
PC.

  Thanks,

     Matt


> Looks weird even if it's not blocking for now (I know there is problem but
> I can by pass it)
>
> >
> >    Barry
> >
> > >
> > > Franck
> > >
> > > PetscErrorCode PCSetFromOptions_mypc(PetscOptionItems *
> PetscOptionsObject,
> > > PC pcPC) {
> > > PetscOptionsHead
> > > PetscOptionsBegin
> > > ... // PetscOptionsStringArray
> > > PetscOptionsEnd
> > > PetscOptionsTail
> > >
> > >
> > > ----- 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é: Dimanche 31 Décembre 2017 15:01:43
> > >> Objet: Re: [petsc-dev] How to pass user data to a registered PC
> > >> (PCRegister) ?
> > >>
> > >> 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 ?
> > >>
> > >> Seems I get things to work (without compose function).
> > >>
> > >> 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 ?
> > >>
> > >>
> > >> ----- 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/20180102/537c3bea/attachment.html>


More information about the petsc-dev mailing list