Armadillo C++ 无法对角化更大的矩阵

Armadillo C++ fails to diagonalize bigger matrices

我正在使用适用于 C++ 的 Armadillo 线性代数库在使用 SLURM 运行的集群上对高达 65k x 65k 的大型矩阵进行对角化。对于大于 30k x 30k 的矩阵,我收到以下错误消息:

Intel MKL ERROR: Parameter 9 was incorrect on entry to DSYTRD.

Intel MKL ERROR: Parameter 8 was incorrect on entry to DSTEDC.

Intel MKL ERROR: Parameter 12 was incorrect on entry to DORMTR.

我认为这可能是由于使用 int32 而不是 int64 引起的,即使我启用了 arma 宏 ARMA_USE_64bit、ARMA_USE_BLASS_LONG_LONG 等,所以内部代码应该对 64 位整数进行操作。这是我的编译行

    g++ main.cpp IsingModel.cpp IsingModel_disorder.cpp IsingModel_sym.cpp tools.cpp\ user_interface.cpp -o Ising.o -pthread -I../LIBRARIES_CPP/armadillo-10.8.0/include/ \
-L${MKLROOT}/lib/intel64 -fopenmp -lmkl_intel_lp64 -lmkl_core -lmkl_intel_ilp64\
 -lmkl_sequential  -lpthread -lm -lmkl_gnu_thread -lstdc++fs -llapack -fcx-fortran-rules\
 -fomit-frame-pointer -lblas -std=c++20 -std=c++17 -O3

对于那些了解 SLURM 的人,这里是我正在使用的模块:

module load Armadillo/9.900.1-foss-2020a
module load imkl/2021.4.0
module load OpenBLAS/0.3.18-GCC-11.2.0

提前感谢您的帮助!

对不起,我没有足够的声誉在下面发表评论,所以我必须把它作为一个答案。

在我使用 Armadillo 期间,我发现当前版本的 Armadillo 和 Intel MKL 无法正常工作并且可能存在错误 (Ubuntu 20)。确实有很多关于这方面的报道,但我们很难做任何事情,因为链接到这些库的是 Armadillo 库。也许这对开发者来说可以是an issue

我自己发现 OpenBlas 是英特尔 MKL 的一个很好的替代品,因为它支持犰狳。这真的很有效。此外,如果您有 Nvidia GPU,则 NVBlas 可以很好地与 OpenBlas 配合使用。 (在我的 answer 中详细介绍了将 NVBlas 与 OpenBlas 一起使用的 cmake 解决方案。) 如果您使用 cmake 安装 Armadillo 库,请稍微更改 CmakeLists.txt 文件以禁用对 MKL 的检测。

CMake 解决方案

If MKL is installed and it is persistently giving problems during linking, Support for MKL can be disabled by editing the CMakeLists.txt file, deleting CMakeCache.txt and re-running the cmake based installation. (Armadillo README)

CMakeLists.txt 中,注释掉包含以下内容的行 (Line 327):

INCLUDE(ARMA_FindMKL)

g++ 解决方案

使用 g++,删除 Intel MKL 的链接库,使用 -lopenblas 用于 OpenBlas

g++ main.cpp IsingModel.cpp IsingModel_disorder.cpp IsingModel_sym.cpp tools.cpp \
user_interface.cpp -o Ising.o -pthread -I../LIBRARIES_CPP/armadillo-10.8.0/include/ \
-fopenmp -lpthread -lm -lstdc++fs -llapack -fcx-fortran-rules \
-fomit-frame-pointer -lblas -lopenblas -std=c++20 -O3