Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/328.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python numba递归函数的提前编译_Python_Recursion_Numba - Fatal编程技术网

Python numba递归函数的提前编译

Python numba递归函数的提前编译,python,recursion,numba,Python,Recursion,Numba,我试图提前编译一个递归函数。作为MCVE,让我们使用以下函数: #import numba as nb from numba.pycc import CC cc = CC('precompiled') #@nb.njit @cc.export('gsum', 'int64(int64)') def gsum(n): if n>1: return n+gsum(n-1) else: return 1 if __name__== '__mai

我试图提前编译一个递归函数。作为MCVE,让我们使用以下函数:

#import numba as nb
from numba.pycc import CC
cc = CC('precompiled')

#@nb.njit
@cc.export('gsum', 'int64(int64)')
def gsum(n):
    if n>1:
        return n+gsum(n-1)
    else:
        return 1

if __name__== '__main__':
##    print(gsum(5))
    cc.compile()
如果运行此代码,则会得到以下错误跟踪:

Traceback (most recent call last):
  File "numba_ahead.py", line 17, in <module>
    cc.compile()
  File "/opt/local/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/numba/compiler_lock.py", line 32, in _acquire_compile_lock
    return func(*args, **kwargs)
  File "/opt/local/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/numba/pycc/cc.py", line 212, in compile
    objects, dll_exports = self._compile_object_files(build_dir)
  File "/opt/local/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/numba/compiler_lock.py", line 32, in _acquire_compile_lock
    return func(*args, **kwargs)
  File "/opt/local/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/numba/pycc/cc.py", line 200, in _compile_object_files
    compiler.write_native_object(temp_obj, wrap=True)
  File "/opt/local/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/numba/pycc/compiler.py", line 198, in write_native_object
    library = self._cull_exports()
  File "/opt/local/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/numba/compiler_lock.py", line 32, in _acquire_compile_lock
    return func(*args, **kwargs)
  File "/opt/local/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/numba/pycc/compiler.py", line 157, in _cull_exports
    locals={}, library=library)
  File "/opt/local/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/numba/compiler.py", line 904, in compile_extra
    return pipeline.compile_extra(func)
  File "/opt/local/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/numba/compiler.py", line 367, in compile_extra
    return self._compile_bytecode()
  File "/opt/local/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/numba/compiler.py", line 835, in _compile_bytecode
    return self._compile_core()
  File "/opt/local/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/numba/compiler.py", line 822, in _compile_core
    res = pm.run(self.status)
  File "/opt/local/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/numba/compiler_lock.py", line 32, in _acquire_compile_lock
    return func(*args, **kwargs)
  File "/opt/local/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/numba/compiler.py", line 253, in run
    raise patched_exception
  File "/opt/local/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/numba/compiler.py", line 244, in run
    stage()
  File "/opt/local/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/numba/compiler.py", line 477, in stage_nopython_frontend
    self.locals)
  File "/opt/local/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/numba/compiler.py", line 1005, in type_inference_stage
    infer.build_constraint()
  File "/opt/local/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/numba/typeinfer.py", line 816, in build_constraint
    self.constrain_statement(inst)
  File "/opt/local/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/numba/typeinfer.py", line 1016, in constrain_statement
    self.typeof_assign(inst)
  File "/opt/local/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/numba/typeinfer.py", line 1079, in typeof_assign
    self.typeof_global(inst, inst.target, value)
  File "/opt/local/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/numba/typeinfer.py", line 1177, in typeof_global
    typ = self.resolve_value_type(inst, gvar.value)
  File "/opt/local/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/numba/typeinfer.py", line 1100, in resolve_value_type
    raise TypingError(msg, loc=inst.loc)
numba.errors.TypingError: Failed in nopython mode pipeline (step: nopython frontend)
Untyped global name 'gsum': cannot determine Numba type of <class 'function'>

File "numba_ahead.py", line 9:
def gsum(n):
    <source elided>
    if n>1:
        return n+gsum(n-1)
        ^
