Using make tune, speed_measure error
Hi y'all, I'm doing a clean build of GMP 6.2.1, trying to follow all of the steps finally. My "./configfsf.guess" output is "x86_64-pc-linux-gnu", and this is basically the same infothat "./config.guess" and "uname -a" produces. I built using "./configure" and make, this went fine I think. Then I cd'ed into /tune and ran "make tune". I think it runs through most of this makefile fine. In particular, after running "make tune" a 2nd time, it says "'tuneup' is up to date" and leaves tune/ directory. It outputs the parameters for "gmp-mparam.h", and then #define's a bunch of constants. The last constants it defines before the error are #define MUL_TOOM6H_THRESHOLD 298 #define MUL_TOOM8H_THRESHOLD 406 Reading the gmp-mparam.h file, I guess it's failing the next test, for optimizing MUL_TOOM32_TO_TOOM43_THRESHOLD? The error then goes " speed_measure() could not get 4 results within 1.0% ... (2 column table. The first row says "is about 1.0%" in a 3rd column, but blank for the other rows) ... ", and the next line reads "Aborted (core dumped)". if that's informative. I can include the table data or whatever else might be helpful. Thank y'all for GMP, it's amazing! Best, Aaron ___ gmp-bugs mailing list gmp-bugs@gmplib.org https://gmplib.org/mailman/listinfo/gmp-bugs
GMP does not detect float exponent overflow while reading floating point numbers
While using GMP to read floating point numbers, I noticed that when the exponent is too large, the exponent overflows without warning or error. GMP version: gmp-6.2.1-2.fc36.x86_64, installed using dnf on Fedora 36. Test program: a.c and b.cpp, see attachment. To run a.c, use "gcc a.c -o a -lgmp && ./a". The output on my machine is "0.1e-3215911262793760767". To run b.cpp, use "g++ b.cpp -o b -lgmp -lgmpxx && ./b". The output on my machine is "1e+-1294967296". The results are wrong because I entered a very large number, but got a number between 0 and 1. I am expecting GMP to return an error in mpf_init_set_str() indicating that the exponent is too large. Thanks to https://stackoverflow.com/a/73740744, looks like the cause of the bug it that GMP triggered a signed overflow in the following code (from https://gmplib.org/repo/gmp/file/feb796a7f683/mpf/set_str.c#l315) : while (dig < exp_base) { exp_in_base = exp_in_base * exp_base; exp_in_base += dig; c = (unsigned char) *expptr++; dig = digit_value[c]; } My gcc version information: Using built-in specs. COLLECT_GCC=gcc COLLECT_LTO_WRAPPER=/usr/libexec/gcc/x86_64-redhat-linux/12/lto-wrapper OFFLOAD_TARGET_NAMES=nvptx-none OFFLOAD_TARGET_DEFAULT=1 Target: x86_64-redhat-linux Configured with: ../configure --enable-bootstrap --enable- languages=c,c++,fortran,objc,obj-c++,ada,go,d,lto --prefix=/usr -- mandir=/usr/share/man --infodir=/usr/share/info --with- bugurl=http://bugzilla.redhat.com/bugzilla --enable-shared --enable- threads=posix --enable-checking=release --enable-multilib --with- system-zlib --enable-__cxa_atexit --disable-libunwind-exceptions -- enable-gnu-unique-object --enable-linker-build-id --with-gcc-major- version-only --enable-libstdcxx-backtrace --with-linker-hash-style=gnu --enable-plugin --enable-initfini-array --with- isl=/builddir/build/BUILD/gcc-12.2.1-20220819/obj-x86_64-redhat- linux/isl-install --enable-offload-targets=nvptx-none --without-cuda- driver --enable-offload-defaulted --enable-gnu-indirect-function -- enable-cet --with-tune=generic --with-arch_32=i686 --build=x86_64- redhat-linux --with-build-config=bootstrap-lto --enable-link- serialization=1 Thread model: posix Supported LTO compression algorithms: zlib zstd gcc version 12.2.1 20220819 (Red Hat 12.2.1-1) (GCC) My uname -a: Linux HOSTNAME 5.19.8-200.fc36.x86_64 #1 SMP PREEMPT_DYNAMIC Thu Sep 8 19:02:21 UTC 2022 x86_64 x86_64 x86_64 GNU/Linux /* gcc a.c -o a -lgmp && ./a */ #include #include #include int main(void) { mpf_t f; const char *s = "1e300"; assert(mpf_init_set_str(f, s, 10) == 0); assert(mpf_out_str(NULL, 10, 100, f)); printf("\n"); } // g++ b.cpp -o b -lgmp -lgmpxx && ./b #include #include int main(void) { mpf_class f("1e30"); std::cout << f << std::endl; } ___ gmp-bugs mailing list gmp-bugs@gmplib.org https://gmplib.org/mailman/listinfo/gmp-bugs
Re: mini-gmp mpz_powm incorrect result
Ciao, Il 2022-09-05 21:23 ni...@lysator.liu.se ha scritto: Marco Bodrato writes: I propose to also add a couple of tests to mini-gmp/tests/t-powm.c , to keep track of this. Definitely needed, thanks for looking into that. + if (mpz_cmp_ui (res, 1) <= 0) +mpz_add_ui (res, res, 9); Adding 9 looks very arbitrary? It is arbitrary. It is large enough to not be completely trivial and small enough to be short to write. I added a comment, saying that it is arbitrary :-) Can we test mpz_powm (res, b, e, m), with e set to 0, and first |m| > 1, then m = ±1? To get coverage for various signs and values for b and m. The code handling e=0 is not so complex to deserve a sophisticated test. Anyway, of course the test can be improved. BTW, it seems docs for mpz_powm doesn't say explicitly what 0^0 (mod m) should give? But docs for mpz_*_pow_ui does say that 0^0 yields 1, so for consitency, powm should give 1 mod m, which I think is what the code (with fix) does. Especially for _powm it is a good idea to return [1] for any x^0, regardless of x (i.e. also when x is 0). Otherwise, we should check whether x is 0 or not mod m. We just added the exception that the class [1] is represented by 0 when the modulus m=0. But that's not an exception wrt the above idea. Ĝis, m ___ gmp-bugs mailing list gmp-bugs@gmplib.org https://gmplib.org/mailman/listinfo/gmp-bugs
Re: mini-gmp mpz_powm incorrect result
Marco Bodrato writes: >>> or even (mn == 0 check just above this code rules out |m| < 1) >>> >>>mpz_set_ui (r, mpz_cmpabs_ui (m, 1)); > > I agree with this solution. Will you commit it? Committed, and I've verified that it fixes Guido's test case. > I propose to also add a couple of tests to mini-gmp/tests/t-powm.c , > to keep track of this. Definitely needed, thanks for looking into that. > 8<-- > diff -r b0d6b9f5807e mini-gmp/tests/t-powm.c > --- a/mini-gmp/tests/t-powm.c Sat Aug 20 18:44:17 2022 +0200 > +++ b/mini-gmp/tests/t-powm.c Mon Sep 05 19:02:23 2022 +0200 > @@ -53,6 +53,31 @@ > abort (); > } > } > + > + if (mpz_cmp_ui (res, 1) <= 0) > +mpz_add_ui (res, res, 9); Adding 9 looks very arbitrary? > + mpz_set_ui (e, 0); > + /* Test the case m^0 (mod m), expect 1 (m is greater than 1). */ > + mpz_powm (res, res, e, res); Can we test mpz_powm (res, b, e, m), with e set to 0, and first |m| > 1, then m = ±1? To get coverage for various signs and values for b and m. BTW, it seems docs for mpz_powm doesn't say explicitly what 0^0 (mod m) should give? But docs for mpz_*_pow_ui does say that 0^0 yields 1, so for consitency, powm should give 1 mod m, which I think is what the code (with fix) does. Regards, /Niels -- Niels Möller. PGP key CB4962D070D77D7FCB8BA36271D8F1FF368C6677. Internet email is subject to wholesale government surveillance. ___ gmp-bugs mailing list gmp-bugs@gmplib.org https://gmplib.org/mailman/listinfo/gmp-bugs
Re: mini-gmp mpz_powm incorrect result
Ciao, Il 2022-08-30 10:25 Vincent Lefevre ha scritto: or even (mn == 0 check just above this code rules out |m| < 1) mpz_set_ui (r, mpz_cmpabs_ui (m, 1)); I agree with this solution. Will you commit it? Concerning this second solution, the GMP manual says: -- Function: int mpz_cmpabs_ui (const mpz_t OP1, unsigned long int OP2) Compare the absolute values of OP1 and OP2. Return a positive value if abs(OP1) > abs(OP2), zero if abs(OP1) = abs(OP2), or a negative value if abs(OP1) < abs(OP2). So if the mpz_cmpabs_ui implementation is changed so that it can return a value larger than 1, you need to make sure to remember to update the code. I propose to also add a couple of tests to mini-gmp/tests/t-powm.c , to keep track of this. 8<-- diff -r b0d6b9f5807e mini-gmp/tests/t-powm.c --- a/mini-gmp/tests/t-powm.c Sat Aug 20 18:44:17 2022 +0200 +++ b/mini-gmp/tests/t-powm.c Mon Sep 05 19:02:23 2022 +0200 @@ -53,6 +53,31 @@ abort (); } } + + if (mpz_cmp_ui (res, 1) <= 0) +mpz_add_ui (res, res, 9); + + mpz_set_ui (e, 0); + /* Test the case m^0 (mod m), expect 1 (m is greater than 1). */ + mpz_powm (res, res, e, res); + if (mpz_cmp_ui (res, 1) != 0) +{ + fprintf (stderr, "mpz_powm failed: b=m, e=0; 1 expected,\n"); + dump ("m", res); + dump ("r", res); + abort (); +} + + /* Now res is 1. */ + /* Test the case 1^0 (mod 1), expect 0. */ + mpz_powm (res, res, e, res); + if (mpz_size (res)) +{ + fprintf (stderr, "mpz_powm failed: b=1, e=0, m=1; 0 expected,\n"); + dump ("r", res); + abort (); +} + mpz_clear (b); mpz_clear (e); mpz_clear (m); 8<-- Ĝis, m ___ gmp-bugs mailing list gmp-bugs@gmplib.org https://gmplib.org/mailman/listinfo/gmp-bugs
Re: mini-gmp mpz_powm incorrect result
Il 2022-09-05 19:04 Marco Bodrato ha scritto: Il 2022-08-30 10:25 Vincent Lefevre ha scritto: or even (mn == 0 check just above this code rules out |m| < 1) mpz_set_ui (r, mpz_cmpabs_ui (m, 1)); I agree with this solution. Will you commit it? I incorrectly removed the "Niels Möller wrote:" line. The question is for Niels, of course. I propose to also add a couple of tests to mini-gmp/tests/t-powm.c , to keep track of this. I'll push the tests just after the correction... Ĝis, m PS: thanks for the report ___ gmp-bugs mailing list gmp-bugs@gmplib.org https://gmplib.org/mailman/listinfo/gmp-bugs