Subject: [FFC-dev] Patch with shared_ptr support to ffc.

From: Johan Hake <[email-masked]>
Date: Tue, 13 Jan 2009 12:01:33 +0100

Hello!

Here comes the anounced patch adding shared_ptr support to ffc. I also changed 
the shared_ptr from tr1 to boost.

It needs an hg pull/hg up from both ufc and instant to work.

Johan
# HG changeset patch
# User "Johan Hake <[email-masked]>"
# Date 1231844355 -3600
# Node ID b80bb2cc2be9cf8c6082554e010bb6eea8f974b1
# Parent  fa30ffef20bdfb45820323efc08cd96992dbcc9c
Added shared_ptr support for jit compiled module.
 - Changed the shared_ptr from tr1 to boost in dolfin_format

diff -r fa30ffef20bd -r b80bb2cc2be9 ffc/common/constants.py
--- a/ffc/common/constants.py	Mon Jan 12 23:45:15 2009 +0100
+++ b/ffc/common/constants.py	Tue Jan 13 11:59:15 2009 +0100
@@ -18,4 +18,4 @@
                "form_postfix": True,
                "cache_dir": None,
                "output_dir": ".",
-               "shared_ptr":False}
+               "shared_ptr":True}
diff -r fa30ffef20bd -r b80bb2cc2be9 ffc/compiler/format/dolfinformat.py
--- a/ffc/compiler/format/dolfinformat.py	Mon Jan 12 23:45:15 2009 +0100
+++ b/ffc/compiler/format/dolfinformat.py	Tue Jan 13 11:59:15 2009 +0100
@@ -1,18 +1,19 @@
 "Code generation for the UFC 1.0 format with DOLFIN"
 
 __author__ = "Anders Logg ([email-masked])"
-__date__ = "2007-03-24 -- 2008-10-23"
-__copyright__ = "Copyright (C) 2007-2008 Anders Logg"
+__date__ = "2007-03-24 -- 2009-01-12"
+__copyright__ = "Copyright (C) 2007-2009 Anders Logg"
 __license__  = "GNU GPL version 3 or any later version"
 
 # Modified by Kristian B. Oelgaard 2008
 # Modified by Dag Lindbo, 2008
+# Modified by Johan Hake, 2009
 
 # Python modules
 import os
 
 # UFC code templates
-from ufc import *
+from ufc_utils import *
 
 # FFC common modules
 from ffc.common.utils import *
@@ -245,8 +246,8 @@
         constructor_args_r  = ", ".join(["const dolfin::FunctionSpace& V%d" % k for k in range(form_data.rank)])
         constructor_args_rc = ", ".join(["const dolfin::FunctionSpace& V%d" % k for k in range(form_data.rank)] +
                                         ["dolfin::Function& w%d" % k for k in range(form_data.num_coefficients)])
