首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何为Python编译C扩展,其中C函数使用LAPACK库?

如何为Python编译C扩展,其中C函数使用LAPACK库?
EN

Stack Overflow用户
提问于 2018-08-31 00:25:42
回答 3查看 813关注 0票数 3

我为Python编写了一个C表达式,该模块成功地编译在一个.so文件中。但是,当我试图在Python中使用包装的C函数(在python中调用包装C函数的测试代码)时,我得到了以下ImportError

代码语言:javascript
运行
复制
ImportError: /home/username/newModule.cpython-36m-x86_64-linux-gnu.so: undefined symbol: dgetri_

我确信导入错误中的undefined symbol: dgetri_是因为生成的.so文件没有找到指向LAPACK库的链接。所以我的问题如下,

当包装的C函数依赖于LAPACK库生成格式的模块时,如何编译python的c扩展代码?

目前,我正在使用python的utils.core模块编译C代码。我认为我需要将C代码从命令行编译到链接LAPACK,但不确切地知道使用哪些命令是合适的?

任何帮助都是非常感谢的。

EN

回答 3

Stack Overflow用户

发布于 2018-09-01 21:33:40

您可能对使用LAPACK的scipy.linalg.cython.感兴趣,它提供了对LAPACK函数dgetri等的访问。好消息是:

这样就可以从任何第三方Cython模块中使用SciPy的BLAS和LAPACK,而无需与库进行明确的链接。这意味着像scikit这样的项目--学习模型和状态模型--不需要维护对BLAS和LAPACK的独立构建依赖。

使用dger的示例可在直接使用SciPy接口和Cython调用BLAS / LAPACK上获得。还请参阅使用内部数组定义改进Cython性能? --我在回答MPI python-Open时详细介绍了如何使用cython_blas,下面是如何将其适应于dgetri:

  1. 代码的关键部分是用Cython编写的,在一个专用文件myinverse.pyx中。
  2. 此文件由Cython转换为myinverse.c文件。
  3. 此c文件由您最喜欢的c++编译器gcc编译,以构建共享库myinverse.so
  4. 优化的函数可以在import myinverse之后的程序中使用。

下面是一个cython模块,放在.pyx文件中:

代码语言:javascript
运行
复制
import numpy

cimport numpy
cimport scipy.linalg.cython_lapack
ctypedef numpy.float64_t DTYPE_t
cimport cython
from libc.stdlib cimport malloc, free

@cython.boundscheck(False)
@cython.wraparound(False)
@cython.nonecheck(False)
def invert(numpy.ndarray[DTYPE_t, ndim=2] array):

    cdef  int rows = array.shape[0]
    cdef   int cols = array.shape[1]
    cdef  int info = 0
    if cols !=rows:
        return array,1,"not a square matrix"

    cdef int* ipiv = <int *> malloc(rows * sizeof(int))
    if not ipiv:
        raise MemoryError()

    scipy.linalg.cython_lapack.dgetrf(&cols,&rows,&array[0,0],&rows,ipiv,&info)
    if info !=0:
        free(ipiv)
        return array,info,"dgetrf failed, INFO="+str(info)
    #workspace query
    cdef double workl
    cdef int lwork=-1
    scipy.linalg.cython_lapack.dgetri(&cols,&array[0,0],&rows,ipiv,&workl,&lwork,&info)
    if info !=0:
        free(ipiv)
        return array,info,"dgetri failed, workspace query, INFO="+str(info)
    #allocation workspace
    lwork= int(workl)
    cdef double* work = <double *> malloc(lwork * sizeof(double))
    if not work:
        raise MemoryError()

    scipy.linalg.cython_lapack.dgetri(&cols,&array[0,0],&rows,ipiv,work,&lwork,&info)
    if info !=0:
        free(ipiv)
        free(work)
        return array,info,"dgetri failed, INFO="+str(info)

    free(ipiv)
    free(work)

    return array,info,""

要计算和编译.pyx文件,可以使用以下makefile (我希望您使用的是Linux.)

代码语言:javascript
运行
复制
all: myinverse myinverseb


myinverse: myinverse.pyx
    cython -a myinverse.pyx

myinverseb: myinverse.c
    gcc -shared -pthread -fPIC -fwrapv -O2 -Wall -fno-strict-aliasing -I/usr/include/python2.7 -o myinverse.so myinverse.c

在主要python文件中调用了新的pythonmy反向函数chainng的dgetrf()dgetri()

代码语言:javascript
运行
复制
import numpy as np

import myinverse
n=42

#A=np.zeros((n,n))
#for i in range(n):
#    A[i,i]=10
A=np.random.rand(n,n)
#A=np.zeros((n,n))
Am,info,string=myinverse.invert(A.copy())
if info==0:
    print np.linalg.norm(A.dot(Am)-np.identity(n), np.inf)
else :
    print "inversion failed, info=",info, string
票数 2
EN

Stack Overflow用户

发布于 2018-09-02 05:59:02

或者,在linux中编译时,我使用了以下两行代码来处理代码

代码语言:javascript
运行
复制
$gcc -DNDEBUG -Wall -Wstrict-prototypes -fPIC -I/home/username/anaconda3/include/python3.6m -c stackDoc.cpp -o mydemo.o
$gcc -shared mydemo.o -o mydemo.so

下面的链接我觉得很有用,https://docs.python.org/2/extending/building.html

票数 1
EN

Stack Overflow用户

发布于 2020-04-03 10:40:35

或者,您可以使模块被链接到对漏洞。

例如:

代码语言:javascript
运行
复制
from distutils.core import setup
from distutils.extension import Extension

setup(
    name='MyExtension',
    version='0.1',
    ext_modules=[
        Extension('lib_name', ['lib_name.cpp'], extra_link_args=['-lopenblas']),
    ],
    scripts=['lib_name.cpp', '__init__.py'],
)
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/52106978

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档