numba函数什么时候编译?

时间:2014-12-16 17:50:53

标签: python multithreading jit numba

我正在尝试这个例子:

http://numba.pydata.org/numba-doc/0.15.1/examples.html#multi-threading

并说明:

  

您应该确保在此时编译inner_func,因为编译必须在主线程上进行。这个例子就是这种情况,因为我们使用jit()。

在示例中,在函数上调用jit可以确保在那时进行编译。

多线程示例是否可以工作,而不是在我们使用jit的函数上调用jit并将参数类型指定为装饰器?我认为这相当于询问是否在定义时使用装饰器来编译函数。

import numba as nb
import numpy as np
def inner_func(result, a, b):
    threadstate = savethread()
    for i in range(len(result)):
        result[i] = np.exp(2.1 * a[i] + 3.2 * b[i])
    restorethread(threadstate)
signature = nb.void(nb.double[:], nb.double[:], nb.double[:])
inner_func_nb = nb.jit(signature, nopython=True)(inner_func)

VS

import numba as nb
import numpy as np
signature = nb.void(nb.double[:], nb.double[:], nb.double[:])
@nb.jit(signature, nopython=True)
def inner_func(result, a, b):
    threadstate = savethread()
    for i in range(len(result)):
        result[i] = np.exp(2.1 * a[i] + 3.2 * b[i])
    restorethread(threadstate)

1 个答案:

答案 0 :(得分:4)

除非我遗漏了一些东西,否则你的两个例子完全等同,不是因为任何numba(或者不做),而是因为装饰者的工作原理。我将解释一般原则,你可以仔细检查这是否是你所要求的转变。这段代码:

@d(arg)
def f(x): ...
根据定义,

相当于:

_decorator = d(arg)
def f(x): ...
f = _decorator(f)

如果我们做出d(arg)没有副作用的合理假设,可以改写为:

def f(x): ...
f = d(arg)(f)

装饰者甚至无法区分(不会故意使用脆弱的黑魔法)。

唯一的区别在于,在第一个示例中,您调用了修饰函数inner_func_nb,而不是用它替换inner_func。如果您调用inner_func,这会导致不同的行为,因为在第一个示例中,您将调用未装饰的非jitted函数。这并不意味着jitting不会发生,只是它的结果以不同的名称存储。