Strange behavior using python interface for Lammps and LIGGGHTS side-by-side

Submitted by TobRas on Thu, 08/18/2016 - 11:00

We have a scenario where our python application runs both Lammps and LIGGGHTS in the same process. However, we have a couple of problems doing so. We are trying to patch and fix the LIGGGHTS interface and therefore your help would be appreciated.

In a preliminary step, we built Lammps and LIGGGHTS(R)-PUBLIC (newest version of both as hosted on github) as shared library (with options "ubuntu_simple" and "fedora_fpic") causing the first issue since LIGGGHTS uses the exact same names as Lammps for its shared library (liblammps.so) and its python wrapper (lammps.py). However, this fix was easy. Renaming the LIGGGHTS library to libliggghts.so and changing the appropriate entries in the wrapper file (renamed accordingly to liggghts.py) solved this issue.
We then moved the shared libraries and the wrapper files into the system and python library path respectively.

However, we faced a strange problem:
When importing Lammps in a python environment, we can get a Lammps wrapper as expected:

import lammps # points to lammps.py
lmp = lammps.lammps() # interface to liblammps.so

Trying the same with LIGGGHTS fails, however:

import liggghts # points to liggghts.py
lgts = liggghts.liggghts() # interface to libliggghts.so but creates a lammps interface

returns again a Lammps instance.

Repeating the last step a few times caused segmentation fault.

Moreover, we had the same problem the other way round: Importing LIGGGHTS first results in returning LIGGGHTS instances only, independent of the command "lmp = lammps.lammps()" or "lgts = liggghts.liggghts()" being used.

Our purpose is, however, to have a lammps and a liggghts instance at the same time. We checked the wrapper files lammps.py and liggghts.py and didn't find anything causing this problem. So, we assume that it is somewhere in the shared library (some naming confusion).

Moreover, we set `-soname=libliggghts.so` linker parameter to make sure that the shared libraries would have their unique so name. We also made sure that there was no obvious error in place, e.g. pointing to the same library. We also traced the confusing error back to the shared-library itself, but not further. Finally, we came to the conclusion that, for any unknown reason inside the shared library of Lammps and LIGGGHTS, they cannot share one process. Instantiating a Lammps class from any of the python wrappers, will cause some state change somewhere in the process that will render the second instantiation to have no effect.

Therefore, we'd like to ask if anybody of you knows about this problem and can give us a hint, how to solve the problem or which portion of the code has to be modified.

Thanks a lot in advance and best regards,

Tobias

ckloss's picture

ckloss | Tue, 09/13/2016 - 15:06

Hi Tobias,

thanks for letting us know! I put it on the list of things to have a look at for our team before the next release!

Thanks and best wishes!
Christoph

arnom's picture

arnom | Fri, 01/13/2017 - 15:53

Hi Tobias,

I suspect that this issue still persists. Can you please copy the following into a file python.patch:

19c19
< class lammps:
---
> class liggghts:
22,23c22,23
< # load liblammps.so by default
< # if name = "g++", load liblammps_g++.so
---
> # load libliggghts.so by default
> # if name = "g++", load libliggghts_g++.so
26,27c26,27
< if not name: self.lib = CDLL("liblammps.so",RTLD_GLOBAL)
< else: self.lib = CDLL("liblammps_%s.so" % name,RTLD_GLOBAL)
---
> if not name: self.lib = CDLL("libliggghts.so",RTLD_GLOBAL)
> else: self.lib = CDLL("libliggghts_%s.so" % name,RTLD_GLOBAL)
31c31
< raise OSError,"Could not load LAMMPS dynamic library"
---
> raise OSError,"Could not load LIGGGHTS dynamic library"
39c39
< cmdargs.insert(0,"lammps.py")
---
> cmdargs.insert(0,"liggghts.py")

and then run
patch lammps.py < python.patch in the folder where your lammps.py is located.

Please let me know if this solves the issue.

Best regards,
Arno

DCS team member & LIGGGHTS(R) core developer

aaigner's picture

aaigner | Mon, 01/16/2017 - 17:30

Hello Tobias,

I tested it on my machine with the changes provided from arnom. By renaming the class within the liggghts.py (original lammps.py) you can create one instance of each class and thus everything should work as expected.

I hope I did not forget any own changes and that it will work on your machine too.
Best regards,
Andreas