Speed up RcppArmadillo: How to link to OpenBlas in an R package

▼魔方 西西 提交于 2020-12-30 08:36:24

问题


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

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!