Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

pyAMG leaking memory #198

Closed
dionhaefner opened this issue May 18, 2017 · 19 comments
Closed

pyAMG leaking memory #198

dionhaefner opened this issue May 18, 2017 · 19 comments
Assignees
Milestone

Comments

@dionhaefner
Copy link

Test script:

import numpy as np
import pyamg

stencil = [ [-1,-1,-1],[-1,8,-1],[-1,-1,-1] ]
A = pyamg.gallery.stencil_grid(stencil, (100,100), dtype=float, format='csr')
near_null_space = np.ones(A.shape[0])
ml = pyamg.smoothed_aggregation_solver(A, near_null_space[:, np.newaxis])

for _ in range(10000):
    rhs = np.random.randn(A.shape[0])
    x0 = np.random.randn(A.shape[0])
    solution = ml.solve(b=rhs.flatten(), x0=x0.flatten(), accel="bicgstab")

Running mprof python test.py and mprof plot reveals a steady rise of memory consumption:

memoryleak

Output of pip freeze:

appdirs==1.4.3
cycler==0.10.0
functools32==3.2.3.post2
matplotlib==2.0.2
memory-profiler==0.47
numpy==1.12.1
packaging==16.8
pkg-resources==0.0.0
psutil==5.2.2
py==1.4.33
pyamg==3.2.1
pyparsing==2.2.0
pytest==3.0.7
python-dateutil==2.6.0
pytz==2017.2
scipy==0.19.0
six==1.10.0
subprocess32==3.2.7

Output of python --version:

Python 2.7.12

I am running on Ubuntu 17.04.

@lukeolson
Copy link
Member

Thanks for this. I can reproduce in Python 3 as well. I've narrow the issue to relaxation. If I leave out pre/post smoothing then the memory stays bounded:

figure_1

In fact, just adding gauss_seidel to the loop results in the same thing:

figure_2

I'm using the following:

from memory_profiler import profile

@profile
def prof():
    import numpy as np
    import pyamg

    stencil = [ [-1,-1,-1],[-1,8,-1],[-1,-1,-1] ]
    n = 25
    A = pyamg.gallery.stencil_grid(stencil, (n,n), dtype=float, format='csr')
    ml = pyamg.smoothed_aggregation_solver(A, max_levels=3)

    b = np.random.randn(A.shape[0])
    x = np.zeros(A.shape[0])

    for i in range(50000):
        print(i)
        #solution = ml.solve(b)
        pyamg.relaxation.relaxation.gauss_seidel(A, x, b)

if __name__ == '__main__':
    prof()

@lukeolson
Copy link
Member

It may be the way we're binding with SWIG. I'll take a look. I'm also looking at using pybind11 going forward, which may help.

@lukeolson lukeolson added this to the 4.0.0 milestone Jul 10, 2017
@lukeolson
Copy link
Member

Update. If I wrap gauss_seidel with pybind11, then the memory leak appears to be fixed.

figure_1

In addition, it's slightly faster:

Pybind11:
66.8 ms ± 423 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)

SWIG:
69.4 ms ± 645 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)

It's unclear what is contributing to the memory leak with SWIG. Looking at moving all of amg_core to pybind11 since it was relatively easy.

@dionhaefner
Copy link
Author

Thanks for the update. Looking forward to the fix!

@lukeolson
Copy link
Member

@dionhaefner can you try the pybind11prototype branch? This avoids swig and it requires pybind11 but resolves the memory leak.

@dionhaefner
Copy link
Author

I am currently on vacation. Will try it out next week!

@dionhaefner
Copy link
Author

It still seems to leak a little, but nowhere near as much as before the fix:

figure_1

This is good enough for my purpose, so I would consider the problem fixed for now. Thanks!

@lukeolson
Copy link
Member

@dionhaefner would you mind posting your test script? I agree it's minor but to "leak a little" is still worrisome 😁

@dionhaefner
Copy link
Author

I used the script from my opening post, I think. If you can't reproduce it let me know and I will try again.

@lukeolson
Copy link
Member

Yes, I see something different:

figure_2

As a start, try my script above which only calls pyamg.relaxation.relaxation.gauss_seidel(A, x, b). This may help isolate the issue. I'll move to the solve call now...

@lukeolson
Copy link
Member

lukeolson commented Oct 5, 2017

And if I run your top script ...
figure_3

cycler==0.10.0
matplotlib==2.0.2
memory-profiler==0.47
numpy==1.13.3
psutil==5.3.1
py==1.4.34
pyamg==3.3.0.dev0+bea4090
pybind11==2.2.1
pyparsing==2.2.0
pytest==3.2.3
python-dateutil==2.6.1
pytz==2017.2
scipy==0.19.1
six==1.11.0

@lukeolson
Copy link
Member

@jbschroder can you test?

I pushed two scripts testmemory.py and testmemory2.py in the amg_core directory for lack of a better place.

Then

mprof run testmemory.py
mprof plot

@jbschroder
Copy link
Member

jbschroder commented Oct 5, 2017 via email

@jbschroder
Copy link
Member

test_memory1
test_memory2

@jbschroder
Copy link
Member

cycler==0.10.0
matplotlib==2.0.2
memory-profiler==0.47
numpy==1.13.1
pyamg==3.3.0.dev0+bec23ff
pybind11==2.1.1
Pygments==2.2.0
pyparsing==2.2.0
pytest==3.2.1
python-dateutil==2.6.1
scipy==0.19.1

@dionhaefner
Copy link
Author

That's strange. Let me repeat my test during the weekend and then get back to you.

@lukeolson
Copy link
Member

Thanks. Keep us posted. I also added a np.random.seed so that we're all running the same experiment.

@lukeolson lukeolson self-assigned this Oct 7, 2017
@dionhaefner
Copy link
Author

I can confirm @jbschroder's findings. testmemory2.py leaks a little, but nowhere as much as in my post from Aug 26, which is odd - maybe there was a leak in a dependency like NumPy at the time.

@lukeolson
Copy link
Member

Closing this issue in 851b7b8 (probably should squash)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants