openmm / openmm-plumed

OpenMM plugin to interface with PLUMED
55 stars 23 forks source link

Ongoing ABI problem #24

Closed gitkol closed 4 years ago

gitkol commented 4 years ago

Hi, I know there have been multiple tickets addressing this problem, I myself contributed to them too, but the problem still seems to persist with the latest conda OpenMM build. I installed OpenMM with conda under anaconda3, 'conda install -c omnia/label/cuda100 openmm' and installed openmm-plumed with cmake. The only way openmm-plumed compiled was with this setting:

$ grep ABI CMakeCache.txt
CMAKE_CXX_FLAGS:STRING=-D_GLIBCXX_USE_CXX11_ABI=0

With ABI=1 or 'CMAKE_CXX_FLAGS:STRING=' I get the following error:

$ make install
-- Configuring done
-- Generating done
-- Build files have been written to: /raid/istvan/opt/openmm-plumed-build
[  3%] Building CXX object CMakeFiles/OpenMMPlumed.dir/openmmapi/src/PlumedForce.cpp.o
[  7%] Building CXX object CMakeFiles/OpenMMPlumed.dir/openmmapi/src/PlumedForceImpl.cpp.o
[ 11%] Building CXX object CMakeFiles/OpenMMPlumed.dir/serialization/src/PlumedForceProxy.cpp.o
[ 15%] Building CXX object CMakeFiles/OpenMMPlumed.dir/serialization/src/PlumedSerializationProxyRegistration.cpp.o
[ 19%] Linking CXX shared library libOpenMMPlumed.so
[ 19%] Built target OpenMMPlumed
[ 23%] Building CXX object serialization/tests/CMakeFiles/TestSerializePlumedForce.dir/TestSerializePlumedForce.cpp.o
[ 26%] Linking CXX executable TestSerializePlumedForce
CMakeFiles/TestSerializePlumedForce.dir/TestSerializePlumedForce.cpp.o: In function `testSerialization()':
TestSerializePlumedForce.cpp:(.text+0x27f): undefined reference to `OpenMM::throwException(char const*, int, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)'
CMakeFiles/TestSerializePlumedForce.dir/TestSerializePlumedForce.cpp.o: In function `void OpenMM::XmlSerializer::serialize<PlumedPlugin::PlumedForce>(PlumedPlugin::PlumedForce const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::ostream&)':
TestSerializePlumedForce.cpp:(.text._ZN6OpenMM13XmlSerializer9serializeIN12PlumedPlugin11PlumedForceEEEvPKT_RKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERSo[_ZN6OpenMM13XmlSerializer9serializeIN12PlumedPlugin11PlumedForceEEEvPKT_RKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERSo]+0x72): undefined reference to `OpenMM::SerializationNode::setName(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)'
TestSerializePlumedForce.cpp:(.text._ZN6OpenMM13XmlSerializer9serializeIN12PlumedPlugin11PlumedForceEEEvPKT_RKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERSo[_ZN6OpenMM13XmlSerializer9serializeIN12PlumedPlugin11PlumedForceEEEvPKT_RKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERSo]+0xe3): undefined reference to `OpenMM::SerializationNode::hasProperty(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) const'
TestSerializePlumedForce.cpp:(.text._ZN6OpenMM13XmlSerializer9serializeIN12PlumedPlugin11PlumedForceEEEvPKT_RKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERSo[_ZN6OpenMM13XmlSerializer9serializeIN12PlumedPlugin11PlumedForceEEEvPKT_RKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERSo]+0x123): undefined reference to `OpenMM::SerializationProxy::getTypeName[abi:cxx11]() const'
TestSerializePlumedForce.cpp:(.text._ZN6OpenMM13XmlSerializer9serializeIN12PlumedPlugin11PlumedForceEEEvPKT_RKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERSo[_ZN6OpenMM13XmlSerializer9serializeIN12PlumedPlugin11PlumedForceEEEvPKT_RKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERSo]+0x185): undefined reference to `OpenMM::SerializationProxy::getTypeName[abi:cxx11]() const'
TestSerializePlumedForce.cpp:(.text._ZN6OpenMM13XmlSerializer9serializeIN12PlumedPlugin11PlumedForceEEEvPKT_RKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERSo[_ZN6OpenMM13XmlSerializer9serializeIN12PlumedPlugin11PlumedForceEEEvPKT_RKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERSo]+0x1cd): undefined reference to `OpenMM::SerializationNode::setStringProperty(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)'
../../libOpenMMPlumed.so: undefined reference to `OpenMM::Platform::createKernel(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, OpenMM::ContextImpl&) const'
../../libOpenMMPlumed.so: undefined reference to `OpenMM::SerializationNode::getIntProperty(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) const'
../../libOpenMMPlumed.so: undefined reference to `OpenMM::SerializationNode::getStringProperty(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) const'
../../libOpenMMPlumed.so: undefined reference to `OpenMM::SerializationNode::setIntProperty(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, int)'
../../libOpenMMPlumed.so: undefined reference to `OpenMM::SerializationProxy::SerializationProxy(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)'
collect2: error: ld returned 1 exit status
make[2]: *** [serialization/tests/CMakeFiles/TestSerializePlumedForce.dir/build.make:96: serialization/tests/TestSerializePlumedForce] Error 1
make[1]: *** [CMakeFiles/Makefile2:123: serialization/tests/CMakeFiles/TestSerializePlumedForce.dir/all] Error 2
make: *** [Makefile:141: all] Error 2

With ABI=0, openmm-plumed successfully compiles but then when I run a test job with PlumedForce I get the following error:

Traceback (most recent call last):
  File "run-meta-eABF-1D-adaptive-path.py", line 8, in <module>
    from openmmplumed import PlumedForce
  File "/raid/istvan/anaconda3/lib/python3.7/site-packages/openmmplumed.py", line 15, in <module>
    import _openmmplumed
ImportError: /raid/istvan/anaconda3/lib/python3.7/site-packages/_openmmplumed.cpython-37m-x86_64-linux-gnu.so: undefined symbol: _ZNK12PlumedPlugin11PlumedForce9getScriptB5cxx11Ev

which indicates a Cxx11 issue. So, it seems that OpenMM 7.4.1 was compiled with a different ABI setting. Can you tell me what setting it was? I should compile openmm-plumed with the same setting, but so far I could only compile it with ABI=0 and that doesn't work.

Hopefully, the following ldd output might give a clue. First, I compared libOpenMMPlumed.so in the openmm-plumed-build directory and in the /raid/istvan/anaconda3/pkgs/openmm-7.4.1-py37_cuda100_rc_1/lib directory. The latter was created by the 'make PythonInstall' command and I would think it should be identical with the one in the local build directory.

$ ll /raid/istvan/anaconda3/pkgs/openmm-7.4.1-py37_cuda100_rc_1/lib/libOpenMMPlumed.so
-rw-r--r-- 1 istvan istvan 66944 Jan 22 22:40 /raid/istvan/anaconda3/pkgs/openmm-7.4.1-py37_cuda100_rc_1/lib/libOpenMMPlumed.so
$ ll /raid/istvan/opt/openmm-plumed-build/libOpenMMPlumed.so 
-rwxr-xr-x 1 istvan istvan 66944 Jan 22 22:40 /raid/istvan/opt/openmm-plumed-build/libOpenMMPlumed.so

They are the same size, but their ldd output is diiferent:

$ ldd /raid/istvan/anaconda3/pkgs/openmm-7.4.1-py37_cuda100_rc_1/lib/libOpenMMPlumed.so
    linux-vdso.so.1 (0x00007ffef03fc000)
    libOpenMM.so => not found
    libstdc++.so.6 => /usr/lib/x86_64-linux-gnu/libstdc++.so.6 (0x00007f9eb561f000)
    libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007f9eb5407000)
    libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f9eb5016000)
    libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007f9eb4c78000)
    /lib64/ld-linux-x86-64.so.2 (0x00007f9eb5bb4000)
$ ldd /raid/istvan/opt/openmm-plumed-build/libOpenMMPlumed.so 
    linux-vdso.so.1 (0x00007fff7c396000)
    libOpenMM.so => /raid/istvan/anaconda3/pkgs/openmm-7.4.1-py37_cuda100_rc_1/lib/libOpenMM.so (0x00007f7f30158000)
    libstdc++.so.6 => /usr/lib/x86_64-linux-gnu/libstdc++.so.6 (0x00007f7f2fdcf000)
    libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007f7f2fbb7000)
    libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f7f2f7c6000)
    librt.so.1 => /lib/x86_64-linux-gnu/librt.so.1 (0x00007f7f2f5be000)
    libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007f7f2f3ba000)
    libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007f7f2f19b000)
    libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007f7f2edfd000)
    /lib64/ld-linux-x86-64.so.2 (0x00007f7f308c0000)

So, it seems that libOpenMMPlumed.so generated by 'make PythonInstall' actually doesn't know about OpenMM!? The ldd on libOpenMM.so prints:

$ ldd /raid/istvan/anaconda3/pkgs/openmm-7.4.1-py37_cuda100_rc_1/lib/libOpenMM.so
    linux-vdso.so.1 (0x00007ffee1da0000)
    librt.so.1 => /lib/x86_64-linux-gnu/librt.so.1 (0x00007fab281ee000)
    libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007fab27fea000)
    libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007fab27dcb000)
    libstdc++.so.6 => /usr/lib/x86_64-linux-gnu/libstdc++.so.6 (0x00007fab27a42000)
    libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007fab276a4000)
    libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007fab2748c000)
    libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fab2709b000)
    /lib64/ld-linux-x86-64.so.2 (0x00007fab28952000)

Could you help me fix this problem? Of course, I can compile OpenMM from source and then I won't have this issue, but it is so nice to use conda. Thank you very much for your kind assistance.

Best regards,

Istvan

peastman commented 4 years ago

Everything needs to be compiled with the same ABI: OpenMM, the Plumed plugin, and the Python module. It looks to me like the problem is that the plugin library is compiled with one ABI, but the Python module is compiled with the other. If you edit the setup.py file, you can use the extra_compile_args and extra_link_args variables to pass extra options to the compiler and linker telling it what ABI to use.

https://github.com/peastman/openmm-plumed/blob/2c2c9d8484f0875575f69c5a50a34f6a90405e5f/python/setup.py#L12-L13

Of course, in an ideal world everything would just work...

gitkol commented 4 years ago

Yes, adding '-D_GLIBCXX_USE_CXX11_ABI=0' to extra_compile_args did solve the problem. Thanks for the clue. What exactly does make PythonInstall do as opposed to make install?

Thanks again,

Istvan

peastman commented 4 years ago

make PythonInstall is just a shortcut for setting a few environment variables and then running setup.py. So they're pretty much independent. Compiling the libraries is handled by CMake, while compiling the Python module is handled by distutils.

gitkol commented 4 years ago

Thank you, Peter.