在 cython 中使用 MKL 失败,在来自 MKL 的共享对象中使用未定义的符号,但直接执行很好

如何解决在 cython 中使用 MKL 失败,在来自 MKL 的共享对象中使用未定义的符号,但直接执行很好

我正在使用英特尔数学内核库 (MKL) 用 C 语言编写物理模拟,并希望使用 cython 从 python 代码中直接调用它。 cython 编译本身可以工作(如果示例中不包含 MKL,则程序运行不会出错)并且如果我直接在 gcc 中使用

编译我的 C 代码

gcc -O3 -Wall -m64 -I"${MKLROOT}/include" bar.c -L${MKLROOT}/lib/intel64 -Wl,--no-as-needed -lmkl_intel_lp64 -lmkl_sequential -lmkl_core -lpthread -lm -ldl

效果很好。编译器标志由 MKL Link line Advisor 生成。 但是,如果我现在尝试使用 cython 编译相同的代码,则会收到错误消息

INTEL MKL ERROR: /opt/intel/oneapi/mkl/latest/lib/intel64/libmkl_avx2.so.1: undefined symbol: mkl_sparse_optimize_bsr_trsm_i8. Intel MKL FATAL ERROR: Cannot load libmkl_avx2.so.1 or libmkl_def.so.1.

我还尝试将我的程序(没有主程序)编译到共享库(.so)中,以便在 cython 之外完成 MKL 链接,然后直接链接到它,但是在将该库摆弄成LD_LIBRARY_PATH 我刚刚又出现了同样的行为。

知道如何使链接正确吗?

我可以将使用过的 cblas_ 函数替换为不同的函数(例如 cblas_drot 和更多尝试过的函数)并得到相同的错误。

我已经阅读了很多其他问题(很多关于 anaconda 中的 MKL,我的 MKL 是手动安装在 /opt 中的,如上面的路径所示),包括 this,它试图在 Java 中使用 MKL 和得到了同样的错误。 我可以重现关于 nm 语句(在 libmkl_avx2.so.1 中未定义,但在 libmkl_gnu_thread.so 中定义)的相同结果,但我未能将那个问题的答案应用于我的问题。如果我尝试在下面显示的 -lmkl_gnu_thread 脚本中添加 setup.py,我会得到不同的未实现的依赖项,通过还包括 -fopenmp 来修复旧错误...

更多信息和使用过的文件

LD_LIBRARY_PATH=/opt/intel/oneapi/mkl/latest/lib/intel64:/opt/intel/oneapi/compiler/2021.1.1/linux/lib:/opt/intel/oneapi/compiler/2021.1.1/linux/lib/x64:/opt/intel/oneapi/compiler/2021.1.1/linux/lib/emu:/opt/intel/oneapi/compiler/2021.1.1/linux/compiler/lib/intel64_lin:/opt/intel/oneapi/compiler/2021.1.1/linux/compiler/lib:/opt/intel/oneapi/tbb/2021.1.1/env/../lib/intel64/gcc4.8(由 mkl setvars 脚本设置,由 echo $LD_LIBRARY_PATH 获得) python 可能会对这个变量做些什么奇怪的事情?

readelf -d $MKLROOT/lib/intel64/libmkl_avx2.so.1 | grep NEEDED 0x0000000000000001 (NEEDED) 返回 Shared library: [libdl.so.2],表明它声称只依赖于 libdl (我没有找到我从哪里得到那个命令的问题,但它也是针对这个主题的,只是文件名中缺少 .1)

使用过的文件

setup.py

​​>

(包含第二个版本作为 comamnd,可以这样运行)

from Cython.Distutils import build_ext
#from Cython.Build import cythonize
from distutils.extension import Extension
from distutils.core import setup
import numpy

extensions = [
    Extension("foo",["foo.pyx"],include_dirs=[numpy.get_include()],extra_compile_args=["-Wall","-m64","-I\"${MKLROOT}/include\""],extra_link_args=["-fopenmp","-L${MKLROOT}/lib/intel64","-Wl,--no-as-needed","-lmkl_gnu_thread","-lmkl_intel_lp64","-lmkl_sequential","-lmkl_core","-lpthread","-lm","-ldl"])
]

for e in extensions:
    e.cython_directives = {'language_level': "3"} #all are Python-3

# produce the same behaviour,first:
setup(ext_modules=cythonize(extensions))
#second
#setup(ext_modules=cythonize(extensions),#      cmdclass = {'build_ext':build_ext})

用于 python setup.py build_ext --inplace

根据评论,

编辑另一个版本更好地使用关键字。它给出了同样的错误。

from Cython.Build import cythonize
from distutils.extension import Extension
from distutils.core import setup
import numpy

