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

FEniCS / ffcx / 19770323370

28 Nov 2025 05:22PM UTC coverage: 77.933% (-5.1%) from 83.044%
19770323370

Pull #801

github

schnellerhase
Try with Path
Pull Request #801: Add `numba` backend

55 of 359 new or added lines in 21 files covered. (15.32%)

85 existing lines in 4 files now uncovered.

3740 of 4799 relevant lines covered (77.93%)

0.78 hits per line

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

95.35
/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

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

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

23

24
def generator(ir: IntegralIR, domain: basix.CellType, options):
1✔
25
    """Generate C code for an integral."""
26
    logger.info("Generating code for integral:")
1✔
27
    logger.info(f"--- type: {ir.expression.integral_type}")
1✔
28
    logger.info(f"--- name: {ir.expression.name}")
1✔
29

30
    factory_name = f"{ir.expression.name}_{domain.name}"
1✔
31

32
    # Format declaration
33
    declaration = ufcx_integrals.declaration.format(factory_name=factory_name)
1✔
34

35
    # Create FFCx backend
36
    backend = FFCXBackend(ir, options)
1✔
37

38
    # Configure kernel generator
39
    ig = IntegralGenerator(ir, backend)
1✔
40

41
    # Generate code ast for the tabulate_tensor body
42
    parts = ig.generate(domain)
1✔
43

44
    # Format code as string
45
    CF = Formatter(options["scalar_type"])
1✔
46
    body = CF.format(parts)
1✔
47

48
    # Generate generic FFCx code snippets and add specific parts
49
    code = {}
1✔
50

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

62
    code["tabulate_tensor"] = body
1✔
63

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

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

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

96
    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