2017-10-11 5 views
2

Ich muss eine Unähnlichkeitsmatrix für eine generische Metrik erstellen. Da ich den Algorithmus schnell ausführen muss, habe ich numba 0.35 in nopython Modus verwendet. Hier ist mein CodeNumba Jit Nopython Modus: Tell NUMBA die Unterschrift einer externen arbiträre Funktion

import numpy as np 
from numba import jit 
from jellyfish import levenshtein_distance 

def _dissimilarity_matrix(metric): 
    @jit(nopython=True) 
    def dm(data): 
     n = data.shape[0] 
     diss = np.zeros((n, n)) 
     for i in range(n): 
      for j in range(i+1): 
       dist = metric(data[i], data[j]) 
       diss[i, j] = dist 
       diss[j, i] = dist 
     return diss 

    return dm 

@jit(nopython=True) 
def euclidean_distance(vec1, vec2): 
    return np.sqrt(((vec1 - vec2)**2).sum()) 

test1 = np.random.randn(10, 2) 
dissimilarity_matrix1 = _dissimilarity_matrix(euclidean_distance) 
diss1 = dissimilarity_matrix1(test1) 

test2 = np.array(["this", "is", "a", "test"]) 
dissimilarity_matrix2 = _dissimilarity_matrix(levenshtein_distance) 
diss2 = dissimilarity_matrix2(test2) 

aber die Ausgabe ist:

numba.errors.TypingError: Failed at nopython (nopython frontend) 
Untyped global name 'metric': cannot determine Numba type of <class 'builtin_function_or_method'> 
File "test.py", line 12 

Beachten Sie, dass die Funktion euclidean_distance von mir definiert ist und den Dekorateur @jit(nopython=True), während die Funktion levenshtein_distance von einem externen Modul kommt (nicht geschrieben von mir). Gibt es eine Möglichkeit, numba explizit die Signatur der Funktion zu übergeben (d. H. metric in _dissimilarity_matrix)? Ich brauche wirklich die Funktion _dissimilarity_matrix im nopython Modus laufen zu lassen und als Eingabe eine beliebige Funktion zu akzeptieren.

+0

Sie können im Nopython-Modus keine beliebigen Python-Funktionen aufrufen. Das ist der Kern, der das Merkmal des nopython-Modus definiert: kein Python. – user2357112

+0

Also, wenn ich nicht alle Funktionen selbst definieren und sie im 'nopython'-Modus laufen lassen, gibt es keine Möglichkeit? –

Antwort

1

Ihr Code funktioniert für mich, wenn metriceuclidean_distance ist, denn das ist eine Funktion, die auch eine nopython Jitted Numba-Funktion ist. Sie können jedoch keine beliebigen Funktionen übergeben. Damit etwas im nopython Modus funktioniert, muss jede aufrufbare Funktion von numba unterstützt werden (siehe http://numba.pydata.org/numba-doc/latest/reference/pysupported.html und http://numba.pydata.org/numba-doc/latest/reference/numpysupported.html) oder benutzerdefiniert als Funktion numba nopython sein. Um diese Einschränkung geht es nicht.

+0

Danke. Nicht einmal etwas wie 'jit (levenshtein_distance)' oder 'njit (levenshtein_distance)' wird es tun, oder? Ich muss meine eigene Funktion schreiben, die mit '@jit (nopython = True)' verziert ist. –

+1

Wenn 'levenshtein_distance' so geschrieben wurde, dass numba es jit könnte, dann würde es funktionieren, aber es müsste den unterstützten Funktionen in den Links entsprechen, die ich dafür bereitgestellt habe. – JoshAdel

Verwandte Themen