From debbf75fa25b2e2c2207b983adf4cfe161cbcf58 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B8rgen=20Dokken?= Date: Wed, 23 Feb 2022 18:33:24 +0000 Subject: [PATCH 1/9] First test --- ffcx/codegeneration/form.py | 9 ++++++--- ffcx/ir/representation.py | 11 +++++------ ffcx/naming.py | 4 ++-- 3 files changed, 13 insertions(+), 11 deletions(-) diff --git a/ffcx/codegeneration/form.py b/ffcx/codegeneration/form.py index 80ec501d3..c9eae5bf6 100644 --- a/ffcx/codegeneration/form.py +++ b/ffcx/codegeneration/form.py @@ -88,12 +88,15 @@ def generator(ir, parameters): cases_ids = [] for itg_type in ("cell", "interior_facet", "exterior_facet"): if len(ir.integral_names[itg_type]) > 0: + values = [] + for itg in ir.integral_names[itg_type]: + for _ in ir.subdomain_ids[itg_type]: + values.append(L.AddressOf(L.Symbol(itg))) code += [L.ArrayDecl( "static ufcx_integral*", f"integrals_{itg_type}_{ir.name}", - values=[L.AddressOf(L.Symbol(itg)) for itg in ir.integral_names[itg_type]], - sizes=len(ir.integral_names[itg_type]))] + values=values, + sizes=len(values))] cases.append((L.Symbol(itg_type), L.Return(L.Symbol(f"integrals_{itg_type}_{ir.name}")))) - code_ids += [L.ArrayDecl( "static int", f"integral_ids_{itg_type}_{ir.name}", values=ir.subdomain_ids[itg_type], sizes=len(ir.subdomain_ids[itg_type]))] diff --git a/ffcx/ir/representation.py b/ffcx/ir/representation.py index 32c0cb337..d0e745152 100644 --- a/ffcx/ir/representation.py +++ b/ffcx/ir/representation.py @@ -79,8 +79,8 @@ def compute_ir(analysis, object_names, prefix, parameters, visualise): for fd_index, fd in enumerate(analysis.form_data): form_names[fd_index] = naming.form_name(fd.original_form, fd_index, prefix) for itg_index, itg_data in enumerate(fd.integral_data): - integral_names[(fd_index, itg_index)] = naming.integral_name(fd.original_form, itg_data.integral_type, - fd_index, itg_data.subdomain_id, prefix) + integral_names[(fd_index, itg_index)] = naming.integral_name( + fd.original_form, itg_data.integral_type, fd_index, prefix) ir_elements = [ _compute_element_ir(e, analysis.element_numbers, finite_element_names) @@ -449,11 +449,10 @@ def _compute_form_ir(form_data, form_id, prefix, form_names, integral_names, ele ir["subdomain_ids"][integral_type] = [-1] + ir["subdomain_ids"][integral_type] ir["integral_names"][integral_type] = [ integral_names[(form_id, itg_index)]] + ir["integral_names"][integral_type] - elif itg_data.subdomain_id < 0: - raise ValueError("Integral subdomain ID must be non-negative.") + elif min(itg_data.subdomain_id) < 0: + raise ValueError("Integral subdomain IDs must be non-negative.") else: - assert isinstance(itg_data.subdomain_id, int) - ir["subdomain_ids"][integral_type] += [itg_data.subdomain_id] + ir["subdomain_ids"][integral_type] += list(itg_data.subdomain_id) ir["integral_names"][integral_type] += [integral_names[(form_id, itg_index)]] return ir_form(**ir) diff --git a/ffcx/naming.py b/ffcx/naming.py index 155601f55..c04278a32 100644 --- a/ffcx/naming.py +++ b/ffcx/naming.py @@ -66,8 +66,8 @@ def compute_signature(ufl_objects, tag): return hashlib.sha1(string.encode('utf-8')).hexdigest() -def integral_name(original_form, integral_type, form_id, subdomain_id, prefix): - sig = compute_signature([original_form], str((prefix, integral_type, form_id, subdomain_id))) +def integral_name(original_form, integral_type, form_id, prefix): + sig = compute_signature([original_form], str((prefix, integral_type, form_id))) return f"integral_{sig}" From dffde202fe49c15fcf066a7b7ba8c627b3671e50 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B8rgen=20Dokken?= Date: Thu, 24 Feb 2022 11:38:27 +0000 Subject: [PATCH 2/9] At least code is compiled. NOw to check for correctness.. --- ffcx/codegeneration/form.py | 19 ++++++++++-------- ffcx/ir/representation.py | 39 +++++++++++++------------------------ test/test_jit_expression.py | 3 +-- 3 files changed, 26 insertions(+), 35 deletions(-) diff --git a/ffcx/codegeneration/form.py b/ffcx/codegeneration/form.py index c9eae5bf6..820696727 100644 --- a/ffcx/codegeneration/form.py +++ b/ffcx/codegeneration/form.py @@ -87,19 +87,22 @@ def generator(ir, parameters): code_ids = [] cases_ids = [] for itg_type in ("cell", "interior_facet", "exterior_facet"): - if len(ir.integral_names[itg_type]) > 0: - values = [] - for itg in ir.integral_names[itg_type]: - for _ in ir.subdomain_ids[itg_type]: - values.append(L.AddressOf(L.Symbol(itg))) + # Get list of integrals and subdomain_ids for each kernel + values = [] + id_values = [] + for idx in ir.integral_names[itg_type].keys(): + values.append(L.AddressOf(L.Symbol(ir.integral_names[itg_type][idx]))) + id_values.extend(list(ir.subdomain_ids[itg_type][idx])) + if len(values) > 0: code += [L.ArrayDecl( "static ufcx_integral*", f"integrals_{itg_type}_{ir.name}", - values=values, - sizes=len(values))] + values=values, sizes=len(values))] cases.append((L.Symbol(itg_type), L.Return(L.Symbol(f"integrals_{itg_type}_{ir.name}")))) + + if len(id_values) > 0: code_ids += [L.ArrayDecl( "static int", f"integral_ids_{itg_type}_{ir.name}", - values=ir.subdomain_ids[itg_type], sizes=len(ir.subdomain_ids[itg_type]))] + values=id_values, sizes=len(id_values))] cases_ids.append((L.Symbol(itg_type), L.Return(L.Symbol(f"integral_ids_{itg_type}_{ir.name}")))) code += [L.Switch("integral_type", cases, default=L.Return(L.Null()))] diff --git a/ffcx/ir/representation.py b/ffcx/ir/representation.py index d0e745152..985a2c832 100644 --- a/ffcx/ir/representation.py +++ b/ffcx/ir/representation.py @@ -80,7 +80,7 @@ def compute_ir(analysis, object_names, prefix, parameters, visualise): form_names[fd_index] = naming.form_name(fd.original_form, fd_index, prefix) for itg_index, itg_data in enumerate(fd.integral_data): integral_names[(fd_index, itg_index)] = naming.integral_name( - fd.original_form, itg_data.integral_type, fd_index, prefix) + fd.original_form, itg_data.integral_type, itg_index, prefix) ir_elements = [ _compute_element_ir(e, analysis.element_numbers, finite_element_names) @@ -226,7 +226,6 @@ def _compute_integral_ir(form_data, form_index, element_numbers, integral_names, cellname = cell.cellname() tdim = cell.topological_dimension() assert all(tdim == itg.ufl_domain().topological_dimension() for itg in itg_data.integrals) - ir = { "integral_type": itg_data.integral_type, "subdomain_id": itg_data.subdomain_id, @@ -430,31 +429,21 @@ def _compute_form_ir(form_data, form_id, prefix, form_names, integral_names, ele # Store names of integrals and subdomain_ids for this form, grouped by integral types # Since form points to all integrals it contains, it has to know their names # for codegen phase - ir["integral_names"] = {} - ir["subdomain_ids"] = {} ufcx_integral_types = ("cell", "exterior_facet", "interior_facet") - for integral_type in ufcx_integral_types: - ir["subdomain_ids"][integral_type] = [] - ir["integral_names"][integral_type] = [] - - for itg_index, itg_data in enumerate(form_data.integral_data): - if (itg_data.integral_type == integral_type): - if itg_data.subdomain_id == "otherwise": - # UFL is using "otherwise" for default integrals (over whole mesh) - # but FFCx needs integers, so otherwise = -1 - if len(ir["subdomain_ids"][integral_type]) > 0 and ir["subdomain_ids"][integral_type][0] == -1: - raise ValueError("Only one default ('otherwise') integral allowed.") - - # Put default integral as first - ir["subdomain_ids"][integral_type] = [-1] + ir["subdomain_ids"][integral_type] - ir["integral_names"][integral_type] = [ - integral_names[(form_id, itg_index)]] + ir["integral_names"][integral_type] - elif min(itg_data.subdomain_id) < 0: - raise ValueError("Integral subdomain IDs must be non-negative.") - else: - ir["subdomain_ids"][integral_type] += list(itg_data.subdomain_id) - ir["integral_names"][integral_type] += [integral_names[(form_id, itg_index)]] + ir["subdomain_ids"] = {itg_type: {} for itg_type in ufcx_integral_types} + ir["integral_names"] = {itg_type: {} for itg_type in ufcx_integral_types} + for itg_index, itg_data in enumerate(form_data.integral_data): + # UFL is using "otherwise" for default integrals (over whole mesh) + # but FFCx needs integers, so otherwise = -1 + integral_type = itg_data.integral_type + subdomain_ids = set(sid if sid != "otherwise" else -1 for sid in itg_data.subdomain_id) + if min(subdomain_ids) < -1: + raise ValueError("Integral subdomain IDs must be non-negative.") + ir["subdomain_ids"][integral_type][itg_index] = subdomain_ids + ir["integral_names"][integral_type][itg_index] = integral_names[(form_id, itg_index)] + from IPython import embed + embed() return ir_form(**ir) diff --git a/test/test_jit_expression.py b/test/test_jit_expression.py index 4c3313fe4..f7343eee9 100644 --- a/test/test_jit_expression.py +++ b/test/test_jit_expression.py @@ -174,12 +174,11 @@ def test_elimiate_zero_tables_tensor(compile_args): # Using same basix element for coordinate element and coefficient coeff_points = basix_c_e.points - # Compile expression at interpolation points of second order Lagrange space b_el = basix.create_element(basix.ElementFamily.P, basix.cell.string_to_type(cell), 0, True) points = b_el.points obj, module, code = ffcx.codegeneration.jit.compile_expressions( - [(expr, points)], cffi_extra_compile_args=compile_args) + [(expr, points)]) ffi = cffi.FFI() expression = obj[0] From 3564dffeac328147b86fcf4b798f4dfe507f44fa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B8rgen=20Dokken?= Date: Thu, 24 Feb 2022 12:06:30 +0000 Subject: [PATCH 3/9] Remove import --- ffcx/ir/representation.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/ffcx/ir/representation.py b/ffcx/ir/representation.py index 985a2c832..ea65196e7 100644 --- a/ffcx/ir/representation.py +++ b/ffcx/ir/representation.py @@ -442,8 +442,6 @@ def _compute_form_ir(form_data, form_id, prefix, form_names, integral_names, ele raise ValueError("Integral subdomain IDs must be non-negative.") ir["subdomain_ids"][integral_type][itg_index] = subdomain_ids ir["integral_names"][integral_type][itg_index] = integral_names[(form_id, itg_index)] - from IPython import embed - embed() return ir_form(**ir) From f433ca5f00a7198675da8aca392a1de0e6a66865 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B8rgen=20Dokken?= Date: Thu, 24 Feb 2022 13:50:39 +0000 Subject: [PATCH 4/9] Merge integrals with common integral data (up to subdomain id) --- ffcx/codegeneration/form.py | 19 ++++++++++++++----- ffcx/ir/representation.py | 3 ++- 2 files changed, 16 insertions(+), 6 deletions(-) diff --git a/ffcx/codegeneration/form.py b/ffcx/codegeneration/form.py index 820696727..7f23e8d66 100644 --- a/ffcx/codegeneration/form.py +++ b/ffcx/codegeneration/form.py @@ -9,6 +9,8 @@ import logging +import numpy + from ffcx.codegeneration import form_template logger = logging.getLogger("ffcx") @@ -33,7 +35,10 @@ def generator(ir, parameters): code = [] cases = [] for itg_type in ("cell", "interior_facet", "exterior_facet"): - cases += [(L.Symbol(itg_type), L.Return(len(ir.subdomain_ids[itg_type])))] + num_integrals = 0 + for ids in ir.subdomain_ids[itg_type].values(): + num_integrals += len(ids) + cases += [(L.Symbol(itg_type), L.Return(num_integrals))] code += [L.Switch("integral_type", cases, default=L.Return(0))] d["num_integrals"] = L.StatementList(code) @@ -68,8 +73,8 @@ def generator(ir, parameters): if len(ir.finite_elements) > 0: d["finite_elements"] = f"finite_elements_{ir.name}" d["finite_elements_init"] = L.ArrayDecl("ufcx_finite_element*", f"finite_elements_{ir.name}", values=[ - L.AddressOf(L.Symbol(el)) for el in ir.finite_elements], - sizes=len(ir.finite_elements)) + L.AddressOf(L.Symbol(el)) for el in ir.finite_elements], + sizes=len(ir.finite_elements)) else: d["finite_elements"] = L.Null() d["finite_elements_init"] = "" @@ -91,8 +96,12 @@ def generator(ir, parameters): values = [] id_values = [] for idx in ir.integral_names[itg_type].keys(): - values.append(L.AddressOf(L.Symbol(ir.integral_names[itg_type][idx]))) - id_values.extend(list(ir.subdomain_ids[itg_type][idx])) + integrals = list(ir.subdomain_ids[itg_type][idx]) + values.extend([L.AddressOf(L.Symbol(ir.integral_names[itg_type][idx]))] * len(integrals)) + id_values.extend(integrals) + value_sort = numpy.argsort(id_values) + values = [values[value_sort[i]] for i in range(len(values))] + id_values = [id_values[value_sort[i]] for i in range(len(id_values))] if len(values) > 0: code += [L.ArrayDecl( "static ufcx_integral*", f"integrals_{itg_type}_{ir.name}", diff --git a/ffcx/ir/representation.py b/ffcx/ir/representation.py index ea65196e7..16f0a6732 100644 --- a/ffcx/ir/representation.py +++ b/ffcx/ir/representation.py @@ -79,8 +79,9 @@ def compute_ir(analysis, object_names, prefix, parameters, visualise): for fd_index, fd in enumerate(analysis.form_data): form_names[fd_index] = naming.form_name(fd.original_form, fd_index, prefix) for itg_index, itg_data in enumerate(fd.integral_data): + # Unique ID for integrals is 2**form_index * 3**integral_index integral_names[(fd_index, itg_index)] = naming.integral_name( - fd.original_form, itg_data.integral_type, itg_index, prefix) + fd.original_form, itg_data.integral_type, 2**fd_index * 3**itg_index, prefix) ir_elements = [ _compute_element_ir(e, analysis.element_numbers, finite_element_names) From d893397cdc160a818cc0c47a6738895d4873e729 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B8rgen=20Dokken?= Date: Thu, 24 Feb 2022 14:17:23 +0000 Subject: [PATCH 5/9] Update CI --- .github/workflows/dolfin-tests.yml | 2 +- .github/workflows/pythonapp.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/dolfin-tests.yml b/.github/workflows/dolfin-tests.yml index fa551c87b..d99baa152 100644 --- a/.github/workflows/dolfin-tests.yml +++ b/.github/workflows/dolfin-tests.yml @@ -33,7 +33,7 @@ jobs: python3 -m pip install --upgrade pip - name: Install UFL and Basix run: | - python3 -m pip install git+https://github.com/FEniCS/ufl.git + python3 -m pip install git+https://github.com/FEniCS/ufl.git@dokken/group_integrals python3 -m pip install git+https://github.com/FEniCS/basix.git - name: Install FFCx diff --git a/.github/workflows/pythonapp.yml b/.github/workflows/pythonapp.yml index 6cfee32d7..35edb70c3 100644 --- a/.github/workflows/pythonapp.yml +++ b/.github/workflows/pythonapp.yml @@ -42,7 +42,7 @@ jobs: - name: Install FEniCS dependencies (Python) run: | - python -m pip install git+https://github.com/FEniCS/ufl.git + python -m pip install git+https://github.com/FEniCS/ufl.git@dokken/group_integrals python -m pip install git+https://github.com/FEniCS/basix.git - name: Install FFCx From 958c214e153c712a733b6cace21d3aa281b3cf6b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B8rgen=20Schartum=20Dokken?= Date: Thu, 24 Feb 2022 14:36:38 +0000 Subject: [PATCH 6/9] revert change in expression test --- test/test_jit_expression.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/test_jit_expression.py b/test/test_jit_expression.py index f7343eee9..62dc13ec0 100644 --- a/test/test_jit_expression.py +++ b/test/test_jit_expression.py @@ -178,7 +178,7 @@ def test_elimiate_zero_tables_tensor(compile_args): b_el = basix.create_element(basix.ElementFamily.P, basix.cell.string_to_type(cell), 0, True) points = b_el.points obj, module, code = ffcx.codegeneration.jit.compile_expressions( - [(expr, points)]) + [(expr, points)], cffi_extra_compile_args=compile_args) ffi = cffi.FFI() expression = obj[0] From abf80ddd1462d37173fb866b59d29cc1ff7d7a38 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B8rgen=20Dokken?= Date: Tue, 29 Mar 2022 09:43:51 +0000 Subject: [PATCH 7/9] Follow Michal's comment + some typing --- ffcx/ir/representation.py | 17 ++++++++++++----- ffcx/naming.py | 25 ++++++++++++++----------- 2 files changed, 26 insertions(+), 16 deletions(-) diff --git a/ffcx/ir/representation.py b/ffcx/ir/representation.py index bf4d7b6ec..7e8345be8 100644 --- a/ffcx/ir/representation.py +++ b/ffcx/ir/representation.py @@ -18,12 +18,14 @@ import itertools import logging +import typing import warnings from collections import namedtuple import numpy import ufl from ffcx import naming +from ffcx.analysis import ufl_data from ffcx.element_interface import create_element from ffcx.ir.integral import compute_integral_ir from ffcx.ir.representationutils import (QuadratureRule, @@ -63,7 +65,8 @@ ir_data = namedtuple('ir_data', ['elements', 'dofmaps', 'integrals', 'forms', 'expressions']) -def compute_ir(analysis, object_names, prefix, parameters, visualise): +def compute_ir(analysis: ufl_data, object_names: typing.Dict, prefix: str, parameters: typing.Dict, + visualise: bool): """Compute intermediate representation.""" logger.info(79 * "*") logger.info("Compiler stage 2: Computing intermediate representation of objects") @@ -81,7 +84,7 @@ def compute_ir(analysis, object_names, prefix, parameters, visualise): for itg_index, itg_data in enumerate(fd.integral_data): # Unique ID for integrals is 2**form_index * 3**integral_index integral_names[(fd_index, itg_index)] = naming.integral_name( - fd.original_form, itg_data.integral_type, 2**fd_index * 3**itg_index, prefix) + fd.original_form, itg_data.integral_type, fd_index, itg_index, prefix) ir_elements = [ _compute_element_ir(e, analysis.element_numbers, finite_element_names) @@ -115,7 +118,9 @@ def compute_ir(analysis, object_names, prefix, parameters, visualise): expressions=ir_expressions) -def _compute_element_ir(ufl_element, element_numbers, finite_element_names): +def _compute_element_ir(ufl_element: ufl.finiteelement.FiniteElementBase, + element_numbers: typing.Dict[ufl.finiteelement.FiniteElementBase, int], + finite_element_names: typing.Dict[ufl.finiteelement.FiniteElementBase, str]) -> ir_element: """Compute intermediate representation of element.""" logger.info(f"Computing IR for element {ufl_element}") @@ -160,7 +165,9 @@ def _compute_element_ir(ufl_element, element_numbers, finite_element_names): return ir_element(**ir) -def _compute_dofmap_ir(ufl_element, element_numbers, dofmap_names): +def _compute_dofmap_ir(ufl_element: ufl.finiteelement.FiniteElementBase, + element_numbers: typing.Dict[ufl.finiteelement.FiniteElementBase, int], + dofmap_names: typing.Dict[ufl.finiteelement.FiniteElementBase, str]) -> ir_dofmap: """Compute intermediate representation of dofmap.""" logger.info(f"Computing IR for dofmap of {ufl_element}") @@ -205,7 +212,7 @@ def _compute_dofmap_ir(ufl_element, element_numbers, dofmap_names): def _compute_integral_ir(form_data, form_index, element_numbers, integral_names, - finite_element_names, parameters, visualise): + finite_element_names, parameters, visualise) -> list[ir_integral]: """Compute intermediate represention for form integrals.""" _entity_types = { "cell": "cell", diff --git a/ffcx/naming.py b/ffcx/naming.py index c0d3d3327..83e861198 100644 --- a/ffcx/naming.py +++ b/ffcx/naming.py @@ -5,17 +5,19 @@ # SPDX-License-Identifier: LGPL-3.0-or-later import hashlib - +import typing +import numpy import ufl import ffcx -def compute_signature(ufl_objects, tag): +def compute_signature( + ufl_objects: typing.Union[ufl.Form, ufl.FiniteElementBase, + typing.Tuple[ufl.core.expr.Expr, numpy.ndarray]], tag: str) -> str: """Compute the signature hash. - Based on the UFL type of the objects and an additional optional - 'tag'. + Based on the UFL type of the objects and an additional optional 'tag'. """ object_signature = "" for ufl_object in ufl_objects: @@ -66,35 +68,36 @@ def compute_signature(ufl_objects, tag): return hashlib.sha1(string.encode('utf-8')).hexdigest() -def integral_name(original_form, integral_type, form_id, prefix): - sig = compute_signature([original_form], str((prefix, integral_type, form_id))) +def integral_name(original_form: ufl.form.Form, integral_type: str, form_id: int, integral_id: int, prefix: str) -> str: + """Compute signature for an integral in an ufl form""" + sig = compute_signature([original_form], str((prefix, integral_type, form_id, integral_id))) return f"integral_{sig}" -def form_name(original_form, form_id, prefix): +def form_name(original_form: ufl.form.Form, form_id: int, prefix: str) -> str: sig = compute_signature([original_form], str((prefix, form_id))) return f"form_{sig}" -def finite_element_name(ufl_element, prefix): +def finite_element_name(ufl_element: ufl.FiniteElementBase, prefix: str) -> str: assert isinstance(ufl_element, ufl.FiniteElementBase) sig = compute_signature([ufl_element], prefix) return f"element_{sig}" -def dofmap_name(ufl_element, prefix): +def dofmap_name(ufl_element: ufl.FiniteElementBase, prefix: str) -> str: assert isinstance(ufl_element, ufl.FiniteElementBase) sig = compute_signature([ufl_element], prefix) return f"dofmap_{sig}" -def expression_name(expression, prefix): +def expression_name(expression: ufl.core.expr.Expr, prefix: str) -> str: assert isinstance(expression[0], ufl.core.expr.Expr) sig = compute_signature([expression], prefix) return f"expression_{sig}" -def cdtype_to_numpy(cdtype): +def cdtype_to_numpy(cdtype: str) -> str: """Map a C data type string NumPy datatype string.""" if cdtype == "double": return "float64" From 9c468d773868ffe9fa4b3a20d376ecab3bf0ea56 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B8rgen=20Dokken?= Date: Tue, 29 Mar 2022 10:20:26 +0000 Subject: [PATCH 8/9] Alter typing to get mypy to pass --- ffcx/ir/representation.py | 20 ++++++++------------ ffcx/naming.py | 18 +++++++----------- 2 files changed, 15 insertions(+), 23 deletions(-) diff --git a/ffcx/ir/representation.py b/ffcx/ir/representation.py index 7e8345be8..737fe0e41 100644 --- a/ffcx/ir/representation.py +++ b/ffcx/ir/representation.py @@ -65,7 +65,7 @@ ir_data = namedtuple('ir_data', ['elements', 'dofmaps', 'integrals', 'forms', 'expressions']) -def compute_ir(analysis: ufl_data, object_names: typing.Dict, prefix: str, parameters: typing.Dict, +def compute_ir(analysis: ufl_data, object_names: typing.Dict, prefix: typing.Optional[str], parameters: typing.Dict, visualise: bool): """Compute intermediate representation.""" logger.info(79 * "*") @@ -118,9 +118,7 @@ def compute_ir(analysis: ufl_data, object_names: typing.Dict, prefix: str, param expressions=ir_expressions) -def _compute_element_ir(ufl_element: ufl.finiteelement.FiniteElementBase, - element_numbers: typing.Dict[ufl.finiteelement.FiniteElementBase, int], - finite_element_names: typing.Dict[ufl.finiteelement.FiniteElementBase, str]) -> ir_element: +def _compute_element_ir(ufl_element, element_numbers, finite_element_names): """Compute intermediate representation of element.""" logger.info(f"Computing IR for element {ufl_element}") @@ -153,11 +151,11 @@ def _compute_element_ir(ufl_element: ufl.finiteelement.FiniteElementBase, ir["num_sub_elements"] = ufl_element.num_sub_elements() ir["sub_elements"] = [finite_element_names[e] for e in ufl_element.sub_elements()] - if hasattr(basix_element, "block_size"): + try: ir["block_size"] = basix_element.block_size ufl_element = ufl_element.sub_elements()[0] basix_element = create_element(ufl_element) - else: + except AttributeError: ir["block_size"] = 1 ir["entity_dofs"] = basix_element.entity_dofs @@ -165,9 +163,7 @@ def _compute_element_ir(ufl_element: ufl.finiteelement.FiniteElementBase, return ir_element(**ir) -def _compute_dofmap_ir(ufl_element: ufl.finiteelement.FiniteElementBase, - element_numbers: typing.Dict[ufl.finiteelement.FiniteElementBase, int], - dofmap_names: typing.Dict[ufl.finiteelement.FiniteElementBase, str]) -> ir_dofmap: +def _compute_dofmap_ir(ufl_element, element_numbers, dofmap_names): """Compute intermediate representation of dofmap.""" logger.info(f"Computing IR for dofmap of {ufl_element}") @@ -183,10 +179,10 @@ def _compute_dofmap_ir(ufl_element: ufl.finiteelement.FiniteElementBase, ir["sub_dofmaps"] = [dofmap_names[e] for e in ufl_element.sub_elements()] ir["num_sub_dofmaps"] = ufl_element.num_sub_elements() - if hasattr(basix_element, "block_size"): + try: ir["block_size"] = basix_element.block_size basix_element = basix_element.sub_element - else: + except AttributeError: ir["block_size"] = 1 # Precompute repeatedly used items @@ -212,7 +208,7 @@ def _compute_dofmap_ir(ufl_element: ufl.finiteelement.FiniteElementBase, def _compute_integral_ir(form_data, form_index, element_numbers, integral_names, - finite_element_names, parameters, visualise) -> list[ir_integral]: + finite_element_names, parameters, visualise): """Compute intermediate represention for form integrals.""" _entity_types = { "cell": "cell", diff --git a/ffcx/naming.py b/ffcx/naming.py index 83e861198..252aede24 100644 --- a/ffcx/naming.py +++ b/ffcx/naming.py @@ -5,16 +5,12 @@ # SPDX-License-Identifier: LGPL-3.0-or-later import hashlib -import typing -import numpy import ufl - +import typing import ffcx -def compute_signature( - ufl_objects: typing.Union[ufl.Form, ufl.FiniteElementBase, - typing.Tuple[ufl.core.expr.Expr, numpy.ndarray]], tag: str) -> str: +def compute_signature(ufl_objects, tag): """Compute the signature hash. Based on the UFL type of the objects and an additional optional 'tag'. @@ -68,30 +64,30 @@ def compute_signature( return hashlib.sha1(string.encode('utf-8')).hexdigest() -def integral_name(original_form: ufl.form.Form, integral_type: str, form_id: int, integral_id: int, prefix: str) -> str: +def integral_name(original_form: ufl.form.Form, integral_type: str, form_id: int, integral_id: int, prefix: typing.Optional[str]) -> str: """Compute signature for an integral in an ufl form""" sig = compute_signature([original_form], str((prefix, integral_type, form_id, integral_id))) return f"integral_{sig}" -def form_name(original_form: ufl.form.Form, form_id: int, prefix: str) -> str: +def form_name(original_form: ufl.form.Form, form_id: int, prefix: typing.Optional[str]) -> str: sig = compute_signature([original_form], str((prefix, form_id))) return f"form_{sig}" -def finite_element_name(ufl_element: ufl.FiniteElementBase, prefix: str) -> str: +def finite_element_name(ufl_element: ufl.FiniteElementBase, prefix: typing.Optional[str]) -> str: assert isinstance(ufl_element, ufl.FiniteElementBase) sig = compute_signature([ufl_element], prefix) return f"element_{sig}" -def dofmap_name(ufl_element: ufl.FiniteElementBase, prefix: str) -> str: +def dofmap_name(ufl_element: ufl.FiniteElementBase, prefix: typing.Optional[str]) -> str: assert isinstance(ufl_element, ufl.FiniteElementBase) sig = compute_signature([ufl_element], prefix) return f"dofmap_{sig}" -def expression_name(expression: ufl.core.expr.Expr, prefix: str) -> str: +def expression_name(expression: ufl.core.expr.Expr, prefix: typing.Optional[str]) -> str: assert isinstance(expression[0], ufl.core.expr.Expr) sig = compute_signature([expression], prefix) return f"expression_{sig}" From 29ad3379b9a686475089d131b516646e1202b4e9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B8rgen=20Dokken?= Date: Tue, 29 Mar 2022 10:27:16 +0000 Subject: [PATCH 9/9] Flake8 --- ffcx/naming.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/ffcx/naming.py b/ffcx/naming.py index 252aede24..585015b67 100644 --- a/ffcx/naming.py +++ b/ffcx/naming.py @@ -64,7 +64,8 @@ def compute_signature(ufl_objects, tag): return hashlib.sha1(string.encode('utf-8')).hexdigest() -def integral_name(original_form: ufl.form.Form, integral_type: str, form_id: int, integral_id: int, prefix: typing.Optional[str]) -> str: +def integral_name(original_form: ufl.form.Form, integral_type: str, form_id: int, integral_id: int, + prefix: typing.Optional[str]) -> str: """Compute signature for an integral in an ufl form""" sig = compute_signature([original_form], str((prefix, integral_type, form_id, integral_id))) return f"integral_{sig}"