Astropy: Möglicher passender Memmap-Fehler: Memmap funktioniert einfach nicht.

Erstellt am 26. Aug. 2013  ·  12Kommentare  ·  Quelle: astropy/astropy

Ich versuche, einige gigantische FITS-Datensatztabellen mit memmap=True zu laden, und ich erhalte error: [Errno 12] Cannot allocate memory .

Eine Beispielsitzung:

filename = '/home/sdfits/AGBT12B_221_01/AGBT12B_221_01.raw.acs.fits'
import astropy.io.fits as fits
filefits = fits.open(filename,memmap=True)
data = filefits[2].data[:50]

Der Fehler ist in dieser Zeile:

/users/aginsbur/anaconda/lib/python2.7/site-packages/numpy/core/memmap.py(253)__new__()
--> 253             mm = mmap.mmap(fid.fileno(), bytes, access=acc, offset=start)

ipdb> bytes
23718381056L
ipdb> bytes/1024**2
22619L
ipdb> start
413921280
ipdb> acc
3

Ich weiß nicht genau, was los ist, aber ich vermute, dass memmap nicht richtig entscheidet, wie viele Daten gelesen werden sollen. Irgendwelche Tipps zum weiteren Debuggen? Ist dies tatsächlich ein FITS-Problem oder ein Numpy-Problem?

Einzelheiten:

In [15]: numpy.__version__
Out[15]: '1.7.1'

In [16]: astropy.__version__
Out[16]: '0.2.4'

In [18]: sys.maxint
Out[18]: 9223372036854775807
Bug Effort-medium Package-intermediate io.fits

Alle 12 Kommentare

Welches Betriebssystem?

Was gibt ulimit -v zurück?

OS ist eine Variante von Linux; Ich weiß es nicht von oben oder unten
einfachster Befehl, um herauszufinden.

Außerdem wurde eine Anaconda-Installation von Python / Astropy / Numpy verwendet, aber aktualisiert
Astropie über Pip.

$ ulimit -v
unbegrenzt

Am Dienstag, den 27. August 2013 um 16:02 Uhr schrieb Erik Bray [email protected] :

Welches Betriebssystem?

Was gibt ulimit -v zurück?

- -
Antworten Sie direkt auf diese E-Mail oder sehen Sie sie sich auf Gi tHubhttps an: //github.com/astropy/astropy/issues/1380#issuecomment -23374814
.

Adam

Was zeigt cat /proc/meminfo ?

$ cat /proc/meminfo
MemTotal:        1903396 kB
MemFree:          203864 kB
Buffers:          215320 kB
Cached:           884708 kB
SwapCached:         2268 kB
Active:           492052 kB
Inactive:         954324 kB
Active(anon):     165684 kB
Inactive(anon):   181096 kB
Active(file):     326368 kB
Inactive(file):   773228 kB
Unevictable:           0 kB
Mlocked:               0 kB
SwapTotal:       1048568 kB
SwapFree:        1031460 kB
Dirty:                24 kB
Writeback:             0 kB
AnonPages:        344352 kB
Mapped:            65676 kB
Shmem:               432 kB
Slab:             191348 kB
SReclaimable:     151148 kB
SUnreclaim:        40200 kB
KernelStack:        2312 kB
PageTables:        22940 kB
NFS_Unstable:          0 kB
Bounce:                0 kB
WritebackTmp:          0 kB
CommitLimit:     2000264 kB
Committed_AS:     847268 kB
VmallocTotal:   34359738367 kB
VmallocUsed:      286128 kB
VmallocChunk:   34359439336 kB
HardwareCorrupted:     0 kB
AnonHugePages:     12288 kB
HugePages_Total:       0
HugePages_Free:        0
HugePages_Rsvd:        0
HugePages_Surp:        0
Hugepagesize:       2048 kB
DirectMap4k:        8188 kB
DirectMap2M:     2070528 kB

... das scheint eine winzige Menge an Speicher zu sein; 2 GB? Hrmph.

@keflavich - sehen Sie dieses Problem immer noch?

Völlig vergessen. MemTotal ist nur der insgesamt verfügbare physische Speicher. Diese 2 GB sind sicher nicht viel, aber das sollte nicht das Problem sein. Sie haben ungefähr 32 TB für VmallocTotal , was hier wichtig sein sollte - im Prinzip sollte mmap in der Lage sein, das meiste davon zu verwenden. Hier ist also etwas faul.

Ah! Ich denke, ich sehe das Problem hier. Standardmäßig verwendet PyFITS beim Öffnen einer Datei im schreibgeschützten Modus MAP_PRIVATE sodass Benutzer das Datenarray weiterhin so ändern können, als ob die gesamte Datei dem Hauptspeicher zugeordnet wäre.

Das Problem ist, dass im Prinzip die gesamte Datei überschrieben werden kann, sodass mmap in der Lage sein muss, im Voraus genügend Speicher zuzuweisen, falls dies auftreten sollte. Deshalb passiert das hier. PyFITS / Astropy sollte dieses Szenario auf jeden Fall erfassen und einen hilfreicheren Fehler liefern.

Derzeit gibt es zwei Möglichkeiten, dies zu umgehen: Sie können die Datei mit mode='denywrite öffnen. Ich habe das vor einiger Zeit speziell für diesen Fall hinzugefügt, aber es wird selten verwendet. Dadurch wird die mmap mit MAP_SHARED | PROT_READ geöffnet. Dies bedeutet, dass die Seiten schreibgeschützt sind (jeder Versuch, das Array zu ändern, führt zu einer Ausnahme). Aber wenn Sie nur die Daten lesen müssen, funktioniert dies einwandfrei und erfordert keine Zuweisung von Swap-Speicherplatz, glaube ich nicht.

Eine andere Möglichkeit ist das Öffnen mit mode='update' . Dann können alle Änderungen am Array direkt wieder mit der Datei synchronisiert werden, was in Ordnung ist, wenn Sie das möchten, aber natürlich nicht so sehr, wenn Sie dies nicht tun.

Auf der Manpage sieht es so aus, als gäbe es zumindest unter Linux auch ein Flag namens MAP_NORESERVE das verhindert, dass Speicherplatz für das Kopieren beim Schreiben vorab zugewiesen wird. Wenn Sie also keine Änderungen am gesamten Array schreiben müssen, könnte dies auch funktionieren. Aber wir müssten in der Lage sein, das resultierende SIGSEGV zu fangen, wenn Ihnen am Ende der Swap-Speicherplatz ausgeht.

Es ist gelungen, dies direkt zu reproduzieren - tatsächlich funktionieren beide von mir angebotenen Problemumgehungen ( mode='denywrite' und mode='update' . Ich werde immer noch versuchen zu sehen, was ich gegen MAP_NORESERVE tun kann, und ansonsten diesen Fehler abfangen und eine bessere Fehlermeldung bereitstellen.

Ärger: numpy.memmap erlaubt es nicht, die Flags zu optimieren, die an den Aufruf von mmap . Wenn man es betrachtet, ist es nicht viel mehr als eine leichte Unterklasse von ndarray , die die Arbeit erledigt, eine mmap mit den richtigen Flags zu erstellen und dann ndarray.__new__ mit der mmap als Puffer aufzurufen. Außerdem wird eine flush -Methode hinzugefügt.

Es sollte einfach genug sein, die Verwendung von numpy.memmap überhaupt zu vermeiden und mmap selbst zu handhaben. Aber das ist noch mehr, als ich vorerst tun möchte. Stattdessen werde ich dieses Problem beheben, indem ich den Fehler abfange und eine der vorhandenen Problemumgehungen vorschlage.

Beachten Sie, dass wir mit # 7597 nicht mehr np.memmap , daher sollte es einfacher sein, andere Flags zu verwenden, wenn dies nützlich ist.

Dies kann jetzt geschlossen werden, da eine Problemumgehung in https://github.com/astropy/astropy/pull/7926 zusammengeführt wurde. MAP_NORESERVE ist in Python nicht verfügbar, daher ist dies leider keine Lösung.

War diese Seite hilfreich?
0 / 5 - 0 Bewertungen