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

Memory leak with Chem.Atom() constructor #2639

Closed
AlanKerstjens opened this issue Sep 4, 2019 · 6 comments
Closed

Memory leak with Chem.Atom() constructor #2639

AlanKerstjens opened this issue Sep 4, 2019 · 6 comments
Assignees
Labels
Milestone

Comments

@AlanKerstjens
Copy link
Contributor

AlanKerstjens commented Sep 4, 2019

The following bit of code quickly gobbles up all available memory. Maybe I'm missing something but it looks like a memory leak.

from rdkit import Chem

while True:
    atom = Chem.Atom(0)

RDKit version: 2019.03.3.
Platform: Ubuntu (release 18.04)

I'm trying to use this code to create pseudoatoms. Is there perhaps any alternative?

@bp-kelley
Copy link
Contributor

bp-kelley commented Sep 4, 2019

This is an unfortunate by product of wrapping a c++ library. An Atom is designed to be cleaned up when a molecule is destructed. The overhead of bookkeeping if an atom is "owned" by a molecule hasn't been implemented in Python since the basic design of RDKit implies that an Atom really should be managed by a molecule. To do this in python, you'll need to add the atom to a molecule.

>>> from rdkit.Chem import RWMol, Atom
>>> while True:
...   m = RWMol()
...   m.AddAtom(Atom(6))

We probably should have a function:

  atom = m.AddAtom(6)

for quality of life.

@AlanKerstjens
Copy link
Contributor Author

Thank you for your swift reply!

The usage example you provided is very similar to what I would like to do: create an Atom and add it to a RWMol. But even when the RWMol is destructed the memory associated with an explicitly constructed Atom doesn't seem to be recovered. For instance, when running the code you provided I run into the same memory issue.

By contrast, when adding an Atom from a different source (e.g. another Mol) this doesn't happen:

from rdkit import Chem

benzene = Chem.MolFromSmiles("c1ccccc1")

while True:
    mol = Chem.RWMol()
    mol.AddAtom(benzene.GetAtomWithIdx(0))

I also tried wrapping the molecule creation in a function and manually deleting the reference to the molecule just to make sure that the refcount drops to 0 and that the Mol is destructed, but I can't seem to free up the memory.

@bp-kelley
Copy link
Contributor

Atoms are definitely leaking. I'm just unsure of why. The reason that adding an atom from another molecule is working, is that the other molecule has ownership and deletes the atom.

This is a silly stop gap for now, I'll file it as a bug and investigate it.

@bp-kelley bp-kelley self-assigned this Sep 4, 2019
@bp-kelley bp-kelley added the bug label Sep 4, 2019
@bp-kelley bp-kelley added this to the 2019_03_5 milestone Sep 4, 2019
@AlanKerstjens
Copy link
Contributor Author

AlanKerstjens commented Sep 5, 2019

Thanks for the follow up.

In the meantime, if anyone else runs into this problem, it seems to be possible to initialize only one ownerless Atom and then re-use this Atom whenever needed. The downside is that if one needs to use different types of Atoms for each molecule it requires some extra function calls. It isn't very elegant but it gets the job done.

from rdkit import Chem

atom = Chem.Atom(0)

while True:
    mol = Chem.RWMol()
    atom_idx = mol.AddAtom(atom)
    mol.GetAtomWithIdx(atom_idx).SetAtomicNum(6)

@bp-kelley
Copy link
Contributor

@AlanKerstjens

Yeah, that's suboptimal :) Although you could do:

C = Atom(6)
N = Atom(7)

mol.AddAtom(C)

which might be more literal.

I think I'll pass this by Greg:

mol.AddAtom(6)

to avoid creating a leaky atom at all.

@greglandrum greglandrum changed the title Potential memory leak with Chem.Atom() constructor Memory leak with Chem.Atom() constructor Oct 7, 2019
greglandrum added a commit to greglandrum/rdkit that referenced this issue Oct 7, 2019
Required some changes to the StereoGroups wrapper code too
@greglandrum
Copy link
Member

I don't think Chem.Atom(6) should be something that leaks. The change to avoid it (#2639) is straightforward.

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

No branches or pull requests

3 participants