Memory Leak in mutipolynomial evaluation

37 views
Skip to first unread message

Gabriel Furstenheim Milerud

unread,
May 25, 2014, 5:01:59 AM5/25/14
to sage-s...@googlegroups.com
There is a memory leak in the evaluation of multivariable polynomials:

-C.<x,y,z>=GF(2)[]
-f=x^4+x*y^3+z^6

-get_memory_usage()
.....1014.47265625
- for i in xrange(1000000):
    a=f(1,0,0)
-get_memory_usage()
.....1052.47265625

I think the problem is in the implementation of the __call__ method in rings/polynomials/multi_polynomial_element.py . It has:

 def __call__(self,*x,**kwds): 

[...]

 try:
    K = x[0].parent()
  except AttributeError:
    K = self.parent().base_ring()
  y = K(0)
  for (m,c) in self.element().dict().iteritems():
     y += c*misc.mul([ x[i]**m[i] for i in range(n) if m[i] != 0])
  return y

So in every loop a new ring K is created and saved

Simon King

unread,
May 25, 2014, 8:08:54 AM5/25/14
to sage-s...@googlegroups.com
Hi Gabriel,

On 2014-05-25, Gabriel Furstenheim Milerud <furst...@gmail.com> wrote:
> There is a memory leak in the evaluation of multivariable polynomials:
>
> -C.<x,y,z>=GF(2)[]
> -f=x^4+x*y^3+z^6
>
> -get_memory_usage()
> .....1014.47265625
> - for i in xrange(1000000):
> a=f(1,0,0)
> -get_memory_usage()
> .....1052.47265625

Note that you first request the memory usage before assigning
"a=f(1,0,0)". But to some extend, I can confirm an increase of memory
usage (with Sage 6.2):

sage: C.<x,y,z> = GF(2)[]
sage: f = x^4+x*y^3+z^6
sage: a = f(1,0,0)
sage: get_memory_usage()
176.08984375
sage: for i in xrange(1000000):
....: a = f(1,0,0)
....:
sage: get_memory_usage()
198.08984375
sage: for i in xrange(1000000):
....: a = f(1,0,0)
....:
sage: get_memory_usage()
222.08984375


We have an increase of 22-24 megabytes in 10^6 rounds, thus 23-25 byte per round.
Actually I wonder how such a tiny leak is even possible! In any case, it
should be fixed.

> try:
> K = x[0].parent()
> except AttributeError:
> K = self.parent().base_ring()
> y = K(0)
> for (m,c) in self.element().dict().iteritems():
> y += c*misc.mul([ x[i]**m[i] for i in range(n) if m[i] != 0])
> return y
>
> So in every loop a new ring K is created and saved

No, K is already there, it is either x[0].parent() or self.parent().base_ring().
Actually it is K=GF(2), if I am not mistaken. Moreover, I don't think this branch
of code is evaluated in your example.

Anyway, thank you for the example!
Best regards,
Simon


leif

unread,
May 25, 2014, 8:40:56 AM5/25/14
to sage-s...@googlegroups.com
I'm getting more:

sage: import gc
sage: gc.collect()
182
sage: get_memory_usage()
292.03515625
sage: C.<x,y,z>=GF(2)[]
sage: f=x^4+x*y^3+z^6
sage: get_memory_usage()
292.19921875
sage: for i in xrange(1000000):
....: a=f(1,0,0)
....:
sage: get_memory_usage()
338.19921875
sage: gc.collect()
11
sage: get_memory_usage()
338.19921875

(Sage 6.2, MacOS X 10.6 x86_64)


-leif

--
() The ASCII Ribbon Campaign
/\ Help Cure HTML E-Mail

Jori Mantysalo

unread,
May 26, 2014, 3:34:10 AM5/26/14
to sage-s...@googlegroups.com
On Sun, 25 May 2014, Gabriel Furstenheim Milerud wrote:

> There is a memory leak in the evaluation of multivariable polynomials:

I wrote about same problem on sage-devel at 2014-05-08.

> -C.<x,y,z>=GF(2)[]

My example did not use GF, just QQ.

--
Jori Mäntysalo

Gabriel Furstenheim Milerud

unread,
May 28, 2014, 2:54:12 PM5/28/14
to sage-s...@googlegroups.com
Hi Simon,

You're completely right. Actually I messed up the libraries, the __call__ method used should be the one from Mpolynomial_libsingular.
Reply all
Reply to author
Forward
0 new messages