加速 RcppArmadillo:如何在 R 包中链接到 OpenBlas

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

本文关键字:包中 链接 OpenBlas RcppArmadillo 加速      更新时间:2023-10-16

我正在开发一个使用RcppArmadillo的R包。我正在尝试利用 OpenBLAS 中更快的矩阵乘法。在C++犰狳库的文档中,它说如果我们的机器上有OpenBLAS,那么犰狳将使用OpenBLAS而不是BLAS。但是,当我编译我的 R 包时,我得到如下内容:

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

因此,它正在使用-lRlapack-lRblas选项进行编译。如何正确修改MakevarsMakevars.win文件,让 RcppArmadillo 使用选项-lopenblas编译软件包?我尝试解决此问题是通过以下方式修改Makevars文件:

PKG_LIBS = $(LAPACK_LIBS) $(BLAS_LIBS) $(FLIBS)
PKG_CXXFLAGS =-fopenmp -std=c++11 -lopenblas
PKG_CXX1XFLAGS = $(PKG_CXXFLAGS)

该软件包确实使用-lopenblas编译,但这是最好的方法吗?

这是您的 RedHat 安装的问题,它在安装 R 时选择依赖内部 LAPACK 源 R--- 加上 RcppArmadillo 使用 R 使用的任何内容。

在我的基于 Debian/Ubuntu 的机器上,情况有所不同。即 对于

R> library(Rcpp)
R> cppFunction("arma::mat foo(arma::mat x) { return x + x;} ", depends="RcppArmadillo", verbose=TRUE)

我得到(除其他外(

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

我们看到了-llapack -lblas -lgfortran预期。

编译

R,OpenBLAS和将R与OpenBLAS(GNU/Linux(链接的说明

我相信你最大的问题是将R链接到OpenBLAS库。因此,我在下面编写的步骤可以帮助您在此链接中取得成功。

编译开放BLAS

最初在OpenBLAS中下载ROpenBLAS(开放优化BLAS库(源代码。在文件目录中,执行以下步骤。

tar -zxvf OpenBLAS*
cd OpenBLAs*
make -j $nproc
sudo make install
export LD_LIBRARY_PATH=/opt/OpenBLAS/lib/

git clone https://github.com/xianyi/OpenBLAS.git
cd OpenBLAS*
make -j $nproc
sudo make install
export LD_LIBRARY_PATH=/opt/OpenBLAS/lib/

注意:这将使使用 CPU 的所有功能使编译运行得更快。要知道内核的数量,请执行以下操作:nproc.

使用 OpenBLAS 编译犰狳C++

对于那些使用Rcpp库在R中使用C++代码的人来说,使用OpenBLAS库设置Armadillo可能会有一些好处。

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

注意:有关犰狳图书馆汇编的更多详细信息,请参阅 https://gitlab.com/conradsnicta/armadillo-code。

使用 OpenBLAS 编译 R

编译OpenBLAS后,下载R代码。没有必要编译R来使用OpenBLAS,但是编译语言可能会带来一些好处,这些好处可能微不足道,这取决于R中正在做什么。这样,下载语言R的源代码。

注意:在我的操作系统中,ArchLinux,OpenBLAS(安装在/opt目录中。在您的 GNU/Linux 发行版中搜索OpenBLAS安装目录。

在下载R的目录中,执行以下操作:

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

OpenBLAS库很可能绑定到R。若要进行检查,请在R中运行sessionInfo()代码。应该出现类似于以下输出的内容:

Matrix products: default
BLAS/LAPACK: /opt/OpenBLAS/lib/libopenblas_haswellp-r0.3.6.dev.so

如果未发生链接,请按照以下代码中概述的步骤操作。

我们需要将R与文件libopenblas_*链接,在编译库OpenBLAS的过程中创建。就我而言,该文件是ibopenblas_haswellp r0.2.20.so。在/opt/OpenBLAS/lib或在您的 GNU/Linux 系统上安装OpenBLAS的目录中查找此内容。另查找在R语言安装目录中找到的 libRblas.so文件目录。在 Arch 中,此目录/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

启动语言R的一部分并执行sessionInfo()。您应该注意以下内容:

Matrix products: default
BLAS/LAPACK: /opt/OpenBLAS/lib/libopenblas_haswellp-r0.3.6.dev.so

若要使用多线程处理,请在开始R部分之前执行export OPENBLAS_NUM_THREADS=1

:对于英特尔处理器,sudo cpupower frequency-set -g performance可以提高性能。在 https://wiki.archlinux.org/index.php/CPU_frequency_scaling 阅读更多内容。