Warm tip: This article is reproduced from serverfault.com, please click

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

(python - Unable to allocate array with shape and data type)

发布于 2019-08-15 09:48:35

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

我想一个numpy的阵列形状分配内存(156816, 36, 53806) 使用

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 上也失败了

Questioner
Martin Brisiak
Viewed
0
119 2021-05-02 17:13:10

这可能是由于你系统的过量使用处理模式造成的。

在默认模式下0

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

此处没有很好地解释所使用的确切启发式方法,但在Linux 上通过提交启发式方法此页面上对此进行了更多讨论

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

$ 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

然后,你可以继续写入阵列中的任何位置,系统只会在你明确写入该页面时分配物理页面。所以你可以小心地将它用于稀疏数组。