使用 numba 提供显式类型时,njit 编译期间出现输入错误
Typing error during njit compilation when providing explicit types with numba
我正在尝试使用 "nopython" 模式对 python 中的函数进行 jit 编译。当我不通过简单地使用 @numba.njit
装饰器提供类型信息时,函数编译。
这是应用了装饰器并包含键入信息的函数定义:
from numba import njit, float64, int64
@njit(float64(float64, int64))
def PowerCurve(flow, head):
if head==326:
if flow<(10.788/3.03): #speed no load approximation
return 0
else:
return 3.03*flow - 10.788 #approximating power for each gross head using equation to avoid interpolation
elif head==328:
if flow<(10.939/3.0525):
return 0
else:
return 3.0525*flow - 10.969
elif head==330:
if flow<(10.982/3.0683):
return 0
else:
return 3.0683*flow - 10.982
elif head==332:
if flow<(11.006/3.0842):
return 0
else:
return 3.0842*flow - 11.006
elif head==334:
if flow<(11.025/3.1001):
return 0
else:
return 3.1001*flow - 11.025
elif head==336:
if flow<(11.043/3.116):
return 0
else:
return 3.116*flow - 11.043
elif head==338:
if flow<(11.063/3.1317):
return 0
else:
return 3.1317*flow - 11.063
elif head==340:
if flow<(11.086/3.1477):
return 0
else:
return 3.1477*flow - 11.086
elif head==342:
if flow<(11.103/3.1636):
return 0
else:
return 3.1636*flow - 11.103
elif head==344:
if flow<(11.135/3.1798):
return 0
else:
return 3.1798*flow - 11.135
elif head==346:
if flow<(11.315/3.2021):
return 0
else:
return 3.2021*flow - 11.315
elif head==348:
if flow<(11.344/3.2181):
return 0
else:
return 3.2181*flow - 11.344
当我 运行 这段代码没有调用函数时,我得到以下错误:
Traceback (most recent call last):
File "Optimize.py", line 516, in <module>
@njit(float64(float64, int64))
File "C:\Users\patri\Miniconda3\lib\site-packages\numba\decorators.py", line 199, in wrapper
disp.compile(sig)
File "C:\Users\patri\Miniconda3\lib\site-packages\numba\dispatcher.py", line 579, in compile
cres = self._compiler.compile(args, return_type)
File "C:\Users\patri\Miniconda3\lib\site-packages\numba\dispatcher.py", line 80, in compile
flags=flags, locals=self.locals)
File "C:\Users\patri\Miniconda3\lib\site-packages\numba\compiler.py", line 740, in compile_extra
return pipeline.compile_extra(func)
File "C:\Users\patri\Miniconda3\lib\site-packages\numba\compiler.py", line 360, in compile_extra
return self._compile_bytecode()
File "C:\Users\patri\Miniconda3\lib\site-packages\numba\compiler.py", line 699, in _compile_bytecode
return self._compile_core()
File "C:\Users\patri\Miniconda3\lib\site-packages\numba\compiler.py", line 686, in _compile_core
res = pm.run(self.status)
File "C:\Users\patri\Miniconda3\lib\site-packages\numba\compiler.py", line 246, in run
raise patched_exception
File "C:\Users\patri\Miniconda3\lib\site-packages\numba\compiler.py", line 238, in run
stage()
File "C:\Users\patri\Miniconda3\lib\site-packages\numba\compiler.py", line 452, in stage_nopython_frontend
self.locals)
File "C:\Users\patri\Miniconda3\lib\site-packages\numba\compiler.py", line 841, in type_inference_stage
infer.propagate()
File "C:\Users\patri\Miniconda3\lib\site-packages\numba\typeinfer.py", line 773, in propagate
raise errors[0]
File "C:\Users\patri\Miniconda3\lib\site-packages\numba\typeinfer.py", line 129, in propagate
constraint(typeinfer)
File "C:\Users\patri\Miniconda3\lib\site-packages\numba\typeinfer.py", line 154, in __call__
typeinfer.copy_type(self.src, self.dst, loc=self.loc)
File "C:\Users\patri\Miniconda3\lib\site-packages\numba\typeinfer.py", line 791, in copy_type
unified = self.typevars[dest_var].union(self.typevars[src_var], loc=loc)
File "C:\Users\patri\Miniconda3\lib\site-packages\numba\typeinfer.py", line 83, in union
self.add_type(other.type, loc=loc)
File "C:\Users\patri\Miniconda3\lib\site-packages\numba\typeinfer.py", line 47, in add_type
loc=loc)
numba.errors.TypingError: Failed at nopython (nopython frontend)
No conversion from none to float64 for '2.2', defined at None
File "Optimize.py", line 577
[1] During: typing of assignment at Optimize.py (577)
此错误消息所指的函数行包括:return 3.2181*flow - 11.344
。当我调试这个函数时,我注意到这一行 flow
的值是 None
。谁能告诉我我做错了什么以及如何包含输入信息?
每个 Python 函数隐式地 returns None
如果没有给出最终的 return
。这就是它显示 No conversion from none to float64
的原因。 Numba 和 Python 不能确定您将始终传递与您的任何分支匹配的 head
然后它会 return None
。但是你指定的签名只能 return float64
s!
在您的情况下(如果不是疏忽)只需在所有 if
和 elif
分支之后添加一个 return 0.
:
...
elif head==348:
if flow<(11.344/3.2181):
return 0
else:
return 3.2181*flow - 11.344
return 0
我正在尝试使用 "nopython" 模式对 python 中的函数进行 jit 编译。当我不通过简单地使用 @numba.njit
装饰器提供类型信息时,函数编译。
这是应用了装饰器并包含键入信息的函数定义:
from numba import njit, float64, int64
@njit(float64(float64, int64))
def PowerCurve(flow, head):
if head==326:
if flow<(10.788/3.03): #speed no load approximation
return 0
else:
return 3.03*flow - 10.788 #approximating power for each gross head using equation to avoid interpolation
elif head==328:
if flow<(10.939/3.0525):
return 0
else:
return 3.0525*flow - 10.969
elif head==330:
if flow<(10.982/3.0683):
return 0
else:
return 3.0683*flow - 10.982
elif head==332:
if flow<(11.006/3.0842):
return 0
else:
return 3.0842*flow - 11.006
elif head==334:
if flow<(11.025/3.1001):
return 0
else:
return 3.1001*flow - 11.025
elif head==336:
if flow<(11.043/3.116):
return 0
else:
return 3.116*flow - 11.043
elif head==338:
if flow<(11.063/3.1317):
return 0
else:
return 3.1317*flow - 11.063
elif head==340:
if flow<(11.086/3.1477):
return 0
else:
return 3.1477*flow - 11.086
elif head==342:
if flow<(11.103/3.1636):
return 0
else:
return 3.1636*flow - 11.103
elif head==344:
if flow<(11.135/3.1798):
return 0
else:
return 3.1798*flow - 11.135
elif head==346:
if flow<(11.315/3.2021):
return 0
else:
return 3.2021*flow - 11.315
elif head==348:
if flow<(11.344/3.2181):
return 0
else:
return 3.2181*flow - 11.344
当我 运行 这段代码没有调用函数时,我得到以下错误:
Traceback (most recent call last):
File "Optimize.py", line 516, in <module>
@njit(float64(float64, int64))
File "C:\Users\patri\Miniconda3\lib\site-packages\numba\decorators.py", line 199, in wrapper
disp.compile(sig)
File "C:\Users\patri\Miniconda3\lib\site-packages\numba\dispatcher.py", line 579, in compile
cres = self._compiler.compile(args, return_type)
File "C:\Users\patri\Miniconda3\lib\site-packages\numba\dispatcher.py", line 80, in compile
flags=flags, locals=self.locals)
File "C:\Users\patri\Miniconda3\lib\site-packages\numba\compiler.py", line 740, in compile_extra
return pipeline.compile_extra(func)
File "C:\Users\patri\Miniconda3\lib\site-packages\numba\compiler.py", line 360, in compile_extra
return self._compile_bytecode()
File "C:\Users\patri\Miniconda3\lib\site-packages\numba\compiler.py", line 699, in _compile_bytecode
return self._compile_core()
File "C:\Users\patri\Miniconda3\lib\site-packages\numba\compiler.py", line 686, in _compile_core
res = pm.run(self.status)
File "C:\Users\patri\Miniconda3\lib\site-packages\numba\compiler.py", line 246, in run
raise patched_exception
File "C:\Users\patri\Miniconda3\lib\site-packages\numba\compiler.py", line 238, in run
stage()
File "C:\Users\patri\Miniconda3\lib\site-packages\numba\compiler.py", line 452, in stage_nopython_frontend
self.locals)
File "C:\Users\patri\Miniconda3\lib\site-packages\numba\compiler.py", line 841, in type_inference_stage
infer.propagate()
File "C:\Users\patri\Miniconda3\lib\site-packages\numba\typeinfer.py", line 773, in propagate
raise errors[0]
File "C:\Users\patri\Miniconda3\lib\site-packages\numba\typeinfer.py", line 129, in propagate
constraint(typeinfer)
File "C:\Users\patri\Miniconda3\lib\site-packages\numba\typeinfer.py", line 154, in __call__
typeinfer.copy_type(self.src, self.dst, loc=self.loc)
File "C:\Users\patri\Miniconda3\lib\site-packages\numba\typeinfer.py", line 791, in copy_type
unified = self.typevars[dest_var].union(self.typevars[src_var], loc=loc)
File "C:\Users\patri\Miniconda3\lib\site-packages\numba\typeinfer.py", line 83, in union
self.add_type(other.type, loc=loc)
File "C:\Users\patri\Miniconda3\lib\site-packages\numba\typeinfer.py", line 47, in add_type
loc=loc)
numba.errors.TypingError: Failed at nopython (nopython frontend)
No conversion from none to float64 for '2.2', defined at None
File "Optimize.py", line 577
[1] During: typing of assignment at Optimize.py (577)
此错误消息所指的函数行包括:return 3.2181*flow - 11.344
。当我调试这个函数时,我注意到这一行 flow
的值是 None
。谁能告诉我我做错了什么以及如何包含输入信息?
每个 Python 函数隐式地 returns None
如果没有给出最终的 return
。这就是它显示 No conversion from none to float64
的原因。 Numba 和 Python 不能确定您将始终传递与您的任何分支匹配的 head
然后它会 return None
。但是你指定的签名只能 return float64
s!
在您的情况下(如果不是疏忽)只需在所有 if
和 elif
分支之后添加一个 return 0.
:
...
elif head==348:
if flow<(11.344/3.2181):
return 0
else:
return 3.2181*flow - 11.344
return 0