如何在编译期间强制犰狳库链接到本地​​ OpenBLAS

Posted

技术标签:

【中文标题】如何在编译期间强制犰狳库链接到本地​​ OpenBLAS【英文标题】:How to force armadillo library to link to local OpenBLAS during compilation 【发布时间】:2015-05-05 16:32:04 【问题描述】:

我需要将犰狳(当前版本为 5.100.1)作为 $HOME(集群应用程序,不能安装在每个计算节点上,但 $HOME 是共享文件夹)中的本地库提供。我正在使用 cmake 来管理应用程序,并且已经能够让 cmake 链接到 $HOME(例如 boost)中的本地库,而不是其他地方就好了。犰狳需要 BLAS 和 LAPACK,尽管它可以同时使用(实际上也建议使用)OpenBLAS。但是,我不明白如何强制犰狳使用 OpenBLAS,即使它自己的 cmake .configure 确认它已找到 OpenBLAS。这是在原始犰狳文件夹上运行 ./configure 的输出:

$ ./configure
-- Configuring Armadillo 5.100.1
-- CMAKE_SYSTEM_NAME          = Linux
-- CMAKE_CXX_COMPILER_ID      = GNU
-- CMAKE_CXX_COMPILER_VERSION = 4.9.1
-- CMAKE_COMPILER_IS_GNUCXX   = 1
-- Found MKL libraries: /opt/intel/composer_xe_2013_sp1.2.144/mkl/lib/intel64/libmkl_rt.so
-- Found OpenBLAS: /home/rolf/lib/libopenblas.so
-- Found BLAS: /usr/lib64/libblas.so
-- Found LAPACK: /usr/lib64/liblapack.so
--      MKL_FOUND = YES
--   ACMLMP_FOUND = NO
--     ACML_FOUND = NO
-- OpenBLAS_FOUND = YES
--    ATLAS_FOUND = NO
--     BLAS_FOUND = YES
--   LAPACK_FOUND = YES
-- 
-- *** If the MKL or ACML libraries are installed in non-standard locations such as
-- *** /opt/intel/mkl, /opt/intel/composerxe/, /usr/local/intel/mkl
-- *** make sure the run-time linker can find them.
-- *** On Linux systems this can be done by editing /etc/ld.so.conf
-- *** or modifying the LD_LIBRARY_PATH environment variable.
-- 
-- *** On systems with SELinux enabled (eg. Fedora, RHEL),
-- *** you may need to change the SELinux type of all MKL/ACML libraries
-- *** to fix permission problems that may occur during run-time.
-- *** See README.txt for more information
-- 
-- Found ARPACK: /usr/lib64/libarpack.so
-- ARPACK_FOUND = YES
-- Could not find SuperLU
-- SuperLU_FOUND = NO
-- 
-- *** Armadillo wrapper library will use the following libraries:
-- *** ARMA_LIBS = /opt/intel/composer_xe_2013_sp1.2.144/mkl/lib/intel64/libmkl_rt.so;/usr/lib64/libarpack.so
-- 
-- Detected gcc 4.8.3 or later. Added '-std=c++11' to compiler flags
-- Copying /home/rolf/work/pdefect/armadillo/include/ to /home/rolf/work/pdefect/armadillo/tmp/include/
-- Generating /home/rolf/work/pdefect/armadillo/tmp/include/config.hpp
-- Generating /home/rolf/work/pdefect/armadillo/examples/Makefile
-- CMAKE_CXX_FLAGS           =  -std=c++11 -O2
-- CMAKE_SHARED_LINKER_FLAGS =  -Wl,--no-as-needed
-- CMAKE_REQUIRED_INCLUDES   = 
-- *** CMAKE_INSTALL_PREFIX was initalised by cmake to the default value of /usr/local
-- *** CMAKE_INSTALL_PREFIX changed to /usr
-- *** Detected 64 bit system
-- *** /usr/lib64/ exists, so destination directory for the run-time library changed to /usr/lib64/
-- *** Your system and/or compiler must search /usr/lib64/ during linking
-- CMAKE_INSTALL_PREFIX = /usr
-- INSTALL_LIB_DIR      = /usr/lib64
-- INSTALL_INCLUDE_DIR  = /usr/include
-- INSTALL_DATA_DIR     = /usr/share
-- INSTALL_BIN_DIR      = /usr/bin
-- Generating '/home/rolf/work/pdefect/armadillo/ArmadilloConfig.cmake'
-- Generating '/home/rolf/work/pdefect/armadillo/ArmadilloConfigVersion.cmake'
-- Generating '/home/rolf/work/pdefect/armadillo/InstallFiles/ArmadilloConfig.cmake'
-- Generating '/home/rolf/work/pdefect/armadillo/InstallFiles/ArmadilloConfigVersion.cmake'
-- Configuring done
-- Generating done
-- Build files have been written to: /home/rolf/work/pdefect/armadillo

所以它成功地在 $HOME 中找到它,但是如果我在之后查询该库到共享库的链接

$ cmake .
$ make

