astamm / nloptr

nloptr provides an R interface to NLopt, a free/open-source library for nonlinear optimization providing a common interface to a number of different optimization routines which can handle nonlinear constraints and lower and upper bounds for the controls.

Home Page:https://astamm.github.io/nloptr/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Error installing `nloptr` from source on CentOS cluster

isaactpetersen opened this issue · comments

I am trying to install nloptr from source in R version 4.1.3 on a cluster (CentOS). However I receive the following error:

/cvmfs/argon.hpc.uiowa.edu/2022.1/prefix/usr/lib/gcc/x86_64-pc-linux-gnu/9.4.0/../../../../x86_64-pc-linux-gnu/bin/ld: cannot find -lnlopt
collect2: error: ld returned 1 exit status
make: *** [/cvmfs/argon.hpc.uiowa.edu/2022.1/apps/linux-centos7-broadwell/gcc-9.4.0/r-4.1.3-ljofaul/rlib/R/share/make/shlib.mk:10: nloptr.so] Error 1
ERROR: compilation failed for package ‘nloptr’

Here's the full output:

trying URL 'https://mirror.las.iastate.edu/CRAN/src/contrib/nloptr_2.0.3.tar.gz'
Content type 'application/x-gzip' length 2219877 bytes (2.1 MB)
==================================================
downloaded 2.1 MB

