Commits

Martin Alnæs  committed b15b8aa

Allow setting uflacs compiler parameters from ffc commandline.

Example:
ffc -r uflacs -fscore_threshold=1 -fenable_factorization Myform.ufl

  • Participants
  • Parent commits 0147ef5

Comments (0)

Files changed (6)

File site-packages/test_uflacs/test_dolfin_expression_compilation.py

 
 import numpy
 
+import hashlib
+
 #import uflacs, uflacs.codeutils
 #from uflacs.codeutils.expr_formatter import ExprFormatter
+from uflacs.params import default_parameters
 
 from uflacs.backends.dolfin.expression import format_dolfin_expression
 from uflacs.backends.dolfin.dolfin_compiler import compile_dolfin_expression_body
             pass
     return res
 
-import hashlib
 class Ufl2DolfinExpressionCompilerTest(UflTestCase):
     """Tests of Dolfin C++ Expression compilation from UFL expressions."""
 
     def _test_dolfin_expression_compilation(self, uexpr, expected_lines, expected_values,
                                             members={}):
+        parameters = default_parameters()
         # Compile expression
-        compiled_lines, member_names = compile_dolfin_expression_body(uexpr)
+        compiled_lines, member_names = compile_dolfin_expression_body(uexpr, parameters)
 
         # Check expected compilation output
         if flattened_nonempty_lines(compiled_lines) != expected_lines:
 
 
     def test_dolfin_expression_compilation_of_math_functions(self):
-        #import uflacs.params
-        #uflacs.params.params["enable_factorization"] = True
-        #uflacs.params.params["score_threshold"] = 3
-
         dolfin = self.require_dolfin()
 
         # Define some PyDOLFIN coefficients

File site-packages/uflacs/backends/dolfin/dolfin_compiler.py

 from uflacs.backends.dolfin.dolfin_language_formatter import DolfinExpressionLanguageFormatter
 from uflacs.backends.dolfin.dolfin_statement_formatter import DolfinExpressionStatementFormatter
 
-def compile_dolfin_expression_body(expr, object_names=None):
+from uflacs.params import default_parameters
+
+def compile_dolfin_expression_body(expr, parameters, object_names=None):
     "Generate (code for eval, member names dict) for a single UFL expression."
     # Setup generic compiler arguments (TODO: get from preprocessed expr data?)
     cell = expr.cell() # FIXME: Need to preprocess this?
         object_names = {}
 
     # Compile expression into intermediate representation (partitions in ssa form)
-    ir = compile_expression_partitions(expr, form_argument_mapping)
+    ir = compile_expression_partitions(expr, form_argument_mapping, parameters)
 
     # Compile eval function body with generic compiler routine
     code, dh = generate_expression_code(ir, cell, form_argument_mapping, object_names,
 
     return code, member_names
 
-def compile_dolfin_expression_class(expr, name, object_names):
+def compile_dolfin_expression_class(expr, name, parameters, object_names):
     """Generate code for a single dolfin Expression from a single UFL Expr.
 
     *Arguments*
     classname = 'UflacsExpression_%s' % name
     shape = expr.shape()
 
-    eval_body, member_names = compile_dolfin_expression_body(expr, object_names)
+    eval_body, member_names = compile_dolfin_expression_body(expr, parameters, object_names)
 
     # Stitch together the full class
     code = format_dolfin_expression(classname=classname,
 
         Full contents of header file with compiled expressions.
     """
+    parameters = default_parameters() # FIXME: Get as input
+
     # Generate code for each expression
     file_code = []
     classnames = []
     for k, expr in enumerate(expressions):
         name = object_names.get(id(expr), 'e%d' % k)
-        code, classname = compile_dolfin_expression_class(expr, name, object_names)
+        code, classname = compile_dolfin_expression_class(expr, name, parameters, object_names)
         file_code.append(code)
         classnames.append(classname)
 

File site-packages/uflacs/backends/ffc/ffc_compiler.py

 from uflacs.backends.ffc.ffc_language_formatter import FFCLanguageFormatter
 from uflacs.backends.ffc.ffc_statement_formatter import FFCStatementFormatter
 
+from uflacs.params import default_parameters
+
 def build_element_counter_map(integrals_dict, element_replace_map):
     element_counter_map = {}
     for num_points in sorted(integrals_dict.keys()):
                                integrals_dict,
                                form_data,
                                parameters):
+    # Hack before we get default parameters properly into ffc
+    p = default_parameters()
+    p.update(parameters)
+    parameters = p
+
     # These are already inserted by ffc representation code:
     #ir["domain_type"]
     #ir["quadrature_weights"] = { num_points: (w, (x,y)) }
     #ir["body_ir"] = {}
     for num_points in sorted(integrals_dict.keys()):
         integrand = integrals_dict[num_points].integrand()
