Python 运行 的多个实例同时限制为 35

Multiple instances of Python running simultaneously limited to 35

我正在 运行将 Python 3.6 脚本作为并行计算集群的不同处理器上的多个独立进程。 最多 35 个进程 运行 同时没有问题,但第 36 个(以及更多)进程因第二行 import pandas as pd 上的分段错误而崩溃。有趣的是,第一行 import os 不会导致问题。 完整的错误信息是:

OpenBLAS blas_thread_init: pthread_create: Resource temporarily unavailable
OpenBLAS blas_thread_init: RLIMIT_NPROC 1024 current, 2067021 max
OpenBLAS blas_thread_init: pthread_create: Resource temporarily unavailable
OpenBLAS blas_thread_init: RLIMIT_NPROC 1024 current, 2067021 max
OpenBLAS blas_thread_init: pthread_create: Resource temporarily unavailable
OpenBLAS blas_thread_init: RLIMIT_NPROC 1024 current, 2067021 max
OpenBLAS blas_thread_init: pthread_create: Resource temporarily unavailable
OpenBLAS blas_thread_init: RLIMIT_NPROC 1024 current, 2067021 max
OpenBLAS blas_thread_init: pthread_create: Resource temporarily unavailable
OpenBLAS blas_thread_init: RLIMIT_NPROC 1024 current, 2067021 max
OpenBLAS blas_thread_init: pthread_create: Resource temporarily unavailable
OpenBLAS blas_thread_init: RLIMIT_NPROC 1024 current, 2067021 max
OpenBLAS blas_thread_init: pthread_create: Resource temporarily unavailable
OpenBLAS blas_thread_init: RLIMIT_NPROC 1024 current, 2067021 max
OpenBLAS blas_thread_init: pthread_create: Resource temporarily unavailable
OpenBLAS blas_thread_init: RLIMIT_NPROC 1024 current, 2067021 max
OpenBLAS blas_thread_init: pthread_create: Resource temporarily unavailable
OpenBLAS blas_thread_init: RLIMIT_NPROC 1024 current, 2067021 max
OpenBLAS blas_thread_init: pthread_create: Resource temporarily unavailable
OpenBLAS blas_thread_init: RLIMIT_NPROC 1024 current, 2067021 max
OpenBLAS blas_thread_init: pthread_create: Resource temporarily unavailable
OpenBLAS blas_thread_init: RLIMIT_NPROC 1024 current, 2067021 max
OpenBLAS blas_thread_init: pthread_create: Resource temporarily unavailable
OpenBLAS blas_thread_init: RLIMIT_NPROC 1024 current, 2067021 max
OpenBLAS blas_thread_init: pthread_create: Resource temporarily unavailable
OpenBLAS blas_thread_init: RLIMIT_NPROC 1024 current, 2067021 max
OpenBLAS blas_thread_init: pthread_create: Resource temporarily unavailable
OpenBLAS blas_thread_init: RLIMIT_NPROC 1024 current, 2067021 max
OpenBLAS blas_thread_init: pthread_create: Resource temporarily unavailable
OpenBLAS blas_thread_init: RLIMIT_NPROC 1024 current, 2067021 max
OpenBLAS blas_thread_init: pthread_create: Resource temporarily unavailable
OpenBLAS blas_thread_init: RLIMIT_NPROC 1024 current, 2067021 max
Traceback (most recent call last):
  File "/home/.../myscript.py", line 32, in <module>
    import pandas as pd
  File "/home/.../python_venv2/lib/python3.6/site-packages/pandas/__init__.py", line 13, in <module>
    __import__(dependency)
  File "/home/.../python_venv2/lib/python3.6/site-packages/numpy/__init__.py", line 142, in <module>
    from . import add_newdocs
  File "/home/.../python_venv2/lib/python3.6/site-packages/numpy/add_newdocs.py", line 13, in <module>
    from numpy.lib import add_newdoc
  File "/home/.../python_venv2/lib/python3.6/site-packages/numpy/lib/__init__.py", line 8, in <module>
    from .type_check import *
  File "/home/.../python_venv2/lib/python3.6/site-packages/numpy/lib/type_check.py", line 11, in <module>
    import numpy.core.numeric as _nx
  File "/home/.../python_venv2/lib/python3.6/site-packages/numpy/core/__init__.py", line 16, in <module>
    from . import multiarray
