mpz reuse test takes too much time

Niels Möller nisse at lysator.liu.se
Fri Nov 25 19:32:36 UTC 2016


tg at gmplib.org (Torbjörn Granlund) writes:

> nisse at lysator.liu.se (Niels Möller) writes:
>
>   tg at gmplib.org (Torbjörn Granlund) writes:
>   
>   > Please check that reuse.c whacks gcdext appropriately.
>   
>   It doesn't check the cases where both input operands overlap some output
>   operands, e.g.,
>   
>   	  mpz_gcdext (res1, res2, res3, res1, res3);
>   
>   or
>   
>   	  mpz_gcdext (res1, res2, res3, res2, res2);
>   
>   Should it do that, or is it enough that the reuse tests overlap one
>   operand at a time? Doing all combinations everywhere does blow up the
>   number of tests a bit.
>   
> Let's make the test slower as a reaction to Vincent's complaint!  :-)
>
> Seriously, I think we should exercise all combinations.

Below patch tries to do that. What do you think? Analogous changes should be applied
to mini-gmp/tests/t-reuse too.

/Niels


*** /tmp/extdiff.NYb3Az/gmp.fbc88b42a197/tests/mpz/reuse.c	2016-11-25 20:24:48.143687820 +0100
--- /home/nisse/hack/gmp/tests/mpz/reuse.c	2016-09-28 23:40:06.073658624 +0200
*************** main (int argc, char **argv)
*** 475,563 ****
  	  MPZ_CHECK_FORMAT (ref3);
  
  	  mpz_set (res1, in1);
! 	  mpz_gcdext (res1, res2, res3, res1, in2);
! 	  MPZ_CHECK_FORMAT (res1);
! 	  MPZ_CHECK_FORMAT (res2);
! 	  MPZ_CHECK_FORMAT (res3);
! 	  if (mpz_cmp (ref1, res1) != 0 || mpz_cmp (ref2, res2) != 0
! 	      || mpz_cmp (ref3, res3) != 0)
! 	    FAIL2 (mpz_gcdext, in1, in2, NULL);
  
  	  mpz_set (res2, in1);
! 	  mpz_gcdext (res1, res2, res3, res2, in2);
! 	  MPZ_CHECK_FORMAT (res1);
! 	  MPZ_CHECK_FORMAT (res2);
! 	  MPZ_CHECK_FORMAT (res3);
! 	  if (mpz_cmp (ref1, res1) != 0 || mpz_cmp (ref2, res2) != 0
! 	      || mpz_cmp (ref3, res3) != 0)
! 	    FAIL2 (mpz_gcdext, in1, in2, NULL);
  
  	  mpz_set (res3, in1);
! 	  mpz_gcdext (res1, res2, res3, res3, in2);
! 	  MPZ_CHECK_FORMAT (res1);
! 	  MPZ_CHECK_FORMAT (res2);
! 	  MPZ_CHECK_FORMAT (res3);
! 	  if (mpz_cmp (ref1, res1) != 0 || mpz_cmp (ref2, res2) != 0
! 	      || mpz_cmp (ref3, res3) != 0)
! 	    FAIL2 (mpz_gcdext, in1, in2, NULL);
  
  	  mpz_set (res1, in2);
! 	  mpz_gcdext (res1, res2, res3, in1, res1);
! 	  MPZ_CHECK_FORMAT (res1);
! 	  MPZ_CHECK_FORMAT (res2);
! 	  MPZ_CHECK_FORMAT (res3);
! 	  if (mpz_cmp (ref1, res1) != 0 || mpz_cmp (ref2, res2) != 0
! 	      || mpz_cmp (ref3, res3) != 0)
! 	    FAIL2 (mpz_gcdext, in1, in2, NULL);
  
  	  mpz_set (res2, in2);
! 	  mpz_gcdext (res1, res2, res3, in1, res2);
! 	  MPZ_CHECK_FORMAT (res1);
! 	  MPZ_CHECK_FORMAT (res2);
! 	  MPZ_CHECK_FORMAT (res3);
! 	  if (mpz_cmp (ref1, res1) != 0 || mpz_cmp (ref2, res2) != 0
! 	      || mpz_cmp (ref3, res3) != 0)
! 	    FAIL2 (mpz_gcdext, in1, in2, NULL);
  
  	  mpz_set (res3, in2);
! 	  mpz_gcdext (res1, res2, res3, in1, res3);
! 	  MPZ_CHECK_FORMAT (res1);
! 	  MPZ_CHECK_FORMAT (res2);
! 	  MPZ_CHECK_FORMAT (res3);
! 	  if (mpz_cmp (ref1, res1) != 0 || mpz_cmp (ref2, res2) != 0
! 	      || mpz_cmp (ref3, res3) != 0)
! 	    FAIL2 (mpz_gcdext, in1, in2, NULL);
  
  	  mpz_set (res1, in1);
! 	  mpz_gcdext (res1, res2, NULL, res1, in2);
! 	  MPZ_CHECK_FORMAT (res1);
! 	  MPZ_CHECK_FORMAT (res2);
! 	  if (mpz_cmp (ref1, res1) != 0 || mpz_cmp (ref2, res2) != 0
! 	      || mpz_cmp (ref3, res3) != 0)
! 	    FAIL2 (mpz_gcdext, in1, in2, NULL);
  
  	  mpz_set (res2, in1);
! 	  mpz_gcdext (res1, res2, NULL, res2, in2);
! 	  MPZ_CHECK_FORMAT (res1);
! 	  MPZ_CHECK_FORMAT (res2);
! 	  if (mpz_cmp (ref1, res1) != 0 || mpz_cmp (ref2, res2) != 0
! 	      || mpz_cmp (ref3, res3) != 0)
! 	    FAIL2 (mpz_gcdext, in1, in2, NULL);
  
  	  mpz_set (res1, in2);
