2010-11-30 14 views
16

Grundsätzlich bekomme ich einen Speicherfehler in Python beim Versuch, eine algebraische Operation auf einer numpy Matrix durchzuführen. Die Variable u, ist eine große Matrix von Double (im Fehlerfall ist es eine 288x288x156 Matrix von Doppel. Ich bekomme nur diesen Fehler in diesem großen Fall, aber ich bin in der Lage, dies auf anderen großen Matrizen zu tun, nur nicht so groß). Hier ist die Python-Fehler:Python/Numpy MemoryError

Traceback (most recent call last): 

File "S:\3D_Simulation_Data\Patient SPM Segmentation\20 pc 
t perim erosion flattop\SwSim.py", line 121, in __init__ 
    self.mainSimLoop() 

File "S:\3D_Simulation_Data\Patient SPM Segmentation\20 pc 
t perim erosion flattop\SwSim.py", line 309, in mainSimLoop 
    u = solver.solve_cg(u,b,tensors,param,fdHold,resid) # Solve the left hand si 
de of the equation Au=b with conjugate gradient method to approximate u 

File "S:\3D_Simulation_Data\Patient SPM Segmentation\20 pc 
t perim erosion flattop\conjugate_getb.py", line 47, in solv 
e_cg 

u = u + alpha*p 

MemoryError 

u = u + alpha*p ist die Codezeile, die fehlschlägt.

alpha ist nur ein Doppel, während u und r sind die großen Matrizen oben beschrieben (beide von der gleichen Größe).

Ich weiß nicht viel über Speicherfehler besonders in Python. Irgendwelche Einblicke/Tipps zur Lösung dieses Problems wären sehr willkommen!

Dank

Antwort

39

Rewrite

p *= alpha 
u += p 

und dies wird viel weniger Speicher. Wohingegen p = p*alpha eine ganze neue Matrix für das Ergebnis von p*alpha zuweist und dann die alte p verwirft; p*= alpha macht das gleiche an Ort und Stelle.

Im Allgemeinen versuchen Sie bei großen Matrizen op= Zuweisung zu verwenden.

+0

Dies ist sehr hilfreich, ich wusste das nicht. – tylerthemiler

5

Ihre Matrix hat 288x288x156 = 12.939.264 Einträge, die für double zu 400 MB im Speicher kommen könnten. numpy Werfen Sie eine MemoryError an Sie bedeutet nur, dass in der Funktion, die Sie den Speicher aufgerufen, die zur Ausführung der Operation benötigt wurde nicht vom Betriebssystem verfügbar war.

Wenn Sie mit dünn besetzten Matrizen arbeiten können, können Sie viel Speicherplatz sparen.

+2

Aber mein Computer hat 24 GB RAM ... Gibt es einen Weg, um sicherzustellen, dass mehr von Windows verfügbar ist? Edit: Die Version von Python, die wir verwenden, ist aus irgendeinem Grund 32-Bit:/Edit2: Leider sind Sparse-Matrizen keine Option, da es in allen Elementen Werte gibt (Wärmeleitungs-ähnliches Problem). – tylerthemiler

+0

Danke, ich habe ein paar Dinge aus dem Gedächtnis gelöscht und kann das jetzt laden. – tylerthemiler

+0

@tylerthemiler: Verwenden Sie die inoffiziellen 64-Bit-Builds http://www.lfd.uci.edu/~gohlke/pythonlibs/ – endolith

9

Ein weiterer Tipp, den ich gefunden habe, um Speicherfehler zu vermeiden, ist die manuelle Kontrolle garbage collection. Wenn Objekte gelöscht werden oder den Gültigkeitsbereich des Bereichs verlassen, wird der für diese Variablen verwendete Speicher erst freigegeben, wenn eine Speicherbereinigung ausgeführt wird. Ich habe mit einigen meiner Code mit großen numpy Arrays gefunden, dass ich einen MemoryError bekomme, aber das kann ich vermeiden, wenn ich Aufrufe von gc.collect() an geeigneten Stellen einfügen.

Sie sollten nur in diese Option schauen, wenn Sie "op =" Stil-Operatoren usw. verwenden, löst Ihr Problem nicht, da es wahrscheinlich nicht die beste Kodierungspraxis ist, überall gc.collect() -Aufrufe zu haben.

+0

Ja, ich habe das gemacht. Danke für den Vorschlag. – tylerthemiler

+0

Warum löst MemoryError die Garbage Collection nicht automatisch aus? – endolith

+2

@endolith aus dem gleichen Grund, dass Sie Speicher nicht pausieren und aufräumen können, wenn Ihr 'malloc()' fehlschlägt - es ist zu spät, _ _ready_ ist fehlgeschlagen. Du könntest dann zurückgehen, GC und es noch einmal versuchen, aber ich denke, die NumPy-Entwickler würden lieber deinen Code reparieren, als sich auf ein Pflaster zu verlassen. – PythonNut

Verwandte Themen