• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

FEniCS / ffcx / 20003645541

07 Dec 2025 11:37AM UTC coverage: 84.457% (+1.4%) from 83.044%
20003645541

Pull #801

github

web-flow
Update test/poisson.py

Co-authored-by: Michal Habera <michal.habera@gmail.com>
Pull Request #801: Add `numba` backend

340 of 368 new or added lines in 22 files covered. (92.39%)

6 existing lines in 3 files now uncovered.

4059 of 4806 relevant lines covered (84.46%)

0.84 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

95.45
/ffcx/codegeneration/C/integrals.py
1
# Copyright (C) 2015-2021 Martin Sandve Alnæs, Michal Habera, Igor Baratta
2
#
3
# This file is part of FFCx. (https://www.fenicsproject.org)
4
#
5
# SPDX-License-Identifier:    LGPL-3.0-or-later
6
"""Generate UFC code for an integral."""
7

8
import logging
1✔
9
import sys
1✔
10

11
import basix
1✔
12
import numpy as np
1✔
13
from numpy import typing as npt
1✔
14

15
from ffcx.codegeneration.backend import FFCXBackend
1✔
16
from ffcx.codegeneration.C import integrals_template as ufcx_integrals
1✔
17
from ffcx.codegeneration.C.implementation import Formatter
1✔
18
from ffcx.codegeneration.integral_generator import IntegralGenerator
1✔
19
from ffcx.codegeneration.utils import dtype_to_c_type, dtype_to_scalar_dtype
1✔
20
from ffcx.ir.representation import IntegralIR
1✔
21

22
logger = logging.getLogger("ffcx")
1✔
23

24

25
def generator(
1✔
26
    ir: IntegralIR, domain: basix.CellType, options: dict[str, int | float | npt.DTypeLike]
27
):
28
    """Generate C code for an integral."""
29
    logger.info("Generating code for integral:")
1✔
30
    logger.info(f"--- type: {ir.expression.integral_type}")
1✔
31
    logger.info(f"--- name: {ir.expression.name}")
1✔
32

33
    factory_name = f"{ir.expression.name}_{domain.name}"
1✔
34

35
    # Format declaration
36
    declaration = ufcx_integrals.declaration.format(factory_name=factory_name)
1✔
37

38
    # Create FFCx backend
39
    backend = FFCXBackend(ir, options)
1✔
40

41
    # Configure kernel generator
42
    ig = IntegralGenerator(ir, backend)
1✔
43

44
    # Generate code ast for the tabulate_tensor body
45
    parts = ig.generate(domain)
1✔
46

47
    # Format code as string
48
    CF = Formatter(options["scalar_type"])  # type: ignore
1✔
49
    body = CF.format(parts)
1✔
50

51
    # Generate generic FFCx code snippets and add specific parts
52
    code = {}
1✔
53

54
    if len(ir.enabled_coefficients) > 0:
1✔
55
        values = ", ".join("1" if i else "0" for i in ir.enabled_coefficients)
1✔
56
        sizes = len(ir.enabled_coefficients)
1✔
57
        code["enabled_coefficients_init"] = (
1✔
58
            f"bool enabled_coefficients_{ir.expression.name}_{domain.name}[{sizes}] = {{{values}}};"
59
        )
60
        code["enabled_coefficients"] = f"enabled_coefficients_{ir.expression.name}_{domain.name}"
1✔
61
    else:
62
        code["enabled_coefficients_init"] = ""
1✔
63
        code["enabled_coefficients"] = "NULL"
1✔
64

65
    code["tabulate_tensor"] = body
1✔
66

67
    code["tabulate_tensor_float32"] = ".tabulate_tensor_float32 = NULL,"
1✔
68
    code["tabulate_tensor_float64"] = ".tabulate_tensor_float64 = NULL,"
1✔
69
    if sys.platform.startswith("win32"):
1✔
UNCOV
70
        code["tabulate_tensor_complex64"] = ""
×
UNCOV
71
        code["tabulate_tensor_complex128"] = ""
×
72
    else:
73
        code["tabulate_tensor_complex64"] = ".tabulate_tensor_complex64 = NULL,"
1✔
74
        code["tabulate_tensor_complex128"] = ".tabulate_tensor_complex128 = NULL,"
1✔
75
    np_scalar_type = np.dtype(options["scalar_type"]).name  # type: ignore
1✔
76
    code[f"tabulate_tensor_{np_scalar_type}"] = (
1✔
77
        f".tabulate_tensor_{np_scalar_type} = tabulate_tensor_{factory_name},"
78
    )
79

80
    assert ir.expression.coordinate_element_hash is not None
1✔
81
    implementation = ufcx_integrals.factory.format(
1✔
82
        factory_name=factory_name,
83
        enabled_coefficients=code["enabled_coefficients"],
84
        enabled_coefficients_init=code["enabled_coefficients_init"],
85
        tabulate_tensor=code["tabulate_tensor"],
86
        needs_facet_permutations="true" if ir.expression.needs_facet_permutations else "false",
87
        scalar_type=dtype_to_c_type(options["scalar_type"]),  # type: ignore
88
        geom_type=dtype_to_c_type(dtype_to_scalar_dtype(options["scalar_type"])),  # type: ignore
89
        coordinate_element_hash=f"UINT64_C({ir.expression.coordinate_element_hash})",
90
        tabulate_tensor_float32=code["tabulate_tensor_float32"],
91
        tabulate_tensor_float64=code["tabulate_tensor_float64"],
92
        tabulate_tensor_complex64=code["tabulate_tensor_complex64"],
93
        tabulate_tensor_complex128=code["tabulate_tensor_complex128"],
94
        domain=int(domain),
95
    )
96

97
    # TODO: Check that no keys are redundant or have been missed (ref. numba/integrals.py)
98

99
    return declaration, implementation
1✔
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc