Barry, please take a look at this thread in Python-Dev mailing list, just the first and second mail.
http://mail.python.org/pipermail/python-dev/2003-July/036898.html Python 2.X does exactly the same as PETSc for defining derived object structures. #define PyObject_HEAD \ _PyObject_HEAD_EXTRA \ Py_ssize_t ob_refcnt; \ struct _typeobject *ob_type; typedef struct _object { PyObject_HEAD } PyObject; typedef struct { PyObject_HEAD double ob_fval; } PyFloatObject; But For Python 3.X, they will be using... typedef struct _object { Py_ssize_t ob_refcnt; struct _typeobject *ob_type; } PyObject; #define PyObject_HEAD PyObject ob_base; typedef struct { PyObject_HEAD double ob_fval; } PyFloatObject; This is the way I'm trying to redefine PetscObject for PETSc. On 9/29/07, Barry Smith <bsmith at mcs.anl.gov> wrote: > > > > Well, I followed the approach in Python 3.0 for > > defining the base object header for derived objects. > > Lisandro, > > Please send a reference to where this is discussed and an explanation > why this type of caste is allowed with strict aliasing? (the web page > http://www.cellperformance.com/mike_acton/2006/06/understanding_strict_aliasing.html > does not discuss this case nor does it give any indication that this > "trick" is legal with strict alaising). > > Thanks > > Barry > > > > On Wed, 26 Sep 2007, Lisandro Dalcin wrote: > > > On 9/25/07, Barry Smith <bsmith at mcs.anl.gov> wrote: > > > Please explain in detail. > > > > Well, this article explains strict aliasing in some detail (just in > > case you does not know the details) > > > > http://www.cellperformance.com/mike_acton/2006/06/understanding_strict_aliasing.html > > > > In the particular case of PETSc, if I understand correctly, the > > designed object's struct inheritance based in the current PETSCHEADER > > approach will not make it possible to enable strict aliasing rules. > > For the compiler, PetscObject and Vec are different types of objects, > > so if you do > > > > PetscObject o = (PetscObject)v; > > > > you are breacking strict aliasing rules, using o->comm and v->comm to > > access the vector communicator could possibly fail with aggresive > > compiler optimization. > > > > How to solve this?? Well, I followed the approach in Python 3.0 for > > defining the base object header for derived objects. In the case of > > PETSc, this amounts to the following: > > > > #define PETSCHEADERBASE \ > > PetscCookie cookie; > > MPI_Comm comm; > > char* prefix; > > char* type_name; > > /* etc ....*/ > > > > struct _p_PetscObject { > > PETSCHEADERBASE > > }; > > > > #define PETSCHEADER(ObjectOps) \ > > struct _p_PetscObject header; > > ObjectOps *ops; > > > > And now the Vec struct is declared as before: > > > > struct _p_Vec { > > PETSCHEADER(struct _VecOps); > > /* etc ... */ > > }; > > > > Now, there is no way to access things like cookie/comm/prefix fro a > > Vec, for doing it you need to cast to PetscObject. This removes the > > possibility of accesing 'comm' or 'prefix' though pointers of > > different types. As a side effect, you need to always cast to > > PetscObject to get comm/prefix/type_name (by far the more commonly > > accessed members when implementing Vec/Mat/KSP etc...) > > > > I'm started this work at home, I do not have the code here at my > > office right now, but I could remove almost all the warnings related > > to strict aliasing in 'src/sys' and 'src > > > > > > I have also some problems when calling PetscObjectQueryFunction, > > > > Yes this function pointer casting stuff is a royal pain and ugly. > > > > Perhaps I can find better way of doing this using a macro. > > > > > > > > Might be easier to just rewrite everything in C++. :-) > > > > > > > Well, having error handling based on C++ exceptions is really > > tempting. But C++ polymorphism would make it easier to derive specific > > implementations of objects, and using smart pointer would help for the > > automatic reference counting of owned objects, and a lot of more good > > things. BUT... the PETSc way of doing polimorphism is a bit more > > powerful than the C++ virtual table. That is, each object instance > > have its own table of functions pointers, and you can freely replace > > it in a object by object base (and done in some MatConvert() calls). > > Of course, a C++ implementation could still use tables of function > > pointer, and dispatching code based on that table. > > > > All this would require a lot, lot of redesing and work. :) > > > > BTW, Could you please teach me some easy way of replacing in PETSc > > source code the following: > > > > 'something>comm' by '((PetscObject)something)->comm' > > > > I never found the time to learn regular expresions and 'sed' :-(. > > > > > > > > > > > > Barry > > > > > > > In case > > > > you want me to continue this work, I will need a bit of help in a few > > > > places related to low-level calls related to sockets and sys calls. > > > > > > > > > > > > > > > > > > > > > > -- Lisandro Dalc?n --------------- Centro Internacional de M?todos Computacionales en Ingenier?a (CIMEC) Instituto de Desarrollo Tecnol?gico para la Industria Qu?mica (INTEC) Consejo Nacional de Investigaciones Cient?ficas y T?cnicas (CONICET) PTLC - G?emes 3450, (3000) Santa Fe, Argentina Tel/Fax: +54-(0)342-451.1594