我看到它已链接到登录节点的 BLAS 和 LAPACK 标准副本,但没有使用 OpenBLAS:

$ ldd libarmadillo.so.5.100.1
        linux-vdso.so.1 =>  (0x00007fff05b9b000)
        libmkl_rt.so => /opt/intel/composer_xe_2013_sp1.2.144/mkl/lib/intel64/libmkl_rt.so (0x00007f14d2558000)
        libarpack.so.2 => /home/rolf/lib/libarpack.so.2 (0x00007f14d230a000)
        libstdc++.so.6 => /usr/lib64/libstdc++.so.6 (0x00007f14d1fe9000)
        libm.so.6 => /lib64/libm.so.6 (0x00007f14d1d64000)
        libgcc_s.so.1 => /lib64/libgcc_s.so.1 (0x00007f14d1b4e000)
        libc.so.6 => /lib64/libc.so.6 (0x00007f14d17ba000)
        /lib64/ld-linux-x86-64.so.2 (0x0000003d83400000)
        libdl.so.2 => /lib64/libdl.so.2 (0x00007f14d15b5000)
        libblas.so.3 => /usr/lib64/libblas.so.3 (0x00007f14d135e000)
        liblapack.so.3 => /usr/lib64/atlas/liblapack.so.3 (0x00007f14d0b3d000)
        libgfortran.so.3 => /usr/lib64/libgfortran.so.3 (0x00007f14d084a000)
        libf77blas.so.3 => /usr/lib64/atlas/libf77blas.so.3 (0x00007f14d062d000)
        libcblas.so.3 => /usr/lib64/atlas/libcblas.so.3 (0x00007f14d040c000)
        libatlas.so.3 => /usr/lib64/atlas/libatlas.so.3 (0x00007f14cfcfe000)
        libpthread.so.0 => /lib64/libpthread.so.0 (0x00007f14cfae1000)

很遗憾,libblas.so.3 和 liblapack.so.3 在节点上不可用:

$ ssh node01 'ldd  /home/rolf/work/pdefect/armadillo/libarmadillo.so.5.100.1 | grep "not found" '
    libblas.so.3 => not found
    liblapack.so.3 => not found

如何强制犰狳编译并链接到我的本地 OpenBLAS 副本,而不是 /usr/lib64 中的标准 BLAS 和 LAPACK 副本。 faq 中有一条说明

*  For Linux-based systems the automatic installer can figure out that
OpenBLAS, MKL, ACML or ATLAS are installed, and will use them instead of
the standard LAPACK and BLAS libraries. See README.txt within the Armadillo
archive for more information. 

但从上面的结果来看,情况似乎并非如此。谁能指出我在这里做错了什么?

【问题讨论】:

好吧,我没有找到 OpenBLAS 问题的答案,但由于我在 $HOME/lib 中有库存 libblas.so 和 liblapack.so,我至少可以通过提供犰狳源文件夹中的 cmake 如下: cmake -DLAPACK_LIBRARY="$HOME/lib/liblapack.so" -DBLAS_LIBRARY="$HOME/lib/libblas.so" . 如果我将 $HOME/libblas* 移开,然后发出 cmake -DLAPACK_LIBRARY="$HOME/lib/liblapack.so" -DOpenBLAS_LIBRARY="$HOME /lib/libopenblas_sandybridgep-r0.2.14.so" -DBLAS_LIBRARY="$HOME/lib/libopenblas_sandybridgep-r0.2.14.so" 。 , cmake 将以 $HOME/lib/libopenblas.so 的形式宣布找到 BLAS 和 OpenBLAS,但随后它将使用系统的 BLAS ... 【参考方案1】:

您可以告诉 Armadillo 直接使用您想要的任何 BLAS 和 LAPACK 以及它们的位置。您需要在包含犰狳标头之前定义ARMA_DONT_USE_WRAPPER,然后与您拥有的任何BLAS 和LAPACK 链接。

例如:

g++ code.cpp -o code -O3 -DARMA_DONT_USE_WRAPPER -L/home/abc/libs -lmyblas -lmylapack

/home/abc/libs 替换为包含您的库的目录。将 -lmyblas -lmylapack 更改为实现 BLAS 和 LAPACK 功能的任何库(例如:-lopenblas

请记住,系统链接器也需要找到您的库。您可能需要设置LD_LIBRARY_PATH 环境变量。例如:

export LD_LIBRARY_PATH=/home/abc/libs:$LD_LIBRARY_PATH

或者,您可以在编译期间静态链接(请参阅 g++ 中的 -static 开关)

【讨论】:

以上是关于如何在编译期间强制犰狳库链接到本地​​ OpenBLAS的主要内容,如果未能解决你的问题,请参考以下文章

使用 PGI 编译器链接到犰狳库的 Makefile

将犰狳 lapack blas 链接到代码时出错:未定义对“dtrsm_”的引用

了解 Makefile。 make 无法链接犰狳库

在 C++ Xcode 中链接犰狳库

如何使用指定的 gcc 编译犰狳库?

犰狳线性系统求解器(带有openblas)