[petsc-dev] How to pass user data to a registered PC (PCRegister) ?
Matthew Knepley
knepley at gmail.com
Tue Jan 2 07:53:42 CST 2018
On Tue, Jan 2, 2018 at 8:47 AM, Franck Houssen <franck.houssen at inria.fr>
wrote:
> I'll try to fetch/pull the git clone: maybe there is a reg on the code
> level I am on.
>
> ----- 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é: Mardi 2 Janvier 2018 13:22:16
> > Objet: Re: [petsc-dev] How to pass user data to a registered PC
> (PCRegister) ?
> >
> >
> > static PetscErrorCode PCSetFromOptions_Jacobi(PetscOptionItems
> > *PetscOptionsObject,PC pc)
> > {
> > PC_Jacobi *jac = (PC_Jacobi*)pc->data;
> > PetscErrorCode ierr;
> > PetscBool flg;
> > PCJacobiType deflt,type;
> >
> > PetscFunctionBegin;
> > ierr = PCJacobiGetType(pc,&deflt);CHKERRQ(ierr);
> > ierr = PetscOptionsHead(PetscOptionsObject,"Jacobi
> options");CHKERRQ(ierr);
> > ierr = PetscOptionsEnum("-pc_jacobi_type","How to construct diagonal
> > matrix","PCJacobiSetType",PCJacobiTypes,(PetscEnum)
> deflt,(PetscEnum*)&type,&flg);CHKERRQ(ierr);
> > if (flg) {
> > ierr = PCJacobiSetType(pc,type);CHKERRQ(ierr);
> > }
> > ierr = PetscOptionsBool("-pc_jacobi_abs","Use absolute values of
> diagaonal
> > entries","PCJacobiSetUseAbs",jac->useabs,&jac->useabs,NULL)
> ;CHKERRQ(ierr);
> > ierr = PetscOptionsTail();CHKERRQ(ierr);
> > PetscFunctionReturn(0);
> > }
> >
> > Note how PetscOptionsHead() is called with the argument
> PetscOptionsObject
>
> I do call PetscOptionsHead(PetscOptionsObject, ...);
>
> > which is passed in from above. My guess is that you don't
> > call it with this argument? You would get behavior you describe if you
> don't.
> > Please send your REAL setupfromoptions_mypc() not just pseudo code.
> >
>
> #define SETERRABT(msg) SETERRABORT(PETSC_COMM_WORLD,
> PETSC_ERR_ARG_NULL,msg)
>
> static PetscErrorCode setUpGenEOPCFromOptions(PetscOptionItems *
> PetscOptionsObject, PC pcPC) {
> // Get the context.
>
> if (!pcPC) SETERRABT("GenEO preconditioner is invalid");
> geneoContext * gCtx = (geneoContext *) pcPC->data;
> if (!gCtx) SETERRABT("GenEO preconditioner without context");
>
> // Check arguments.
>
> PetscErrorCode pcRC = PetscOptionsHead(PetscOptionsObject, "GenEO
> options");
> CHKERRQ(pcRC);
> pcRC = PetscOptionsBegin(PETSC_COMM_WORLD, NULL, "GenEO options",
> "GenEO options");
>
You should not call Begin() here.
Matt
> CHKERRQ(pcRC);
>
> PetscBool pcHasOpt = PETSC_FALSE;
> PetscInt nbArgs = 2;
> char *args[2];
> pcRC = PetscOptionsStringArray("-geneo_lvl", "GenEO levels", "GenEO
> levels", args, &nbArgs, &pcHasOpt);
> CHKERRQ(pcRC);
> if (pcHasOpt) {
> ...
>
>
> > Barry
> >
> >
> >
> >
> > > On Jan 2, 2018, at 5: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"
> > >
> > > 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/73422ccf/attachment-0001.html>
More information about the petsc-dev
mailing list