memmap=True
を使用して巨大なFITSレコードテーブルを読み込もうとしていますが、 error: [Errno 12] Cannot allocate memory
取得しています。
セッションの例:
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]
エラーは次の行にあります。
/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
何が起こっているのかはよくわかりませんが、memmapが読み取るデータの量を不適切に決定しているのではないかと思います。 さらにデバッグする方法に関するヒントはありますか? これは実際にはFITSの問題ですか、それとも厄介な問題ですか?
詳細:
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
どのOS?
ulimit -v
は何を返しますか?
OSはLinuxの一種です。 頭のてっぺんからわからない
見つけるのが最も簡単なコマンド。
また、python / astropy / numpyのanacondaインストールを使用していましたが、アップグレードされました
ピップによるアストロピー。
$ ulimit -v
無制限
16:02で火、2013年8月27日には、エリック・ブレイ[email protected]は書きました:
どのOS?
ulimit -vは何を返しますか?
—
このメールに直接返信するか、Gi tHubhttps://github.com/astropy/astropy/issues/1380#issuecomment-23374814で表示してください
。
アダム
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
...それは少量のメモリのようです。 2 GB? ふむ。
@ keflavich-まだこの問題が発生していますか?
これを完全に忘れました。 MemTotal
は、使用可能な物理メモリの合計です。 これらの2GBは確かに多くはありませんが、それが問題になることはないはずです。 VmallocTotal
で約32 TBがあります。これは、ここで重要なことです。原則として、mmapはそのほとんどを使用できるはずです。 だからここで何か怪しいことが起こっている。
ああ! ここに問題があると思います。 デフォルトでは、PyFITSはファイルを読み取り専用モードで開くときにMAP_PRIVATE
を使用するため、ユーザーはファイル全体がメインメモリにマップされている場合と同じようにデータ配列を変更できます。
問題は、原則としてファイル全体が上書きされる可能性があることを意味します。そのため、mmapは、発生した場合に備えて、事前に十分なメモリを割り当てることができる必要があります。 これがここで起こっている理由です。 PyFITS / Astropyは間違いなくそのシナリオをキャッチし、より役立つエラーを提供するはずです。
現在、これを回避する方法は2つあります。 mode='denywrite
使用してファイルを開くことができます。 少し前にこのケースのために特別に追加しましたが、めったに使用されません。 これにより、mmapがMAP_SHARED | PROT_READ
開きます。これは、ページが読み取り専用であることを意味します(配列を変更しようとすると、例外が発生します)。 しかし、必要なのがデータを読み取ることだけである場合、これは正常に機能し、スワップスペースを割り当てる必要はないと思います。
もう1つの可能性は、 mode='update'
開くことです。 次に、配列への変更をファイルに直接同期して戻すことができます。これは、必要に応じて問題ありませんが、必要がない場合は明らかにそれほど多くはありません。
manページを見ると、少なくともLinuxには、 MAP_NORESERVE
というフラグがあり、コピーオンライト用のスペースを事前に割り当てることができないように見えます。 したがって、配列全体に変更を書き込む必要がない場合は、それも機能する可能性があります。 ただし、スワップスペースが不足した場合に発生するSIGSEGVをキャッチできる必要があります。
これを直接再現することができました。実際、私が提供した両方の回避策( mode='denywrite'
とmode='update'
作業。 MAP_NORESERVE
について何ができるかを確認しようとします。それ以外の場合)。このエラーをキャッチし、より適切なエラーメッセージを提供します。
煩わしさ: numpy.memmap
では、 mmap
呼び出しに渡されるフラグを微調整することはできません。 それを見ても、適切なフラグを使用してmmapを作成し、mmapをバッファーとしてndarray.__new__
を呼び出す作業を処理するのは、 ndarray
軽いサブクラスにすぎません。 また、 flush
メソッドを追加します。
numpy.memmap
使用をまったく避けて、mmapを自分で処理するのは簡単なはずです。 しかし、それは私が今のところこれでやりたい以上のものです。 その代わりに、エラーをキャッチして既存の回避策の1つを提案することにより、この問題を解決します。
#7597では、 np.memmap
を使用しなくなったため、他のフラグが役立つ場合は、他のフラグを使用する方が簡単であることに注意してください。
回避策がhttps://github.com/astropy/astropy/pull/7926に統合されたため、これを閉じることができMAP_NORESERVE
はPythonからは利用できないため、残念ながらそれは解決策ではありません。