[petsc-dev] Promote MatShellSetOperation() and MatShellSetContext() to Mat
Barry Smith
bsmith at mcs.anl.gov
Mon Jun 6 15:05:20 CDT 2011
On Jun 6, 2011, at 2:51 PM, Jed Brown wrote:
> On Mon, Jun 6, 2011 at 21:21, Barry Smith <bsmith at mcs.anl.gov> wrote:
> Yes, that is the whole point (in the same way I want DM's propagated down inside mulgrid and fieldsplit created subksps and pcs) So for example it can be set in the main program into the SNES (or TS) and is accessible deep inside some nested preconditioner that is a problem specific PC beasty thing.
>
> So with PCFieldSplit, a DMComposite should be taken apart and have just the pieces forwarded on. The global DMComposite wouldn't be much use for a nested PC.
Correct.
>
> The same occurs with the application context. I imagine that each branch of the PCFieldSplit is almost an independent code that implements the right interface. It should not need to take apart the global app context to find itself. So here's some top-level code. The vht object is the top level app context.
>
> PCFieldSplitSetIS(pc,"s",vht->all.sblock);
> PCFieldSplitSetIS(pc,"e",vht->all.eblock);
> PCFieldSplitGetSubKSP(pc,&nsub,&subksp);
> stk_ksp = subksp[0];
> KSPGetPC(stk_ksp,&stk_pc);
> PCSetType(stk_pc,PCFIELDSPLIT);
> PCFieldSplitSetIS(stk_pc,"u",vht->stokes->ublock);
> PCFieldSplitSetIS(stk_pc,"p",vht->stokes->pblock);
> KSPSetApplicationContext(stk_ksp,vht);
This code is perfectly reasonable and is within my model.
>
> It would be better to replace the last five lines with
>
> StokesKSPConfigure(vht->stokes,stk_ksp);
>
> Which would end up using KSPSetApplicationContext() to set the stokes context on the nested ksp. Note that the Stokes context no longer needs to find itself within a larger scope, and it no longer even has access to that higher level.
>
> > What happens when a component is accessed from multiple places?
>
> Not sure what you mean by multiple places.
>
> For example, a PC containing expensive setup (e.g. direct solve) might be used as part of a stand-alone linear solve and as part of a fieldsplit preconditioner for some larger nonlinear problem. If the user had an application context on that thing, it probably shouldn't be overwritten by SNESSetApplicationContext().
>
> The argument here is just that an inner object might not have a unique parent. In such cases, it would seem easier to manage if the first parent (or a direct call by the user) took precedence instead of the last parent.
Hmm. Weak argument?
>
> >
> > I wonder if this forwarding should be made to not overwrite what is already there. That is, if the user sets it explicitly, then it will not be overwritten by a parent.
>
> Hmm, yes this gets tricky. I general I think it should overwrite and the user needs to set it differently if they want after they set it on the outside. So they do TSSetApplicationContext() and then TSGetSNES, SNESGetKSP, KSPGetPC etc etc to change it down there.
>
> This is fine, but adds a little order dependence at configuration time. It does not seem too onerous if the user does something like StokesKSPConfigure() above.
I don't think there is a perfect solution to handling the nesting and I certainly don't think we have enough experience to come up with a great model to handle the nesting yet. We need to start down that road and see where it leads (look we don't even handle the nesting of DM well yet).
>
> > How should MatShellSetOperation behave? Should it error or do nothing when the matrix type is not MATSHELL?
>
> Error
>
>
> Okay, this is not the current behavior and this pre-historic snippet indicates the current behavior is intentional.
>
> if (op == MATOP_DESTROY) {
> ierr = PetscTypeCompare((PetscObject)mat,MATSHELL,&flg);CHKERRQ(ierr);
> if (flg) {
Changes to PETSc source are good :-) previously I must have thought it was good to ignore.
>
> > If the current behavior is to be preserved, what is your recommended way to get a context into the function overloading a method on a non-MATSHELL Mat?
>
> PetscObjectCompose()
>
> This means that the user's context has to be a PetscObject. I'm always torn whether to make my application context a PetscObject. I usually end up doing so, but it seems to me that it should only be necessary for extraordinay things. Maybe this qualifies.
You can use PetscContainerCreate() to keep the pointer to the struct.
>
>
> If there is one particular pattern of a non-MATSHELL matrix needing a user provided function overloading on a regular basis we need to examine that pattern and see what is most appropriate.
>
> I use it to provide matrix-free implementations of the global operation with MatNest. Thus I'm not using MatMult_Nest(), but I am taking advantage of MatGetSubMatrix_Nest() and similar. The reason for the global operation is that it makes one traversal of the mesh instead of one traversal per "block". I don't want to depend on an assembled format because assembling the true Jacobian is very expensive and the assembled matrix is slow to work with.
Sounds like something special to MatNest()? Why not just have special MatNest code?
Barry
More information about the petsc-dev
mailing list