* installing *source* package ‘nloptr’ ...
** package ‘nloptr’ successfully unpacked and MD5 sums checked
** using staged installation
checking whether the C++ compiler works... yes
checking for C++ compiler default output file name... a.out
checking for suffix of executables...
checking whether we are cross compiling... no
checking for suffix of object files... o
checking whether the compiler supports GNU C++... yes
checking whether /cvmfs/argon.hpc.uiowa.edu/2022.1/prefix/usr/x86_64-pc-linux-gnu/gcc-bin/9.4.0/g++ -std=gnu++14 accepts -g... yes
checking for /cvmfs/argon.hpc.uiowa.edu/2022.1/prefix/usr/x86_64-pc-linux-gnu/gcc-bin/9.4.0/g++ -std=gnu++14 option to enable C++11 features... none needed
checking how to run the C++ preprocessor... /cvmfs/argon.hpc.uiowa.edu/2022.1/prefix/usr/x86_64-pc-linux-gnu/gcc-bin/9.4.0/g++ -std=gnu++14 -E
checking whether the compiler supports GNU C++... (cached) yes
checking whether /cvmfs/argon.hpc.uiowa.edu/2022.1/prefix/usr/x86_64-pc-linux-gnu/gcc-bin/9.4.0/g++ -std=gnu++14 accepts -g... (cached) yes
checking for /cvmfs/argon.hpc.uiowa.edu/2022.1/prefix/usr/x86_64-pc-linux-gnu/gcc-bin/9.4.0/g++ -std=gnu++14 option to enable C++11 features... (cached) none needed
checking for pkg-config... /cvmfs/argon.hpc.uiowa.edu/2022.1/prefix/usr/bin/pkg-config
checking if pkg-config knows NLopt... yes
checking for pkg-config checking NLopt version... >= 2.7.0
configure: creating ./config.status
config.status: creating src/Makevars
** libs
/cvmfs/argon.hpc.uiowa.edu/2022.1/prefix/usr/x86_64-pc-linux-gnu/gcc-bin/9.4.0/gcc -I"/cvmfs/argon.hpc.uiowa.edu/2022.1/apps/linux-centos7-broadwell/gcc-9.4.0/r-4.1.3-ljofaul/rlib/R/include" -DNDEBUG -I../inst/include -I/cvmfs/argon.hpc.uiowa.edu/2022.1/apps/linux-centos7-broadwell/gcc-9.4.0/nlopt-2.7.0-u5x4377/include  -I'/Users/itpetersen/R/x86_64-pc-linux-gnu-library/4.1/testthat/include' -I/usr/local/include   -fpic  -g -O2  -c init_nloptr.c -o init_nloptr.o
/cvmfs/argon.hpc.uiowa.edu/2022.1/prefix/usr/x86_64-pc-linux-gnu/gcc-bin/9.4.0/gcc -I"/cvmfs/argon.hpc.uiowa.edu/2022.1/apps/linux-centos7-broadwell/gcc-9.4.0/r-4.1.3-ljofaul/rlib/R/include" -DNDEBUG -I../inst/include -I/cvmfs/argon.hpc.uiowa.edu/2022.1/apps/linux-centos7-broadwell/gcc-9.4.0/nlopt-2.7.0-u5x4377/include  -I'/Users/itpetersen/R/x86_64-pc-linux-gnu-library/4.1/testthat/include' -I/usr/local/include   -fpic  -g -O2  -c nloptr.c -o nloptr.o
/cvmfs/argon.hpc.uiowa.edu/2022.1/prefix/usr/x86_64-pc-linux-gnu/gcc-bin/9.4.0/g++ -std=gnu++11 -I"/cvmfs/argon.hpc.uiowa.edu/2022.1/apps/linux-centos7-broadwell/gcc-9.4.0/r-4.1.3-ljofaul/rlib/R/include" -DNDEBUG -I../inst/include -I/cvmfs/argon.hpc.uiowa.edu/2022.1/apps/linux-centos7-broadwell/gcc-9.4.0/nlopt-2.7.0-u5x4377/include  -I'/Users/itpetersen/R/x86_64-pc-linux-gnu-library/4.1/testthat/include' -I/usr/local/include   -fpic  -g -O2  -c test-C-API.cpp -o test-C-API.o
/cvmfs/argon.hpc.uiowa.edu/2022.1/prefix/usr/x86_64-pc-linux-gnu/gcc-bin/9.4.0/g++ -std=gnu++11 -I"/cvmfs/argon.hpc.uiowa.edu/2022.1/apps/linux-centos7-broadwell/gcc-9.4.0/r-4.1.3-ljofaul/rlib/R/include" -DNDEBUG -I../inst/include -I/cvmfs/argon.hpc.uiowa.edu/2022.1/apps/linux-centos7-broadwell/gcc-9.4.0/nlopt-2.7.0-u5x4377/include  -I'/Users/itpetersen/R/x86_64-pc-linux-gnu-library/4.1/testthat/include' -I/usr/local/include   -fpic  -g -O2  -c test-runner.cpp -o test-runner.o
/cvmfs/argon.hpc.uiowa.edu/2022.1/prefix/usr/x86_64-pc-linux-gnu/gcc-bin/9.4.0/g++ -std=gnu++11 -shared -L/cvmfs/argon.hpc.uiowa.edu/2022.1/apps/linux-centos7-broadwell/gcc-9.4.0/r-4.1.3-ljofaul/rlib/R/lib -L/cvmfs/argon.hpc.uiowa.edu/2022.1/apps/linux-centos7-broadwell/gcc-9.4.0/r-4.1.3-ljofaul/rlib/R/lib -Wl,-rpath,/cvmfs/argon.hpc.uiowa.edu/2022.1/apps/linux-centos7-broadwell/gcc-9.4.0/r-4.1.3-ljofaul/rlib/R/lib -o nloptr.so init_nloptr.o nloptr.o test-C-API.o test-runner.o -L/cvmfs/argon.hpc.uiowa.edu/2022.1/apps/linux-centos7-broadwell/gcc-9.4.0/r-4.1.3-ljofaul/rlib/R/lib -lRlapack -L/cvmfs/argon.hpc.uiowa.edu/2022.1/apps/linux-centos7-broadwell/gcc-9.4.0/r-4.1.3-ljofaul/rlib/R/lib -lRblas -lgfortran -lm -lquadmath -L/cvmfs/argon.hpc.uiowa.edu/2022.1/apps/linux-centos7-broadwell/gcc-9.4.0/nlopt-2.7.0-u5x4377/lib -lnlopt -L/cvmfs/argon.hpc.uiowa.edu/2022.1/apps/linux-centos7-broadwell/gcc-9.4.0/r-4.1.3-ljofaul/rlib/R/lib -lR
/cvmfs/argon.hpc.uiowa.edu/2022.1/prefix/usr/lib/gcc/x86_64-pc-linux-gnu/9.4.0/../../../../x86_64-pc-linux-gnu/bin/ld: cannot find -lnlopt
collect2: error: ld returned 1 exit status
make: *** [/cvmfs/argon.hpc.uiowa.edu/2022.1/apps/linux-centos7-broadwell/gcc-9.4.0/r-4.1.3-ljofaul/rlib/R/share/make/shlib.mk:10: nloptr.so] Error 1
ERROR: compilation failed for package ‘nloptr’
* removing ‘/Users/itpetersen/R/x86_64-pc-linux-gnu-library/4.1/nloptr’