回溯(最近一次呼叫最后一次):
文件“numba_ahead.py”,第17行,在
cc.compile()
文件“/opt/local/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site packages/numba/compiler\u lock.py”,第32行,在“获取\u编译\u lock”中
返回函数(*args,**kwargs)
文件“/opt/local/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site packages/numba/pycc/cc.py”,编译中的第212行
对象,dll\u exports=self.\u编译\u对象\u文件(build\u dir)
文件“/opt/local/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site packages/numba/compiler\u lock.py”,第32行,在“获取\u编译\u lock”中
返回函数(*args,**kwargs)
文件“/opt/local/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site packages/numba/pycc/cc.py”,第200行,在编译对象文件中
compiler.write_native_对象(temp_obj,wrap=True)
文件“/opt/local/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site packages/numba/pycc/compiler.py”,第198行,在write\u native\u对象中
library=self.\u cull\u exports()
文件“/opt/local/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site packages/numba/compiler\u lock.py”,第32行,在“获取\u编译\u lock”中
返回函数(*args,**kwargs)
文件“/opt/local/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site packages/numba/pycc/compiler.py”,第157行,在“cull”导出中
局部变量={},库=库)
文件“/opt/local/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site packages/numba/compiler.py”,第904行,在compile\u extra中
返回管道.compile_extra(func)
文件“/opt/local/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site packages/numba/compiler.py”,第367行,在compile\u extra中
返回self.\u编译\u字节码()
文件“/opt/local/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site packages/numba/compiler.py”,第835行,在字节码中
返回self.\u编译\u核心()
文件“/opt/local/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site packages/numba/compiler.py”,第822行,在编译内核中
res=pm.run(self.status)
文件“/opt/local/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site packages/numba/compiler\u lock.py”,第32行,在“获取\u编译\u lock”中
返回函数(*args,**kwargs)
文件“/opt/local/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site packages/numba/compiler.py”,第253行,运行中
引发修补的\u异常
文件“/opt/local/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site packages/numba/compiler.py”,第244行,运行中
阶段(
文件“/opt/local/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site packages/numba/compiler.py”,第477行,在stage_nopython_frontend中
(本地人)
文件“/opt/local/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site packages/numba/compiler.py”,第1005行,在类型推理阶段
推断.build_约束()
文件“/opt/local/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site packages/numba/typeinfer.py”,第816行,内部版本约束
self.constraint_语句(inst)
文件“/opt/local/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site packages/numba/typeinfer.py”,第1016行,在CONSTRAINT_语句中
分配的自身类型(inst)
文件“/opt/local/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site packages/numba/typeinfer.py”,第1079行,在typeof_assign中
全局的自身类型(指令、指令目标、值)
文件“/opt/local/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site packages/numba/typeinfer.py”,第1177行,在typeof_global中
类型=自身解析值类型(仪表、gvar值)
文件“/opt/local/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site packages/numba/typerefer.py”,第1100行,解析值类型
升起打字机(msg,loc=inst.loc)
numba.errors.TypingError:在nopython模式管道中失败(步骤:nopython前端)
非类型化全局名称“gsum”:无法确定
文件“numba_ahead.py”,第9行:
def gsum(n):
如果n>1:
返回n+gsum(n-1)
^

显然,
cc.export
不知道它正在编译的函数的类型,如果该函数调用自己的话。有办法解决这个问题吗?当我用
njit
(注释掉的行)及时编译相同的代码时,代码编译得很好。

我发现,当使用
numba
时,有时简单地改变我执行特定循环和计算的方式就可以解决这些问题。在您的情况下,
gsum
以下功能有效:

#将numba作为nb导入
从numba.pycc导入CC
cc=cc(‘预编译’)
#@nb.njit
@抄送导出('gsum'、'int64(int64'))
def gsum(n):
运行=真
sm=n
而n:
n=n-1
sm+=n
返回sm
def slow_gsum(n):
运行=真
sm=n
而n:
n=n-1
sm+=n
返回sm
def慢速_gsum2(n):
如果n>1:
返回n+慢速_gsum2(n-1)
其他:
返回1
cc.compile()
您可以这样进行测试:

导入预编译
N=1e2
%超时1=预编译的.gsum(N)
%超时2=慢_gsum(N)
%超时3=慢\u gsum2(N)
out1==out2,out1==out3,out1
“”“输出:
CPU时间:用户6µs,系统:0 ns,总计:6µs
壁时间:11µs
CPU时间:用户12微秒,系统:1e+03纳秒,总计:13微秒
壁时间:15µs
CPU时间:用户44微秒,系统:1e+03纳秒,总计:45微秒
壁时间:48.9µs
(对,对,5050)
"""
在这里,我设置了
N=1e2
,这样我们就可以针对您的递归解决方案进行测试(越高会产生最大递归错误)。您可以通过转到更高的
N
值,真正看到
numba
加速:

N=1e8
%超时1=预编译的.gsum(N)
%时间