Astropy: Possible correspond au bogue de memmap: memmap ne fonctionne tout simplement pas.

Créé le 26 août 2013  ·  12Commentaires  ·  Source: astropy/astropy

J'essaye de charger des tables d'enregistrement FITS gigantesques en utilisant memmap=True , et j'obtiens error: [Errno 12] Cannot allocate memory .

Un exemple de session:

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]

L'erreur est à cette ligne:

/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

Je ne sais pas vraiment ce qui se passe, mais je soupçonne que Memmap ne décide pas correctement de la quantité de données à lire. Des conseils sur la façon de poursuivre le débogage? Est-ce vraiment un problème FITS ou un problème numpy?

Des détails:

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

Tous les 12 commentaires

Quel OS?

Que retourne ulimit -v ?

OS est une certaine saveur de Linux; je ne sais pas de ma tête ou
commande la plus simple à découvrir.

En outre, utilisait l'installation anaconda de python / astropy / numpy mais mis à niveau
astropie via pip.

$ ulimit -v
illimité

Le mar 27 août 2013 à 16 h 02, Erik Bray [email protected] a écrit:

Quel OS?

Que renvoie ulimit -v?

-
Répondez directement à cet e-mail ou consultez-le sur Gi tHubhttps: //github.com/astropy/astropy/issues/1380#issuecomment -23374814
.

Adam

Que montre 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

... cela semble être une petite quantité de mémoire; 2 Go? Hrmph.

@keflavich -

J'en ai totalement oublié. MemTotal est juste la mémoire physique totale disponible. Ces 2 Go, ce n'est pas beaucoup, bien sûr, mais cela ne devrait pas être le problème. Vous avez environ 32 To pour VmallocTotal ce qui devrait être important ici - en principe, mmap devrait pouvoir en utiliser la plupart. Il se passe donc quelque chose de louche ici.

Ah! Je pense que je vois le problème ici. Par défaut, PyFITS utilise le MAP_PRIVATE lors de l'ouverture d'un fichier en mode lecture seule afin que les utilisateurs puissent toujours modifier le tableau de données en place comme ils le feraient si le fichier entier était mappé dans la mémoire principale.

Le problème est que cela signifie qu'en principe, le fichier entier peut être écrasé, donc mmap doit pouvoir allouer suffisamment de mémoire à l'avance si cela se produit. C'est pourquoi cela se produit ici. PyFITS / Astropy devrait certainement attraper ce scénario et fournir une erreur plus utile.

Actuellement, il existe deux façons de contourner ce problème: Vous pouvez ouvrir le fichier avec mode='denywrite . J'ai ajouté cela il y a quelque temps spécifiquement pour ce cas, mais il est rarement utilisé. Cela ouvre le mmap avec MAP_SHARED | PROT_READ cela signifie que les pages sont en lecture seule (toute tentative de modification du tableau entraînera une exception). Mais si tout ce dont vous avez besoin est de lire les données, cela fonctionne bien et ne nécessite pas d'allouer d'espace de swap, je ne pense pas.

Une autre possibilité est d'ouvrir avec mode='update' . Ensuite, toutes les modifications apportées au tableau peuvent être synchronisées directement avec le fichier, ce qui est bien si vous le souhaitez, mais évidemment pas autant si vous ne le faites pas.

En regardant la page de manuel, il semble qu'il y ait aussi un indicateur, au moins sous Linux, appelé MAP_NORESERVE qui l'empêchera de pré-allouer de l'espace pour la copie en écriture. Donc, si vous n'avez pas besoin d'écrire des modifications sur l'ensemble du tableau, cela pourrait également fonctionner. Mais nous devrions être en mesure d'attraper le SIGSEGV qui en résulte si vous finissez par manquer d'espace de swap.

J'ai réussi à reproduire cela directement - en effet, les deux solutions de contournement que j'ai proposées ( mode='denywrite' et mode='update' fonctionnent. J'essaierai toujours de voir ce que je peux faire à propos de MAP_NORESERVE , et sinon attraper cette erreur et fournir un meilleur message d'erreur.

Désagrément: numpy.memmap ne permet pas de modifier les indicateurs qui sont passés à l'appel mmap . En regardant cela, ce n'est pas beaucoup plus qu'une sous-classe légère de ndarray qui gère le travail de création d'un mmap avec les bons indicateurs, puis d'appeler ndarray.__new__ avec le mmap comme tampon. Il ajoute également une méthode flush .

Il devrait être assez facile d'éviter d'utiliser numpy.memmap et de gérer nous-mêmes mmap. Mais c'est encore plus que ce que je veux faire là-dessus pour le moment. Donc, à la place, je vais résoudre ce problème en détectant l'erreur et en suggérant l'une des solutions de contournement existantes.

Notez qu'avec # 7597, nous n'utilisons plus np.memmap , il devrait donc être plus facile d'utiliser d'autres indicateurs si cela est utile.

Cela peut maintenant être fermé, car une solution de contournement a été fusionnée dans https://github.com/astropy/astropy/pull/7926. MAP_NORESERVE n'est pas disponible depuis Python, donc ce n'est malheureusement pas une solution.

Cette page vous a été utile?
0 / 5 - 0 notes

Questions connexes

dhomeier picture dhomeier  ·  3Commentaires

Amarchuk picture Amarchuk  ·  3Commentaires

nstarman picture nstarman  ·  3Commentaires

simontorres picture simontorres  ·  3Commentaires

JWDobken picture JWDobken  ·  3Commentaires