稱他們也許最優雅的解決方案是使Python代碼是MPI應用程序的一部分。然後,它將能夠直接發送數據(通過MPI消息)到MPI應用程序的其餘部分,因爲它將成爲它的一部分。這裏有兩種不同的方法:
1)將Python二進制作爲0級插入到MPI作業中。爲了排除參與mpibinary
的集體行動,您必須設立一個排除0級的子通信員,並將其用於mpibinary
的所有進一步集體通信。第一步是簡單的部分。在開放MPI,你會怎麼做:
mpirun --hostfile hosts -np 1 pythonbinary args : -np 32 mpibinary args
這就是所謂的MPMD(多程序多數據)推出,它會啓動pythonbinary
一個副本將成爲等級0,也mpibinary
32份,這將成爲1級,等級2,......等級32(總共33個過程)。其他MPI實現也爲MPMD發佈提供了非常類似的機制。然後你會使用MPI_Comm_split()
來創建一個不包含Python程序的新通信器。拆分溝通者是一項集體行動。這就是爲什麼你必須在Python代碼和C++應用程序中調用它。 MPI_Comm_split()
採取「顏色」和一個按鍵,並根據不同的顏色在多個子通信器中分解通信器。然後根據鍵值對具有相同顏色的處理進行排序。你很可能會想這樣稱呼它:
在Python:
python_comm = mpi.mpi_comm_split(mpi.MPI_COMM_WORLD, 0, 0)
在C++
:
int rank;
MPI_Comm c_comm;
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
MPI_Comm_split(MPI_COMM_WORLD, 1, rank, &c_comm);
通過使用rank
關鍵一個保證過程的順序c_comm
將與之前的拆分相同,即從MPI_COMM_WORLD
的排名1將在c_comm
中成爲排名0,排名2將成爲排名1等。
從現在開始,C++應用程序可以使用c_comm
像往常一樣執行集合操作。爲了在Python和C++代碼之間進行通信,您仍然需要使用MPI_COMM_WORLD
,並且Python代碼仍然會排在第0位。
2)使用MPI-2過程管理設施。首先你可以運行MPI作業只包含了Python二進制的:
mpirun --hostfile hosts -np 1 pythonbinary args
然後Python的二進制會催生直接使用MPI_Comm_spawn()
與新工藝所需數量的其他MPI二進制文件。新衍生的流程將擁有自己的MPI_COMM_WORLD
,您不需要使用MPI_Comm_split()
。此外,spawn操作將建立一個互通器,它將允許Python代碼將消息發送到MPI應用程序的其他部分。
在這兩種情況下,hosts
文件將包含可執行二進制MPI所有執行主機的定義。您還需要使用其中一種可用的Python MPI綁定。
請注意,您只需要添加一些MPI來電來樣MPI_Init
,MPI_Finalize
,MPI_Comm_split
和相關MPI_Send
/MPI_Recv
您的Python腳本。你不需要平行。 MPI非常靈活,不僅可以將其用於並行工作共享,還可以用作一般消息傳遞框架。但請注意,Python綁定應該使用與程序其餘部分相同的MPI庫。
另一種解決方案是使用一些消息隊列庫或文件池(這實際上是一個粗糙的MQ實現)。
您可以使用命名管道或套接字將命令發送到Python的根MPI等級,而不是觀察文件以進行更改(這看起來很脆弱)。 –
Thx爲響應。使用套接字當然比看文件更「優雅」,但所有這些提到的解決方案都需要編寫大量的代理存根。我仍然在尋找不那麼費時的事情。 – thisch