-        body_ir = compile_expression_partitions(integrand, ir["function_replace_map"])
+        body_ir = compile_expression_partitions(integrand, ir["function_replace_map"], parameters)
         #ir["body_ir"][num_points] = body_ir # TODO: Like this?
         ir.update(body_ir) # For now, single rule only
 
 
 
 def optimize_tabulate_tensor_ir(ir, parameters):
+    # Hack before we get default parameters properly into ffc
+    p = default_parameters()
+    p.update(parameters)
+    parameters = p
+
     # TODO: Implement some optimization here!
     oir = ir
     return oir

File site-packages/uflacs/backends/toy/toy_compiler.py

 from uflacs.backends.toy.toy_language_formatter import ToyCppLanguageFormatter
 from uflacs.backends.toy.toy_statement_formatter import ToyCppStatementFormatter
 
+from uflacs.params import default_parameters
+
 def compile_expression(expr, prefix=""):
     "Toy compiler, translating an expression to a block of code that is not quite compilable."
 
+    parameters = default_parameters() # FIXME: Get as input
+
     # Preprocess expression
     # TODO: Use ufl ExprData preprocessing, unify expr data with form data:
     expr = expand_compounds(expr)
     form_argument_mapping = {}
 
     # Compile expression into intermediate representation (partitions in ssa form)
-    ir = compile_expression_partitions(expr, form_argument_mapping)
+    ir = compile_expression_partitions(expr, form_argument_mapping, parameters)
 
     # Hack to automatically disable integral accumulation in statement formatter
     ir["entitytype"] = None
 def compile_form(form, prefix=""):
     "Toy compiler, translating a Form to a block of code that is not quite compilable."
 
+    parameters = default_parameters() # FIXME: Get as input
+
     # Preprocess form
     form_data = form.compute_form_data()
 
                                     if isinstance(k, Argument))
 
             # Compile expression into intermediate representation (partitions in ssa form)
-            ir = compile_expression_partitions(expr, form_argument_mapping)
+            ir = compile_expression_partitions(expr, form_argument_mapping, parameters)
 
             # Build code representation
             integral_code, dh = generate_expression_code(ir, cell,

File site-packages/uflacs/generation/compiler.py

 from uflacs.codeutils.expr_formatter import ExprFormatter
 from uflacs.codeutils.element_tensor_formatter import build_loops, format_assignments, format_scaled_additions
 
-from uflacs.params import params
-
-def compile_expression_partitions(expression, form_argument_mapping):
+def compile_expression_partitions(expression, form_argument_mapping, parameters):
     # Timing object
     tt = TicToc('compile_expression_partitions')
 
     # Compute factorization of arguments
     tt.step('compute_dependencies')
     # FIXME: Fix factorization algorithm for multiple target variables! Or is there any point?
-    if params["enable_factorization"] and len(target_variables) == 1:
+    if parameters["enable_factorization"] and len(target_variables) == 1:
         #AV, FV, IM
         argument_factors, factorized_vertices, argument_factorization = compute_argument_factorization(SV, target_variables, dependencies)
         SV, se2i, dependencies = rebuild_scalar_graph_from_factorization(argument_factors, factorized_vertices, argument_factorization)
     # Allocate variables to store subexpressions in
     tt.step('allocate_registers')
     allocations = allocate_registers(active, partitions, target_variables,
-                                     scores, params["max_registers"], params["score_threshold"])
+                                     scores, int(parameters["max_registers"]), int(parameters["score_threshold"]))
     target_registers = [allocations[r] for r in target_variables]
     num_registers = sum(1 if x >= 0 else 0 for x in allocations)
     # TODO: Could allocate registers separately for each partition?
 
     # Print timing
     tt.stop()
-    if params["enable_profiling"]:
+    if parameters["enable_profiling"]:
         print "Profiling results:"
         print tt
 

File site-packages/uflacs/params.py

 
-def default_params():
+def default_parameters():
     return  {
         "enable_profiling": False,
-        "enable_factorization": True,
-        "max_registers": 1024, # 8 B * 1024 = 8 KB
-        "score_threshold": 3,
+        "enable_factorization": False, #True, # Fails for hyperelasticity demo in dolfin, needs debugging
+        "max_registers": 1024, # 8 B * 1024 = 8 KB # TODO: Tune this for something very complex
+        "score_threshold": 3, # TODO: Scoring is work in progress and this will change meaning later
         }
-
-# TODO: Pass params throughout compiler pipeline
-params = default_params()