Skip to content

Single-precision (fp32) build support#5033

Open
hardik-corintis wants to merge 19 commits into
firedrakeproject:mainfrom
Corintis:fp32-support
Open

Single-precision (fp32) build support#5033
hardik-corintis wants to merge 19 commits into
firedrakeproject:mainfrom
Corintis:fp32-support

Conversation

@hardik-corintis
Copy link
Copy Markdown
Contributor

@hardik-corintis hardik-corintis commented Apr 15, 2026

fixes #3040

Description

Adds single-precision (fp32) build support. Firedrake can now run on a PETSc installation compiled with --with-precision=single. The approach mirrors complex mode: precision is detected at import time from PETSc's build variables and flows through from there.

AI disclosure: Parts of this PR were developed with assistance from Claude (Anthropic). All changes have been reviewed, tested locally, and are fully understood by the author.

Prerequisite

Requires https://gitlab.com/petsc/petsc/-/merge_requests/9272 (petsc4py: handle PETSC_DOUBLE in DMSwarm.getField). Without it, DMSwarm.getField() raises AssertionError on fp32 builds because PETSC_DOUBLE is not mapped to a numpy dtype in the single-precision case where PETSC_REAL != PETSC_DOUBLE.

Changes

scripts/firedrake-configure

  • Adds --arch single / ScalarType.SINGLE; passes --with-precision=single to PETSc configure; excludes fftw and suitesparse (no fp32 support in those libraries)

tsfc/parameters.py, tsfc/loopy.py, tsfc/kernel_interface/common.py, tsfc/ufl_utils.py

  • scalar_type / scalar_type_c derived from PETSc precision at import time; constant initializers cast to the kernel scalar dtype

Core (evaluate.h, locate.c, pointquery_utils.py, pointeval_utils.py, mg/kernels.py)

  • Replace hardcoded double / int with PetscReal / PetscInt in generated C code
  • Convergence epsilon in point query tightened to 1e-6 in fp32 mode vs 1e-12 in fp64, to stay within single-precision range

firedrake/mesh.py, firedrake/utility_meshes.py

  • Vertex coordinates and reference-cell distances use PETSc.RealType; physical coordinate arrays for rtree and DMSwarmPIC_coor remain float64 (required by the rtree C API and PETSc swarm internals)

firedrake/function.py

  • Point evaluation coerces coordinates to float64 regardless of ScalarType, for geometric robustness in cell location

firedrake/assemble.py, firedrake/functionspaceimpl.py, pyop2/codegen/builder.py

  • Replace dtype=int with dtype=IntType in numpy.prod and array allocation calls

firedrake/utils.py

  • Adds single_mode boolean flag (mirrors complex_mode)

Tests

  • Adds @pytest.mark.skipsingle marker for tests incompatible with fp32
  • tests/firedrake/conftest.py: registers the marker and wires it up
  • Skips a small set of tests that require double-precision accuracy (test_locate_cell, test_interpolate_cross_mesh[extrudedcube], test_parallel_high_order_location)

.github/workflows/core.yml

  • Adds single to the CI matrix alongside default and complex

Known limitations

test_parallel_high_order_location is skipped in fp32: high-order cell location in a warped mesh requires double-precision accuracy that fp32 cannot provide at tolerance=0.0001.

@hardik-corintis hardik-corintis marked this pull request as draft April 15, 2026 14:13
@connorjward
Copy link
Copy Markdown
Contributor

Thanks for this.

adds --arch single

What about single+complex? Isn't that a valid configuration?

PETSc version bump (v3.24.5 → v3.25.0)

This isn't necessary. That's all going to be taken care of when I release the next major version in the next 24 hours.

Fix needed upstream in petsc4py: if ctype == PETSC_DOUBLE: typenum = NPY_DOUBLE in petsc4py/PETSc/DMSwarm.pyx.

Can you get this fixed upstream? Clearly Claude already knows what to do.

@hardik-corintis hardik-corintis marked this pull request as ready for review May 10, 2026 00:18
@hardik-corintis
Copy link
Copy Markdown
Contributor Author

Thanks for this.

adds --arch single

What about single+complex? Isn't that a valid configuration?

Added ScalarType.SINGLE_COMPLEX (--arch single-complex) to firedrake-configure for all four platform targets: single_mode (from PETSC_PRECISION) and complex_mode (from PETSC_SCALAR) are detected independently, and ScalarType already resolves to numpy.complex64 for a single+complex build.

PETSc version bump (v3.24.5 → v3.25.0)

This isn't necessary. That's all going to be taken care of when I release the next major version in the next 24 hours.

Removed from the PR description — thanks.

Fix needed upstream in petsc4py: if ctype == PETSC_DOUBLE: typenum = NPY_DOUBLE in petsc4py/PETSc/DMSwarm.pyx.

Can you get this fixed upstream? Clearly Claude already knows what to do.

Opened a PR here: https://gitlab.com/petsc/petsc/-/merge_requests/9272

Copy link
Copy Markdown
Contributor

@connorjward connorjward left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've just looked at the CI/install related side of this (at a glance everything else seems pretty good).

We just have to be careful about adding new test builds to Firedrake. I will try and figure out a solution soon.

fail-fast: false
matrix:
arch: [default, complex]
arch: [default, complex, single]
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This will add an extra 50% to the load on our CI runners. I will try and redesign our CI system so that we can reasonably support extra configurations like single precision.

],
),

(OS.UBUNTU_2404_AARCH64, ScalarType.SINGLE, GPUPlatform.NO_GPU): Arch(
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Because we don't test aarch on CI apart from the basic real+complex we shouldn't be adding them here. They can be added as 'Community Archs' in the dict below.

The same applies to macOS.

This might be easier once #5085 is merged as that adds our first 'community' options.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Support precisions other than double

2 participants