无法分配具有形状和数据类型的数组

2023-12-06

我在 Ubuntu 18 上遇到了在 numpy 中分配巨大数组的问题,而在 MacOS 上则没有遇到同样的问题。

我正在尝试为具有形状的 numpy 数组分配内存(156816, 36, 53806) with

np.zeros((156816, 36, 53806), dtype='uint8')

当我在 Ubuntu 操作系统上遇到错误时

>>> import numpy as np
>>> np.zeros((156816, 36, 53806), dtype='uint8')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
numpy.core._exceptions.MemoryError: Unable to allocate array with shape (156816, 36, 53806) and data type uint8

我在 MacOS 上没有得到它:

>>> import numpy as np 
>>> np.zeros((156816, 36, 53806), dtype='uint8')
array([[[0, 0, 0, ..., 0, 0, 0],
        [0, 0, 0, ..., 0, 0, 0],
        [0, 0, 0, ..., 0, 0, 0],
        ...,
        [0, 0, 0, ..., 0, 0, 0],
        [0, 0, 0, ..., 0, 0, 0],
        [0, 0, 0, ..., 0, 0, 0]],

       [[0, 0, 0, ..., 0, 0, 0],
        [0, 0, 0, ..., 0, 0, 0],
        [0, 0, 0, ..., 0, 0, 0],
        ...,
        [0, 0, 0, ..., 0, 0, 0],
        [0, 0, 0, ..., 0, 0, 0],
        [0, 0, 0, ..., 0, 0, 0]],

       [[0, 0, 0, ..., 0, 0, 0],
        [0, 0, 0, ..., 0, 0, 0],
        [0, 0, 0, ..., 0, 0, 0],
        ...,
        [0, 0, 0, ..., 0, 0, 0],
        [0, 0, 0, ..., 0, 0, 0],
        [0, 0, 0, ..., 0, 0, 0]],

       ...,

       [[0, 0, 0, ..., 0, 0, 0],
        [0, 0, 0, ..., 0, 0, 0],
        [0, 0, 0, ..., 0, 0, 0],
        ...,
        [0, 0, 0, ..., 0, 0, 0],
        [0, 0, 0, ..., 0, 0, 0],
        [0, 0, 0, ..., 0, 0, 0]],

       [[0, 0, 0, ..., 0, 0, 0],
        [0, 0, 0, ..., 0, 0, 0],
        [0, 0, 0, ..., 0, 0, 0],
        ...,
        [0, 0, 0, ..., 0, 0, 0],
        [0, 0, 0, ..., 0, 0, 0],
        [0, 0, 0, ..., 0, 0, 0]],

       [[0, 0, 0, ..., 0, 0, 0],
        [0, 0, 0, ..., 0, 0, 0],
        [0, 0, 0, ..., 0, 0, 0],
        ...,
        [0, 0, 0, ..., 0, 0, 0],
        [0, 0, 0, ..., 0, 0, 0],
        [0, 0, 0, ..., 0, 0, 0]]], dtype=uint8)

我在某处读到过np.zeros不应真正分配数组所需的全部内存,而应仅分配非零元素。尽管Ubuntu机器有64GB内存,而我的MacBook Pro只有16GB。

版本:

Ubuntu
os -> ubuntu mate 18
python -> 3.6.8
numpy -> 1.17.0

mac
os -> 10.14.6
python -> 3.6.4
numpy -> 1.17.0

PS:在Google Colab上也失败了


这可能是由于您的系统过度使用处理 mode.

在默认模式下,0,

启发式过度使用处理。明显的地址空间过量使用将被拒绝。用于典型系统。它确保严重的疯狂分配失败,同时允许过度使用以减少交换使用。在此模式下,允许根分配稍多的内存。这是默认设置。

这里没有很好地解释所使用的确切启发式方法,但对此有更多讨论Linux 过度提交启发式 and 在本页.

您可以通过运行来检查当前的过度使用模式

$ cat /proc/sys/vm/overcommit_memory
0

在这种情况下,您要分配

>>> 156816 * 36 * 53806 / 1024.0**3
282.8939827680588

~282 GB,内核说得很好,显然我无法向此提交那么多物理页面,并且它拒绝分配。

如果(以 root 身份)运行:

$ echo 1 > /proc/sys/vm/overcommit_memory

这将启用“始终过量使用”模式,并且您会发现系统确实允许您进行分配,无论它有多大(至少在 64 位内存寻址内)。

我自己在 32 GB RAM 的机器上进行了测试。具有过量使用模式0我也得到了一个MemoryError,但改回后1有用:

>>> import numpy as np
>>> a = np.zeros((156816, 36, 53806), dtype='uint8')
>>> a.nbytes
303755101056

然后,您可以继续写入数组中的任何位置,系统只会在您显式写入该页面时分配物理页面。因此,您可以谨慎地将其用于稀疏数组。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

无法分配具有形状和数据类型的数组 的相关文章

随机推荐