Paul van Wamelen on Tue, 23 May 2000 17:31:38 -0500 (CDT)


[Date Prev] [Date Next] [Thread Prev] [Thread Next] [Date Index] [Thread Index]

qfminim bug 3


Dear Pari developers,

In qfminim with the flag equal to 2 (that is for dealing with
non-integral coefficients), if you want more vectors returned than can
fit on the stack, you are more than likely to get a segmentation
fault:


                   GP/PARI CALCULATOR Version 2.0.19 (beta)
                 UltraSparc (MicroSparc kernel) 32-bit version
               (readline v2.2 enabled, extended help available)

                          Copyright (C) 1989-1999 by
          C. Batut, K. Belabas, D. Bernardi, H. Cohen and M. Olivier.

Type ? for help, \q to quit.
Type ?12 for how to get moral (and possibly technical) support.

   realprecision = 28 significant digits
   seriesprecision = 16 significant terms
   format = g0.28

parisize = 4000000, primelimit = 500000
? Qmat = [0.1121838950156262993198861903, -0.002294825170315502480266502542, -0.0003341361628152951755992730843, -0.01013912749586145381073809834, 0.02116023427426229437120984486, -0.04256500745397313843968688094; -0.002294825170315502480266502542, 0.0101
5200067110896037957565105, -0.01062142221979604038700374101, 0.02221761484223348391636273181, -0.04692817364343353260667839410, 0.09682920303695533048890485886; -0.0003341361628152951755992730843, -0.01062142221979604038700374101, 0.0232236177136219324940
5380743, -0.04916043776688522464771472577, 0.1039418432338874002700813232, -0.2172034509288058753060698920; -0.01013912749586145381073809834, 0.02221761484223348391636273181, -0.04916043776688522464771472577, 0.1063794149634527727718385934, -0.22753531414
34766490036291424, 0.4811386293014932004986704852; 0.02116023427426229437120984486, -0.04692817364343353260667839410, 0.1039418432338874002700813232, -0.2275353141434766490036291424, 0.4923171763996275063527134313, -1.053129742820247211799751080; -0.04256
500745397313843968688094, 0.09682920303695533048890485886, -0.2172034509288058753060698920, 0.4811386293014932004986704852, -1.053129742820247211799751080, 2.278649858405744971446804119];
? qfminim(Qmat*100,1,100000,2)[1]
  ***   bug in GP (Segmentation Fault), please report
? 





The reason for this seems to be that in line 2656 of basemath/bibli1.c:
         for (i=s+1; i<=stockmax; i++) S[i]=zero;
the S array gets filled up with zeros instead of zero vectors.

The following fixes this:


diff -r1.25 bibli1.c
2650c2651
< 	GEN *gptr[8];
---
> 	GEN *gptr[8],dum;
2651a2653
>         long jj;
2656c2658,2662
<           for (i=s+1; i<=stockmax; i++) S[i]=zero;
---
>           for (i=s+1; i<=stockmax; i++)
>           {
>             dum=cgetg(N,t_COL); S[i]=(long)dum;
>             for (jj=1; jj<N; jj++) dum[jj] = zero;
>           }



