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

Franck Houssen franck.houssen at inria.fr
Tue Jan 2 05:04:42 CST 2018


----- 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"

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
> >>>> 
> >>>> 
> >>> 
> >> 
> 
> 


More information about the petsc-dev mailing list