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