diff --git a/ffcx/codegeneration/C/form.py b/ffcx/codegeneration/C/form.py index 471bc9afe..b5cef225b 100644 --- a/ffcx/codegeneration/C/form.py +++ b/ffcx/codegeneration/C/form.py @@ -67,14 +67,16 @@ def generator(ir, options): d["constant_names_init"] = "" d["constant_names"] = "NULL" - if len(ir.finite_elements) > 0: - d["finite_elements"] = f"finite_elements_{ir.name}" - values = ", ".join(f"{el}" for el in ir.finite_elements) - sizes = len(ir.finite_elements) - d["finite_elements_init"] = f"long int finite_elements_{ir.name}[{sizes}] = {{{values}}};" + if len(ir.finite_element_hashes) > 0: + d["finite_element_hashes"] = f"finite_element_hashes_{ir.name}" + values = ", ".join(f"{0 if el is None else el}ull" for el in ir.finite_element_hashes) + sizes = len(ir.finite_element_hashes) + d["finite_element_hashes_init"] = ( + f"uint64_t finite_element_hashes_{ir.name}[{sizes}] = {{{values}}};" + ) else: - d["finite_elements"] = "NULL" - d["finite_elements_init"] = "" + d["finite_element_hashes"] = "NULL" + d["finite_element_hashes_init"] = "" integrals = [] integral_ids = [] diff --git a/ffcx/codegeneration/C/form_template.py b/ffcx/codegeneration/C/form_template.py index 011ee583b..ad8b81abf 100644 --- a/ffcx/codegeneration/C/form_template.py +++ b/ffcx/codegeneration/C/form_template.py @@ -19,7 +19,7 @@ // Code for form {factory_name} {original_coefficient_position_init} -{finite_elements_init} +{finite_element_hashes_init} {form_integral_offsets_init} {form_integrals_init} {form_integral_ids_init} @@ -39,7 +39,7 @@ .coefficient_name_map = {coefficient_names}, .constant_name_map = {constant_names}, - .finite_elements = {finite_elements}, + .finite_element_hashes = {finite_element_hashes}, .form_integrals = {form_integrals}, .form_integral_ids = {form_integral_ids}, diff --git a/ffcx/codegeneration/C/integrals.py b/ffcx/codegeneration/C/integrals.py index d301eceda..9489ce53f 100644 --- a/ffcx/codegeneration/C/integrals.py +++ b/ffcx/codegeneration/C/integrals.py @@ -67,6 +67,8 @@ def generator(ir: IntegralIR, options): np_scalar_type = np.dtype(options["scalar_type"]).name code[f"tabulate_tensor_{np_scalar_type}"] = f"tabulate_tensor_{factory_name}" + element_hash = 0 if ir.coordinate_element_hash is None else ir.coordinate_element_hash + implementation = ufcx_integrals.factory.format( factory_name=factory_name, enabled_coefficients=code["enabled_coefficients"], @@ -75,7 +77,7 @@ def generator(ir: IntegralIR, options): needs_facet_permutations="true" if ir.needs_facet_permutations else "false", scalar_type=dtype_to_c_type(options["scalar_type"]), geom_type=dtype_to_c_type(dtype_to_scalar_dtype(options["scalar_type"])), - coordinate_element=f"{ir.coordinate_element}", + coordinate_element_hash=f"{element_hash}ull", tabulate_tensor_float32=code["tabulate_tensor_float32"], tabulate_tensor_float64=code["tabulate_tensor_float64"], tabulate_tensor_complex64=code["tabulate_tensor_complex64"], diff --git a/ffcx/codegeneration/C/integrals_template.py b/ffcx/codegeneration/C/integrals_template.py index 65884e801..937f759ae 100644 --- a/ffcx/codegeneration/C/integrals_template.py +++ b/ffcx/codegeneration/C/integrals_template.py @@ -31,7 +31,7 @@ .tabulate_tensor_complex64 = {tabulate_tensor_complex64}, .tabulate_tensor_complex128 = {tabulate_tensor_complex128}, .needs_facet_permutations = {needs_facet_permutations}, - .coordinate_element = {coordinate_element}, + .coordinate_element_hash = {coordinate_element_hash}, }}; // End of code for integral {factory_name} diff --git a/ffcx/codegeneration/ufcx.h b/ffcx/codegeneration/ufcx.h index f50b793e6..38895c9b0 100644 --- a/ffcx/codegeneration/ufcx.h +++ b/ffcx/codegeneration/ufcx.h @@ -127,8 +127,8 @@ extern "C" ufcx_tabulate_tensor_complex128* tabulate_tensor_complex128; bool needs_facet_permutations; - /// Get the coordinate element associated with the geometry of the mesh. - long int coordinate_element; + /// Get the hash of the coordinate element associated with the geometry of the mesh. + uint64_t coordinate_element_hash; } ufcx_integral; typedef struct ufcx_expression @@ -223,7 +223,7 @@ extern "C" /// /// @param i Argument number if 0 <= i < r Coefficient number j = i /// - r if r + j <= i < r + n - long int* finite_elements; + uint64_t* finite_element_hashes; /// List of cell, interior facet and exterior facet integrals ufcx_integral** form_integrals; diff --git a/ffcx/ir/representation.py b/ffcx/ir/representation.py index 35a7d0cad..0f61329fc 100644 --- a/ffcx/ir/representation.py +++ b/ffcx/ir/representation.py @@ -49,7 +49,7 @@ class FormIR(typing.NamedTuple): original_coefficient_position: list[int] coefficient_names: list[str] constant_names: list[str] - finite_elements: list[int] + finite_element_hashes: list[int] integral_names: dict[str, list[str]] subdomain_ids: dict[str, list[int]] @@ -78,7 +78,7 @@ class IntegralIR(typing.NamedTuple): integrand: dict[QuadratureRule, dict] name: str needs_facet_permutations: bool - coordinate_element: int + coordinate_element_hash: int class ExpressionIR(typing.NamedTuple): @@ -127,7 +127,7 @@ def compute_ir( # Compute object names # NOTE: This is done here for performance reasons, because repeated calls # within each IR computation would be expensive due to UFL signature computations - finite_element_hashes = {e: hash(e) for e in analysis.unique_elements} + finite_element_hashes = {e: e.basix_hash() for e in analysis.unique_elements} integral_names = {} form_names = {} for fd_index, fd in enumerate(analysis.form_data): @@ -221,7 +221,9 @@ def _compute_integral_ir( "rank": form_data.rank, "entitytype": entitytype, "enabled_coefficients": itg_data.enabled_coefficients, - "coordinate_element": finite_element_hashes[itg_data.domain.ufl_coordinate_element()], + "coordinate_element_hash": finite_element_hashes[ + itg_data.domain.ufl_coordinate_element() + ], } # Get element space dimensions @@ -449,7 +451,7 @@ def _compute_form_ir( ir["original_coefficient_position"] = form_data.original_coefficient_positions - ir["finite_elements"] = [ + ir["finite_element_hashes"] = [ finite_element_hashes[e] for e in form_data.argument_elements + form_data.coefficient_elements ]