Как заставить библиотеку броненосца ссылаться на локальный OpenBLAS во время компиляции
Мне нужно, чтобы armadillo (текущая версия 5.100.1) был доступен в виде локальной библиотеки в $HOME (кластерное приложение, и не может быть установлен на каждом вычислительном узле, но $ HOME является общей папкой). Я использую cmake для управления приложением, и мне удалось заставить cmake связываться с локальными библиотеками в $HOME (например, boost), а не в другом месте, просто отлично. Armadillo нуждается в 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
Как заставить armadillo компилировать и ссылаться на мою локальную копию OpenBLAS, а не на стандартные копии BLAS и LAPACK в /usr/lib64. В часто задаваемых вопросах есть примечание, что
* 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.
но из приведенных выше результатов, похоже, это не так. Может кто-нибудь указать мне, что я здесь делаю неправильно?
1 ответ
Вы можете сказать Армадилло, чтобы он напрямую использовал любые 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}
Кроме того, вы можете просто статически ссылаться во время компиляции (см. -static
переключиться в g++)