While trying to track this down I came across something else that
seems to be a bug. After doing a garbage collection in smallvectors,
the stack might in fact now be fuller than it was before the garbage
collection. This is because as we collect vectors lots of components
of these vectors point to the same actual data. (if two saved vectors
differ only in the last few entries, the unchanged entries point to
the same integers in memory). While doing a gerepilemany these vectors
get gcopy'ied, which means that all components of all vectors now
point to unique data. (In fact a forcecopy gets done which also
expands all the zero's with which S gets filled up). This can take up
more space than the garbage that was collected. The real problem is
that this can now lead to a very slow death: everytime a new vector is
found, a garbage collection gets done. I "fixed" this by changing the
limit for garbage collection just after a garbage collection was done:


diff -r1.25 bibli1.c
2664a2671
>         lim=stack_lim(avma,1);


I'm not so sure this won't cause other problems...

Here is a diff -c of all three of the previous bug fixes:





diff -c -r1.25 bibli1.c
*** src/basemath/bibli1.c	2000/04/20 17:48:01	1.25
--- src/basemath/bibli1.c	2000/05/23 22:22:04
***************
*** 2590,2596 ****
    v=cgetg(N,t_VEC);
  
    av2=avma;
!   S = cgetg(stockmax+1,t_MAT);
    norms = cgetg(stockmax+1,t_VEC);
    x=cgetg(N,t_COL);
    y=cgetg(N,t_COL);
--- 2590,2597 ----
    v=cgetg(N,t_VEC);
  
    av2=avma;
!   if(stockmax)
!     S = cgetg(stockmax+1,t_MAT);
    norms = cgetg(stockmax+1,t_VEC);
    x=cgetg(N,t_COL);
    y=cgetg(N,t_COL);
***************
*** 2647,2659 ****
        }
        if (low_stack(lim, stack_lim(av,1)))
        {
! 	GEN *gptr[8];
          int a = 4;
  	if(DEBUGMEM>1) err(warnmem,"smallvectors");
  	gptr[0]=&x; gptr[1]=&y; gptr[2]=&z; gptr[3]=&normax1;
  	if (stockmax)
          {
!           for (i=s+1; i<=stockmax; i++) S[i]=zero;
            gptr[4]=&S; a++;
          }
          if (check)
--- 2648,2665 ----
        }
        if (low_stack(lim, stack_lim(av,1)))
        {
! 	GEN *gptr[8],dum;
          int a = 4;
+         long jj;
  	if(DEBUGMEM>1) err(warnmem,"smallvectors");
  	gptr[0]=&x; gptr[1]=&y; gptr[2]=&z; gptr[3]=&normax1;
  	if (stockmax)
          {
!           for (i=s+1; i<=stockmax; i++)
!           {
!             dum=cgetg(N,t_COL); S[i]=(long)dum;
!             for (jj=1; jj<N; jj++) dum[jj] = zero;
!           }
            gptr[4]=&S; a++;
          }
          if (check)
***************
*** 2662,2667 ****
--- 2668,2674 ----
            for (i=s+1; i<=stockmax; i++) norms[i]=zero;
            a+=3;
          }
+         lim=stack_lim(avma,1);
  	gerepilemany(av2,gptr,a);
        }
        if (DEBUGLEVEL>3)
***************
*** 2746,2753 ****
    }
    u=cgetg(4,t_VEC);
    u[1]=lstoi(s<<1);
!   u[2]=(long)normax1; setlg(S,stockmax+1);
!   u[3]=(long)S; return u;
  }
  
  /* return T2 norm of the polynomial defining nf */
--- 2753,2767 ----
    }
    u=cgetg(4,t_VEC);
    u[1]=lstoi(s<<1);
!   u[2]=(long)normax1;
!   if(stockmax)
!   {
!     setlg(S,stockmax+1);
!     u[3]=(long)S;
!   }
!   else
!     u[3]=lgetg(1,t_MAT);
!   return u;
  }
  
  /* return T2 norm of the polynomial defining nf */
***************
*** 2858,2864 ****
    i = check? 2: 1; if (i == n) i--;
    for (   ; i<n; i++)
    {
!     res = smallvectors(gram,gceil(bound? bound: gcoeff(gram,i,i)),
                         stockmax,flag,prec,check);
      if (!res) goto PRECPB;
      if (!check || lg(res[2]) > 1) break;
--- 2872,2878 ----
    i = check? 2: 1; if (i == n) i--;
    for (   ; i<n; i++)
    {
!     res = smallvectors(gram,bound? bound: gcoeff(gram,i,i),
                         stockmax,flag,prec,check);
      if (!res) goto PRECPB;
      if (!check || lg(res[2]) > 1) break;


Happy computing!
Paul van Wamelen