From guillaume.melquiond at inria.fr Mon Feb 10 17:25:34 2020 From: guillaume.melquiond at inria.fr (Guillaume Melquiond) Date: Mon, 10 Feb 2020 18:25:34 +0100 Subject: Overflow in mpz_cmp Message-ID: <99b63a98-0d66-b4f3-806d-38fac631649b@inria.fr> Dear GMP developers, When the operand sizes do not match, the mpz_cmp function function just returns the difference of the signed sizes. Unfortunately, this difference might not fit inside the "int" return type, when the numbers are of opposite sign. This is extremely unlikely to happen in practice, as this requires 8GB numbers. The bug was noticed when formally verifying this function. Using GMP 6.1.2 (as packaged by Debian) on an x86-64 architecture, the testcase at the end of the email displays: x: +1 * 2^85899345857 y: -1 * 2^68719476673 x < y Obviously, it should display "x >= y" on the last line. The code of mpz_cmp is unchanged at the tip of the hg repository, so the bug is likely present there too. #include #include int main() { mpz_t x, y; mpz_init(x); mpz_realloc(x, 0x50000000); mpz_init(y); mpz_realloc(y, 0x40000000); // create numbers by hand to avoid trashing 19GB of memory x->_mp_size = x->_mp_alloc; x->_mp_d[x->_mp_size - 1] = 1; y->_mp_size = y->_mp_alloc; y->_mp_d[y->_mp_size - 1] = 1; mpz_neg(y, y); printf("x: %+d * 2^%ld\n", mpz_sgn(x), mpz_sizeinbase(x, 2)); printf("y: %+d * 2^%ld\n", mpz_sgn(y), mpz_sizeinbase(y, 2)); int res = mpz_cmp(x, y); if (res >= 0) printf("x >= y\n"); else printf("x < y\n"); } From klausz at haus-gisela.de Sun Feb 16 20:55:40 2020 From: klausz at haus-gisela.de (Klaus Ziegler - owner of sunfreeware.de) Date: Sun, 16 Feb 2020 21:55:40 +0100 Subject: error compiling gmp-6.2.0 on sparc-sun-solaris2.11 - v9os Message-ID: Hi, I'm currently trying to bring back more life into the SPARC port of illumos, aka v9os. Therefore I would like to use gmp-6.2.0 for my next compiler build. At first I'll have to say thank you for the perfomance boost in 6.2.0, here are my very small benchmarks for 6.1.2 and 6.2.0 on a very old Sun Ultra-60 runing: ??? v9os: http://www.milax.fi/v9os.html The measured times are only for the reuse test in subdir mpz: gmp-6.1.2: ========== ultra2 2x 450Mhz 2048MB: gcc-7.4.0: -m32 -O2 -pedantic -mcpu=ultrasparc -Wa,-Av8plusa - gas 2.33.1 9:38 min. gcc-4.7.4: -O2 -pedantic -m64 -mptr64 -mcpu=ultrasparc -Wa,-Av9a - gas 2.33.1 5:03 min. studio12.2 -m64 -xcode=pic32 -xO3 -xtarget=ultra2 -xarch=sparcvis 5:14 min. ultra2 2x 400Mhz snv_130 studio12.2: 11:45 min. gmp-6.2.0: ========== ultra2 2x 450Mhz 2048MB gcc-5.1.0: -O2 -m64 -mptr64 -mcpu=ultrasparc -Wa,-Av9a - gas: 2.33.1 1:50 min. studio12.2 -m64 -xO2 -xcode=pic32 1:49 min. studio12.2 -m64 -xO2 -xcode=pic32 1:56 min. gcc-4.7.4: -O2 -pedantic -m64 -mptr64 -mcpu=ultrasparc -Wa,-Av9a - gas: 2.33.1 1:45 min. ultra10 1x 400Mhz 1024MB - Solaris10 studio12.3 -m64 -xO2 -xcode=pic32 1:56 min. You may wonder about all these -xcode=pic32 settings, the -xcode=pic32 option, was introduced for SPARC in Sun C 5.3, and was outlined equivalent to -KPIC. Later man pages for Sun C, obsolete the -KPIC option for SPARC moreprecisely, Sun C 5.11 for example: ???? -KPIC ????????? (SPARC) Obsolete. You should not use this option. Use ??? ????? -xcode=pic32 instead. For a complete list of obsolete ??? ? ? ? options and flags, see the C User's Guide. therefore I've written a small patch to gmp's configure script, which changes the PICFLAG onwards from Sun C 5.3 to -xcode=pic32, but only for SPARC, please see the second hunk in the attached patch: gmp-6.2.0.patch. The fix for gmp-h.in in the attached patch is carried forward for me since 6.0.0, probably much longer and only enables Sun C 5.3 users to benefit from gmp's inlining feature. The last hunk gmp-impl.h eliminates the following warning on Solaris10 / Studio12.3: gmp-6.2.0/gmp-impl.h", line 734: Warning (Anachronism): Attempt to redefine __builtin_constant_p without using #undef. But now to my real problem, if I try to compile gmp-6.2.0 on v9os using Sun C 5.11, I'll get the following very long lines: gmp-6.2.0/gmpxx.h", line 3375: Error: static __gmp_expr<__mpz_struct[1], __mpz_struct[1]>::factorial(signed char), returning __gmp_expr<__mpz_struct[1], __gmp_unary_expr>, was previously declared returning __gmp_expr<__mpz_struct[1], __gmp_unary_expr>. 10 times and then for lines 3376/77 ten times, when compiling gmp-6.2.0/cxx/limits.cc could you please have a look into the attachment: Studio11-gmp-6.2.0.log for more details. I'm using gmp-6.1.2 without problems on v9os with Sun C 5.11, but 5.13 and newer, isn't an option on v9os, because of some internal library handling between v9os and Sun C 5.13 e.g. 5.13 simply does not work on v9os. But the gcc-5.1.0 included in v9os isn't able to build a working combination of gmp/mpfr in 64bit format. So I'm stuck with Sun C 5.11 for now, would you please help me in fixing the C++ erros occuring from gmp-6.2.0/cxx/limits.cc Thanks very much in advance Best Regards Klaus Ziegler -------------- next part -------------- A non-text attachment was scrubbed... Name: gmp-6.2.0.patch Type: text/x-patch Size: 2439 bytes Desc: not available URL: -------------- next part -------------- A non-text attachment was scrubbed... Name: studio12.2-gmp-6.2.0.log Type: text/x-log Size: 17326 bytes Desc: not available URL: From nisse at lysator.liu.se Mon Feb 17 09:05:24 2020 From: nisse at lysator.liu.se (Niels =?utf-8?Q?M=C3=B6ller?=) Date: Mon, 17 Feb 2020 10:05:24 +0100 Subject: error compiling gmp-6.2.0 on sparc-sun-solaris2.11 - v9os In-Reply-To: (Klaus Ziegler's message of "Sun, 16 Feb 2020 21:55:40 +0100") References: Message-ID: "Klaus Ziegler - owner of sunfreeware.de" writes: > But now to my real problem, if I try to compile gmp-6.2.0 on v9os > using Sun C 5.11, > I'll get the following very long lines: > gmp-6.2.0/gmpxx.h", line 3375: Error: static > __gmp_expr<__mpz_struct[1], __mpz_struct[1]>::factorial(signed char), > returning __gmp_expr<__mpz_struct[1], __gmp_unary_expr __gmp_fac_function>>, was previously declared returning > __gmp_expr<__mpz_struct[1], __gmp_unary_expr __gmp_fac_function>>. I'm afraid I've not familiar enough with C++ to undersnd the error, but Sun C 5.11 must be a pretty old C++ compiler, right? Maybe it simply doesn't understand current C++? Do you really need the C++ glue to boostrap gmp and gcc? If not, try configuring gmp with --disable-cxx. Regards, /Niels -- Niels M?ller. PGP-encrypted email is preferred. Keyid 368C6677. Internet email is subject to wholesale government surveillance. From Paul.Zimmermann at inria.fr Sat Feb 29 10:54:38 2020 From: Paul.Zimmermann at inria.fr (paul zimmermann) Date: Sat, 29 Feb 2020 11:54:38 +0100 Subject: efficiency bug in mpz_powm_ui? Message-ID: Hi, it seems that mpz_powm_ui is highly inefficient when BASE^EXP has about the same size as MOD, in which case it could first compute BASE^EXP exactly, then perform only one reduction: zimmerma at tomate:/tmp$ ./a.out 100000 GMP version: 6.2.0 mpz_ui_pow_ui+mpz_mod took 100ms set_ui+mpz_powm_ui took 2048ms zimmerma at tomate:/tmp$ ./a.out 1000000 GMP version: 6.2.0 mpz_ui_pow_ui+mpz_mod took 1005ms set_ui+mpz_powm_ui took 31138ms This was detected in the mpfr_remainder function, which is called from mpfr_sin to reduce huge arguments modulo Pi. Paul #include #include #include #include #include #include int cputime () { struct rusage rus; getrusage (0, &rus); return rus.ru_utime.tv_sec * 1000 + rus.ru_utime.tv_usec / 1000; } int main (int argc, char *argv[]) { unsigned long n = atoi (argv[1]), e; mpz_t x, y, r1, r2; int t; printf ("GMP version: %s\n", gmp_version); /* compute x mod y in two ways, where x=2^e is twice as large as y */ mpz_init (x); mpz_init (y); mpz_init (r1); mpz_init (r2); mpz_random (y, n); e = 2 * mpz_size (y) * mp_bits_per_limb; t = cputime (); mpz_ui_pow_ui (x, 2, e); mpz_mod (r1, x, y); t = cputime () - t; printf ("mpz_ui_pow_ui+mpz_mod took %dms\n", t); t = cputime (); mpz_set_ui (x, 2); mpz_powm_ui (r2, x, e, y); t = cputime () - t; printf ("set_ui+mpz_powm_ui took %dms\n", t); assert (mpz_cmp (r1, r2) == 0); mpz_clear (x); mpz_clear (y); mpz_clear (r1); mpz_clear (r2); return 0; } From bodrato at mail.dm.unipi.it Sat Feb 29 23:19:21 2020 From: bodrato at mail.dm.unipi.it (Marco Bodrato) Date: Sun, 01 Mar 2020 00:19:21 +0100 Subject: efficiency bug in mpz_powm_ui? In-Reply-To: References: Message-ID: <6cd8af5ddab9a051b57e6608cf44383b@student.dm.unipi.it> Ciao, Il 2020-02-29 11:54 paul zimmermann ha scritto: > it seems that mpz_powm_ui is highly inefficient when BASE^EXP has about > the > same size as MOD, in which case it could first compute BASE^EXP > exactly, then > perform only one reduction: You are right, mpz_powm_ui does not implement an algorithm that is optimal for every possible use-case. But I'd not consider this a bug :-) > mpz_ui_pow_ui (x, 2, e); > mpz_mod (r1, x, y); I'm not sure that mpz_ui_pow_ui (x, 2, e) is the more efficient way to obtain a value x with only the bit e set to 1 :-) But of course, in this context, the following _mod dominates asymptotically. > mpz_set_ui (x, 2); > mpz_powm_ui (r2, x, e, y); Thanks to a recent change, this function should be faster now, when base is 2: https://gmplib.org/repo/gmp/rev/63e53ddfd210 Even if there is not jet any special code for the special case "BASE^EXP has about the same size as MOD". ?is, m