The downloaded source packages are in
        ‘/localscratch/RtmpjRwOfX/downloaded_packages’
Warning message:
In install.packages("nloptr") :
  installation of package ‘nloptr’ had non-zero exit status

I am on a university cluster and cannot run sudo commands.

The cmake version is: 2.8.12.2

Before running R, I loaded the following version of nlopt: 2.7.0_gcc-9.4.0

Here is my sessionInfo():

> sessionInfo()
R version 4.1.3 (2022-03-10)
Platform: x86_64-pc-linux-gnu (64-bit)
Running under: CentOS Linux 7 (Core)

Matrix products: default
BLAS/LAPACK: /cvmfs/argon.hpc.uiowa.edu/2022.1/apps/linux-centos7-x86_64/gcc-9.4.0/intel-oneapi-mkl-2022.0.2-s35g6hp/mkl/2022.0.2/lib/intel64/libmkl_gf_lp64.so.2

locale:
 [1] LC_CTYPE=en_US.UTF-8       LC_NUMERIC=C
 [3] LC_TIME=en_US.UTF-8        LC_COLLATE=en_US.UTF-8
 [5] LC_MONETARY=en_US.UTF-8    LC_MESSAGES=en_US.UTF-8
 [7] LC_PAPER=en_US.UTF-8       LC_NAME=C
 [9] LC_ADDRESS=C               LC_TELEPHONE=C
[11] LC_MEASUREMENT=en_US.UTF-8 LC_IDENTIFICATION=C

attached base packages:
[1] stats     graphics  grDevices utils     datasets  methods   base

loaded via a namespace (and not attached):
[1] compiler_4.1.3 tools_4.1.3

You have a fairly unusual file structure there. That should not upset the code, but it does. Can you possible dive in at

  • unpack the CRAN sources from their tar.gz
  • run ./configure and see what it does / inspect the created src/Makevars
    - maybe try to run the nlopt compilation alone and then point to the created libnlopt.a

If you have the ability to install libnlopt*,so from the system, do -- as it reduces the amount of work the package has to do.

Sorry, I misread. So you tried with preinstalled libnlopt and that failed. So you need to figure out why. From the logs you posted we only see that the linker is unhappy -- why that is so we cannot tell.

I would in such a situation try gcc on a very short example program to see if I can compile and link with that libnlopt you have. If so, you need to check what is different in how R compiles and links packages on your cluster.

The installation process in the package "usually" works. Something differs at your end but we cannot tell what from here.

Thanks for your prompt response. I'm a bit new to Linux and am not sure how to do what you suggested, i.e.:

  • unpack the CRAN sources from their tar.gz
  • run ./configure and see what it does / inspect the created src/Makevars
  • try gcc on a very short example program to see if it can compile and link with that libnlopt I have

I know how to download the tar.gz for nloptr from CRAN and to unpack it on Windows, but am not sure how to do what you suggested on a CentOS cluster. Thank you for your patience; any additional guidance would be greatly appreciated.

You probably want to reach out to a local admin at your HPC center who has looked after R before.

Will do, thanks! I will post here if I have any updates that help clarify or resolve this issue. Thanks for pointing me in the right direction.

Yes, and rope us in as needed. This should be fairly straightforward for a sys admin a little more at ease with debugging on the Unix side of things.

I contacted our sys admin. He was able to figure out the issue. Here was his response, in case it's helpful to anyone else in the future.


The build environment for nloptr uses pkg-config to get information about nlopt. It turns out that the pkg-config file has an error. It has

libdir=${exec_prefix}/lib

but the library is actually located in

libdir=${exec_prefix}/lib64

That does not show up in the packaging environment because LIBRARY_PATH is set for the dependency chain. I will need to fix the pkg-config file in the package recipe, but you can work around it as follows:

  1. load environment modules:
