2017-12-06 3 views
1

Ich versuche mit Numba die Python-Leistung von scipy.integrate.odeint zu steigern. Zu diesem Zweck muss ich @ nb.jit (nopython = True) für die Funktion verwenden, die das ODE-System definiert. Diese Funktion muss jedoch eine andere Python-Klasseninstanz als Argument in meinem Programm verwenden. Ich musste die Klasse auch mit @ nb.jitclass (spec) mit entsprechenden Spezifikationen jit. Dies funktionierte gut, bis ich ein ernstes Problem fand, wenn die Spezifikationen der Klasse einen anderen Typ von Klasseninstanzen als Methode enthielten. Mein Code folgt.Wie numba jitclass angeben, wenn das Attribut der Klasse eine andere Klasseninstanz enthält?

import numba as nb 
from scipy.integrate import odeint 


spec1=[("hi", nb.i4)] 
@nb.jitclass(spec1) 
class Hi(object): 
    def __init__(self): 
     self.hi = 0 

spec2=[("dummy", nb.i4), ("dummy1", nb.i4)] 
@nb.jitclass(spec2) 
class Dummy(object): 
    def __init__(self, anotherClassInstance): 
     self.dummy = 0 
     self.dummy1 = anotherClassInstance 

class A: 
    def __init__(self, someClassInstance): 
     self.a1 = someClassInstance 

    def odeSystem(self, x, t): 
     return _odeSystem(x, t, self.a1) 

    def odeSolve(self, iValues, ts): 
     sol = odeint(self.odeSystem, iValues, ts) 
     return sol 

@nb.jit(nopython=True) 
def _odeSystem(x, t, someClassInstance): 
    return 1-x 



if __name__ == "__main__": 
    c = Hi() 
    b = Dummy(c) 
    a = A(b) 
    print a.odeSolve(0.5, range(0, 10)) 

Zusammengefasst: So hier "Klasse A" ist meine Ode Löser.

  1. Um die Methode "odeSystem" mit numba zu kompilieren, muss es keine Klassenmethode sein. Also habe ich eine andere Funktion außerhalb der Klasse "_odeSystem" gemacht.

  2. Leider muss mein odeSystem eine Klasseninstanz als Argument haben. Daher habe ich @jitclass verwendet, um das Klasseninstanzargument korrekt zu kompilieren.

  3. Ich stieß wieder auf ein anderes Problem, wo diese Klasse "Dummy" auch eine andere Art von Klasseninstanz als eines seiner Attribute nimmt. Ich habe keine Ahnung, wie man "spec" für diese Klasse setzt. Ich habe den Typ für "dummy1" mit "nb.typeof (Hi)" versucht, aber es hat nicht funktioniert.

Bitte helfen Sie mir. Danke im Voraus.

+0

Willkommen bei SO! Bitte seien Sie genauer, was * ernstes Problem * Sie angetroffen haben und was * nicht funktioniert * bedeuten? (Erwartetes vs. Ist-Ergebnis, Fehlermeldungen usw.). – kazemakase

+0

@kazemakase Hallo, Entschuldigung für meine vagen Sätze. Es sollte bedeuten, dass das Argument "spec" für "@jitclass (spec)" nicht klar ist, wenn ich eine Klasseninstanz als Attribut der aktuellen Klasse festlegen möchte. In meinem Code ist "dummy1" der Klasse "Dummy" eine Art Klasseninstanzobjekt. Also was soll ich für "dummy1" in "spec2" einstellen? Jetzt stelle ich es einfach als ("dummy1", nb.i4) ein, aber das ist eindeutig kein int-Typ. Also, wenn ich diese Datei ausführen, endete es mit einem langen Fehler, der – hopeso

+0

einen langen Fehler sagt "[1] während: Senken" (self) .dummy1 = anotherClassInstance "at test.py (16) [2] während: Auflösen aufgerufene Typ: jitclass.Dummy # 25a0a20 [3] Während: Tippen von Anruf bei (3) – hopeso

Antwort

1

Sie können in Ihrer Spezifikationsdefinition .class_type.instance_type verwenden, um eine Instanz eines anderen Typs zu halten. Siehe Beispiel im Numba-Quellenbaum here

spec2=[("dummy", nb.i4), ("dummy1", Hi.class_type.instance_type)] 
@nb.jitclass(spec2) 
class Dummy(object): 
    def __init__(self, anotherClassInstance): 
     self.dummy = 0 
     self.dummy1 = anotherClassInstance 
Verwandte Themen