numba函数何时编译?

eva*_*n54 5 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)
Run Code Online (Sandbox Code Playgroud)

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)
Run Code Online (Sandbox Code Playgroud)

小智 4

除非我遗漏了一些东西,否则你的两个例子是完全相同的,不是因为 numba 做了(或没有做)任何事情,而是因为这就是装饰器的工作方式。我将解释一般原则,您可以仔细检查这是否是您所要求的转换。这段代码:

@d(arg)
def f(x): ...
Run Code Online (Sandbox Code Playgroud)

根据定义相当于:

_decorator = d(arg)
def f(x): ...
f = _decorator(f)
Run Code Online (Sandbox Code Playgroud)

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

def f(x): ...
f = d(arg)(f)
Run Code Online (Sandbox Code Playgroud)

装饰者甚至无法区分(如果没有故意使用脆弱的黑魔法)。

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