【问题标题】:When does a numba function compile?numba 函数何时编译?
【发布时间】:2014-12-17 04:39:12
【问题描述】:

我正在处理这个例子:

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)

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)

【问题讨论】:

    标签: python multithreading jit numba


    【解决方案1】:

    除非我遗漏了什么,否则您的两个示例完全等效,不是因为 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,这将导致不同的行为,因为在第一个示例中,您将调用未装饰的未抖动函数。这并不意味着 jitting 不会发生,只是它的结果以不同的名称存储。

    【讨论】:

    • 很好的解释。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2022-01-09
    • 2019-11-18
    • 1970-01-01
    • 2020-10-27
    • 2018-03-24
    • 1970-01-01
    • 2022-01-23
    相关资源
    最近更新 更多