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

[BUGFIX] Memory leak: free C++ memory before deallocing Python object #4164

Merged
merged 1 commit into from
Oct 13, 2022

Conversation

cphyc
Copy link
Member

@cphyc cphyc commented Oct 12, 2022

PR Summary

This fixes a memory leak issue reported in https://mail.python.org/archives/list/yt-users@python.org/thread/H3WCK5PA2WNGEDBVHOCWV5YCPV2ZYIXY/.

The root cause of the issue is that, for octree datasets (RAMSES, ART), the base grid is stored using a tree-like structure that is allocated in C. Unfortunately, when associated Python gets deleted, we were not freeing the memory in the process.

This PR fixes this by explicitely removing all entries in the query tree updon deallocation of the Python object.

Notes

For very large datasets, the operation may be quite slow O(N log(N)), where N is the number of base grid elements. For a RAMSES dataset with levelmin=8, that would be ~3 × 8 × (2^8)^3 operations.
It should in principle be possible to deallocate everything in 3 × N operations by beeing clever. Alternatively, a longer term solution would be to move away from the manually-implemented tsearch function and use e.g. a C++-backed regular hashmap.

@cphyc cphyc changed the title Cleanup memory before deallocing [BUGFIX] Memory leak: free C++ memory before deallocing Python object Oct 12, 2022
@matthewturk
Copy link
Member

The only reason, if I remember correctly, that I used tsearch instead of something (better) like C++ hashmap was to try to avoid any additional dependencies and remain "pure C." I am not sure those are concerns anymore!

cdef OctKey *ikey
for i in range(self.num_root):
ikey = &self.root_nodes[i]
tdelete(<void *>ikey, &self.tree_root, root_node_compare)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm struggling to find documentation about this. Can you show me where tdelete comes from ?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It shows up in man tdelete and is part of search.h https://pubs.opengroup.org/onlinepubs/009695399/functions/tdelete.html

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thanks ! I don't feel competent to review this from the technical angle, but I can check that this resolves the issue. Will report back as soon as I'm able to.

Copy link
Member Author

@cphyc cphyc Oct 13, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Soooo, actually, it seems to be shadowed by our own version of tdelete if you feel like reading good ol' C!

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh good! I forgot we had this.

@neutrinoceros neutrinoceros added this to the 4.1.1 milestone Oct 12, 2022
Copy link
Member

@neutrinoceros neutrinoceros left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I confirm that this fixes the memory leak, thank you !
I'll refrain from merging right away in case @matthewturk wants to make a more technical review

@cphyc
Copy link
Member Author

cphyc commented Oct 13, 2022

I guess the only question on the table is whether we want to roll with this fix or remove tsearch/tdelete altogether? We could use a C++ map https://github.com/cython/cython/blob/master/Cython/Includes/libcpp/map.pxd for example.

@neutrinoceros
Copy link
Member

neutrinoceros commented Oct 13, 2022

AFAIC I'd favour the current, minimal fix, since we should backport it and it's preferable to keep backports's footprints as small as possible. (which doesn't prevent doing the larger clean up later on the dev branch)

Copy link
Member

@matthewturk matthewturk left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lgtm

@neutrinoceros neutrinoceros merged commit 9abad77 into yt-project:main Oct 13, 2022
meeseeksmachine pushed a commit to meeseeksmachine/yt that referenced this pull request Oct 13, 2022
neutrinoceros added a commit that referenced this pull request Oct 14, 2022
…4-on-yt-4.1.x

Backport PR #4164 on branch yt-4.1.x ([BUGFIX] Memory leak: free C++ memory before deallocing Python object)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants