Bagaimana cara menentukan tupel dalam tanda tangan Numba Vectorize?
Dalam fungsi numba.vectorize
Anda tidak dapat menggunakan Tuple. Itu karena vectorize
membuat vektorisasi kode untuk array jenis ini.
Jadi menggunakan tanda tangan float, float, tuple
membuat fungsi yang mengharapkan dua array berisi float dan satu array berisi tupel. Masalahnya adalah tidak ada dtype untuk array yang berisi tupel - ini bisa berfungsi jika Anda menggunakan array terstruktur alih-alih array yang berisi tupel tetapi saya belum mencobanya.
Bagaimana cara menentukan tupel di tanda tangan Numba jit
?
Cara yang benar untuk menentukan UniTuple
pada tanda tangan numba adalah dengan numba.types.containers.UniTuple
. Dalam kasus Anda:
nb.types.containers.UniTuple(nb.types.float64, 9)
Jadi tanda tangan yang benar adalah seperti ini:
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
Saya sering menghindari mengetikkan fungsi numba saya secara eksplisit - tetapi ketika melakukannya saya merasa sangat berguna untuk menggunakan numba.typeof
, misalnya:
>>> 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.
Jadi semua informasinya ada di sana: Ini adalah numba.types.containes.UniTuple
dan Anda membuat instance dengan dua argumen, dtype
(di sini float64
) dan nomor (dalam hal ini 9
).
Jika Anda ingin melakukan vektorisasi pada array float saja
Jika Anda tidak ingin memvektorkan fungsi untuk argumen Tuple, Anda cukup membuat fungsi yang divektorkan di dalam fungsi lain dan memanggilnya di sana:
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)
Ini membuat tuple tersedia di dalam fungsi vectorize
d. Namun ia harus membuat fungsi dalam dan mengompilasinya setiap kali Anda memanggil fungsi luar, jadi ini mungkin sebenarnya lebih lambat. Saya juga tidak yakin ini akan berhasil dengan target="cuda"
, Anda mungkin perlu mengujinya sendiri.
person
MSeifert
schedule
20.04.2019