Repository navigation
Memory management issue in the diskless API #317
Description
Activity
Fixing API issues is a high priority for me, but I'll be busy for the next 2 weeks with moving and switching jobs, so I can't deal with this immediately. MOPAC development will no longer be part of my new job and career path (I couldn't find a job that would allow me to continue developing for MOPAC professionally), but I'll still be maintaining MOPAC for the foreseeable future as an unpaid hobby.
I just looked over the MOZYME initialization in the API, and it looks like I'm not initializing all of the sizing information for the MOZYME API data structure when it is created from scratch in Python. I initialize the primary size variable,
numat, to zero and it is safe to infer that the other array size variables are zero when that is zero, but I think this needs to be done explicitly for all of the logic on the Fortran side to behave correctly. This problem isn't necessarily the cause of the bug you are reporting, but it is a reasonably likely candidate.I looked at it a bit more and I tracked the issue down to parsing the bond orders in mopac_api_finalize.F90.
The code was writing beyond the end of the
bond_orderarray in the mozyme part of the mopac_record routine. This is caused by a mismatch between the 1st pass and 2nd pass loops. I suppose the 1st pass is correct, while the 2nd pass was writing the (i|i) term multiple times as it was in the loop over j.I reworked the 2nd pass loop to match pass 1, and it solved the crashes. I also verified that the
kknow index stays in the allocated bounds. I haven't looked at the bond order matrix it produces, but I think the logic of the algorithm is now correct - please check it too. I created a pull request hereNote that there may be other bugs unrelated to this issue - the example I posted above still crashes with an error elsewhere in the code, but this fix helped with multiple other calculations that previously failed.
I also identified another issue that caused the example to crash for some molecules: I had not set the
system.natom_movevariable. Initialising it to the number of atoms in the system reliably resolved the issue.I did not expect this for a single-point calculation, which should not depend on setting the number of moving atoms. The segfault error message was not very helpful in identifying the issue. Ideally, this could be solved by either fixing the MOPAC code that computes the derivatives to accept the default value of 0, or by ensuring that the API does not use 0 as a default (it would make more sense to make all atoms moving as a default used silently), and providing a descriptive error message when it is deliberately set to 0.
natom_moveis relevant to single-point calculations because you can choose to evaluate forces on a limited set of atoms (move is referring to atoms treated by MOPAC as a dynamical degree of freedom for all purposes, including gradient evaluation). MOPAC is very flexible in turning dynamic variables on or off (each Cartesian coordinate of each atom can be flagged in a MOPAC input file), but I wanted to streamline it in the API because that is too much flexibility for the vast majority of use. Specifically, the current design is mainly catering to molecular docking, which I see as the primary use case of freezing some atoms. If there is enough interest, future major-version updates to the API could change how dynamic variables are chosen (e.g. an atom-based freeze/move flag might be a better compromise).I'll consider a better choice of defaults as I debug and adjust the Python wrapper to the API. Python might accommodate this with
Noneinitializations that are converted to sensible defaults before making the API calls.
Describe the bug
I ran into a problem with MOZYME calculations ran through the API via the mopactools python interface. When The calculations of larger molecules fail with a core dump (but water molecule is OK). The same calculation ran normally with MOPAC works, so the issue seems to be specific to the API. I tried to debug it, and found that the calculation actually finishes (the energy is calculated), but then it crashes when de-allocating the arrays.
To Reproduce
Here is a minimal example where normal SCF works and MOZYME fails:
Operating system
Linux. I get the same issue (sometimes with different memory-management related error messages) when using libmopac.so from the conda package as well as one I built myself.