我的问题与提出here的问题非常相似,所以我试图在那里的答案中实现所提出的内容,基于调用与python捆绑的bla example。我的代码只是该example.pyx的略微修改版本,这里是我的相关代码(文件f2pyptr.h不变):
#example.pyx (single precision linear system solver via lapack)
import numpy as np
import scipy.linalg.lapack
import cython
cimport numpy as np
cdef extern from "/(pwd)/f2pyptr.h":
void *f2py_pointer(object) except NULL
ctypedef int sgesv_t(
int *N, int *NRHS,
float *A, int* LDA,
int* IPIV,
float *B,
int *LDB,
int *INFO)
cdef sgesv_t *sgesv = <sgesv_t*>f2py_pointer(scipy.linalg.lapack.sgesv._cpointer)
def myfunc_sgesv():
cdef int N, NRHS, LDA, LDB, INFO
N = 10
NRHS = 1
LDA = 10
LDB = 10
cdef np.ndarray[np.float32_t, ndim=2] A = np.ones((N,N), np.float32, order = "F")
cdef np.ndarray[np.float32_t, ndim=2] B = np.ones((N, NRHS),np.float32, order = "F")
cdef np.ndarray[np.int_t, ndim=1] IPIV = np.empty((N,), dtype = np.int)
sgesv(&N, &NRHS, &A[0,0], &LDA, &IPIV, &B[0,0], &LDB, &INFO)*
def myfunc_sgesv():
cdef int N, NRHS, LDA, LDB, INFO
N = 10
NRHS = 1
LDA = 10
LDB = 10
cdef np.ndarray[np.float32_t, ndim=2] A = np.ones((N,N), np.float32, order = "F")
cdef np.ndarray[np.float32_t, ndim=2] B = np.ones((N, NRHS),np.float32, order = "F")
cdef np.ndarray[np.int_t, ndim=1] IPIV = np.empty((N,), dtype = np.int)
sgesv(&N, &NRHS, &A[0,0], &LDA, &IPIV, &B[0,0], &LDB, &INFO)
使用标准的setup.py文件,我打电话 python setup.py build_ext --inplace
导致
Compiling example.pyx because it changed.
Cythonizing example.pyx
Error compiling Cython file:
------------------------------------------------------------
...
cdef np.ndarray[np.float32_t, ndim=2] A = np.ones((N,N), np.float32, order = "F")
cdef np.ndarray[np.float32_t, ndim=2] B = np.ones((N, NRHS),np.float32, order = "F")
cdef np.ndarray[np.int_t, ndim=1] IPIV = np.empty((N,), dtype = np.int)
sgesv(&N, &NRHS, &A[0,0], &LDA, &IPIV, &B[0,0], &LDB, &INFO)
^
------------------------------------------------------------
example.pyx:103:33: Cannot take address of Python variable
Traceback (most recent call last):
File "setup.py", line 5, in <module>
ext_modules = cythonize("example.pyx")
File "/idiap/home/jnewling/.local/lib/python2.7/site-packages/Cython-0.20.1/Cython/Buil/Dependencies.py", line 785, in cythonize
cythonize_one(*args[1:]) File "/idiap/home/jnewling/.local/lib/python2.7/site-packages/Cython-0.20.1/Cython/Buil/Dependencies.py", line 902, in cythonize_one raise CompileError(None, pyx_file) Cython.Compiler.Errors.CompileError: example.pyx
我原来的example.pyx正常运行,以及修改后的单精度版本(即sgemm),因此无法理解为什么我的sgesv实现失败。
非常欢迎任何特定的替代方法的诊断或建议。
答案 0 :(得分:3)
不确定这个答案是否正确,但我会告诉你我尝试了什么,因为它可以帮到你:
我在编译代码时在不同的地方收到了错误Cannot take address of Python variable
。我在& IPIV
收到错误。然后我注意到它是一个数组,所以我把它改成了:
sgesv(&N, &NRHS, &A[0,0], &LDA, &IPIV[0], &B[0,0], &LDB, &INFO)
。然后我收到错误Cannot assign type 'int_t *' to 'int *'
。然后找到以下答案:Passing numpy integer array to c code并将代码更改为:
cdef np.ndarray[int, ndim=1, mode='c'] IPIV = np.empty((N,), dtype = ctypes.c_int)
sgesv(&N, &NRHS, &A[0,0], &LDA, &IPIV[0], &B[0,0], &LDB, &INFO)
现在它编译没有任何错误。