在 Python-C++-C-Fortran 2003 程序中链接英特尔的 MKL

Posted

技术标签:

【中文标题】在 Python-C++-C-Fortran 2003 程序中链接英特尔的 MKL【英文标题】:Linking Intel's MKL within Python-C++-C-Fortran 2003 program 【发布时间】:2012-12-19 11:56:22 【问题描述】:

我正在尝试链接一个性质相当复杂的程序:

在 Linux Fedora 下开发和运行 用 fortran 2003 编写的主要代码严重依赖于 Intel 的 MKL 库和一小段 ANSI C 代码 它有 C++ 接口(使用 iso_c_binding) c++ 接口是通过 boost.python 从 python 访问的

在运行时我得到以下文本

MKL FATAL ERROR: Cannot load neither libmkl_avx.so nor libmkl_def.so

之后程序停止。

我检查了libmkl_avx.solibmkl_def.so 都在$LD_LIBRARY_PATH

最后的链接是通过:

g++ -g3 -shared -Wl,-soname,libFrrBoost_rt.so interfejs.o t83.o gen_random2.o 
-L/opt/intel/composerxe/mkl/lib/intel64 -lpython2.7 -lifport -lifcore -lboost_python     
-Wl,--start-group -lmkl_sequential -lmkl_intel_lp64 -lmkl_core  -Wl,--end-group 
-o libFrrBoost_rt.so 

libFrrBoost 是被链接的模块,那么

运行python t83.py(特别是链接器在准备二进制文件时不会抱怨)导入模块libFrrBoost会导致错误。

试图谷歌。我发现的所有信息都与用 C/Fortran 编写的“常规程序”有关,其中包括英特尔的 MKL。我能够毫无问题地运行这类程序。我认为 Makefile 中链接线的 MKL 部分在这两种情况下都是等价的,但一定有一个隐藏的谜团。问题通常是错误的链接 - 我认为这不适用(库与英特尔手册中的完全一样 - 接口、线程和计算库非常标准)

使用的编译器:

ifort 12.1.0、icpc 12.1.0、python Python 2.7.1、icc 12.1.0(小C sn-p也叫MKL,但是)

编辑(由于 Hirsto Iliev 的评论)

我是这样运行 strace 的:strace python t83.py;结果是(grepping libmkl:

open("/opt/intel/composer_xe_2011_sp1.7.256/mkl/lib/intel64/libmkl_avx.so", O_RDONLY) = 3
open("/usr/bin/libmkl_avx.so", O_RDONLY) = -1 ENOENT (No such file or directory)
open("/opt/slurm-2.2.5/lib/libmkl_avx.so", O_RDONLY) = -1 ENOENT (No such file or directory)
open("/opt/intel/composer_xe_2011_sp1.7.256/compiler/lib/intel64/libmkl_avx.so", O_RDONLY) = -1 ENOENT (No such file or directory)
open("/opt/intel/composer_xe_2011_sp1.7.256/debugger/lib/intel64/libmkl_avx.so", O_RDONLY) = -1 ENOENT (No such file or directory)
open("/opt/intel/composer_xe_2011_sp1.7.256/mkl/lib/intel64/libmkl_avx.so", O_RDONLY) = 3

我了解 open 的规范与 here 中的一样,特别是 3,4 是正数,表示 open 找到了一个文件并为其分配了文件描述符。我已验证该文件确实存在于该位置。

这也是“好的”英特尔编译器目录:

czeslaw@stefan:~/prog/FoCpy3 $ which ifort
/opt/intel/composer_xe_2011_sp1.7.256/bin/intel64/ifort 

所以版本是一样的——显然这不是版本问题。

libmkl_def.so 的一切都是一样的。

免责声明:虽然我听起来对我写的东西很有信心,但我不是。每个句子都应该以“如果我没记错的话”开头。

【问题讨论】:

使用strace -f -e trace=file -o trace.out ./program args... 跟踪您的程序,然后在trace.out 中查找libmkl_def 以查看dlopen() 实际在哪些位置查找它。 亲切!我不知道这个命令。然而,结果并不令人满意。我将编辑主要帖子并在那里回答,因为我需要更多的空间和更多的格式选项而不是评论。 接受一些专业建议 -- software.intel.com/sites/products/mkl -- 不止一次帮助了我 谢谢 - 我刚刚尝试过。不幸的是,它生成了与我在 Makefile 中使用的相同的链接行(唯一的区别:其中没有 -Wl,--start-group-Wl,--end-group - 这无关紧要(而且它没有 - 我已经通过重新编译进行了检查)) 【参考方案1】:

对我来说,intel site 上提出的解决方案效果很好

export LD_PRELOAD=/opt/intel/mkl/lib/intel64/libmkl_core.so:/opt/intel/mkl/lib/intel64/libmkl_sequential.so

这似乎是某种错误。

【讨论】:

+1,当我使用英特尔编译的 python numpy/scipy 针对 mkl 库构建的错误时发现此错误时,也对我有用。 locate mkl 会显示你的位置,如果它没有安装在默认位置 非常感谢。我正在构建 .configure 脚本中没有链接到 mkl_rt 的东西。这节省了一天!【参考方案2】:

似乎解决方案是链接-lmkl_rt 而不是-lmkl_sequential -lmkl_intel_lp64 -lmkl_core。我不明白为什么一个人应该比另一个人更有优势。我很困惑,但这有效(到目前为止)。

编辑 英特尔人员声称这是 MKL 库错误。

【讨论】:

mkl_rt 是一个包装库,可以为您的平台 dlopen 正确的 mkl_whatever。您应该始终链接到 mkl_rt,而不是特定的 mkl_whatever。 我看到了很多相关的问题/答案,但这个答案只是解决这个问题的一个。

以上是关于在 Python-C++-C-Fortran 2003 程序中链接英特尔的 MKL的主要内容,如果未能解决你的问题,请参考以下文章

C-Fortran 字符串互操作性

在单行命令行中执行多行语句?

通过 swig 为 python-C++ 接口禁用隐式类型检查代码的生成

为啥 `python -c 'print('howdy')'` 会产生错误(在 zsh 中),但 `python -c 'print("howdy")'` 不会?

python -c 执行单行命令/脚本,有点意思

EC2 实例中 Ubuntu 20.04 上的 MySQL 客户端安装错误