aaspip / pyekfmm

A python package for 3D fast-marching-based traveltime calculation and its applications in seismology
GNU General Public License v3.0
47 stars 10 forks source link

Memory leak problem #2

Closed Dengda98 closed 1 year ago

Dengda98 commented 1 year ago

Hi, Thank you for this great project.

I observed a memory leak problem when the traveltime field was computed multiple times. See toy code below.


import pyekfmm as fmm 
import numpy as np 
import psutil

process = psutil.Process()

ar = [6371, 0.0, 1]
at = [57.5, 0.05789473684210478, 96]
ap = [90.5, 0.05960264900662082, 152]

vel = np.sin(4*np.pi/at[-1]*np.arange(at[-1]))[None, :] * np.sin(4*np.pi/ap[-1]*np.arange(ap[-1]))[:, None] * 0.1 + 2

velf = vel.flatten(order='F').astype('f')

src = np.array([6371., 60.81, 91.759])

srclat_dec = (src[1]-at[0])/at[1]+1
srclon_dec = (src[2]-ap[0])/ap[1]+1

for i in range(1000000):
    t1 = fmm.eikonal_rtp(velf, src, ar, at, ap, order=1)
    t = t1.reshape((at[-1], ap[-1]), order='F').T

    sta_colat = 58.3
    sta_lon = 92.4
    slat = (sta_colat-at[0])/at[1] + 1
    slon = (sta_lon-ap[0])/ap[1] + 1

    tlon, tlat = np.gradient(t, at[1], ap[1])

    paths, nrays = fmm.stream2d(-tlat, -tlon, slat, slon, step=0.1)

    if i%500==0:
        print(f'i={i:0>7d}, rss={process.memory_info().rss/1024:>12.3f} Mb')

and the output was like

i=0000000, rss=  102932.000 Mb
i=0000500, rss=  207940.000 Mb
i=0001000, rss=  312648.000 Mb
i=0001500, rss=  417712.000 Mb
i=0002000, rss=  522520.000 Mb
i=0002500, rss=  627592.000 Mb
i=0003000, rss=  732400.000 Mb
i=0003500, rss=  837472.000 Mb
i=0004000, rss=  942280.000 Mb
i=0004500, rss= 1047352.000 Mb
i=0005000, rss= 1152160.000 Mb
i=0005500, rss= 1257232.000 Mb
i=0006000, rss= 1362040.000 Mb
i=0006500, rss= 1466848.000 Mb
i=0007000, rss= 1571920.000 Mb
i=0007500, rss= 1676728.000 Mb
i=0008000, rss= 1781800.000 Mb
i=0008500, rss= 1886608.000 Mb
......

When I check your raw C code eikonal.c, I noticed that the allocated memory using malloc command has not been freed, and function fastmarch_close also appears to have been forgotten to be called. After I add few codes to free the memory, the output seems normal:

i=0000000, rss=  102236.000 Mb
i=0000500, rss=  102716.000 Mb
i=0001000, rss=  102716.000 Mb
i=0001500, rss=  102716.000 Mb
i=0002000, rss=  102716.000 Mb
i=0002500, rss=  102716.000 Mb
i=0003000, rss=  102716.000 Mb
i=0003500, rss=  102716.000 Mb
i=0004000, rss=  102716.000 Mb
i=0004500, rss=  102716.000 Mb
i=0005000, rss=  102716.000 Mb
i=0005500, rss=  102716.000 Mb
i=0006000, rss=  102716.000 Mb
i=0006500, rss=  102716.000 Mb
i=0007000, rss=  102716.000 Mb
i=0007500, rss=  102716.000 Mb
i=0008000, rss=  102716.000 Mb
i=0008500, rss=  102716.000 Mb
......
chenyk1990 commented 1 year ago

Thanks for pointing out this issue. I have revised the eikonal.c code to address it.

Please check to see if the new one makes sense. Let me know if I overlook sth. Also, if you would like to make a contribution to this project, please let me know privately.