! 	  mpz_gcdext (res1, res2, NULL, in1, res1);
! 	  MPZ_CHECK_FORMAT (res1);
! 	  MPZ_CHECK_FORMAT (res2);
! 	  if (mpz_cmp (ref1, res1) != 0 || mpz_cmp (ref2, res2) != 0
! 	      || mpz_cmp (ref3, res3) != 0)
! 	    FAIL2 (mpz_gcdext, in1, in2, NULL);
  
  	  mpz_set (res2, in2);
! 	  mpz_gcdext (res1, res2, NULL, in1, res2);
! 	  MPZ_CHECK_FORMAT (res1);
! 	  MPZ_CHECK_FORMAT (res2);
! 	  if (mpz_cmp (ref1, res1) != 0 || mpz_cmp (ref2, res2) != 0
! 	      || mpz_cmp (ref3, res3) != 0)
! 	    FAIL2 (mpz_gcdext, in1, in2, NULL);
  	}
  
--- 475,573 ----
  	  MPZ_CHECK_FORMAT (ref3);
  
+ #define GCDEXT_CHECK(t, i1,i2) do {					\
+ 	    mpz_gcdext (res1, res2, t ? res3 : NULL, i1, i2);		\
+ 	    MPZ_CHECK_FORMAT (res1);					\
+ 	    MPZ_CHECK_FORMAT (res2);					\
+ 	    MPZ_CHECK_FORMAT (res3);					\
+ 	    if (mpz_cmp (ref1, res1) != 0 || mpz_cmp (ref2, res2) != 0	\
+ 		|| mpz_cmp (ref3, res3) != 0)				\
+ 	      FAIL2 (mpz_gcdext, i1, i2, NULL);				\
+ 	  } while(0)
+ 
  	  mpz_set (res1, in1);
! 	  GCDEXT_CHECK (1, res1, in2);
  
  	  mpz_set (res2, in1);
! 	  GCDEXT_CHECK (1, res2, in2);
  
  	  mpz_set (res3, in1);
! 	  GCDEXT_CHECK (1, res3, in2);
  
  	  mpz_set (res1, in2);
! 	  GCDEXT_CHECK (1, in1, res1);
  
  	  mpz_set (res2, in2);
! 	  GCDEXT_CHECK (1, in1, res2);
! 
! 	  mpz_set (res3, in2);
! 	  GCDEXT_CHECK (1, in1, res3);
  
+ 	  mpz_set (res1, in1);
+ 	  mpz_set (res2, in2);
+ 	  GCDEXT_CHECK (1, res1, res2);
+ 
+ 	  mpz_set (res1, in1);
  	  mpz_set (res3, in2);
! 	  GCDEXT_CHECK (1, res1, res3);
! 
! 	  mpz_set (res2, in1);
! 	  mpz_set (res3, in2);
! 	  GCDEXT_CHECK (1, res2, res3);
! 
! 	  mpz_set (res2, in1);
! 	  mpz_set (res1, in2);
! 	  GCDEXT_CHECK (1, res2, res1);
! 
! 	  mpz_set (res3, in1);
! 	  mpz_set (res1, in2);
! 	  GCDEXT_CHECK (1, res3, res1);
! 
! 	  mpz_set (res3, in1);
! 	  mpz_set (res2, in2);
! 	  GCDEXT_CHECK(1, res3, res2);
  
  	  mpz_set (res1, in1);
! 	  GCDEXT_CHECK (0, res1, in2);
  
  	  mpz_set (res2, in1);
! 	  GCDEXT_CHECK (0, res2, in2);
  
  	  mpz_set (res1, in2);
! 	  GCDEXT_CHECK (0, in1, res1);
  
  	  mpz_set (res2, in2);
! 	  GCDEXT_CHECK (0, in1, res2);
! #undef GCDEXT_CHECK
! 	  /* Identical inputs, gcd(in1, in1). gcd = abs(i1), s = 0, t
! 	     = sgn(i1). */
! 	  mpz_abs(ref1, in1);
! 	  mpz_set_ui(ref2, 0);
! 	  mpz_set_si(ref3, mpz_sgn(in1));
! 
! #define GCDEXT_CHECK_SAME(t, i) do {					\
! 	    mpz_gcdext(res1, res2, t ? res3 : NULL, i, i);		\
! 	    MPZ_CHECK_FORMAT (res1);					\
! 	    MPZ_CHECK_FORMAT (res2);					\
! 	    MPZ_CHECK_FORMAT (res3);					\
! 	    if (mpz_cmp (ref1, res1) != 0 || mpz_cmp (ref2, res2) != 0	\
! 		|| mpz_cmp (ref3, res3) != 0)				\
! 	      FAIL2 (mpz_gcdext, i, i, NULL);				\
! 	  } while(0)
! 
! 	  mpz_set (res1, in1);
! 	  GCDEXT_CHECK_SAME (1, res1);
! 
! 	  mpz_set(res2, in1);
! 	  GCDEXT_CHECK_SAME (1, res2);
! 
! 	  mpz_set(res3, in1);
! 	  GCDEXT_CHECK_SAME (1, res3);
! 
! 	  mpz_set (res1, in1);
! 	  GCDEXT_CHECK_SAME (0, res1);
! 
! 	  mpz_set(res2, in1);
! 	  GCDEXT_CHECK_SAME (0, res2);
! #undef GCDEXT_CHECK_SAME
  	}
  

-- 
Niels Möller. PGP-encrypted email is preferred. Keyid 368C6677.
Internet email is subject to wholesale government surveillance.


More information about the gmp-devel mailing list