Несколько экземпляров Python, запущенных одновременно, ограничены 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 и несколько других пакетов устанавливаются в виртуальной среде. Я продублировал виртуальную среду, чтобы в каждом венге работало не более 24 процессов. Например, приведенный выше скрипт ошибки произошел от скрипта, запущенного в виртуальной среде с именем python_venv2
,
Проблема возникает на 36-м процессе каждый раз, независимо от того, сколько процессов импортируется из конкретного экземпляра Pandas. (Я даже не вникаю в потенциал кластера параллельных вычислений.)
Итак, если это не ограничение на число процессов, обращающихся к Pandas, это ограничение на число процессов, работающих на Python? Почему 35 предел?
Можно ли установить несколько копий Python на машине (в отдельных виртуальных средах?), Чтобы я мог запустить более 35 процессов?
1 ответ
Разложение сообщения об ошибке
Ваше сообщение об ошибке содержит следующую подсказку:
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
дал это.
Поскольку вы работаете в кластере, маловероятно, что ваш пользователь запускает много потоков (в отличие, скажем, если вы работали на своем персональном компьютере и просматривали веб-страницы, проигрывали музыку и т. Д.), Поэтому разумно сделать вывод, что OpenBLAS пытается начать несколько потоков.
Как OpenBLAS использует потоки
OpenBLAS может использовать несколько потоков для ускорения линейной алгебры. Вам может понадобиться множество потоков для быстрого решения одной более крупной проблемы. Вы можете хотеть меньше потоков для решения множества мелких проблем одновременно.
OpenBLAS имеет несколько способов ограничить количество потоков, которые он использует. Они контролируются через:
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 игнорирует OPENBLAS_NUM_THREADS
а также GOTO_NUM_THREADS
при компиляции с USE_OPENMP=1
.)
Если ни одна из вышеперечисленных переменных не установлена, OpenBLAS будет работать с использованием числа потоков, равного количеству ядер на вашем компьютере (32 на вашем компьютере)
Ваша ситуация
Ваш кластер имеет 32-ядерные процессоры. Вы пытаетесь запустить 36 экземпляров Python. Каждый экземпляр требует 1 поток для Python + 32 потока для OpenBLAS. Вам также понадобится 1 поток для вашего SSH-соединения и 1 поток для вашей оболочки. Это означает, что вам нужно 36*(32+1)+2=1190 потоков.
Ядерный вариант решения проблемы заключается в использовании:
export OPENBLAS_NUM_THREADS=1
что должно привести вас к 36*(1+1)+2=74 потоков.
Так как у вас есть запасная емкость, вы можете настроить OPENBLAS_NUM_THREADS
до более высокого значения, но тогда экземпляры OpenBLAS, принадлежащие вашим отдельным процессам Python, будут мешать друг другу. Таким образом, существует компромисс между тем, как быстро вы получаете одно решение, и как быстро вы можете получить много решений. В идеале, вы можете решить эту проблему, запустив меньше Питонов на узел и используя больше узлов.