为什么我不能在此函数上使用带有 `numba.guvectorize` 的 `nopython=True`?

Why can't I use `nopython=True` with `numba.guvectorize` on this function?

如果我尝试在以下函数中使用 nopython=Truenumba.guvectorize,我会得到

NotImplementedError: Don't know how to create implicit output array with 'A'
layout. --%<-----------------------------------------------------------------

关于 nopython=Truenumba.guvectorize 的正确使用方法,文档并不清楚。我查看了 numba --annotate-html 生成的注释输出,我认为原因与 tmp 的初始化方式有关。我正在使用

如有任何帮助,我们将不胜感激。

import numpy as np
import numba

@numba.guvectorize(['(float64[:], float64[:], float64[:], float64[:], float64[:])'], '(),(),(n),() -> (n)')
def _gpcm(theta, a, thresh, D, res):

    tmp = np.zeros(thresh.shape, dtype=np.float64)
    tmp[0] = a *  D * (theta - thresh[0])
    bot = 0

    for j in range(1, thresh.shape[0]):
        if not np.isnan(thresh[j]):
            tmp[j] = tmp[j - 1] + a * D * (theta - thresh[j])

    for j in range(thresh.shape[0]):
        if not np.isnan(thresh[j]):
            tmp[j] = np.exp(tmp[j])
            bot += tmp[j]

    for j in range(thresh.shape[0]):
        if not np.isnan(thresh[j]):
            res[j] = tmp[j] / bot
        else:
            res[j] = 0

来自docs,参考guvectorize

The concrete signature does not allow for scalar values, even though the layout may mention them. In this example, the second argument is declared as int64[:], not int64. This is why it must be dereferenced by fetching y[0].

所以,我只需要更改访问标量的方式。将我的原始功能更改为

import numpy as np
import numba

@numba.guvectorize(['(float64[:], float64[:], float64[:], float64[:], float64[:])'], '(),(),(n),() -> (n)', nopython=True)
def _gpcm(theta, a, thresh, D, res):

    tmp = np.zeros(thresh.shape, dtype=np.float64)
    tmp[0] = a[0] *  D[0] * (theta[0] - thresh[0])
    bot = 0

    for j in range(1, thresh.shape[0]):
        if not np.isnan(thresh[j]):
            tmp[j] = tmp[j - 1] + a[0] * D[0] * (theta[0] - thresh[j])

    for j in range(thresh.shape[0]):
        if not np.isnan(thresh[j]):
            tmp[j] = np.exp(tmp[j])
            bot += tmp[j]

    for j in range(thresh.shape[0]):
        if not np.isnan(thresh[j]):
            res[j] = tmp[j] / bot
        else:
            res[j] = 0

问题解决了。