-
-
Notifications
You must be signed in to change notification settings - Fork 701
Closed
Description
There's a fairly large memory leak that shows up when converting from ZZ and QQ to numpy types. Here's an example:
sage: ls = range(50000)
sage: import numpy
sage: A.<x> = ZZ[]
sage: f = x**3-2*x+1
sage: type(f)
<type 'sage.rings.polynomial.polynomial_integer_dense_ntl.Polynomial_integer_dense_ntl'>
sage: def my_func(f):
tmp = numpy.atleast_1d(f.list())
tmp2 = tmp.astype(float)
....:
sage: get_memory_usage()
'124M+'
sage: for _ in ls: my_func(f)
....:
sage: get_memory_usage()
'133M+'
sage: f = f.change_ring(QQ)
sage: type(f)
<class 'sage.rings.polynomial.polynomial_element_generic.Polynomial_rational_dense'>
sage: get_memory_usage()
'133M+'
sage: for _ in ls: my_func(f)
....:
sage: get_memory_usage()
'150M+'
sage: f = f.change_ring(RDF)
sage: get_memory_usage()
'150M+'
sage: for _ in ls: my_func(f)
....:
sage: get_memory_usage()
'150M+'
This was first noted in trac #2239, where we use numpy.roots(f.list()) instead of the above, but I think it ultimately gets traced to the code above. As you can see, it leaks for both ZZ and QQ, but not for RDF -- or most other types one might try. However, since RR uses GMP, it leaks too:
sage: ls = range(50000)ent Mercurial branch is: abvar
sage: import numpy
sage: B.<x> = RR[]
sage: f = x**3-2*x+1
sage: type(f)
<class 'sage.rings.polynomial.polynomial_element_generic.Polynomial_generic_dense_field'>
sage: def my_func(f):
....: tmp = numpy.atleast_1d(f.list())
....: tmp2 = tmp.astype(float)
....:
sage: def my_func2(f):
tmp = numpy.atleast_1d([ RR(a) for a in f.list() ])
tmp2 = tmp.astype(float)
....:
sage: get_memory_usage()
'124M+'
sage: for _ in ls: my_func(f)
....:
sage: get_memory_usage()
'124M+'
sage: for _ in ls: my_func2(f)
....:
sage: get_memory_usage()
'138M+'
There's a known workaround -- don't convert directly between these types. For example:
sage: def my_func2(f):
tmp = numpy.atleast_1d([ int(a) for a in f.list() ])
tmp2 = tmp.astype(float)
....:
sage: get_memory_usage()
'150M+'
sage: for _ in ls: my_func2(f)
....:
sage: get_memory_usage()
'150M+'
Several people looked at this during SD8, but didn't come up with a solution. If anyone hits on anything, please let us know!
Component: memleak
Issue created by migration from https://trac.sagemath.org/ticket/2383