From 5178b7b871a83c18bf4196e8be67f061ed2f835e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gonzalo=20Tornar=C3=ADa?= Date: Mon, 22 Nov 2021 19:24:50 -0300 Subject: [PATCH] sympow: do not mess with fpu control word if possible Also: add basic tests to detect fpu miscompilation. The program sets the fpu to 53 bit mode to get consistent results. It turns out that doing this on musl breaks fmt_fp (-> printf) which uses long double to format floats. Note this is an issue even on 64 bit musl, although setting fpu to 53 bits is unnecessary on 64 bits because of the default -mfpmath=sse. The way Configure works: it tries different combinations of flags which exercise different methods to change the fpu control word until one works, meaning doubles are effectively 53 bits. The fix here is to try first NOT touching the fpu control word. On x86_64 using the default -mfpmath=sse this will succeed bypassing all fpucw modification. For i686 using -mfpmath=387 (always if sse2 not available) the code will fall back to changing the fpu control word as before. Since this is not a problem for glibc, everything still works. I expect i686-musl to still be broken, but we don't support that arch. A simple way to test the bug on musl is to run $ sympow -curve '[0,0,0,0,1]' -analrank ... Analytic Rank is 0 : L-value 7.01091e-01 When the fpucw is changed, on musl this prints "7.01092e-01" instead. The actual value computed to 128 bits with pari is: $ echo 'elllseries(ellinit([0,0,0,0,1]),1)' | gp -q 0.70109105266272713058750953952514706773 so the glibc output is the correct one. Again: what is broken is not computing but printing, as fmt_fp in musl uses long double, which means messing with fpu control word breaks it. This is important since sagemath parses sympow output. This affects sagemath doctests as in $ sage -t src/sage/lfunctions/sympow.py ... (3 failures) After this commit, the doctest in question passes on the 3 supported archs. --- srcpkgs/sympow/files/test | 51 ++++++++++++++++++ srcpkgs/sympow/files/test.out | 54 +++++++++++++++++++ .../first-try-without-messing-the-fpucw.patch | 14 +++++ srcpkgs/sympow/template | 10 +++- 4 files changed, 128 insertions(+), 1 deletion(-) create mode 100644 srcpkgs/sympow/files/test create mode 100644 srcpkgs/sympow/files/test.out create mode 100644 srcpkgs/sympow/patches/first-try-without-messing-the-fpucw.patch diff --git a/srcpkgs/sympow/files/test b/srcpkgs/sympow/files/test new file mode 100644 index 000000000000..5892937085f2 --- /dev/null +++ b/srcpkgs/sympow/files/test @@ -0,0 +1,51 @@ +#! /bin/sh + +# Quick minimal test for sympow +# +# Compute modular degree and analytic rank for some curves so we check +# that it works and also that fpu arithmetic and output are ok + +# setup sympow to run from cwd +export SYMPOW_PKGDATADIR=. +export SYMPOW_PKGLIBDIR=. +mkdir -p sympow_cache +export SYMPOW_CACHEDIR=sympow_cache + +E11a=[0,-1,1,-10,-20] +E37a=[0,0,1,-1,0] +E389a=[0,1,1,-2,0] +E5077a=[0,0,1,-7,6] +E4=[1,-1,0,-79,289] +E5=[0,0,1,-79,342] +E6=[1,1,0,-2582,48720] +E7=[0,0,0,-10012,346900] + +echo "### Compute modular degree for some curves" +echo "# 11a" +./sympow -quiet -curve $E11a -moddeg +echo "# 37a" +./sympow -quiet -curve $E37a -moddeg +echo "# 389a" +./sympow -quiet -curve $E389a -moddeg +echo "# 5077a" +./sympow -quiet -curve $E5077a -moddeg +echo "# 234446a" +./sympow -quiet -curve $E4 -moddeg + +echo "### Compute analytic rank for some curves" +echo "# 11a" +./sympow -quiet -curve $E11a -analrank +echo "# 37a" +./sympow -quiet -curve $E37a -analrank +echo "# 389a" +./sympow -quiet -curve $E389a -analrank +echo "# 5077a" +./sympow -quiet -curve $E5077a -analrank +echo "# 234446a" +./sympow -quiet -curve $E4 -analrank +echo "# curve of rank 5" +./sympow -quiet -curve $E5 -analrank +echo "# curve of rank 6" +./sympow -quiet -curve $E6 -analrank +echo "# curve of rank 7" +./sympow -quiet -curve $E7 -analrank diff --git a/srcpkgs/sympow/files/test.out b/srcpkgs/sympow/files/test.out new file mode 100644 index 000000000000..b95c57494135 --- /dev/null +++ b/srcpkgs/sympow/files/test.out @@ -0,0 +1,54 @@ +### Compute modular degree for some curves +# 11a +Minimal model of curve is [0,-1,1,-10,-20] +Maximal number of terms is 14 +Modular Degree is 1 +# 37a +Minimal model of curve is [0,0,1,-1,0] +Maximal number of terms is 48 +Modular Degree is 2 +# 389a +Minimal model of curve is [0,1,1,-2,0] +Maximal number of terms is 512 +Modular Degree is 40 +# 5077a +Minimal model of curve is [0,0,1,-7,6] +Maximal number of terms is 8130 +Modular Degree is 1984 +# 234446a +Minimal model of curve is [1,-1,0,-79,289] +Maximal number of terms is 518272 +Modular Degree is 334976 +### Compute analytic rank for some curves +# 11a +Minimal model of curve is [0,-1,1,-10,-20] +Maximal number of terms is 7 +Analytic Rank is 0 : L-value 2.53842e-01 +# 37a +Minimal model of curve is [0,0,1,-1,0] +Maximal number of terms is 10 +Analytic Rank is 1 : L'-value 3.06000e-01 +# 389a +Minimal model of curve is [0,1,1,-2,0] +Maximal number of terms is 43 +Analytic Rank is 2 : leading L-term 7.59317e-01 +# 5077a +Minimal model of curve is [0,0,1,-7,6] +Maximal number of terms is 128 +Analytic Rank is 3 : leading L-term 1.73185e+00 +# 234446a +Minimal model of curve is [1,-1,0,-79,289] +Maximal number of terms is 1064 +Analytic Rank is 4 : leading L-term 8.94385e+00 +# curve of rank 5 +Minimal model of curve is [0,0,1,-79,342] +Maximal number of terms is 7858 +Analytic Rank is 5 : leading L-term 3.02857e+01 +# curve of rank 6 +Minimal model of curve is [1,1,0,-2582,48720] +Maximal number of terms is 184767 +Analytic Rank is 6 : leading L-term 3.20781e+02 +# curve of rank 7 +Minimal model of curve is [0,0,0,-10012,346900] +Maximal number of terms is 1324544 +Analytic Rank is 7 : leading L-term 1.32517e+03 diff --git a/srcpkgs/sympow/patches/first-try-without-messing-the-fpucw.patch b/srcpkgs/sympow/patches/first-try-without-messing-the-fpucw.patch new file mode 100644 index 000000000000..a7b17819b7e5 --- /dev/null +++ b/srcpkgs/sympow/patches/first-try-without-messing-the-fpucw.patch @@ -0,0 +1,14 @@ +--- a/Configure 2020-04-16 14:12:56.000000000 -0300 ++++ b/Configure 2021-11-24 16:04:43.647041822 -0300 +@@ -154,10 +154,10 @@ + try_add_CFLAG $FLAG bypass && break + done + + # Select the most appropriate FPU control scheme +-for FLAG in '-DISOC99_FENV' '-DFPUCONTROLH' '-Dx86'; do ++for FLAG in '' '-DISOC99_FENV' '-DFPUCONTROLH' '-Dx86'; do + try_add_CFLAG $FLAG && break + done + + # Some flags to try as last resort. These hurt performance, so only add + # them if needed. diff --git a/srcpkgs/sympow/template b/srcpkgs/sympow/template index d484cf847f57..b81d2d4097c8 100644 --- a/srcpkgs/sympow/template +++ b/srcpkgs/sympow/template @@ -1,7 +1,7 @@ # Template file for 'sympow' pkgname=sympow version=2.023.6 -revision=2 +revision=3 wrksrc=${pkgname}-v${version} build_style=configure make_build_target=all @@ -15,6 +15,8 @@ distfiles="https://gitlab.com/rezozer/forks/sympow/-/archive/v${version}/sympow- checksum=d153530dfdd46da05c954121640e50771064536fedc22c7fef24fb11083172ef nocross=yes # runs binaries built for target +CFLAGS="-Wno-unused-result" + do_configure() { PREFIX=/usr ./Configure } @@ -22,3 +24,9 @@ do_configure() { post_install() { vlicense COPYING } + +do_check() { + echo "Testing sympow ..." + sh "${FILESDIR}"/test > test.log + diff "${FILESDIR}"/test.out test.log && echo PASS +}