openmopac/mopac

22.0.3 symbol error on Scientific Linux release 7.9 (Nitrogen)

Closed this issue · 5 comments

Symbol link error after install to non-standard location

This may be a bug but I couldnt find a list of supported platforms. I'm using the University of Cambridge's HPC on one of the older nodes, so may just be an unsupported OS.

I note it works fine on the newer nodes (icelake running Rocky Linux release 8.6 (Green Obsidian) )

Version 22.0.3

To Reproduce

Installed to ~/MOPAC2022 (Home dir replaced by XXXX below.)

~/MOPAC2022/bin/mopac

XXXX/MOPAC2022/bin/mopac: relocation error: XXXX/MOPAC2022/bin/../lib/libmopac.so.1: symbol __kmpc_free, version VERSION not defined in file libiomp5.so with link time reference

On [ Scientific Linux release 7.9 (Nitrogen)] Linux

Is this the release version or the development version (active main branch)?

The Linux installer of MOPAC was producing this problem because I didn't package the right OpenMP library, but that instance was resolved in v22.0.3. Could you run ldd -v ... on the mopac executable and on the libmopac.so library and tell me the contents of ~/MOPAC2022/lib? Is your executable working in the build directory before you run the install step? Are you using an Intel script to set environment variables (e.g. setvars.sh)?

The root of this problem seems to be that CMake finds a version of libiomp5.so on many Linux distributions that is a symbolic link to system libraries rather than the Intel OpenMP library (what it should be). I'm presently sidestepping this problem by using the AUTO_BLAS=OFF CMake option and setting the BLAS, LAPACK, and OpenMP library paths by hand with MOPAC_LINK and MOPAC_LINK_PATH when running the CMake setup. I don't have an automated fix yet, but I'll eventually try some fixes. I think this is technically a subtle bug in CMake's find_package(BLAS), but there might be a way to work around the problem.

I installed the .run from here:

https://github.com/openmopac/mopac/releases/download/v22.0.3/mopac-22.0.3-linux.run

rather than building from source. ldd returns this - I suspect the issue is that its picking up the system installed libiomp5.so rather than the one provided in the install.

linux-vdso.so.1 => (0x00007ffc7bfec000)
libmopac.so.1 => XXXX/MOPAC2022/bin/./../lib/libmopac.so.1 (0x00002b880eeca000)
libiomp5.so => /usr/local/Cluster-Apps/intel/2017.4/compilers_and_libraries_2017.4.196/linux/compiler/lib/intel64/libiomp5.so (0x00002b8814822000)
libpthread.so.0 => /lib64/libpthread.so.0 (0x00002b8814bc6000)
libm.so.6 => /lib64/libm.so.6 (0x00002b8814de2000)
libdl.so.2 => /lib64/libdl.so.2 (0x00002b88150e4000)
libc.so.6 => /lib64/libc.so.6 (0x00002b88152e8000)
libgcc_s.so.1 => /lib64/libgcc_s.so.1 (0x00002b88156b6000)
/lib64/ld-linux-x86-64.so.2 (0x00002b880eca6000)

I tried doing LD_LIBRARY_PATH=../lib ; export LD_LIBRARY_PATH and running mopac again. That lets mopac run OK so I think this is the issue.

The standard login on this system sets LD_LIBRARY_PATH to include the offending folder so I think that's the issue.

Thank you for this additional information, this is a bit different from the previous OpenMP dependency problems that were recently reported. I am setting the RPATH in the MOPAC executable to point to the local versions of the MOPAC and OpenMP shared libraries, but the LD_LIBRARY_PATH seems to be overriding RPATH in the situation you are reporting and using an older version of libiomp5.so on your file system. RPATH is supposed to have higher priority than LD_LIBRARY_PATH, and I'll have to more carefully check that I'm using it correctly.

Ok, I have a more definitive response to this after closer examination. The connection between the MOPAC executable and its shared libraries on Linux is based on a RUNPATH rather than an RPATH. RUNPATH is considered the modern standard on Linux and RPATH is considered deprecated, hence CMake supports the use of RUNPATH, not RPATH. A "benefit" of RUNPATH over RPATH is that it has lower (rather than higher) priority than the LD_LIBRARY_PATH environment variable. This feature makes it easy to use LD_LIBRARY_PATH to force the temporary use of other shared libraries, but it can cause accidents such as what you are experiencing. When this happens, the options are:

  1. Remove the offending paths from LD_LIBRARY_PATH (which might affect other programs)
  2. Add the MOPAC library path earlier in LD_LIBRARY_PATH (which also might affect other programs, but less so)
  3. Use tools like patchelf to replace the RUNPATH in the MOPAC executable and library with an RPATH that will override LD_LIBRARY_PATH (won't affect other programs, but considered to be deprecated)

The problem here is really on Intel's side: they changed the interface to their OpenMP library in the last few years, but they do not comply with the Linux standard of shared library versioning so there are libraries with the same file name floating around that are incompatible with each other and can easily break things.

While I could switch from RUNPATH to RPATH on Linux, I don't think it's a good idea because (1) I'd have to do it by hand because CMake commands can't do it for me, (2) RPATH is considered to be deprecated, and (3) the present behavior is more consistent between Mac and Linux, and there are no alternative commands/behaviors on Mac.

I guess the old school way would be to add a wrapper shell script to launch MOPAC; then you could locally deal with the environment, but that may create other complexity that you probably dont want. Any way thanks for the help.