【问题标题】:Calling a cdef nogil function within nogil在 nogil 中调用 cdef nogil 函数
【发布时间】:2021-11-19 17:58:41
【问题描述】:

here 部分解决了这个问题,但我对解决方案不太满意,我想知道:

  1. 有没有办法编写结构并将其映射到扩展类
  2. 为什么会出现错误?函数是cdefnogil,在GIL环境中调用就可以了

第一点对我来说非常重要,因为我将从utils 库中调用很多函数并以here 描述的方式编写所有内容将非常耗时。

代码(iPython 笔记本):

%%cython
import numpy as np
cimport numpy as np
mingw_setup_args={'script_args': ["--compiler=mingw32", "--cython-cplus"], 'include_dirs': np.get_include()}
import pyximport; pyximport.install(setup_args=mingw_setup_args, reload_support=True, language_level=3)

from utils import blas_multiply

D_TYPE = np.dtype(np.float64)

cdef double[:,:] A = np.random.randn(100, 10, dtype=D_TYPE)
cdef double[:] b = np.random.randn(10, dtype=D_TYPE)
cdef double[:] out = np.zeros((A.shape[0], ), dtype=D_TYPE)

# blas_multiply(A, b, out) # works fine

with nogil:
    blas_multiply(A, b, out)

utils.pyx 文件

#!python
# distutils: language=c++
# cython: language_level=3

cimport cython
import numpy as np
cimport numpy as np
cimport scipy.linalg.cython_blas as blas

@cython.cdivision(True)
@cython.boundscheck(False)
@cython.wraparound(False)
@cython.nonecheck(False)
cpdef void blas_multiply(double[:,:] A, double[:] b, double[:] c) nogil:
    """
    calls dgemv from BLAS which computes y = alpha * trans(A) + beta * y
    A: m rows by k columns
    b: k rows by 1 columns
    c: k rows by 1 columns
    """
    cdef int m = A.shape[0]
    cdef int k = A.shape[1]
    cdef int n = 1
    cdef double alpha = 1.0
    cdef double beta = 0.0

    # for F contiguous arrays
    # blas.dgemv("N", &m, &k, &alpha, &A[0, 0], &m, &b[0], &n, &beta, &c[0], &n)

    # for C contiguous arrays
    blas.dgemv("T", &k, &m, &alpha, &A[0, 0], &k, &b[0], &n, &beta, &c[0], &n)

回溯:

Error compiling Cython file:
------------------------------------------------------------
...

# blas_multiply(A, b, out)
# print(out)

with nogil:
    blas_multiply(A, b, out)
                ^
------------------------------------------------------------

C:\Users\...\.ipython\cython\_cython_magic_6b53bffa20f1e5bcc572f847b4b26a3f.pyx:22:17: Discarding owned Python object not allowed without gil

Error compiling Cython file:
------------------------------------------------------------
...

# blas_multiply(A, b, out)
# print(out)

with nogil:
    blas_multiply(A, b, out)
                ^
------------------------------------------------------------

C:\Users\...\.ipython\cython\_cython_magic_6b53bffa20f1e5bcc572f847b4b26a3f.pyx:22:17: Calling gil-requiring function not allowed without gil

Error compiling Cython file:
------------------------------------------------------------
...

# blas_multiply(A, b, out)
# print(out)

with nogil:
    blas_multiply(A, b, out)
   ^
------------------------------------------------------------

C:\Users\...\.ipython\cython\_cython_magic_6b53bffa20f1e5bcc572f847b4b26a3f.pyx:22:4: Accessing Python global or builtin not allowed without gil

Error compiling Cython file:
------------------------------------------------------------
...

# blas_multiply(A, b, out)
# print(out)

with nogil:
    blas_multiply(A, b, out)
                ^
------------------------------------------------------------

C:\Users\...\.ipython\cython\_cython_magic_6b53bffa20f1e5bcc572f847b4b26a3f.pyx:22:17: Constructing Python tuple not allowed without gil

Error compiling Cython file:
------------------------------------------------------------
...

# blas_multiply(A, b, out)
# print(out)

with nogil:
    blas_multiply(A, b, out)
                 ^
------------------------------------------------------------

C:\Users\...\.ipython\cython\_cython_magic_6b53bffa20f1e5bcc572f847b4b26a3f.pyx:22:18: Converting to Python object not allowed without gil

Error compiling Cython file:
------------------------------------------------------------
...

# blas_multiply(A, b, out)
# print(out)

with nogil:
    blas_multiply(A, b, out)
                    ^
------------------------------------------------------------

C:\Users\...\.ipython\cython\_cython_magic_6b53bffa20f1e5bcc572f847b4b26a3f.pyx:22:21: Converting to Python object not allowed without gil

Error compiling Cython file:
------------------------------------------------------------
...

# blas_multiply(A, b, out)
# print(out)

with nogil:
    blas_multiply(A, b, out)
                       ^
------------------------------------------------------------

C:\Users\...\.ipython\cython\_cython_magic_6b53bffa20f1e5bcc572f847b4b26a3f.pyx:22:24: Converting to Python object not allowed without gil

【问题讨论】:

    标签: python c++ jupyter-notebook cython cpython


    【解决方案1】:
    from utils import blas_multiply
    

    此导入 blas_multiply 作为 Python 函数(即比 cpdef 生成的包装器)。因此,它显示为一个通用的 Python 可调用对象,并且所有关于它是 nogil 的信息都丢失了。

    你想要

    from utils cimport blas_multiply
    

    编译时获取blas_multiply 的 Cython 定义。您需要在 .pxd 文件中声明 blas_multiply 的签名才能正常工作。

    【讨论】:

    • 啊,是的,谢谢!这是否意味着utils.pxy 中的每个函数都需要自己的.pxd 文件?
    • 没有。他们都会去utils.pxd
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-01-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多