Skip to content

Cross-platform golden-record drift in Lambda_A traced to adaptive quadrature + libm (env, not code) #90

Description

@krystophny

Summary

Cross-platform golden-record drift in Lambda_A (~4.6e-7 relative) is caused by adaptive quadrature in src/utils/integrate.f90 amplifying ULP-level libm differences. A three-version comparison confirms the drift is purely environment, not code, and reproduces the macOS-vs-Linux symptom already described in #88. The open question is whether to widen the tolerance (#88) or make the quadrature reproducible, which connects to the libneo/fortnum quadrature-replacement work.

What was measured

The golden-record corpus build (plasma/proj/golden/rabe) ran the landremanpaul2021_QH_lowres case three ways and compared with compare_golden.py:

  • A: the committed historical test/golden/expected/rabe.nc (original binary, original build environment).
  • B: the same source rebuilt at commit a8c3b21 with the current toolchain (gfortran 14.2.0).
  • C: current main (1e5ef76), current toolchain.

Result:

  • A vs B (compiler/environment): Lambda_A 4.6e-7, remainder 6.0e-8, Lambda_S 3.6e-9, lambda_LC_bB 2.8e-9, nu_star_crit 1.7e-10; s_tor, split_maxima, R exact.
  • B vs C (code change a8c3b21 -> main): all nine variables bitwise identical.
  • A vs C: identical to A vs B.

So all observed drift between the historical record and a current build is environment. No code change between a8c3b21 and main moves any output. The Lambda_A 4.6e-7 and the ~3e-9 floor match #88 exactly ("~4e-7 for Lambda_A through libm and adaptive-quadrature differences").

Mechanism

Lambda_A, nu_star_crit, and remainder are the variables that go through integrate_1d in src/utils/integrate.f90, which calls quadpack dqag (globally adaptive subdivision, jacobwilliams/quadpack via cmake/quadpack.cmake). The integrand is evaluated through libneo field/spline routines (pinned at libneo 752aae9c in cmake/libneo.cmake). Adaptive subdivision turns ULP-level libm and field-evaluation differences into a different sequence of panels, so the error lands two orders of magnitude above the 3e-9 floor of the non-quadrature outputs. The 3e-9 outputs are direct arithmetic; the 4.6e-7 outputs are the adaptive integrals.

This is the same class of non-reproducibility the libneo modularization and fortnum effort target (itpplasma/libneo#291): adaptive quadrature and special functions whose results depend on the math library and link configuration.

Why this is worth more than a tolerance bump

#88 widens the golden tolerance to 1e-6 and #86 reverted both that and the quadpack link change (#87). Widening to 1e-6 still catches algorithmic regressions (which start at 1e-3), but it hides whether Lambda_A's 4.6e-7 is benign rounding or an ill-conditioned integrand. The two-order gap between the quadrature outputs and the floor is the signal worth checking: a near-singular integrand plus a loose epsabs/epsrel in dqag would produce exactly this, and would also explain the macOS reproduction failures.

Concrete questions:

  1. Is the Lambda_A integrand near-singular at the substitution boundaries (integrate_1d_substituted)? What epsabs/epsrel/limit does dqag use, and does tightening them shrink the cross-platform spread?
  2. Does pinning vs bumping libneo (the field/spline side of the integrand) change Lambda_A independently of the quadrature? Test with LIBNEO_BRANCH against the pinned 752aae9c.
  3. Would a fixed-order or reproducible-adaptive quadrature (a candidate for the fortnum quadrature library, Umbrella: replace avoidable numerical dependencies with AD-ready fortnum libneo#291/#288) make the golden record bit-reproducible across platforms, removing the need for the 1e-6 band-aid?

Suggested split

Use the golden-record corpus to separate the two regimes instead of one tolerance:

  • Same-machine ref-vs-cur (the gr-runner build_ref vs build_cur model) stays strict (1e-10): catches real code changes to machine precision.
  • Cross-platform / cross-compiler check runs at the looser tolerance, documented as the libm + adaptive-quadrature floor, until the quadrature is made deterministic.

References

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions