在 Python 中调用 Pardiso 6

我正在尝试在 Python 中使用 Pardiso 6 稀疏求解器库。问题是我似乎无法加载 Pardiso 共享对象 (SO)。这是我打电话时遇到的错误


import ctypes

pardiso = ctypes.CDLL(pardiso_so_address)

Traceback (most recent call last):

  File "test.py", line 27, in <module>

    pardiso = ctypes.CDLL(lib720)

  File "/home/amin/anaconda3/envs/idp/lib/python3.7/ctypes/__init__.py", line 364, in __init__

    self._handle = _dlopen(self._name, mode)

OSError: ./libpardiso600-GNU720-X86-64.so: undefined symbol: sgetrf_

如果有人能对此有所了解,我将不胜感激。


PS。我已经联系了 Pardiso 开发人员,他们告诉我需要链接优化的 BLAS,但我已经通过conda.


更新1:我mkl通过安装conda,但没有帮助。奇怪的是,我添加import scipy到标题中并且错误消失了。如果我添加import mkl. 因此,出于某种原因,除非scipy或mkl手动导入,否则.so不知道lapack安装存在。无论如何,现在又抛出了另一个错误,我认为这可能与libgfortran库有关。这是错误


Traceback (most recent call last):

  File "test.py", line 34, in <module>

    pardiso = ctypes.CDLL(lib720)

  File "/home/amin/anaconda3/envs/test/lib/python3.7/ctypes/__init__.py", line 364, in __init__

    self._handle = _dlopen(self._name, mode)

OSError: ./libpardiso600-GNU720-X86-64.so: undefined symbol: _gfortran_st_close

我仔细检查了是否libgfortran已安装,确实是:


(test) PyPardisoProject$ ldconfig -p | grep libgfortran

    libgfortran.so.5 (libc6,x86-64) => /lib/x86_64-linux-gnu/libgfortran.so.5

    libgfortran.so.4 (libc6,x86-64) => /lib/x86_64-linux-gnu/libgfortran.so.4

我认为类似的东西可能在起作用,即图书馆在那里但需要触发(类似于import scipy似乎已经为 所做的事情liblapack,但我不知道如何触发它。


注意:我在 Pardiso 网站上的 C 中找到了一个示例,并.so通过它测试了该文件


$ gcc pardiso_sym.c -o pardiso_sym -L . -lpardiso600-GNU720-X86-64 -llapack -fopenmp -lgfortran

$ OMP_NUM_THREADS=1 ./pardiso_sym 

它没有问题(使用我机器上的现有库)。所以,.so作品,只是我不知道如何在 Python 中通知它它的依赖关系。


更新 2:这是输出ldd pardiso_sym:

因此,我添加了公共路径,即/lib/x86_64-linux-gnu和/lib64toPATH并通过以下方式再次运行 Python 脚本:


PATH=$PATH:/lib/x86_64-linux-gnu:/lib64 python padiso_script.py

但同样的错误被抛出。我也尝试添加LD_LIBRARY_PATH,但也没有工作。


慕虎7371278
浏览 211回答 3
3回答

皈依舞

Pardiso 6 sparse solver至少取决于 Lapack 函数sgetrf,该函数使用带有行交换的部分旋转来计算一般 M×N 矩阵 A 的 LU 分解。从我们阅读的内容来看,libpardiso600-GNU720-X86-64.so它与共享的 Lapack 库动态链接。您需要提供一个包含一个实现的 PATH。在启动 Python 之前,我建议您使用LD_LIBRARY_PATH并包含您正在使用的 BLAS/Lapack 库的路径。它可以是 netlib 实现、ATLAS 实现或 MKL 实现。LD_LIRARY_PATH=$LD_LIRARY_PATH:/my_path_to_lapack&nbsp;\python&nbsp;-c"import&nbsp;ctypes;&nbsp;pardiso&nbsp;=&nbsp;ctypes.CDLL(pardiso_so_address)"如果你使用conda,你可以用命令安装conda&nbsp;install&nbsp;-c&nbsp;anaconda&nbsp;mkl在这种情况下,安装可能会直接解决问题。

人到中年有点甜

PATH诀窍是,您需要在加载 Pardiso 库之前在 Python 脚本中显式加载依赖项,即lapack,blas和,而不是将依赖项的位置添加到 system 。gfortran此外,您必须将可选mode=ctypes.RLTD_GLOBAL参数显式传递给ctypes.CDLL方法,以使依赖项全局可访问,因此 Pardiso 可以访问它们。import ctypesimport ctypes.utilshared_libs = ["lapack", "blas", "omp", "gfortran"]for lib in shared_libs:&nbsp; &nbsp; # Fetch the proper name of the dependency&nbsp; &nbsp; libname = ctypes.util.find_library(lib)&nbsp; &nbsp; # Load the dependency and make it globally accessible&nbsp; &nbsp; ctypes.CDLL(libname, mode=ctypes.RTLD_GLOBAL)# Finally, load the Pardiso librarypardiso = ctypes.CDLL(pardiso_so_address)以我的经验,如果您在已安装的conda环境中mkl,您只需将其gfortran列为依赖项,其余的将自动加载和访问,在这种情况下 set shared_libs = ["gfortran"].

幕布斯7119047

Pardiso 6 和 Intel MKL Pardiso 不兼容,因为它们具有不同的 API。您可以尝试从系统路径中删除 MKL,添加 OpenBLAS,然后再次尝试链接您的示例。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Python