VecLoadIntoVector and double dispatch

Barry Smith bsmith at mcs.anl.gov
Thu Dec 3 13:48:21 CST 2009


On Dec 3, 2009, at 12:54 PM, Jed Brown wrote:

> I'm sort of confused about vec->ops->loadintovectornative, this  
> seems to
> just be a way to let users provide *one* custom viewer on a particular
> vector without breaking PETSc's own viewers.  But it really doesn't
> provide a reasonably solution for an intermediate library, or user  
> code
> with multiple viewers.

    Jed,

    It is a hack to allow Vecs with particular layout properties (like  
arising from DA's) to overwrite the load/view operations that they  
inherit from the parent class, but still allow use of the parents  
method if desired. It is equivalent to the super operation in python  
or Java.


>
> Extensible double dispatch is not something C is heralded for, but  
> it's
> not impossible.  An easy-to-code approach is to just do it all with
> PetscObjectFunctionComposeDynamic.  The FList could get a bit long,  
> but
> I think you'd be hard-pressed to find a real code where dispatch time
> for VecLoadIntoVector and (a couple of other viewer-related functions)
> was an issue.  For best performance, PetscObject could acquire a field
> for "type index" or some such (e.g. managed by
> PetscObjectChangeTypeName), which would allow double-dispatch based on
> table lookup.  (There are lots of variants of this idea, many C++
> proposals force the linker to set up the table which is totally broken
> with dynamic loading.)

     This discussion about double dispatch is correct and PETSc does  
not do it properly. For VecView, for example, we dispatch off the  
vector with the function table but then dispatch off the viewer with  
the ugly, nonextendable if ()s.

However, I don't think this has much to do with your original point  
about loadintovectornative.  I view

PetscViewerPushtFormat(viewer,PETSC_VIEWER_NATIVE)
VecView(vec,viewer)

is equivalent to the python

super(self).view(viewer)  [may not be the exact right syntax]

or perhaps

super(VEC_MPI,self).view(viewer)

that is casting the vector up to its parent and then calling the  
viewer method of the parent.

Is this a great way to handle the "calling the method of the parent"?  
Well, probably not. If we wanted to handle it in general using a  
similar style we could have something like

PetscObjectPushUseSuper(vec)
VecView(vec,viewer)
PetscObjectPopUseSuper(vec)

then each derived class would just keep a copy of the previous  
function table (instead of overwriting the function pointers) and each  
Push() would cause it to use the next higher table to find the  
function pointer. So the information about which super of the Vec  
method we want should be stored with the Vec, NOT with the viewer. I  
just implemented as a VIEWER_FORMAT because we already had a viewer  
format mechanism and it was simple to do.  I did not have to introduce  
a hugh new infrastructure. Note that Babel uses the save the previous  
function table to handle its inheritance much as I describe (as Matt  
can attest it can all be done, but leads to relatively complicated  
code).

Note: I am not saying the current design is best or shouldn't be  
changed, it would just be complicated to change "properly" and is  
distinct from handling double dispatch properly.

>
> Visitor isn't great as an extensible solution due to asymmetry and the
> need to change the vtable of the other object.
>
> A simple approach that is probably sufficient for VecLoadIntoVector
> would be to move the pointer into viewer->ops because the viewer
> typically just needs VecGetArray, and there is much more demand for  
> new
> viewer types than for new vector types.

    This is wrong. What about a binary viewer method for the PETSc Vec  
class implemented in SAMRAI? This definitely cannot rely on  
VecGetArray() and belongs with the Vec class not the viewer classes  
(which know nothing about SAMRAI even existing.

    Barry


>
> Thoughts?
>
> Jed




More information about the petsc-dev mailing list