问题
I am working on an R package which uses RcppArmadillo. I am trying to take advantage of faster matrix multiplication found in OpenBLAS. In the documentation of the C++ armadillo library, it says if we have OpenBLAS on our machine then Armadillo would use OpenBLAS instead of BLAS. However, when I compile my R package, I get something like this:
g++ -m64 -std=c++11 -shared -L/usr/lib64/R/lib -Wl,-z,relro -specs=/usr/lib/rpm/redhat/redhat-hardened-ld -o PackageTest.so class1.o class2.o class3.o class4.o class5.o class6.o class7.o RcppExports.o class8.o class9.o class10.o -L/usr/lib64/R/lib -lRlapack -L/usr/lib64/R/lib -lRblas -lgfortran -lm -lquadmath -L/usr/lib64/R/lib -lR
So it is compiling with the -lRlapack
and -lRblas
options. How can I properly modify the Makevars
and Makevars.win
files to have RcppArmadillo compile the package with the option -lopenblas
? My attempt to solve this problem was to modify the Makevars
file in the following way:
PKG_LIBS = $(LAPACK_LIBS) $(BLAS_LIBS) $(FLIBS)
PKG_CXXFLAGS =-fopenmp -std=c++11 -lopenblas
PKG_CXX1XFLAGS = $(PKG_CXXFLAGS)
The package did compile with -lopenblas
, but is this the best way to do it?
回答1:
That is a problem with your RedHat installation which chose to rely on the internal LAPACK sources for R when installing R --- plus the fact that RcppArmadillo uses whatever R uses.
On my Debian/Ubuntu based machine, it happens differently. Ie for
R> library(Rcpp)
R> cppFunction("arma::mat foo(arma::mat x) { return x + x;} ", depends="RcppArmadillo", verbose=TRUE)
I get (inter alia)
g++ -Wl,-S -shared -L/usr/lib/R/lib -Wl,-Bsymbolic-functions \
-Wl,-z,relro -o sourceCpp_4.so file677111d81351.o \
-fopenmp -llapack -lblas -lgfortran -lm -lquadmath \
-L/usr/lib/R/lib -lR
and we see -llapack -lblas -lgfortran
as expected.
回答2:
Instructions for compiling R, OpenBLAS and linking R with OpenBLAS (GNU/Linux)
I believe your biggest problem is linking R to the OpenBLAS library. So the steps I write below can help you succeed in this link.
Compiling OpenBLAS
Initially download the R and OpenBLAS(Open Optimized BLAS Library) source codes in OpenBLAS. In the file directory, perform the following steps.
tar -zxvf OpenBLAS*
cd OpenBLAs*
make -j $nproc
sudo make install
export LD_LIBRARY_PATH=/opt/OpenBLAS/lib/
or
git clone https://github.com/xianyi/OpenBLAS.git
cd OpenBLAS*
make -j $nproc
sudo make install
export LD_LIBRARY_PATH=/opt/OpenBLAS/lib/
Note: This will make the compilation run faster using all the features of your CPU. To know the number of cores, do: nproc
.
Compiling Armadillo C++ with OpenBLAS
For those who use C++ codes in R using the Rcpp library, setting up the Armadillo with the OpenBLAS library may be of some benefit.
tar -xvf armadillo*
cd armadillo*
./configure -DCMAKE_PREFIX_PATH=/opt/OpenBLAS/lib/
cmake . -DCMAKE_PREFIX_PATH=/opt/OpenBLAS/lib/
make -j $nproc
sudo make install
Note: Further details regarding the compilation of the Armadillo library can be found at https://gitlab.com/conradsnicta/armadillo-code.
Compiling R with OpenBLAS
After compiling OpenBLAS, download the R code. It is not necessary to compile R to make use of OpenBLAS, but compiling the language may bring some benefits that may be insignificant depending on what is being done in R. That way, download the source code of the language R.
Note: In my operating system, Arch Linux, OpenBLAS) was installed in the /opt
directory. Search for the OpenBLASinstallation directory in your GNU/Linux distribution.
In the directory where the R was downloaded, do the following:
tar -zxvf R*
cd R-* && ./configure --enable-R-shlib --enable-threads=posix --with-blas="-lopenblas -L/opt/OpenBLAS/lib -I/opt/OpenBLAS/include -m64 -lpthread -lm"
make -j $nproc
sudo make install
Most likely the OpenBLAS library will be bound to R. To check, run in the R the sessionInfo()
code. Something like the output below should appear:
Matrix products: default
BLAS/LAPACK: /opt/OpenBLAS/lib/libopenblas_haswellp-r0.3.6.dev.so
If linking does not occur, follow the steps outlined in the code below.
We need to link the R with the file libopenblas_*
, created in the process of compiling the library OpenBLAS. In my case, the file is ibopenblas_haswellp-r0.2.20.so. Look for this in /opt/OpenBLAS/lib
or in the directory where OpenBLAS was installed on your GNU/Linux system. Also look for the libRblas.so file directory found in the R language installation directory. In Arch, this directory is /usr/local/lib64/R/lib
.
cd /usr/local/lib64/R/lib
mv libRblas.so libRblas.so.keep
ln -s /opt/OpenBLAS/lib/libopenblas_haswellp-r0.2.20.so libRblas.so
Start a section of language R and do sessionInfo()
. You should note something like:
Matrix products: default
BLAS/LAPACK: /opt/OpenBLAS/lib/libopenblas_haswellp-r0.3.6.dev.so
To make use of multithreaded processing, do export OPENBLAS_NUM_THREADS=1
before starting a R section.
NOTE: For intel processors,sudo cpupower frequency-set -g performance
, can boost performance. Read more at https://wiki.archlinux.org/index.php/CPU_frequency_scaling.
来源:https://stackoverflow.com/questions/45009964/speed-up-rcpparmadillo-how-to-link-to-openblas-in-an-r-package