numba.jit(nopython)能处理数组索引和切片吗?

numba.jit(nopython)能处理数组索引和切片吗?,python,arrays,numpy,numba,Python,Arrays,Numpy,Numba,我正在尝试使用numba.jit加速一个简单的Python循环。但jit似乎无法处理基本的数组索引和切片?我能做些什么使这成为可能吗?我不明白如果jit不能处理基本的numpy数组,它怎么会有用 我正在强制nopython模式。它在对象模式下工作,但这根本不会加快代码的速度,所以我需要的是nopython模式 下面的代码只是一个说明问题的示例。我的实际代码也有同样的问题,但有更多的循环和迭代,因此jit非常有用 import numpy as np from numba import jit

我正在尝试使用numba.jit加速一个简单的Python循环。但jit似乎无法处理基本的数组索引和切片?我能做些什么使这成为可能吗?我不明白如果jit不能处理基本的numpy数组,它怎么会有用

我正在强制nopython模式。它在对象模式下工作,但这根本不会加快代码的速度,所以我需要的是nopython模式

下面的代码只是一个说明问题的示例。我的实际代码也有同样的问题,但有更多的循环和迭代,因此jit非常有用

import numpy as np
from numba import jit

n = 100
myarray = np.zeros(n)

@jit(nopython=True)
def compute(n):
    for i in xrange(n):
        myarray[i] += 1  # This indexing causes the error.

compute(n)

"""Sample run:
> python jit_test.py
> ...
> Failed at nopython (nopython frontend)
> Internal error at <numba.typeinfer.SetItemConstrain object at 0x7f700c89a7d0>:
> Immutable array
> File "jit_test.py", line 10
"""

在numba中,全局数组是静态的。在方法中获得只读副本。见:

如果要修改数组,请显式传入或在函数中创建它(在执行数组内存管理的较新版本的Numba中)并返回它

例如:

import numpy as np
import numba as nb

def compute(arr):
    for i in xrange(arr.shape[0]):
        arr[i] += 1

n = 100
myarray = np.zeros(n)

jitcompute = nb.jit(nopython=True)(compute)
然后是时间安排:

In [12]: %timeit compute(myarray)
10000 loops, best of 3: 25.7 µs per loop

In [13]: %timeit jitcompute(myarray)
The slowest run took 17.06 times longer than the fastest. This could mean that an intermediate result is being cached
1000000 loops, best of 3: 461 ns per loop
请注意:

  • 这显然是一个微不足道的例子,但它展示了如何在方法之外定义一个数组,然后让函数修改它
  • 我没有在这里使用
    @jit
    装饰器,这样我就可以编写一次方法定义,并对方法进行计时,有没有使用jit,但是
    jitcompute
    相当于在
    compute
    上使用装饰器所得到的结果
  • 如果您曾经对代码进行基准测试,请确保在计时之前运行该方法一次,否则您将看到jit代码所需的时间和实际执行时间的组合。第二次运行时,只能看到执行时间

我明白了。索引现在可以工作了。但是,arr[:]+=1不起作用。arr[:]=1可以工作。arr[:]=arr[:]+1不工作。arr=arr+1起作用。我也许可以通过反复试验来克服这些限制,但我不明白这里的规则是什么?此外,类似于arr+arr的东西确实起作用,但是arr[0:5]+arr[0:5]不起作用,即使arr2=arr[0:5]起作用。不必执行jit ed函数之外的每一个片段就可以实现这一点吗?此外,numba声称支持布尔值,但它不像Python那样对待0和1?F.ex.:y=np.ones(3);返回np.sum(y==y)。在python中,3个True的总和为3。但是在jit-ed函数中,它只返回“True”,这一点都没有帮助。我是否必须将jit ed函数更像C代码而不是python?
import numpy as np
import numba as nb

def compute(arr):
    for i in xrange(arr.shape[0]):
        arr[i] += 1

n = 100
myarray = np.zeros(n)

jitcompute = nb.jit(nopython=True)(compute)
In [12]: %timeit compute(myarray)
10000 loops, best of 3: 25.7 µs per loop

In [13]: %timeit jitcompute(myarray)
The slowest run took 17.06 times longer than the fastest. This could mean that an intermediate result is being cached
1000000 loops, best of 3: 461 ns per loop