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/