-        constructor_args_s  = ", ".join(["std::tr1::shared_ptr<const dolfin::FunctionSpace> V%d" % k for k in range(form_data.rank)])
-        constructor_args_sc  = ", ".join(["std::tr1::shared_ptr<const dolfin::FunctionSpace> V%d" % k for k in range(form_data.rank)] +
+        constructor_args_s  = ", ".join(["boost::shared_ptr<const dolfin::FunctionSpace> V%d" % k for k in range(form_data.rank)])
+        constructor_args_sc  = ", ".join(["boost::shared_ptr<const dolfin::FunctionSpace> V%d" % k for k in range(form_data.rank)] +
                                          ["dolfin::Function& w%d" % k for k in range(form_data.num_coefficients)])
         constructor_body_r  = "\n".join([add_function_space_r % (k, k, k) for k in range(form_data.rank)])
         constructor_body_rc = "\n".join([add_function_space_r % (k, k, k) for k in range(form_data.rank)])
@@ -268,10 +269,10 @@
             constructor_body_sc += "\n\n"
         constructor_body_rc += assign_coefficients
         constructor_body_sc += assign_coefficients
-        constructor_body_r  += "    _ufc_form = std::tr1::shared_ptr<const ufc::form>(new UFC_%s());" % form_prefix
-        constructor_body_rc += "    _ufc_form = std::tr1::shared_ptr<const ufc::form>(new UFC_%s());" % form_prefix
-        constructor_body_s  += "    _ufc_form = std::tr1::shared_ptr<const ufc::form>(new UFC_%s());" % form_prefix
-        constructor_body_sc += "    _ufc_form = std::tr1::shared_ptr<const ufc::form>(new UFC_%s());" % form_prefix
+        constructor_body_r  += "    _ufc_form = boost::shared_ptr<const ufc::form>(new UFC_%s());" % form_prefix
+        constructor_body_rc += "    _ufc_form = boost::shared_ptr<const ufc::form>(new UFC_%s());" % form_prefix
+        constructor_body_s  += "    _ufc_form = boost::shared_ptr<const ufc::form>(new UFC_%s());" % form_prefix
+        constructor_body_sc += "    _ufc_form = boost::shared_ptr<const ufc::form>(new UFC_%s());" % form_prefix
 
         # Generate class in different ways depending on the situation
         if form_data.rank > 0:
@@ -309,9 +310,9 @@
 public:
 
   %s(const dolfin::Mesh& mesh)
-    : dolfin::FunctionSpace(std::tr1::shared_ptr<const dolfin::Mesh>(&mesh, dolfin::NoDeleter<const dolfin::Mesh>()),
-                            std::tr1::shared_ptr<const dolfin::FiniteElement>(new dolfin::FiniteElement(std::tr1::shared_ptr<ufc::finite_element>(new %s()))),
-                            std::tr1::shared_ptr<const dolfin::DofMap>(new dolfin::DofMap(std::tr1::shared_ptr<ufc::dof_map>(new %s()), mesh)))
+    : dolfin::FunctionSpace(boost::shared_ptr<const dolfin::Mesh>(&mesh, dolfin::NoDeleter<const dolfin::Mesh>()),
+                            boost::shared_ptr<const dolfin::FiniteElement>(new dolfin::FiniteElement(boost::shared_ptr<ufc::finite_element>(new %s()))),
+                            boost::shared_ptr<const dolfin::DofMap>(new dolfin::DofMap(boost::shared_ptr<ufc::dof_map>(new %s()), mesh)))
   {
     // Do nothing
   }
diff -r fa30ffef20bd -r b80bb2cc2be9 ffc/compiler/format/dolfintemplates.py
--- a/ffc/compiler/format/dolfintemplates.py	Mon Jan 12 23:45:15 2009 +0100
+++ b/ffc/compiler/format/dolfintemplates.py	Tue Jan 13 11:59:15 2009 +0100
@@ -19,7 +19,7 @@
 
 # Code for adding function space (reference version)
 add_function_space_r = """\
-    std::tr1::shared_ptr<const dolfin::FunctionSpace> _V%d(&V%d, dolfin::NoDeleter<const dolfin::FunctionSpace>());
+    boost::shared_ptr<const dolfin::FunctionSpace> _V%d(&V%d, dolfin::NoDeleter<const dolfin::FunctionSpace>());
     _function_spaces.push_back(_V%d);"""
 
 # Code for adding function space (shared pointer version)
@@ -28,11 +28,11 @@
 
 # Code for adding coefficient (reference version)
 add_coefficient_r =  """\
-    _coefficients.push_back(std::tr1::shared_ptr<const dolfin::Function>(static_cast<const dolfin::Function*>(0)));"""
+    _coefficients.push_back(boost::shared_ptr<const dolfin::Function>(static_cast<const dolfin::Function*>(0)));"""
 
 # Code for adding coefficient (shared pointer version)
 add_coefficient_s =  """\
-    _coefficients.push_back(std::tr1::shared_ptr<const dolfin::Function>(static_cast<const dolfin::Function*>(0)));"""
+    _coefficients.push_back(boost::shared_ptr<const dolfin::Function>(static_cast<const dolfin::Function*>(0)));"""
 
 # Code for coefficient class
 coefficient_class = """\
diff -r fa30ffef20bd -r b80bb2cc2be9 ffc/compiler/format/ufcformat.py
--- a/ffc/compiler/format/ufcformat.py	Mon Jan 12 23:45:15 2009 +0100
+++ b/ffc/compiler/format/ufcformat.py	Tue Jan 13 11:59:15 2009 +0100
@@ -1,18 +1,18 @@
 "Code generation for the UFC 1.0 format"
 
 __author__ = "Anders Logg ([email-masked])"
-__date__ = "2007-01-08 -- 2008-09-29"
+__date__ = "2007-01-08 -- 2009-01-08"
 __copyright__ = "Copyright (C) 2007-2008 Anders Logg"
 __license__  = "GNU GPL version 3 or any later version"
 
 # Modified by Kristian B. Oelgaard 2008
 # Modified by Dag Lindbo, 2008
-
+# Modified by Johan hake, 2009
 # Python modules
 import os
 
 # UFC code templates
-from ufc import *
+from ufc_utils import *
 
 # FFC common modules
 from ffc.common.utils import *
diff -r fa30ffef20bd -r b80bb2cc2be9 ffc/jit/jit.py
--- a/ffc/jit/jit.py	Mon Jan 12 23:45:15 2009 +0100
+++ b/ffc/jit/jit.py	Tue Jan 13 11:59:15 2009 +0100
@@ -2,11 +2,11 @@
 It uses Instant to wrap the generated code into a Python module."""
 
 __author__ = "Anders Logg ([email-masked])"
-__date__ = "2007-07-20 -- 2008-11-24"
-__copyright__ = "Copyright (C) 2007-2008 Anders Logg"
+__date__ = "2007-07-20 -- 2009-01-12"
+__copyright__ = "Copyright (C) 2007-2009 Anders Logg"
 __license__  = "GNU GPL version 3 or any later version"
 
-# Modified by Johan Hake, 2008
+# Modified by Johan Hake, 2008 - 2009
 # Modified by Ilmar Wilbers, 2008
 
 # Python modules
@@ -55,41 +55,45 @@
 
 def jit_form(form, options=None):
     "Just-in-time compile the given form"
-
+    
     # Make sure that we get a form
     if not isinstance(form, Form):
         form = Form(form)
-
+    
     # Check options
     options = check_options(form, options)
-
+    
     # Wrap input
     jit_object = JITObject(form, options)
-
+    
     # Check cache
     module = instant.import_module(jit_object, cache_dir=options["cache_dir"])
     if module: return extract_form(form, module)
-
+    
     # Generate code
     debug("Calling FFC just-in-time (JIT) compiler, this may take some time...", -1)
     signature = jit_object.signature()
     compile(form, signature, options)
     debug("done", -1)
-
+    
     # Wrap code into a Python module using Instant
     debug("Creating Python extension (compiling and linking), this may take some time...", -1)
     filename = signature + ".h"
-    (cppargs, path, ufc_include) = extract_instant_flags(options)
 
-    # Extract information for producing shared_ptr wrapper code.
-    shared_ptr_definitions, shared_ptr_declarations = \
-                            extract_shared_ptr_information(filename,options)
+    # Swig declarations
+    declarations = '\n%import "swig/ufc.i"\n'
+
+    # Extract any shared_ptr information
+    declarations += extract_shared_ptr_information(filename, options)
+    
+    (cppargs, path) = extract_instant_flags(options)
     
     module = instant.build_module(wrap_headers=[filename],
-                                  additional_definitions  = shared_ptr_definitions,
-                                  additional_declarations = shared_ptr_declarations + \
-                                                            ufc_include,
+                                  additional_declarations = declarations,
+                                  #system_headers=["tr1/memory"],
+                                  system_headers=["boost/shared_ptr.hpp"],
                                   include_dirs=path,
+                                  swig_include_dirs=path,
                                   cppargs=cppargs,
                                   signature=signature,
                                   cache_dir=options["cache_dir"])
@@ -114,7 +118,6 @@
     # Compile form
     (compiled_form, module, form_data) = jit_form(form, options)
 
-    # Extract element and dofmap
     return extract_element_and_dofmap(module)
 
 def check_options(form, options):
@@ -152,9 +155,8 @@
 def extract_element_and_dofmap(module):
     "Extract element and dofmap from module"
     name = module.__name__
-    element = getattr(module, name + "_finite_element_0")()
-    dofmap  = getattr(module, name + "_dof_map_0")()
-    return (element, dofmap)
+    return (getattr(module, name + "_finite_element_0")(),
+            getattr(module, name + "_dof_map_0")())
 
 def extract_instant_flags(options):
     "Extract flags for Instant"
@@ -165,15 +167,14 @@
 
     # Get include directory for ufc.h (might be better way to do this?)
     (path, dummy, dummy, dummy) = instant.header_and_libs_from_pkgconfig("ufc-1")
-    if len(path) == 0: path = [("/").join(sysconfig.get_python_inc().split("/")[:-2]) + "/include"]
-    ufc_include = '%%include "%s/ufc.h"' % path[0]
+    if len(path) == 0: path = [(os.sep).join(sysconfig.get_python_inc().split(os.sep)[:-2]) + os.sep + "include"]
 
-    return (cppargs, path, ufc_include)
+    return (cppargs, path)
 
 def extract_shared_ptr_information(filename,options):
     "Extract information for shared_ptr"
     if not options["shared_ptr"]:
-        return  "",""
+        return  ''
 
     import re
 
@@ -183,25 +184,35 @@
     # Extract the class names
     derived_classes   = re.findall(r"class[ ]+([\w]+)[ ]*: public",code)
     ufc_classes       = re.findall(r"public[ ]+(ufc::[\w]+).*",code)
-    ufc_proxy_classes = [c.replace("ufc::","") for c in ufc_classes]
+    ufc_proxy_classes = [s.replace("ufc::","") for s in ufc_classes]
 
-    shared_ptr_declarations =  """
+    shared_ptr_declarations =  '''
+#if SWIG_VERSION >= 0x010334
 //Uncomment these to produce code for std::tr1::shared_ptr
 //#define SWIG_SHARED_PTR_NAMESPACE std
 //#define SWIG_SHARED_PTR_SUBNAMESPACE tr1
 %include <boost_shared_ptr.i>
-"""
-    shared_ptr_format = """
-SWIG_SHARED_PTR(%(ufc_proxy)s,%(ufc_c)s)
-SWIG_SHARED_PTR_DERIVED(%(der_c)s,%(ufc_c)s,%(der_c)s)"""
+'''
+
+    shared_ptr_format = "SWIG_SHARED_PTR_DERIVED(%(der_class)s,%(ufc_class)s,%(der_class)s)"
+    shared_ptr_declarations += "\n".join(\
+        shared_ptr_format%{"ufc_proxy_class":c[0],"ufc_class":c[1],"der_class":c[2]}\
+        for c in zip(ufc_proxy_classes, ufc_classes, derived_classes)\
+        )
+
+    # Register new objects created by a .create_foo function
+    # FIXME: Add any created sub_elements and sub_dofmaps too.
+    new_objects = []
+    for ufc_class in ufc_classes:
+        stripped = ufc_class.replace("ufc::","")
+        if stripped not in new_objects:
+            new_objects.append(stripped)
     
-    shared_ptr_declarations += "\n".join(\
-        shared_ptr_format%{"ufc_c":c[0],"ufc_proxy":c[1],"der_c":c[2]}\
-        for c in zip(ufc_classes,ufc_proxy_classes,shared_ptr_classes)\
-        )
+    new_object_str = "%%newobject %s::create_"%filename.replace(".h","")
+    shared_ptr_declarations += "\n".join(new_object_str + new_object + ";" \
+                                         for new_object in new_objects)
     
-    shared_ptr_definitions  = """
-#include "boost/shared_ptr.hpp"
-//#include <tr1/memory>
-"""
-    return shared_ptr_definitions, shared_ptr_declarations
+    shared_ptr_declarations += "\n#endif\n"
+
+    return shared_ptr_declarations
+

---

From: Anders Logg <[email-masked]>
Date: Tue, 13 Jan 2009 18:01:28 +0100

Thanks, patch applied.

-- 
Anders

> _______________________________________________
> FFC-dev mailing list
> [email-masked]
> http://www.fenics.org/mailman/listinfo/ffc-dev