我正在使用numba来创建一些在numpy数组上包含循环的函数。
一切都很好,花花公子,我可以使用jit
,我学会了如何定义签名。
现在我尝试在带有可选参数的函数上使用jit,例如:
from numba import jit
import numpy as np
@jit(['float64(float64, float64)', 'float64(float64, optional(float))'])
def fun(a, b=3):
return a + b
这样做有效,但如果我使用optional(float)
代替optional(float64)
,则不会{与int
或int64
相同。我失去了1小时试图找出这种语法(实际上,我的一个朋友偶然发现了这个解决方案,因为他忘了在浮动后写64
),但是,为了爱我,我无法理解为什么就是这样。我在互联网上找不到任何东西,numba关于这个主题的文档充其量是稀缺的(他们指出optional
应该采用numba类型。)
有谁知道这是如何工作的?我错过了什么?
答案 0 :(得分:2)
啊,但异常消息应该提示:
from numba import jit
import numpy as np
@jit(['float64(float64, float64)', 'float64(float64, optional(float64))'])
def fun(a, b=3.):
return a + b
>>> fun(10.)
TypeError: No matching definition for argument type(s) float64, omitted(default=3.0)
这意味着optional
在这里是错误的选择。事实上optional
represents None
or "that type"。但是你想要一个可选的参数,而不是一个可以是float
和None
的参数,例如:
>>> fun(10, None) # doesn't fail because of the signature!
TypeError: unsupported operand type(s) for +: 'int' and 'NoneType'
我怀疑它只是“碰巧”为optional(float)
工作,因为float
只是从numbas角度看的“仲裁Python对象”,所以使用optional(float)
你可以传递< em>任何在那里(这显然包括不给出论点)。使用optional(float64)
时,它只能是None
或float64
。该类别不够广泛,不允许不提供参数。
如果您提供类型Omitted
:
from numba import jit
import numpy as np
@jit(['float64(float64, float64)', 'float64(float64, Omitted(float64))'])
def fun(a, b=3.):
return a + b
>>> fun(10.)
13.0
然而,似乎Omitted
实际上并未包含在文档中,并且它有一些“粗糙边缘”。例如,它不能使用该签名在nopython模式下编译,即使它似乎没有签名:
@njit(['float64(float64, float64)', 'float64(float64, Omitted(float64))'])
def fun(a, b=3):
return a + b
TypingError: Failed at nopython (nopython frontend)
Invalid usage of + with parameters (float64, class(float64))
-----------
@njit(['float64(float64, float64)', 'float64(float64, Omitted(3.))'])
def fun(a, b=3):
return a + b
>>> fun(10.)
TypeError: No matching definition for argument type(s) float64, omitted(default=3)
-----------
@njit
def fun(a, b=3):
return a + b
>>> fun(10.)
13.0