PageRenderTime 49ms CodeModel.GetById 19ms RepoModel.GetById 1ms app.codeStats 0ms

/ffc/backends/ufc/__init__.py

https://bitbucket.org/fenics-project/ffc
Python | 203 lines | 182 code | 0 blank | 21 comment | 0 complexity | 18c9bf73fd93d4d0f547a11876ddc79b MD5 | raw file
  1. # -*- coding: utf-8 -*-
  2. """Code generation format strings for UFC (Unified Form-assembly Code)
  3. Five format strings are defined for each of the following UFC classes:
  4. cell_integral
  5. exterior_facet_integral
  6. interior_facet_integral
  7. custom_integral
  8. cutcell_integral
  9. interface_integral
  10. overlap_integral
  11. function
  12. finite_element
  13. dofmap
  14. coordinate_mapping
  15. form
  16. The strings are named:
  17. '<classname>_header'
  18. '<classname>_implementation'
  19. '<classname>_combined'
  20. '<classname>_jit_header'
  21. '<classname>_jit_implementation'
  22. The header and implementation contain the definition and declaration
  23. of the class respectively, and are meant to be placed in .h and .cpp files,
  24. while the combined version is for an implementation within a single .h header.
  25. The _jit_ versions are used in the jit compiler and contains some additional
  26. factory functions exported as extern "C" to allow construction of compiled
  27. objects through ctypes without dealing with C++ ABI and name mangling issues.
  28. Each string has at least the following format variables: 'classname',
  29. 'members', 'constructor', 'destructor', plus one for each interface
  30. function with name equal to the function name.
  31. For more information about UFC and the FEniCS Project, visit
  32. http://www.fenicsproject.org
  33. https://bitbucket.org/fenics-project/ffc
  34. """
  35. __author__ = "Martin Sandve Alnæs, Anders Logg, Kent-Andre Mardal, Ola Skavhaug, and Hans Petter Langtangen"
  36. __date__ = "2017-05-09"
  37. __version__ = "2018.1.0"
  38. __license__ = "This code is released into the public domain"
  39. import os
  40. from hashlib import sha1
  41. from ffc.backends.ufc.function import *
  42. from ffc.backends.ufc.finite_element import *
  43. from ffc.backends.ufc.dofmap import *
  44. from ffc.backends.ufc.coordinate_mapping import *
  45. from ffc.backends.ufc.integrals import *
  46. from ffc.backends.ufc.form import *
  47. # Get abspath on import, it can in some cases be
  48. # a relative path w.r.t. curdir on startup
  49. _include_path = os.path.dirname(os.path.abspath(__file__))
  50. def get_include_path():
  51. "Return location of UFC header files"
  52. return _include_path
  53. # Platform specific snippets for controlling visilibity of exported symbols in generated shared libraries
  54. visibility_snippet = """
  55. // Based on https://gcc.gnu.org/wiki/Visibility
  56. #if defined _WIN32 || defined __CYGWIN__
  57. #ifdef __GNUC__
  58. #define DLL_EXPORT __attribute__ ((dllexport))
  59. #else
  60. #define DLL_EXPORT __declspec(dllexport)
  61. #endif
  62. #else
  63. #define DLL_EXPORT __attribute__ ((visibility ("default")))
  64. #endif
  65. """
  66. # Generic factory function signature
  67. factory_decl = """
  68. extern "C" %(basename)s * create_%(publicname)s();
  69. """
  70. # Generic factory function implementation. Set basename to the base class,
  71. # and note that publicname and privatename does not need to match, allowing
  72. # multiple factory functions to return the same object.
  73. factory_impl = """
  74. extern "C" DLL_EXPORT %(basename)s * create_%(publicname)s()
  75. {
  76. return new %(privatename)s();
  77. }
  78. """
  79. def all_ufc_classnames():
  80. "Build list of all classnames."
  81. integral_names = ["cell", "exterior_facet", "interior_facet", "vertex", "custom", "cutcell", "interface", "overlap"]
  82. integral_classnames = [integral_name + "_integral" for integral_name in integral_names]
  83. jitable_classnames = ["finite_element", "dofmap", "coordinate_mapping", "form"]
  84. classnames = ["function"] + jitable_classnames + integral_classnames
  85. return classnames
  86. def _build_templates():
  87. "Build collection of all templates to store in the templates dict."
  88. templates = {}
  89. classnames = all_ufc_classnames()
  90. for classname in classnames:
  91. # Expect all classes to have header, implementation, and combined versions
  92. header = globals()[classname + "_header"]
  93. implementation = globals()[classname + "_implementation"]
  94. combined = globals()[classname + "_combined"]
  95. # Construct jit header with class and factory function signature
  96. _fac_decl = factory_decl % {
  97. "basename": "ufc::" + classname,
  98. "publicname": "%(classname)s",
  99. "privatename": "%(classname)s",
  100. }
  101. jit_header = header + _fac_decl
  102. # Construct jit implementation template with class declaration,
  103. # factory function implementation, and class definition
  104. _fac_impl = factory_impl % {
  105. "basename": "ufc::" + classname,
  106. "publicname": "%(classname)s",
  107. "privatename": "%(classname)s",
  108. }
  109. jit_implementation = implementation + _fac_impl
  110. # Store all in templates dict
  111. templates[classname + "_header"] = header
  112. templates[classname + "_implementation"] = implementation
  113. templates[classname + "_combined"] = combined
  114. templates[classname + "_jit_header"] = jit_header
  115. templates[classname + "_jit_implementation"] = jit_implementation
  116. return templates
  117. def _compute_ufc_templates_signature(templates):
  118. # Compute signature of jit templates
  119. h = sha1()
  120. for k in sorted(templates):
  121. h.update(k.encode("utf-8"))
  122. h.update(templates[k].encode("utf-8"))
  123. return h.hexdigest()
  124. def _compute_ufc_signature():
  125. # Compute signature of ufc header files
  126. h = sha1()
  127. for fn in ("ufc.h", "ufc_geometry.h"):
  128. with open(os.path.join(get_include_path(), fn)) as f:
  129. h.update(f.read().encode("utf-8"))
  130. return h.hexdigest()
  131. # Build these on import
  132. templates = _build_templates()
  133. _ufc_signature = _compute_ufc_signature()
  134. _ufc_templates_signature = _compute_ufc_templates_signature(templates)
  135. def get_ufc_signature():
  136. """Return SHA-1 hash of the contents of ufc.h and ufc_geometry.h.
  137. In this implementation, the value is computed on import.
  138. """
  139. return _ufc_signature
  140. def get_ufc_templates_signature():
  141. """Return SHA-1 hash of the ufc code templates.
  142. In this implementation, the value is computed on import.
  143. """
  144. return _ufc_templates_signature
  145. def get_ufc_cxx_flags():
  146. """Return C++ flags for compiling UFC C++11 code.
  147. Return type is a list of strings.
  148. Used internally in some tests.
  149. """
  150. return ["-std=c++11"]
  151. # ufc_signature() already introduced to FFC standard in 1.7.0dev,
  152. # called by the dolfin cmake build system to compare against
  153. # future imported ffc versions for compatibility.
  154. ufc_signature = get_ufc_signature