| 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/