Astropy: 可能适合memmap错误:memmap无效。

创建于 2013-08-26  ·  12评论  ·  资料来源: astropy/astropy

我正在尝试使用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
Bug Effort-medium Package-intermediate io.fits

所有12条评论

什么操作系统?

ulimit -v返回什么?

OS是linux的一种风格。 不知道我的头顶还是
最容易找到的命令。

另外,正在使用蟒蛇蟒蛇/ astropy / numpy的anaconda安装,但已升级
通过点子

$ ulimit -v
无限

在2013年8月27日,星期二,下午4:02,Erik Bray [email protected]写道:

什么操作系统?

ulimit -v返回什么?

-
直接回复此电子邮件或在Gi tHub上查看它

亚当

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? r

@keflavich-您仍然看到此问题吗?

完全忘记了这一点。 MemTotal只是总的可用物理内存。 当然,这2GB的存储空间不是很多,但这不应该成为问题。 VmallocTotal大约有32 TB,这在这里很重要-原则上mmap应该能够使用其中的大部分。 因此,这里发生了一些可疑的事情。

啊! 我想我在这里看到了这个问题。 默认情况下,当以只读模式打开文件时,PyFITS使用MAP_PRIVATE ,以便用户仍然可以像修改整个文件到主内存一样修改数据数组。

问题是,从原则上讲,这意味着整个文件都可以被覆盖,因此mmap需要能够在出现这种情况之前提前分配足够的内存。 这就是为什么这发生在这里。 PyFITS / Astropy绝对应该抓住这种情况,并提供一个更有用的错误。

当前有两种解决方法:可以使用mode='denywrite打开文件。 我是在不久前专门针对这种情况添加的,但很少使用。 这会用MAP_SHARED | PROT_READ打开mmap-这意味着页面是只读的(任何修改数组的尝试都会导致异常)。 但是,如果您所需要做的只是读取数据,那么效果很好,并且不需要分配我不认为的任何交换空间。

另一种可能性是使用mode='update'打开。 然后,对阵列的任何更改都可以直接同步回文件,如果您愿意的话,这很好,但是如果不需要,显然没有那么多。

查看手册页,似乎至少在Linux上还有一个标志,称为MAP_NORESERVE ,它将阻止它为写时复制预分配空间。 因此,如果您不需要对整个数组进行任何更改,也可以将它们写入工作。 但是,如果您最终用尽了交换空间,那么我们必须能够捕获产生的SIGSEGV。

设法直接重现了这一点-实际上,我提供的两种解决方法( mode='denywrite'mode='update'可以使用。仍然会尝试看看我能对MAP_NORESERVE做些什么,否则捕获此错误并提供更好的错误消息。

烦人: numpy.memmap不允许调整传递给mmap调用的标志。 尽管看了一下,它不过是ndarray的轻子类,它处理创建带有正确标志的mmap,然后以mmap作为缓冲区调用ndarray.__new__的工作。 它还添加了flush方法。

完全避免使用numpy.memmap并自己处理mmap应该足够容易。 但这仍然比我现在想做的还要多。 因此,我将通过捕获错误并建议现有的解决方法之一来解决此问题。

注意,在#7597中,我们不再使用np.memmap ,因此,如果有用的话,应该更容易使用其他标志。

由于已在https://github.com/astropy/astropy/pull/7926中合并了一种解决方法,因此现在可以将其关闭MAP_NORESERVE在Python中不可用,因此不幸的是这不是一个解决方案。

此页面是否有帮助?
0 / 5 - 0 等级