首页 > 解决方案 > 如何在 numba 的“@guvectorize”中调用“@guvectorize”?

问题描述

我试图调用一个@guvectorizeinside a@guvectorize但我有一个错误说:

Untyped global name 'regNL_nb': cannot determine Numba type of <class 'numpy.ufunc'>

File "di.py", line 12:
def H2Delay_nb(S1, S2, R2):
    H1 = regNL_nb(S1, S2)
    ^

这是一个 MRE:

import numpy as np
from numba import guvectorize, float64, int64, njit, cuda, jit

@guvectorize(["float64[:], float64[:], float64[:]"], '(n),(n)->(n)')
def regNL_nb(S1, S2, h2):
    for i in range(len(S1)):
        h2[i] = S1[i] + S2[i]

@guvectorize(["float64[:], float64[:],  float64[:]"], '(n),(n)->(n)',nopython=True)
def H2Delay_nb(S1, S2, R2):
    H1 = regNL_nb(S1, S2)
    H2 = regNL_nb(S1, S2,)
    for i in range(len(S1)):
        R2[i] =  H1[i] + H2[i]


S1 = np.array([1,2,3,4,5,6,7,8,9])
S2 = np.array([1,2,3,4,5,6,7,8,9])
H2 = H2Delay_nb(S1, S2)
print(H2)

我不知道如何告诉 numba 函数 regNL_nb 是一个 guvectorize 函数。

标签: pythonnumba

解决方案


@guvectorize(["float64[:], float64[:],  float64[:]"], '(n),(n)->(n)',nopython=True)
def H2Delay_nb(S1, S2, R2):
    H1 = regNL_nb(S1, S2)
    H2 = regNL_nb(S1, S2,)
    for i in range(len(S1)):
        R2[i] =  H1[i] + H2[i]

通过使用该参数nopython = True,您可以停用对象模式,因此 Numba 无法将所有值作为 Python 对象处理(请参阅:https ://numba.pydata.org/numba-doc/latest/glossary.html#term-object -模式

一般来说,如果您使用nopython = True. 只有有限数量的库可以与 Numba Jit 一起使用(在 中nopython)。完整列表可在此处找到:https ://numba.pydata.org/numba-doc/dev/reference/numpysupported.html 。

所以你试图做的事情是不可能的,除了禁用nopython,即:

@guvectorize(["float64[:], float64[:],  float64[:]"], '(n),(n)->(n)',nopython=False)
    def H2Delay_nb(S1, S2, R2):
        H1 = regNL_nb(S1, S2)
        H2 = regNL_nb(S1, S2,)
        for i in range(len(S1)):
            R2[i] =  H1[i] + H2[i]

使用这种方法,程序会输出正确的值,即[ 4. 8. 12. 16. 20. 24. 28. 32. 36.]for H2

我还发现了另一个处理熟悉问题的 StackOverflow 问题:numba - TypingError: cannot determine Numba type of <class 'builtin_function_or_method'>。应得的学分:Kevin K.在提到的线程中建议您应该使用“更简单”的数据类型——这在 CPython 中最常见。除此之外,我在这一点上完全同意他的观点,我不知道在nopython激活模式下有任何可能的解决方案。


资料来源:


推荐阅读