为什么我不能在这个函数上使用`nopython = True`和`numba.guvectorize`?

时间:2015-10-27 19:24:01

标签: python numpy numba

如果我尝试在以下功能上使用nopython=Truenumba.guvectorize,我会

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

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

  • python = 3.4.1.final.0(Anaconda)
  • numpy = 1.9.3
  • numba = 0.21.0
  • llvmpy = 0.12.7

非常感谢任何帮助。

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

1 个答案:

答案 0 :(得分:1)

来自docs,参考guvectorize

  

具体签名不允许标量值,即使   布局可能会提到它们。在这个例子中,第二个参数是   声明为int64 [:],而不是int64。这就是它必须被解除引用的原因   通过获取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

解决了这个问题。