【发布时间】:2022-01-17 19:38:10
【问题描述】:
我在 HPC 上反转非常大的矩阵。显然,这对 RAM 有很高的要求。为了避免内存不足错误,作为临时解决方案,我刚刚请求了大量内存 (TB)。如何使用 numpy.linalg.inv 从输入矩阵大小预测矩阵求逆所需的内存以更有效地运行 HPC 作业?
【问题讨论】:
我在 HPC 上反转非常大的矩阵。显然,这对 RAM 有很高的要求。为了避免内存不足错误,作为临时解决方案,我刚刚请求了大量内存 (TB)。如何使用 numpy.linalg.inv 从输入矩阵大小预测矩阵求逆所需的内存以更有效地运行 HPC 作业?
【问题讨论】:
TL;DR: 对于(n,n) 类型的float64 输入矩阵,最多为O(32 n²) 字节。
numpy.linalg.inv 调用 _umath_linalg.inv internally 而不执行任何复制或创建任何额外的大型临时数组。此内部函数本身调用 LAPACK 函数internally。据我了解,Numpy 的包装层负责分配输出的 Numpy 矩阵。 C 代码本身分配一个临时数组(参见:here)。 Numpy 似乎没有为此操作执行其他数组分配。有几个 Lapack 实现,因此通常无法知道 Lapack 调用请求了多少内存。然而,AFAIK,几乎所有的 Lapack 实现都不会在你的背后分配数据:调用者必须这样做(尤其是这里使用的 sgesv/dgesv)。假设(n, n) 输入矩阵是float64 类型并且FORTRAN 整数是4 字节明智的(在大多数平台上应该是这种情况,尤其是在Windows 上),那么实际所需的内存(由输入矩阵、输出矩阵和临时矩阵)是8 n² + 8 n² + (8 n² + 8 n² + 4 n) 字节,等于(32 n + 4) n 或简单地O(32 n²) 字节。请注意,临时缓冲区是最大大小,可能未完全写入,这意味着操作系统只能物理映射(即保留在物理 RAM 中)分配的空间的一小部分。这就是在我的 (Linux) 机器上使用 OpenBLAS 发生的情况:只有 24 n² 字节似乎实际上是物理映射的。对于float32 矩阵,它是空间的一半。
【讨论】: