簡體   English   中英

mpi4py 在使用 spawn 后進入死鎖

[英]mpi4py enters deadlock after using spawn

我有以下代碼安排:

父母.py

from mpi4py import MPI

... some code ...

for i in range(10):

    ... some code ...

    child_comm = MPI.COMM_SELF.Spawn(sys.executable, args=["runscript_airfoil.py"], maxprocs=9)
    child_comm.Barrier()
    child_comm.Disconnect()

    ... some code ...

孩子.py

from mpi4py import MPI

... some code ...

comm = MPI.COMM_WORLD
comm.Barrier()

這里的主要目標是一次又一次地使用多個處理器運行child.py 我在這里使用了Barrier()方法,因為我希望程序等到child.py被執行。

但是,程序在第一次迭代后就停止了。 我認為該計划正在陷入僵局。 此外,應該釋放child.py使用的所有處理器,以便我可以在下一個循環中使用它們。

我是 MPI 和 mpi4py 的新手,所以我不知道在哪里使用什么功能。 任何幫助實現這一點都將非常有用。

編輯 1

根據評論,我將child.py文件的內容修改為以下內容:

from mpi4py import MPI

... some code ...

comm = MPI.COMM_WORLD
parent_comm = comm.Get_parent()
comm.Barrier()
parent_comm.Disconnect()

程序在第一次迭代后仍然卡住。

編輯 2

根據評論,我進一步修改child.py文件的內容如下:

from mpi4py import MPI

... some code ...

comm = MPI.COMM_WORLD
parent_comm = comm.Get_parent()
parent_comm.Barrier()
parent_comm.Disconnect()

該程序沒有進入死鎖,但是當它嘗試在第二次迭代中生成時,它會出現以下錯誤:系統中沒有足夠的可用插槽來滿足應用程序請求的 9 個插槽。 我的筆記本電腦總共有 10 個處理器,1 個在運行 parent.py 和 rest 9 個在第一次迭代中運行 child.py。 當 parent.py 嘗試使用 9 個處理器第二次生成 child.py 時,它沒有使用之前使用的 9 個處理器,而是試圖找到 9 個新處理器(不可用)。 我認為之前的 spawn 並沒有完全退出。 為了測試這個理論,我運行了原始的parent.pychild.py (來自第二次編輯),其中 maxprocs 為 3 並循環了三次。 這工作得很好。

使用什么命令來完全釋放處理器?

編輯 3

我在編輯 2 末尾的評估是正確的。 我發現當我將 maxprocs 保持為 4 或更少時,無論循環次數如何,它都可以正常工作。 當我將 maxprocs 保持為 5 或更多時,它才會開始給出“插槽不足”錯誤。 我不確定這里的問題是什么。

跟隨 MWE 工作而不會陷入僵局(感謝@Giles 在評論部分的討論:):

父母.py

from mpi4py import MPI

comm = MPI.COMM_WORLD

for i in range(10):

    print("Start {}".format(i))

    child_comm = MPI.COMM_WORLD.Spawn(sys.executable, "child.py", maxprocs=9)
    child_comm.Disconnect()

    print("End {}".format(i))

孩子.py

import time
from mpi4py import MPI

comm = MPI.COMM_WORLD
time.sleep(comm.rank)
print(comm.rank)

parent_comm = comm.Get_parent()
parent_comm.Disconnect()

這在mpi4py 教程中也有描述(之前應該已經看過)。

在這一點之后,我遇到了另一個錯誤。 當我將 parent.py 作為python parent.py運行時,我曾經得到以下 output:

Start 0
0
3
4
7
1
6
2
8
5
End 0
Start 1
--------------------------------------------------------------------------
There are not enough slots available in the system to satisfy the 9
slots that were requested by the application:

  /home/pavan/miniconda3/envs/codelab/bin/python

Either request fewer slots for your application, or make more slots
available for use.

A "slot" is the Open MPI term for an allocatable unit where we can
launch a process.  The number of slots available are defined by the
environment in which Open MPI processes are run:

  1. Hostfile, via "slots=N" clauses (N defaults to number of
     processor cores if not provided)
  2. The --host command line parameter, via a ":N" suffix on the
     hostname (N defaults to 1 if not provided)
  3. Resource manager (e.g., SLURM, PBS/Torque, LSF, etc.)
  4. If none of a hostfile, the --host command line parameter, or an
     RM is present, Open MPI defaults to the number of processor cores

In all the above cases, if you want Open MPI to default to the number
of hardware threads instead of the number of processor cores, use the
--use-hwthread-cpus option.

Alternatively, you can use the --oversubscribe option to ignore the
number of available slots when deciding the number of processes to
launch.
--------------------------------------------------------------------------
Traceback (most recent call last):
  File "parent.py", line 30, in <module>
    child_comm = MPI.COMM_WORLD.Spawn(sys.executable, "child.py", maxprocs=9)
  File "mpi4py/MPI/Comm.pyx", line 1931, in mpi4py.MPI.Intracomm.Spawn
mpi4py.MPI.Exception: MPI_ERR_SPAWN: could not spawn processes

我的筆記本電腦有 10 個內核(使用 lscpu 驗證,我使用 mpirun 命令運行了 10 個處理器的腳本)。 我將腳本運行為mpirun -n 1 python parent.py但我仍然遇到相同的錯誤。

經過一番折騰,我發現在 parent.py 中的 Disconnect 方法后添加一個小的停頓有效: parent.py

import time
from mpi4py import MPI

comm = MPI.COMM_WORLD

for i in range(10):

    print("Start {}".format(i))

    child_comm = MPI.COMM_WORLD.Spawn(sys.executable, "child.py", maxprocs=9)
    child_comm.Disconnect()
    time.sleep(0.25)

    print("End {}".format(i))

Output :

Start 0
7
6
8
4
5
1
0
3
2
End 0
Start 1
7
8
1
6
5
3
2
4
0
End 1

我不確定為什么會這樣,但我建議在 Disconnect 方法結束之前,for 循環會嘗試生成下一組進程。 因此,添加一個小的停頓可以讓 Disconnect 方法有一些時間完成。 我不確定這在使用 MPI(或 mpi4py)時是否常見,但如果有一種優雅的方法來克服這個問題,請告訴我。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM