【问题标题】:Why Numba is not working with time in this code?为什么 Numba 在此代码中不使用时间?
【发布时间】:2021-03-24 15:31:43
【问题描述】:

我正在使用 python3 尝试以下代码:

import time
duration = 5

from numba import njit
@njit 
def myfn(): 
    num = 3
    starttime = time.time()
    while True: 
        print("Checking", num)
        endtime = time.time()
        if (endtime - starttime) > duration: 
            print("Time up.")
            return
        num += 2

myfn()

但是,它给出了以下错误:

Traceback (most recent call last):
  File "/home/abcde/testing_numba", line 20, in <module>
    myfn()
  File "/home/abcde/.local/lib/python3.7/site-packages/numba/core/dispatcher.py", line 414, in _compile_for_args
    error_rewrite(e, 'typing')
  File "/home/abcde/.local/lib/python3.7/site-packages/numba/core/dispatcher.py", line 357, in error_rewrite
    raise e.with_traceback(None)
numba.core.errors.TypingError: Failed in nopython mode pipeline (step: nopython frontend)
Unknown attribute 'time' of type Module(<module 'time' (built-in)>)

File "testing_numba", line 11:
def myfn(): 
    <source elided>
        num = 3
        starttime = time.time()
 ^

During: typing of get attribute at /home/abcde/testing_numba (11)

File "testing_numba", line 11:
def myfn(): 
    <source elided>
        num = 3
        starttime = time.time()
 ^

特别注意Unknown attribute 'time' of type Module(&lt;module 'time' (built-in)&gt;)

没有 numba,代码可以正常工作。

如何纠正这个错误?

【问题讨论】:

    标签: python-3.x time numba


    【解决方案1】:

    简而言之:正如错误消息所示,Numba 不支持此 python 功能(supported python-features 列表)。

    通常情况下,人们会重新考虑在 nopython-numba-functions 中使用此类 python 对象,因为从此类对象中无法获得任何速度方面的信息。

    替代方案是:

    • 使用python模式,即nb.jit(forceobj=True)。在这种情况下,该功能将“工作”,但由于下面解释中的 3. 点而获得的加速增益将丢失。
    • 使用np.objmode-content manager仅对函数的特殊行开启python模式。

    Numba 在 nopython-mode 下的加速来自于

    1. 不需要python-interpreter:代码编译成python-bytecode,必须在python-vm中运行,而是编译成cpu可以直接执行的汇编程序。
    2. 不需要动态分派:变量的类型在编译时推导出/知道,因此像a+b这样的操作的含义一定不能在运行时解析(动态分派)它已经备份到汇编程序中(静态调度)
    3. 不再使用 python 对象(例如 int- 或 float- 或 list-objects),而是使用普通 C 中的“对应”类型,如 64 位整数或双精度。

    虽然摆脱 1. 和 2. 可能会使我们的代码速度提高大约 2-3 倍(但可能根本没有任何收益,具体取决于 1. 和 2. 产生的开销),超速的圣杯最重要的是 3. 点:使用它有可能比纯 python 快 100 倍! This SO-post 是对以上几点的加速潜力的分析(但对 cython 已完成),并提供了更多详细信息。

    显然,为了对python对象使用C类型,numba必须知道Python-object和C类型的对应关系。

    这对于像np.zeros(n, dtype=np.int32) 这样的numpy 数组很容易做到:它或多或少对应于带有附加元信息(如数组长度)的int32_t* 类型的指针。

    可以在运行时将一些 python 构造转换为 C 类型,例如仅由 int 对象(不太大)组成的列表,例如:

    @nb.njit
    def fun(a):
        print(a)
    
    fun([1,2]) # works
    fun([1,2,2**65]) # doesn't work, because 2**65 cannot be represented with uint64
    

    但这显然会在运行时产生开销,应尽可能避免。相反,应该使用typed lists,从内存布局来看,它与 1d-numpy-arrays 非常相似。

    对于像time-module 这样复杂的python 对象,没有对应的C 类型(这将提供有意义的加速),因此在nopython-mode 下numba 不支持。

    【讨论】:

      【解决方案2】:

      很遗憾,numba 不支持time 模块,不能在nopython 模式下使用。它将与 @jit 而不是 @njit 一起使用,但性能提升不会那么好。

      请参阅this answer 了解潜在的解决方案和更多详细信息。

      【讨论】:

        猜你喜欢
        • 2014-05-16
        • 2018-10-01
        • 1970-01-01
        • 2011-09-30
        • 1970-01-01
        • 2021-03-10
        • 2013-01-10
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多