extensions = [
    Extension("foo",include_dirs=[numpy.get_include(),"\"${MKLROOT}/include\""],libraries=["mkl_intel_lp64","mkl_sequential","mkl_core","pthread","m","dl"],library_dirs=["${MKLROOT}/lib/intel64"],"-m64"],extra_link_args=["-Wl,])
]

for e in extensions:
    e.cython_directives = {'language_level': "3"} #all are Python-3

setup(ext_modules=cythonize(extensions))

foo.pyx

cimport numpy as np
import numpy as np
import ctypes

cdef extern from "bar.c":  
    void double_elements(int n,double* vec_y)  

def func(np.ndarray[np.double_t,ndim=1] y not None):
    double_elements(<int> y.size//2,<double*> <size_t> y.__array_interface__['data'][0])
    
    return y

bar.c

#include <mkl.h>
#include <stdio.h>

void double_elements(int n,double* x) {
    cblas_dscal(n,2.,x,1);
}


#ifndef PY_VERSION_HEX // compile the main only,if not using cython
int main() {
    double x[2] = {1.,2.};
    double_elements(2,x);
    printf("%g %g\n",x[0],x[1]);
    return 0;
}
#endif

运行.py

​​>

(用于测试,很无聊,只调用函数)

import numpy as np
import foo

x = np.array([1.,2.])
y = foo.func(x)

print(x)
print(y)

解决方法

我已经通过使用 MKL 的静态链接解决了这个问题。因为我也没有在 setup.py 脚本中应用来自静态链接(它使用组)的所有命令,所以我已经切换到完全自己编译它

gcc -O3 -Wall -m64 -I"${MKLROOT}/include" -c bar.c -o build/bar.o

cythonize foo.pyx

# exchange /path/to/numpy/ by value given by numpy.get_include()
gcc -Wall -O2 -fstack-protector-strong -fwrapv -fstack-protector-strong -D_FORTIFY_SOURCE=2 -fPIC -I/path/to/numpy/core/include -I/usr/include/python3.8 -c foo.c -o build/foo.o -DNPY_NO_DEPRECATED_API=NPY_1_7_API_VERSION

gcc -shared build/foo.o build/bar.o -o foo.cpython-38-x86_64-linux-gnu.so -Wl,--start-group ${MKLROOT}/lib/intel64/libmkl_intel_lp64.a ${MKLROOT}/lib/intel64/libmkl_sequential.a ${MKLROOT}/lib/intel64/libmkl_core.a -Wl,--end-group -lpthread -lm -ldl

这对应于安装脚本完成的编译步骤(不检查更改日期)并删除了一些编译标志(它使用了许多重复项)。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


使用本地python环境可以成功执行 import pandas as pd import matplotlib.pyplot as plt # 设置字体 plt.rcParams[&#39;font.sans-serif&#39;] = [&#39;SimHei&#39;] # 能正确显示负号 p
错误1:Request method ‘DELETE‘ not supported 错误还原:controller层有一个接口,访问该接口时报错:Request method ‘DELETE‘ not supported 错误原因:没有接收到前端传入的参数,修改为如下 参考 错误2:cannot r
错误1:启动docker镜像时报错:Error response from daemon: driver failed programming external connectivity on endpoint quirky_allen 解决方法:重启docker -&gt; systemctl r
错误1:private field ‘xxx‘ is never assigned 按Altʾnter快捷键,选择第2项 参考:https://blog.csdn.net/shi_hong_fei_hei/article/details/88814070 错误2:启动时报错,不能找到主启动类 #
报错如下,通过源不能下载,最后警告pip需升级版本 Requirement already satisfied: pip in c:\users\ychen\appdata\local\programs\python\python310\lib\site-packages (22.0.4) Coll
错误1:maven打包报错 错误还原:使用maven打包项目时报错如下 [ERROR] Failed to execute goal org.apache.maven.plugins:maven-resources-plugin:3.2.0:resources (default-resources)
错误1:服务调用时报错 服务消费者模块assess通过openFeign调用服务提供者模块hires 如下为服务提供者模块hires的控制层接口 @RestController @RequestMapping(&quot;/hires&quot;) public class FeignControl
错误1:运行项目后报如下错误 解决方案 报错2:Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.8.1:compile (default-compile) on project sb 解决方案:在pom.
参考 错误原因 过滤器或拦截器在生效时,redisTemplate还没有注入 解决方案:在注入容器时就生效 @Component //项目运行时就注入Spring容器 public class RedisBean { @Resource private RedisTemplate&lt;String
使用vite构建项目报错 C:\Users\ychen\work&gt;npm init @vitejs/app @vitejs/create-app is deprecated, use npm init vite instead C:\Users\ychen\AppData\Local\npm-
参考1 参考2 解决方案 # 点击安装源 协议选择 http:// 路径填写 mirrors.aliyun.com/centos/8.3.2011/BaseOS/x86_64/os URL类型 软件库URL 其他路径 # 版本 7 mirrors.aliyun.com/centos/7/os/x86
报错1 [root@slave1 data_mocker]# kafka-console-consumer.sh --bootstrap-server slave1:9092 --topic topic_db [2023-12-19 18:31:12,770] WARN [Consumer clie
错误1 # 重写数据 hive (edu)&gt; insert overwrite table dwd_trade_cart_add_inc &gt; select data.id, &gt; data.user_id, &gt; data.course_id, &gt; date_format(
错误1 hive (edu)&gt; insert into huanhuan values(1,&#39;haoge&#39;); Query ID = root_20240110071417_fe1517ad-3607-41f4-bdcf-d00b98ac443e Total jobs = 1
报错1:执行到如下就不执行了,没有显示Successfully registered new MBean. [root@slave1 bin]# /usr/local/software/flume-1.9.0/bin/flume-ng agent -n a1 -c /usr/local/softwa
虚拟及没有启动任何服务器查看jps会显示jps,如果没有显示任何东西 [root@slave2 ~]# jps 9647 Jps 解决方案 # 进入/tmp查看 [root@slave1 dfs]# cd /tmp [root@slave1 tmp]# ll 总用量 48 drwxr-xr-x. 2
报错1 hive&gt; show databases; OK Failed with exception java.io.IOException:java.lang.RuntimeException: Error in configuring object Time taken: 0.474 se
报错1 [root@localhost ~]# vim -bash: vim: 未找到命令 安装vim yum -y install vim* # 查看是否安装成功 [root@hadoop01 hadoop]# rpm -qa |grep vim vim-X11-7.4.629-8.el7_9.x
修改hadoop配置 vi /usr/local/software/hadoop-2.9.2/etc/hadoop/yarn-site.xml # 添加如下 &lt;configuration&gt; &lt;property&gt; &lt;name&gt;yarn.nodemanager.res