module load stack/2022.1
module load nlopt
  1. set LIBRARY_PATH so linker can find library while launching R session (single line below):
LIBRARY_PATH=$ROOT_NLOPT/lib64:$LIBRARY_PATH R
  1. install nloptr in the R console (single line below):
install.packages(verbose=1,'nloptr')

That is a good comment, and on me as the one who wrote that logic! Can you maybe help me find out if we can use R CMD config to retrieve the lib64 logic from R?

Can you try R CMD config --all | grep lib64 ? On my Ubuntu system this comes up empty (as Ubuntu uses only lib, not lib64). That is likely different for you and something I should accommodate.

Or actually it may be the pkg-config file created by (upstream) nlopt. In which case my hands are a little tied...

What does pkg-config --lib nlopt show (maybe after you loaded the module) ?

Here's what I get when running those commands:

[itpetersen@argon-login-1 ~]$ module load stack/2022.1

The following have been reloaded with a version change:
  1) stack/2020.1 => stack/2022.1

[itpetersen@argon-login-1 ~]$ module load r/4.1.3_gcc-9.4.0
[itpetersen@argon-login-1 ~]$ module load nlopt
[itpetersen@argon-login-1 ~]$ R CMD config --all | grep lib64
LIBnn = lib64
[itpetersen@argon-login-1 ~]$ pkg-config --lib nlopt
pkgconf: ambiguous option -- lib

You missed an s there:

$ pkg-config --libs nlopt
-lnlopt
$

Looking at our configure.ac we simply trust pkg-config so I think we have to talk to upstream here to get that fixed:

nloptr/configure.ac

Lines 46 to 53 in fb707b1

if pkg-config --atleast-version=2.7.0 nlopt; then
AC_MSG_RESULT([>= 2.7.0])
nlopt_include=$(pkg-config --cflags nlopt)
nlopt_libs=$(pkg-config --libs nlopt)
AC_SUBST([NLOPT_INCLUDE], "${nlopt_include}")
AC_SUBST([NLOPT_LIBS], "${nlopt_libs}")
need_to_build="no"
else

We trust pkg-config --libs fron line 51.

Okay, here's the output of the updated command:

[itpetersen@argon-login-1 ~]$ pkg-config --libs nlopt
-L/cvmfs/argon.hpc.uiowa.edu/2022.1/apps/linux-centos7-broadwell/gcc-9.4.0/nlopt-2.7.0-u5x4377/lib -lnlopt

And per #123 (comment) we would want that to be

-L/cvmfs/argon.hpc.uiowa.edu/2022.1/apps/linux-centos7-broadwell/gcc-9.4.0/nlopt-2.7.0-u5x4377/lib64 -lnlopt

correct ?

I believe so? Is there a way I could verify?

Yes! The way pkg-config works is that it when used by a library relying on it to convey information about headers and libraries needed, along with their locations, then the library places a file $libraryname.pc somewhere where pkg-config can access it. (The are additional path setting env vars similar to LD_LIBRARY_PATH that come into play, your modules system likely deals with that.)

On my (much simpler) system with default path:

$ locate nlopt.pc
/usr/lib/x86_64-linux-gnu/pkgconfig/nlopt.pc
$ cat /usr/lib/x86_64-linux-gnu/pkgconfig/nlopt.pc
prefix=/usr
exec_prefix=${prefix}
libdir=${exec_prefix}/lib
includedir=${prefix}/include

Name: NLopt
Description: nonlinear optimization libary
Version: 2.7.1
Libs: -L${libdir} -lnlopt
Libs.private: -lm
Cflags: -I${includedir}
$ 

and that is in fact what your sysadmin referred to. We nloptr we now have two choices. Either we cook up an elaborate and likely fragile schema to double-check pkg-config and reimplement some of its functionality. Or we punt and ask you to talk to team nlopt. I would prefer the latter.

Sounds good to me. Let me know what I should communicate to the nlopt team (I presume at this link?), and I'll do my best to pass along the message. Thanks for your help!

Yep. Feel free to cross-reference this ticket and/or tag me. I haven't had to post-process pkg-config files so maybe it is something simpler too...