Repository navigation
JIT: compile kernels with -fno-math-errno by default (#834) - #835
Merged
Merged
Conversation
gcc's default -fmath-errno makes each sqrt, pow and exp call a side effect, so a repeated call with the same argument is computed again. The kernels never read errno. With the flag, a viscoplastic Jacobian's callbacks cost about a third as much on gcc 14 (8.2 to 2.8 microseconds per quadrature point), and the assembled residual and Jacobian, the solutions and the iteration counts are bit-identical (measured on Linux for #823). Apple clang never sets errno, so this is the macOS behaviour already. The flag is prepended with -std=c99, so a UW3_JIT_CFLAGS override, which replaces the optimisation flags, keeps it. The flags are in the generated setup.py, which is part of the cache key: each cached module recompiles once. test_0025 pins the compile arguments, with and without an override. Underworld development team with AI support from Claude Code
- nvc rejects -fno-math-errno (and -g0). Always prepending the flag left a JIT on such a compiler with no way to compile; it is now one of the default flags, which UW3_JIT_CFLAGS replaces. -std=c99 stays fixed. - The comment names clang on Linux as well as gcc and states the bit-identity for the C SymPy prints. - jit-cache.md documents UW3_JIT_CFLAGS. - The bundle capture shared with test_0021 is a conftest fixture, jit_bundles. - test_0025 starts at tier C, as TESTING-RELIABILITY-SYSTEM.md asks of a new test. Underworld development team with AI support from Claude Code
Member
Author
Adversarial review (before opening), and what we didFindings
Attacks that found nothing
Issues: #834 is closed by this PR. #752 is untouched: the flags add no rank-dependent input. |
Contributor
There was a problem hiding this comment.
🟡 Changes recommended
The regression test compiles unsupported defaults on nvc and is incorrectly excluded from gating as Tier C.
2 open findings
What changed in this PR
Adds -fno-math-errno to default JIT kernel flags to improve Linux performance while preserving overrides.
Changes:
- Updates default JIT compile flags.
- Documents
UW3_JIT_CFLAGS. - Adds shared bundle capture and regression tests.
| File | Description |
|---|---|
src/underworld3/utilities/_jitextension.py |
Adds the new default flag. |
docs/developer/subsystems/jit-cache.md |
Documents compile-flag overrides. |
tests/conftest.py |
Adds shared JIT bundle capture. |
tests/test_0021_jit_finds_petsc_headers.py |
Reuses the shared fixture. |
tests/test_0025_jit_compile_flags.py |
Tests default and overridden flags. |
🧠 Review effort: Balanced
Give feedback about Copilot approvals in this survey to enter a drawing for a $150 gift card.
Comment on lines
+20
to
+30
| def _compile_args(bundles): | ||
| """The ``extra_compile_args`` of the bundle a small integral generates.""" | ||
| mesh = uw.meshing.UnstructuredSimplexBox( | ||
| minCoords=(0.0, 0.0), maxCoords=(1.0, 1.0), cellSize=0.5) | ||
| # PETSc integrates only on a mesh that carries a field | ||
| uw.discretisation.MeshVariable("U0025", mesh, 1, degree=1) | ||
| uw.maths.Integral(mesh, 1.0 + mesh.X[0]).evaluate() | ||
| assert bundles, "no JIT bundle was generated" | ||
| match = re.search(r"extra_compile_args=(\[.*?\])", bundles[-1]["setup.py"]) | ||
| assert match, bundles[-1]["setup.py"] | ||
| return ast.literal_eval(match.group(1)) |
|
|
||
| import underworld3 as uw | ||
|
|
||
| pytestmark = [pytest.mark.level_1, pytest.mark.tier_c] |
This was referenced Oct 10, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.


Closes #834.
What changes
The JIT's default compile flags for the pointwise kernels become
-O3 -g0 -fno-math-errno, after the fixed-std=c99.UW3_JIT_CFLAGSstill replaces the defaults, so a compiler that rejects a flag can drop it: nvc rejects both-g0and-fno-math-errno.docs/developer/subsystems/jit-cache.mdnow documentsUW3_JIT_CFLAGS.Why
gcc, and clang on Linux, default to
-fmath-errno. Under it,sqrt,powandexpmay seterrno, so the compiler treats each call as a side effect and cannot merge a repeated call with the same argument. Our kernels never readerrno. clang targeting macOS already defaults to-fno-math-errno, so this makes Linux kernels behave as macOS ones do.Measured on Linux (conda-forge gcc 14.3, a loaded 2× Xeon Gold 6240R), as the cost of the law's callbacks per quadrature point in one Jacobian assembly:
-fno-math-errnoWith and without the flag, these are bit-identical on both fixtures:
The generated C is unchanged. The flags are part of the generated
setup.py, which is in the cache key, so every cached module recompiles once.Tests
test_0025_jit_compile_flags.pypins the compile arguments, with the defaults and with an override. The default case fails ondevelopment, where-fno-math-errnois missing. The bundle capture thattest_0021already used is now a conftest fixture,jit_bundles, which both tests share.The new test is marked tier C, as
TESTING-RELIABILITY-SYSTEM.mdasks of a new test. Recent new tests (test_0021–test_0023) went straight to tier A, so either that practice or the document is out of date. A tier C test does not gate CI. For a pin like this one, promoting it to A is a one-line change once reviewed.Review
The adversarial review is posted below as a comment.
Underworld development team with AI support from Claude Code