在 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.so
和libmkl_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的主要内容,如果未能解决你的问题,请参考以下文章
通过 swig 为 python-C++ 接口禁用隐式类型检查代码的生成
为啥 `python -c 'print('howdy')'` 会产生错误(在 zsh 中),但 `python -c 'print("howdy")'` 不会?