← Back to team overview

dolfin team mailing list archive

Re: [PyCC-dev] Segmentation fault

 

2007/11/1, Anders Logg <logg@xxxxxxxxx>:
> On Wed, Oct 31, 2007 at 10:10:42AM +0100, Martin Sandve Alnæs wrote:
> > 2007/10/31, Martin Sandve Alnæs <martinal@xxxxxxxxx>:
> > > 2007/10/30, Ola Skavhaug <skavhaug@xxxxxxxxx>:
> > > > Anders Logg skrev den 30/10-2007 følgende:
> > > > > The following code gives me a segmentation fault:
> > > > >
> > > > >   from dolfin import *
> > > > >
> > > > >   def foo():
> > > > >       element = FiniteElement("Lagrange", "triangle", 1)
> > > > >       mesh = UnitSquare(2, 2)
> > > > >       return Function(element, mesh, 1.0)
> > > > >
> > > > >   print foo().mesh().numVertices()
> > > > >
> > > > > If the mesh is declared outside foo() it works fine.
> > > > >
> > > > > It seems that Python is calling the Mesh destructor when foo()
> > > > > returns. It shouldn't since the Function created in foo() keeps a
> > > > > reference to the mesh.
> > > > >
> > > > > Does anyone know how to fix this? Is it possible to tell Python that
> > > > > the mesh is referenced by the function?
> > > >
> > > > Take a look at the swig documentation. It might be possible to add some
> > > > directives for this, but it is a major problem. Even the Python bindings for
> > > > vtk have this flaw.
> > >
> > > This is also the same as the memory handling issues we haven't given
> > > any serious thought in the GenericTensor hierarchy: A = Matrix();
> > > assemble(A); A = A.mat(); who owns the underlying PetSCMatrix or
> > > EpetraMatrix now?
> > >
> > > If you can accept a common base class with a reference count for all
> > > dolfin classes, and using str::tr1::shared_ptr in the C++ code, it can
> > > be solved (at least for most use cases).
> >
> > Sorry, that won't work for the linear algebra classes, because it
> > would require a reference count located in the Mat object (with
> > PetSC).
>
> The PETSc Mat pointer is created in the constructor of
> dolfin::PETScMatrix and destroyed in the destructor so we have full
> control over it.

I think that's the best solution, since it's easy to understand, but
it doesn't solve the problem. Let me just explain what the problem is:

# If the user does
def foo(...):
    A = PETScMatrix()
    assemble(A, ...)
    return A.mat()

A = foo(...)
# ... do PETSc stuff only

At this point the PETScMatrix is deleted, deleting the Mat, and A is
invalid. The solution is for the user to store the PETScMatrix
reference somewhere, but that kind of destroys the convenience of
reference counting in the first place... This is the same pattern as
your mesh example.


> What is str::tr1::shared_ptr???
>
> /Anders

I meant std, std::tr1::shared_ptr

It's a reference counted smart pointer, from the boost project but now
part of the C++ standard called Technical Report 1, which will be
merged into the C++ standard library at some point. Should be
supported by most modern compilers now.


#include <tr1/memory>
...
{
  std::tr1::shared_ptr<Foo> mypointer2;
  {
    std::tr1::shared_ptr<Foo> mypointer = new Foo();
    mypointer2 = mypointer;
  }
} // Foo object is deleted here


-- 
Martin


Follow ups

References