numba @vectorize target = 'parallel' TypeError - PullRequest
3 голосов
/ 05 января 2020

Если я определю

import numba as nb
import numpy as np
@nb.vectorize
def nb_vec(x):
    if x>0:
        x=x+100
    return x

, то

x=np.random.random(1000000)
nb_vec(x)

запустится без проблем

Но если я добавлю целевой параметр, например

@nb.vectorize(target='parallel')
def nb_vec(x):
    if x>0:
        x=x+100
    return x

затем

x=np.random.random(1000000)
nb_vec(x)

выводит сообщение об ошибке

---------------------------- ----------------------------------------------- TypeError Traceback ( последний последний вызов) в 1 x = np.random.random (1000000) ----> 2 nb_ve c (x)

Ошибка типа: ufun c 'nb_ve c' не поддерживается для типов ввода, и входы не могут быть безопасно приведены к каким-либо поддерживаемым типам в соответствии с правилом приведения «safe».

Что не так?

1 Ответ

2 голосов
/ 07 января 2020

В numba 0.46 декоратор numba.vectorize без подписи создаст универсальную функцию dynamici c , что означает, что он компилирует код на основе типов при вызове. Таким образом, вам не нужно указывать подпись.

import numpy as np
import numba as nb

@nb.vectorize()
def nb_vec(x):
    if x > 0:
        x = x + 100
    return x

>>> nb_vec
<numba._DUFunc 'nb_vec'>
>>> nb_vec.types
[]
>>> nb_vec(np.ones(5))
array([101., 101., 101., 101., 101.])
>>> nb_vec.types
['d->d']

Однако, если вы укажете target='parallel', это создаст обычную универсальную функцию. Таким образом, он поддерживает только предоставленные подписи. В вашем случае вы пропустили подписи, поэтому он фактически не поддерживает никаких входных данных.

import numpy as np
import numba as nb

@nb.vectorize(target='parallel')
def nb_vec(x):
    if x > 0:
        x = x + 100
    return x

>>> nb_vec
<ufunc 'nb_vec'>
>>> nb_vec.types
[]

Решение здесь заключается в том, чтобы указать сигнатуру с соответствующими типами при использовании параллельной векторизации:

import numpy as np
import numba as nb

@nb.vectorize(
    [nb.int32(nb.int32), 
     nb.int64(nb.int64), 
     nb.float32(nb.float32), 
     nb.float64(nb.float64)], 
    target='parallel')
def nb_vec(x):
    if x > 0:
        x = x + 100
    return x
...