From 1cac244259bb10a4fa149533dbae35b55e87f0d6 Mon Sep 17 00:00:00 2001 From: Richie Cahill Date: Fri, 18 Sep 2026 12:09:42 -0400 Subject: [PATCH] fix(scipy): allow rounding differences in STFT tests Keep STFT tests enabled with precision-appropriate tolerances for x86-64-v3 builds. Add the override under overlays/patches/scipy and remove the commented-out test exclusions. --- overlays/patches/default.nix | 6 +++ overlays/patches/scipy/default.nix | 5 ++ .../patches/scipy/stft-test-tolerances.patch | 51 +++++++++++++++++++ overlays/test-exclusions.nix | 10 ---- 4 files changed, 62 insertions(+), 10 deletions(-) create mode 100644 overlays/patches/scipy/default.nix create mode 100644 overlays/patches/scipy/stft-test-tolerances.patch diff --git a/overlays/patches/default.nix b/overlays/patches/default.nix index 1ffc6e6..df32fe5 100644 --- a/overlays/patches/default.nix +++ b/overlays/patches/default.nix @@ -1,3 +1,9 @@ _final: prev: { gnutls = import ./gnutls { inherit (prev) gnutls; }; + + pythonPackagesExtensions = prev.pythonPackagesExtensions ++ [ + (_pythonFinal: pythonPrev: { + scipy = import ./scipy { inherit (pythonPrev) scipy; }; + }) + ]; } diff --git a/overlays/patches/scipy/default.nix b/overlays/patches/scipy/default.nix new file mode 100644 index 0000000..a6a3b5d --- /dev/null +++ b/overlays/patches/scipy/default.nix @@ -0,0 +1,5 @@ +{ scipy }: +scipy.overridePythonAttrs (old: { + # Keep the STFT tests enabled with tolerances for x86-64-v3 rounding. + patches = (old.patches or [ ]) ++ [ ./stft-test-tolerances.patch ]; +}) diff --git a/overlays/patches/scipy/stft-test-tolerances.patch b/overlays/patches/scipy/stft-test-tolerances.patch new file mode 100644 index 0000000..016bf32 --- /dev/null +++ b/overlays/patches/scipy/stft-test-tolerances.patch @@ -0,0 +1,51 @@ +Subject: [PATCH] signal: allow floating-point rounding in STFT tests + +Keep the STFT tests enabled for x86-64-v3 builds. Allow two float32 +epsilons of relative error when comparing inverse-STFT implementations; +float64 and the existing i686 override remain unchanged. Allow one +float64 epsilon of absolute error in all three scaling round trips, +which otherwise require exact zeros (observed residual: 4e-17 for a +signal with amplitude 2). + +Upstream issue: https://github.com/scipy/scipy/issues/25488 + +--- a/scipy/signal/tests/_scipy_spectral_test_shim.py ++++ b/scipy/signal/tests/_scipy_spectral_test_shim.py +@@ -294,7 +294,7 @@ + + # Adapted tolerances to account for resolution loss: + atol = np.finfo(x.dtype).resolution*2 # instead of default atol = 0 +- rtol = 1e-7 # default for np.allclose() ++ rtol = max(1e-7, 2 * np.finfo(x.dtype).eps) + + # Relax atol on 32-Bit platforms a bit to pass CI tests. + # - Not clear why there are discrepancies (in the FFT maybe?) +--- a/scipy/signal/tests/test_spectral.py ++++ b/scipy/signal/tests/test_spectral.py +@@ -2044,7 +2044,7 @@ + + # Test round trip: + x1 = istft(Zs, boundary=True, scaling='spectrum')[1] +- assert_allclose(x1, x) ++ assert_allclose(x1, x, atol=np.finfo(x.dtype).eps) + + # For a Hann-windowed 256 sample length FFT, we expect a peak at + # frequency 64 (since it is 1/4 the length of X) with a height of 1 +@@ -2074,7 +2074,7 @@ + + # Test round trip: + x1 = istft(Zp, input_onesided=False, boundary=True, scaling='psd')[1] +- assert_allclose(x1, x) ++ assert_allclose(x1, x, atol=np.finfo(x.dtype).eps) + + # The power of the one-sided psd-scaled STFT can be determined + # analogously (note that the two sides are not of equal shape): +@@ -2094,7 +2094,7 @@ + + # Test round trip: + x1 = istft(Zp0, input_onesided=True, boundary=True, scaling='psd')[1] +- assert_allclose(x1, x) ++ assert_allclose(x1, x, atol=np.finfo(x.dtype).eps) + + + class TestSampledSpectralRepresentations: diff --git a/overlays/test-exclusions.nix b/overlays/test-exclusions.nix index ab8089c..48cda46 100644 --- a/overlays/test-exclusions.nix +++ b/overlays/test-exclusions.nix @@ -75,16 +75,6 @@ _final: prev: { ''; }); - # scipy = pythonPrev.scipy.overridePythonAttrs (old: { - # # x86-64-v3 FFT implementations produce rounding differences outside - # # these tests' strict tolerances. We accept the numerical-precision - # # risk for our workloads. - # disabledTests = (old.disabledTests or [ ]) ++ [ - # "test_roundtrip_float32" - # "test_roundtrip_scaling" - # ]; - # }); - sentry-sdk = pythonPrev.sentry-sdk.overridePythonAttrs (old: { # This test globally mocks threading.current_thread while another # thread is running. On Python 3.14, Thread.join can race with that