如何在 Numba Vectorize 签名中指定元组?
How do I specify a tuple in a Numba Vectorize signature?
我正在定义一个函数,并想使用 Numba Vectorize 和 cuda 来加速它。我在函数签名方面遇到了问题。该函数将 return 一个 float64 值。我想传递两个将被矢量化的 float64 值,以及一个 9 元组的 float64 值,这将是标量。
这是我的函数头:
from numba import vectorize
@vectorize(['float64(float64, float64, UniTuple(float64, 9))'], target='cuda')
def fn_vec(E, L, fparams):
# calculations...
return result
但这给出了一个错误:
TypeError: data type "(float64 x 9)" not understood
我尝试了很多变体,包括 (float64, ..., float64) 代替 UniTuple(),但无法使任何东西起作用。我该怎么做?
How do I specify a tuple in a Numba Vectorize signature?
在 numba.vectorize
函数中不能使用元组。那是因为 vectorize
为 这些类型的数组 向量化了代码。
因此使用 float, float, tuple
签名创建了一个函数,该函数需要两个包含浮点数的数组和一个包含元组的数组。问题是包含元组的数组没有 dtype - 如果您使用结构化数组而不是包含元组的数组,它可以工作,但我没有尝试过。
How do I specify a tuple in a Numba jit
signature?
在 numba 签名中指定 UniTuple
的正确方法是使用 numba.types.containers.UniTuple
。你的情况:
nb.types.containers.UniTuple(nb.types.float64, 9)
所以正确的签名应该是这样的:
import numba as nb
@nb.njit(
nb.types.float64(
nb.types.float64,
nb.types.float64,
nb.types.containers.UniTuple(nb.types.float64, 9)))
def func(f1, f2, ftuple):
# ...
return f1
我经常避免显式输入我的 numba 函数 - 但当我这样做时,我发现使用 numba.typeof
非常有用,例如:
>>> nb.typeof((1.0, ) * 9)
tuple(float64 x 9)
>>> type(nb.typeof((1.0, ) * 9))
numba.types.containers.UniTuple
>>> help(type(nb.typeof((1.0, ) * 9))) # I shortened the result:
Help on class UniTuple in module numba.types.containers:
class UniTuple(BaseAnonymousTuple, _HomogeneousTuple, numba.types.abstract.Sequence)
| UniTuple(*args, **kwargs)
|
| Type class for homogeneous tuples.
|
| Methods defined here:
|
| __init__(self, dtype, count)
| Initialize self. See help(type(self)) for accurate signature.
所以信息就在那里:它是 numba.types.containes.UniTuple
,你用两个参数实例化它,dtype
(这里是 float64
)和数字(在本例中是 9
).
In case you wanted to vectorize over the float arrays only
如果您不想为元组参数向量化函数,您可以简单地在另一个函数中创建向量化函数并在那里调用它:
import numba as nb
import numpy as np
def func(E, L, fparams):
@nb.vectorize(['float64(float64, float64)'])
def fn_vec(e, l):
return e + l + fparams[1] # just to illustrate that the tuple is available
return fn_vec(E, L)
这使得元组在 vectorize
d 函数中可用。但是它必须创建内部函数并在每次调用外部函数时编译它,所以这实际上可能更慢。我也不确定这是否适用于 target="cuda"
,您可能需要自己测试一下。
我正在定义一个函数,并想使用 Numba Vectorize 和 cuda 来加速它。我在函数签名方面遇到了问题。该函数将 return 一个 float64 值。我想传递两个将被矢量化的 float64 值,以及一个 9 元组的 float64 值,这将是标量。
这是我的函数头:
from numba import vectorize
@vectorize(['float64(float64, float64, UniTuple(float64, 9))'], target='cuda')
def fn_vec(E, L, fparams):
# calculations...
return result
但这给出了一个错误:
TypeError: data type "(float64 x 9)" not understood
我尝试了很多变体,包括 (float64, ..., float64) 代替 UniTuple(),但无法使任何东西起作用。我该怎么做?
How do I specify a tuple in a Numba Vectorize signature?
在 numba.vectorize
函数中不能使用元组。那是因为 vectorize
为 这些类型的数组 向量化了代码。
因此使用 float, float, tuple
签名创建了一个函数,该函数需要两个包含浮点数的数组和一个包含元组的数组。问题是包含元组的数组没有 dtype - 如果您使用结构化数组而不是包含元组的数组,它可以工作,但我没有尝试过。
How do I specify a tuple in a Numba
jit
signature?
在 numba 签名中指定 UniTuple
的正确方法是使用 numba.types.containers.UniTuple
。你的情况:
nb.types.containers.UniTuple(nb.types.float64, 9)
所以正确的签名应该是这样的:
import numba as nb
@nb.njit(
nb.types.float64(
nb.types.float64,
nb.types.float64,
nb.types.containers.UniTuple(nb.types.float64, 9)))
def func(f1, f2, ftuple):
# ...
return f1
我经常避免显式输入我的 numba 函数 - 但当我这样做时,我发现使用 numba.typeof
非常有用,例如:
>>> nb.typeof((1.0, ) * 9)
tuple(float64 x 9)
>>> type(nb.typeof((1.0, ) * 9))
numba.types.containers.UniTuple
>>> help(type(nb.typeof((1.0, ) * 9))) # I shortened the result:
Help on class UniTuple in module numba.types.containers:
class UniTuple(BaseAnonymousTuple, _HomogeneousTuple, numba.types.abstract.Sequence)
| UniTuple(*args, **kwargs)
|
| Type class for homogeneous tuples.
|
| Methods defined here:
|
| __init__(self, dtype, count)
| Initialize self. See help(type(self)) for accurate signature.
所以信息就在那里:它是 numba.types.containes.UniTuple
,你用两个参数实例化它,dtype
(这里是 float64
)和数字(在本例中是 9
).
In case you wanted to vectorize over the float arrays only
如果您不想为元组参数向量化函数,您可以简单地在另一个函数中创建向量化函数并在那里调用它:
import numba as nb
import numpy as np
def func(E, L, fparams):
@nb.vectorize(['float64(float64, float64)'])
def fn_vec(e, l):
return e + l + fparams[1] # just to illustrate that the tuple is available
return fn_vec(E, L)
这使得元组在 vectorize
d 函数中可用。但是它必须创建内部函数并在每次调用外部函数时编译它,所以这实际上可能更慢。我也不确定这是否适用于 target="cuda"
,您可能需要自己测试一下。