[petsc-dev] How to pass user data to a registered PC (PCRegister) ?
Franck Houssen
franck.houssen at inria.fr
Tue Jan 2 07:47:48 CST 2018
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");
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
> >>>>>>
> >>>>>>
> >>>>>
> >>>>
> >>
> >>
>
>
More information about the petsc-dev
mailing list