Python/Numba: Unknown attribute error with scipy.s

2019-01-26 17:51发布

问题:

I am having an error when running code using the @jit decorator. It appears that some information for the function scipy.special.gammainc() can't be located:

Failed at nopython (nopython frontend)
Unknown attribute 'gammainc' for Module(<module 'scipy.special' from 'C:\home\Miniconda\lib\site-packages\scipy\special\__init__.pyc'>) $164.2 $164.3 = getattr(attr=gammainc, value=$164.2)

Without the @jit decorator the code will run fine. Maybe there is something required to make the attributes of the scipy.special module visible to Numba?

Thanks in advance for any suggestions, comments, etc.

回答1:

The problem is that gammainc isn't one of the small list of functions that Numba inherently knows how to deal with (see http://numba.pydata.org/numba-doc/dev/reference/numpysupported.html) - in fact none of the scipy functions are. This means you can't use it in "nopython" mode, unfortunately - it just has to treat it as a normal python function call.

If you remove nopython=True, it should work. However, that isn't hugely satisfactory, because it may well be slower. Without seeing your code it's difficult to know exact what to suggest. However, in general:

  • loops (that don't contain things like gammainc) will be sped up, even without nopython.

  • gammainc is a "ufunc", which means it can be readily applied to a whole array at a time, and should run quickly anyway.

  • you can call func.inspect_types() to see it's been able to compile.

As a trivial example:

from scipy.special import gammainc
import numba as nb
import numpy as np

@nb.jit # note - no "nopython"
def f(x):
  for n in range(x.shape[0]):
    x[n] += 1
  y = gammainc(x,2.5)
  for n in range(y.shape[0]):
    y[n] -= 1
  return y

f(np.linspace(0,20)) # forces it to be JIT'd and outputs an array

Then f.inspect_types() identifies the two loops as "lifted loops", meaning they'll be JIT'd and run quickly. The bit with gammainc is not JIT'd, but is applied to the whole array at once and so should be fast too.