SystemError: initialization of multiarray raised unreported exception
/var/spool/slurmd/job04590/slurm_script: line 11: 26963 Segmentation fault      python /home/.../myscript.py -x 38

Pandas 和其他一些软件包安装在虚拟环境中。我已经复制了虚拟环境,所以每个venv中的进程不超过24个运行ning。例如,上面的错误脚本来自名为 python_venv2.

的虚拟环境中的脚本 运行ning

无论有多少进程从 Pandas 的特定实例导入,每次第 36 个进程都会出现问题。 (我什至没有削弱并行计算集群的容量。)

那么,如果不是限制访问Pandas的进程数,是不是限制运行ningPython的进程数?为什么限制是 35?

是否可以在机器上安装 Python 的多个副本(在单独的虚拟环境中?)以便我可以 运行 超过 35 个进程?

分解错误信息

您的错误消息包括以下提示:

OpenBLAS blas_thread_init: pthread_create: Resource temporarily unavailable
OpenBLAS blas_thread_init: RLIMIT_NPROC 1024 current, 2067021 max

RLIMIT_NPROC 变量控制用户可以拥有的进程总数。更具体地说,由于它是每个进程设置,当进程调用 fork()clone()vfork()、&c 时,该进程的 RLIMIT_NPROC 值与该进程的父用户的总进程数。如果超过该值,就会关闭,正如您所经历的那样。

错误消息表明 OpenBLAS 无法创建其他线程,因为您的用户已经使用了 RLIMIT_NPROC 提供的所有线程。

由于您 运行 在一个集群上,您的用户不太可能 运行 多个线程(不像,比如说,如果您在您的个人机器上浏览网页,播放音乐,&c),因此可以合理地得出结论,OpenBLAS 正在尝试启动多个线程。

OpenBLAS 如何使用线程

OpenBLAS 可以使用多线程来加速线性代数。您可能需要多个线程来快速解决单个更大的问题。您可能需要更少的线程来同时解决许多较小的问题。

OpenBLAS several ways 限制它使用的线程数。这些通过以下方式控制:

export OPENBLAS_NUM_THREADS=4
export GOTO_NUM_THREADS=4
export OMP_NUM_THREADS=4

优先级为 OPENBLAS_NUM_THREADS > GOTO_NUM_THREADS > OMP_NUM_THREADS。 (我 认为 这意味着 OPENBLAS_NUM_THREADS 覆盖 OMP_NUM_THREADS;但是,OpenBLAS 在使用 [=23= 编译时忽略 OPENBLAS_NUM_THREADSGOTO_NUM_THREADS ].)

如果设置了 none 上述变量,OpenBLAS 将 运行 使用与您机器上的核心数相等的线程数(您机器上的 32 个)

你的情况

您的集群有 32 核 CPU。您正在尝试 运行 36 个 Python 实例。 Python 每个实例需要 1 个线程 + OpenBLAS 需要 32 个线程。您还需要 1 个线程用于 SSH 连接和 1 个线程用于 shell。这意味着您需要 36*(32+1)+2=1190 个线程。

解决问题的核心选项是使用:

export OPENBLAS_NUM_THREADS=1

这应该会减少到 36*(1+1)+2=74 个线程。

由于您有空闲容量,您可以将 OPENBLAS_NUM_THREADS 调整为更高的值,但是您单独的 Python 进程拥有的 OpenBLAS 实例将相互干扰。因此,在获得一个解决方案的速度与获得多个解决方案的速度之间存在权衡。理想情况下,您可以通过 运行 每个节点减少 Python 并使用更多节点来解决此权衡。