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

Potential memory leak in using PyPardisoSolver #76

Open
aatmdelissen opened this issue Dec 12, 2024 · 1 comment
Open

Potential memory leak in using PyPardisoSolver #76

aatmdelissen opened this issue Dec 12, 2024 · 1 comment

Comments

@aatmdelissen
Copy link

The PyPardisoSolver object loads the MKL library on each instance and needs to be released manually by the user, using free_memory(everything=True). If this is not done, memory is leaked and increases for each new solver instance (see example below). I suspect the reason for increasing memory is that the MKL library is loaded each time __init__() is called.

A possible solution might be a loader function that loads the MKL library and stores it in a global variable inside pypardiso.

Example:

import psutil
import pypardiso
import numpy as np
import scipy.sparse as spsp

def test_memory_leak_pypardiso():
    np.random.seed(0)
    K = spsp.rand(1000, 1000, 0.04)
    K = K + K.T  # Make symmetric
    A = spsp.triu(K, format='coo')  # Only use upper part
    # Explicitly set zero diagonal entries, as this is better for Intel Pardiso
    zero_diag_entries, = np.where(A.diagonal() == 0)
    if len(zero_diag_entries) > 0:
        A.row = np.append(A.row, zero_diag_entries)
        A.col = np.append(A.col, zero_diag_entries)
        A.data = np.append(A.data, np.zeros_like(zero_diag_entries))
    A = A.tocsr()

    b = np.random.rand(A.shape[0])

    process = psutil.Process()
    mem, memprev = process.memory_info().rss, 0.0
    for i in range(20):
        solver = pypardiso.PyPardisoSolver(mtype=-2)
        solver.factorize(A)
        solver.solve(A, b)
        # solver.free_memory(everything=True)  # uncomment to release memory

        mem, memprev = process.memory_info().rss, mem
        print(f"mem = {mem}, delta = {mem - memprev}")  # in bytes

Output:

mem = 144121856, delta = 8441856
mem = 153714688, delta = 9592832
mem = 161259520, delta = 7544832
mem = 170823680, delta = 9564160
mem = 179695616, delta = 8871936
mem = 188497920, delta = 8802304
mem = 197685248, delta = 9187328
mem = 206245888, delta = 8560640
mem = 215117824, delta = 8871936
mem = 224055296, delta = 8937472
mem = 233066496, delta = 9011200
mem = 241790976, delta = 8724480
mem = 250490880, delta = 8699904
mem = 258985984, delta = 8495104
mem = 267599872, delta = 8613888
mem = 276353024, delta = 8753152
mem = 285454336, delta = 9101312
mem = 293945344, delta = 8491008
mem = 302751744, delta = 8806400
mem = 311685120, delta = 8933376
@tngTUDOR
Copy link

tngTUDOR commented Dec 12, 2024 via email

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

2 participants