mpi4py: закрыть порождение MPI?

У меня есть код Python, в котором я очень часто создаю несколько процессов. Я получаю сообщение об ошибке:

ORTE_ERROR_LOG: The system limit on number of pipes a process can open was reached in file odls_default_module.c at line 809

Мой код примерно выглядит так

import mpi4py
comm = MPI.COMM_WORLD
...
icomm = MPI.COMM_SELF.Spawn(sys.executable,args=["front_process.py",str(rank)],maxprocs=no_fronts)
...
message = icomm.recv(source=MPI.ANY_SOURCE,tag=21)
...
icomm.Free()

Команда Spawn вызывается очень часто, и я думаю, что они остаются «открытыми» после того, как я закончу, несмотря на то, что дал команду icomm.Free(). Как правильно «закрыть» порожденный процесс?


person user989762    schedule 20.12.2013    source источник
comment
Не могли бы вы предоставить MWE?   -  person MBR    schedule 20.12.2013
comment
По примеру руководства mpi4py по динамическому управлению процессами (стр.14) следует вызывать icomm.Disconnect(). mpi4py.scipy.org   -  person francis    schedule 20.12.2013


Ответы (1)


В спецификации MPI для MPI_COMM_FREE указано, что "... объект фактически освобождается, только если на него нет других активных ссылок." Вы можете отключить процессы, вызвав MPI_COMM_DISCONNECT на обоих концах всех интеркоммуникаторов, которые связывают их. Эквивалентный вызов mpi4py, вероятно, icomm.Disconnect().

Тем не менее ошибка, которую вы видите, вероятно, исходит от orterun (обозначается как mpirun и mpiexec), а не от уровня мастера. orterun — это тот, кто запускает все процессы MPI (первоначальные и порожденные позже), а затем перенаправляет их стандартный вывод на свой собственный стандартный вывод, чтобы вы могли видеть вывод каждого ранга. Когда процессы запускаются на локальном хосте, orterun использует простой механизм fork()/exec() как часть структуры odls для порождения новых рангов и использует каналы для обнаружения успешного запуска и переадресации ввода-вывода. Каналы обнаружения запуска открыты только в течение очень короткого периода времени, но каналы пересылки ввода-вывода остаются открытыми, пока работает ранг. Если у вас одновременно запущено много рангов, многие каналы останутся открытыми и, следовательно, появится сообщение об ошибке.

Сообщение об ошибке немного вводит в заблуждение, поскольку существует два случая «слишком большого количества дескрипторов», и Open MPI не различает их. В первом случае достигается жесткий предел ядра, но обычно это очень большое значение. Второй случай — когда достигнут предел количества файловых дескрипторов для каждого процесса. Последним можно управлять с помощью команды ulimit. Вы должны проверить значение в вашем случае с помощью ulimit -n и в конечном итоге увеличить его. Например:

user@host$ ulimit -n 123456
user@host$ mpiexec -n 1 ... ./spawning_code.py arg1 arg2 ...

Здесь 123456 — желаемое ограничение на количество дескрипторов, и оно не может превышать жесткого ограничения, которое можно получить с помощью ulimit -nH. Если вы запускаете свою программу из сценария (либо для удобства, либо потому, что вы отправляете задания в какую-либо систему пакетной очереди), вы должны поместить строку ulimit -n в сценарий перед вызовом mpirun/mpiexec.

Также в приведенном выше тексте слова ранг и процесс используются для обозначения одного и того же.

person Hristo Iliev    schedule 20.12.2013
comment
Спасибо за объяснение. Раньше я пробовал Disconnect, но не получилось (mca_btl_tcp_frag_recv: readv failed: Connection reset by peer). В ответ на ваш ответ я вызвал Disconnect как для родительского, так и для дочернего процесса, но затем программа просто зависла... Я продолжу переписывать код, поэтому мне нужен только один порожденный дочерний процесс... - person user989762; 23.12.2013