Karim BELABAS on Wed, 28 Jun 2000 11:46:38 +0200 (MET DST)


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

Re: Garbage collection


[Annegret Weng:]
> I have a problem with my stack. Sometimes I get the error:
>           
>             the PARI stack overflows !
> 
> I think I found the part of my program which is responsible for it but I
> do not know what to do. The program itself works and if I do not get the
> error I get the right answer. My only problem is the stack. 

First you can start with a bigger stack, 10MB should be enough for most
purposes though.

> GEN summand(GEN matrix, GEN delta, GEN epsilon, GEN ganz_vector, int prec)
> {
>   long ltop;
>   
>   /*some calculation - I think this is not important to find my problem
>   but maybe it helps*/
>   GEN zwischen1,zwischen2;
>   GEN vector1=gadd(delta,ganz_vector);
>   zwischen1=gmul(gmul(vector1,matrix),gtrans(vector1));
>   zwischen2=gmul(gdeux,gmul(vector1,gtrans(epsilon)));
>   zwischen1=gadd(zwischen1,zwischen2);
>   zwischen1=gmul(gmul(zwischen1,gi),mppi(prec));
>   
>   ltop=avma;
>   return gerepileupto(ltop,gexp(zwischen1,prec));
> }

This only collects the garbage created between the 'ltop=avma' assignment and
the 'gerepileupto' call: i.e nothing. Corrected version:

GEN summand(GEN matrix, GEN delta, GEN epsilon, GEN ganz_vector, int prec)
{
  long ltop = avma;
  
  /*some calculation - I think this is not important to find my problem
  but maybe it helps*/
  GEN zwischen1,zwischen2;
  GEN vector1=gadd(delta,ganz_vector);
  zwischen1=gmul(gmul(vector1,matrix),gtrans(vector1));
  zwischen2=gmul(gdeux,gmul(vector1,gtrans(epsilon)));
  zwischen1=gadd(zwischen1,zwischen2);
  zwischen1=gmul(gmul(zwischen1,gi),mppi(prec));
  
  return gerepileupto(ltop,gexp(zwischen1,prec));
}

> Then I have a command 
> 
> (*)  ltop=avma;
>      summe=gerepileupto(ltop,gadd(summe,(GEN) 
> summand(omega,delta,epsilon,x_vector,prec)));

This in fact corrects the problem mentionned above, since all garbage created
suring the 'summand' call is cleaned up at this point... [so the gerepileupto
in summand is not necessary if this function is not used anywhere else: the
only caller collects the garbage].

> I have initialized "summe" before.
> Now I put 
> 
>    cout << avma << endl;
> 
> before and after the lines (*) and I can see that the value of avma has
> increased. Why?  I haven't created any new variable. If I do not have the
> gerepileupto-command in (*) it is worse.
> The value of avma increases between 20 and 60. This is not very much but I
> am running through a loop and it sums up. So at the end I get the error
> stated above.
[ actually, the value of avma should _decrease_ as new objects are created: if
avma increases, so does the amount of available memory ]

It's not a matter of creating variables (names), it's a matter of creating
objects (data the name points to):

  summe = gerepileupto(...)

creates the object 'summe', whose size is apparently rather small (between 20
and 60 words) [ even though the name 'summe' was already in use ]

I see nothing wrong with this but make sure your loop doesn't create
additional garbage _before_ the 'ltop = avma' assignment. In particular, the
following might be more appropriate [assuming no other objects than 'summe'
are needed from one iteration to the next]

  ltop = avma;
  for (i=1; i<imax; i++)
  {

    summe = gerepileupto(ltop, ...)
  }

[in fact, it will be much more efficient to collect garbage once in a while,
using what the manual calls 'random' garbage collection]

Please re-read carefully section 4.4 of the user's manual, in particular the
examples, and tell us what we should improve in the exposition there.

Good luck,

  Karim.
__
Karim Belabas                    email: Karim.Belabas@math.u-psud.fr
Dep. de Mathematiques, Bat. 425
Universite Paris-Sud             Tel: (00 33) 1 69 15 57 48
F-91405 Orsay (France)           Fax: (00 33) 1 69 15 60 19
--
PARI/GP Home Page: http://www.parigp-home.de/