我有两个大小为 (2500, 208) 和 (208, 2500) 的密集矩阵。我想计算他们的乘积。当它是单个进程时,它运行良好且快速,但当它位于多处理块中时,进程会卡在那里几个小时。我进行了更大尺寸的稀疏矩阵乘法,但没有问题。我的代码如下所示:
with Pool(processes=agents) as pool:
result = pool.starmap(run_func, args)
def run_func(args):
#Do stuff. Including large sparse matrices multiplication.
C = np.matmul(A,B) # or A.dot(B) or even using BLASS library directly dgemm(1, A, B)
#Never go after the line above!
请注意,当函数
run_func
在单个进程中执行时,它可以正常工作。当我在本地计算机上进行多处理时,它工作正常。当我在 HPC 上进行多处理时,它卡住了。我这样分配我的资源:
srun -v --nodes=1 --time 7-0:0 --cpus-per-task=2 --nodes=1 --mem-per-cpu=20G python3 -u run.py 2
其中最后一个参数是上面代码中
agents
的数量。以下是 HPC 支持的 LAPACK 库详细信息(从 numpy 获取):
libraries = ['mkl_rt', 'pthread']
library_dirs = ['**/lib']
define_macros = [('SCIPY_MKL_H', None), ('HAVE_CBLAS', None)]
include_dirs = ['**/include']
blas_opt_info:
libraries = ['mkl_rt', 'pthread']
library_dirs = ['**lib']
define_macros = [('SCIPY_MKL_H', None), ('HAVE_CBLAS', None)]
include_dirs = ['**/include']
lapack_mkl_info:
libraries = ['mkl_rt', 'pthread']
library_dirs = ['**/lib']
define_macros = [('SCIPY_MKL_H', None), ('HAVE_CBLAS', None)]
include_dirs = ['**/include']
lapack_opt_info:
libraries = ['mkl_rt', 'pthread']
library_dirs = ['**/lib']
define_macros = [('SCIPY_MKL_H', None), ('HAVE_CBLAS', None)]
include_dirs = ['**/include']
与我的本地机器相比,HPC 上的所有 python 包和 python 版本都是相同的。有任何关于发生什么事的线索吗?
作为解决方法,我尝试使用多线程而不是多处理,问题现已解决。我不确定多处理背后的问题是什么。
使用
multiprocessing
时,变量不会在进程之间共享,因为多个进程不在同一内存空间中运行。然而,当使用threading
时,线程在相同的内存空间中运行。这就是为什么您的线程解决方案有效。
这里您需要决定是否需要多处理或线程。
threading
将是一个更直接的解决方案,没有额外的技巧来共享对象,就像您的第二个解决方案一样。然而,Python 的全局解释器锁 (GIL) 可能会成为性能瓶颈,因为一次只有一个线程可以控制 Python 解释器。
另一方面,
multiprocessing
可以为您提供多个核心和CPU,您还可以避免Python的全局解释器锁(GIL)。如果您选择多处理,我建议使用 Manager
模块中的 Value
和 multiprocessing
类,并且通过这些类,您仍然可以在不同进程之间共享对象并解决您的问题。 在此答案中您可以找到这些课程的简短摘要。
我也遇到了同样的问题:使用 numpy 进行多处理在我的本地计算机上运行良好(随着内核数量的增加,您会发现时间显着减少),但在 HPC 上不起作用。 到目前为止,我发现一些 numpy 函数会导致这个问题。例如:
random_matrix = np.random.randn(150,150)
eigenvalues = np.linalg.eigvals(random_matrix)
如果 HPC 上的核心数量大于 1,则 np.linalg.eigvales 将使代码极其缓慢。
有些人建议将 numpy 切换为 scipy。也许这有效。