VecLoadIntoVector and double dispatch
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
> with multiple viewers.
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
> Extensible double dispatch is not something C is heralded for, but
> not impossible. An easy-to-code approach is to just do it all with
> PetscObjectFunctionComposeDynamic. The FList could get a bit long,
> 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
is equivalent to the python
super(self).view(viewer) [may not be the exact right syntax]
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
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
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
> 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.
More information about the petsc-dev