Thanks, Yangkang

On Sat, Aug 5, 2023 at 2:52 AM Dengda98 @.***> wrote:

Hi, Thank you for this great project.

I observed a memory leak problem when the traveltime field was computed multiple times. See toy code below.

import pyekfmm as fmm import numpy as np import psutil process = psutil.Process() ar = [6371, 0.0, 1]at = [57.5, 0.05789473684210478, 96]ap = [90.5, 0.05960264900662082, 152] vel = np.sin(4np.pi/at[-1]np.arange(at[-1]))[None, :] np.sin(4np.pi/ap[-1]np.arange(ap[-1]))[:, None] 0.1 + 2 velf = vel.flatten(order='F').astype('f') src = np.array([6371., 60.81, 91.759]) srclat_dec = (src[1]-at[0])/at[1]+1srclon_dec = (src[2]-ap[0])/ap[1]+1 for i in range(1000000): t1 = fmm.eikonal_rtp(velf, src, ar, at, ap, order=1) t = t1.reshape((at[-1], ap[-1]), order='F').T

sta_colat = 58.3
sta_lon = 92.4
slat = (sta_colat-at[0])/at[1] + 1
slon = (sta_lon-ap[0])/ap[1] + 1

tlon, tlat = np.gradient(t, at[1], ap[1])

paths, nrays = fmm.stream2d(-tlat, -tlon, slat, slon, step=0.1)

if i%500==0:
    print(f'i={i:0>7d}, rss={process.memory_info().rss/1024:>12.3f} Mb')

and the output was like

i=0000000, rss= 102932.000 Mb i=0000500, rss= 207940.000 Mb i=0001000, rss= 312648.000 Mb i=0001500, rss= 417712.000 Mb i=0002000, rss= 522520.000 Mb i=0002500, rss= 627592.000 Mb i=0003000, rss= 732400.000 Mb i=0003500, rss= 837472.000 Mb i=0004000, rss= 942280.000 Mb i=0004500, rss= 1047352.000 Mb i=0005000, rss= 1152160.000 Mb i=0005500, rss= 1257232.000 Mb i=0006000, rss= 1362040.000 Mb i=0006500, rss= 1466848.000 Mb i=0007000, rss= 1571920.000 Mb i=0007500, rss= 1676728.000 Mb i=0008000, rss= 1781800.000 Mb i=0008500, rss= 1886608.000 Mb ......

When I check your raw C code eikonal.c, I noticed that the allocated memory using malloc command has not been freed, and function fastmarch_close also appears to have been forgotten to be called. After I add few codes to free the memory, the output seems normal:

i=0000000, rss= 102236.000 Mb i=0000500, rss= 102716.000 Mb i=0001000, rss= 102716.000 Mb i=0001500, rss= 102716.000 Mb i=0002000, rss= 102716.000 Mb i=0002500, rss= 102716.000 Mb i=0003000, rss= 102716.000 Mb i=0003500, rss= 102716.000 Mb i=0004000, rss= 102716.000 Mb i=0004500, rss= 102716.000 Mb i=0005000, rss= 102716.000 Mb i=0005500, rss= 102716.000 Mb i=0006000, rss= 102716.000 Mb i=0006500, rss= 102716.000 Mb i=0007000, rss= 102716.000 Mb i=0007500, rss= 102716.000 Mb i=0008000, rss= 102716.000 Mb i=0008500, rss= 102716.000 Mb ......

— Reply to this email directly, view it on GitHub https://github.com/aaspip/pyekfmm/issues/2, or unsubscribe https://github.com/notifications/unsubscribe-auth/ADHCWEXXJNX25BFHNPS3OGTXTX3SJANCNFSM6AAAAAA3FBVLII . You are receiving this because you are subscribed to this thread.Message ID: @.***>

Dengda98 commented 1 year ago

Thanks, the new one works well :)