2012-05-14 144 views
3

我想以某種方式通過例如(串行)python腳本觸發執行某個MPI程序(用C++編寫)的某些函數。這python腳本應該在期初,如啓動MPI程序,通過(Non-MPI)python腳本與MPI二進制文件進行交互

subprocess.call(['mpirun','-np', '4', 'mpibinary', 'args' ]) 

我需要調用此MPI程序的功能,多次和我想避免重新啓動對不同輸入的程序,因爲我有重新初始化所有我的數據結構,這是昂貴的。因此,當MPI程序空閒時,我曾想過外部觸發一個函數。我認爲這可以通過文件IO完成,也就是說,MPI程序的根級別在while(1)循環中觀察某個文件,並且一旦其內容改變,它解析新內容就會通知其他等級並調用一個函數。有沒有更好的解決我的問題?

最好的解決辦法通過有一個Python類包裝了C++ MPI程序的重要功能,這樣我可以從蟒蛇與

mpiprogram.superfunction(a,b) 
+1

您可以使用命名管道或套接字將命令發送到Python的根MPI等級,而不是觀察文件以進行更改(這看起來很脆弱)。 –

+0

Thx爲響應。使用套接字當然比看文件更「優雅」,但所有這些提到的解決方案都需要編寫大量的代理存根。我仍然在尋找不那麼費時的事情。 – thisch

回答

5

稱他們也許最優雅的解決方案是使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_InitMPI_FinalizeMPI_Comm_split和相關MPI_Send/MPI_Recv您的Python腳本。你不需要平行。 MPI非常靈活,不僅可以將其用於並行工作共享,還可以用作一般消息傳遞框架。但請注意,Python綁定應該使用與程序其餘部分相同的MPI庫。

另一種解決方案是使用一些消息隊列庫或文件池(這實際上是一個粗糙的MQ實現)。

+0

1)是否意味着我需要修改mpibinary?誰應該調用MPI_Comm_split? – thisch

+0

不幸的是,1)和2)都需要對MPI二進制文件進行一些修改。方法2)比1)需要更少的修改。我已經擴展了答案,以包含關於如何調用'MPI_Comm_split'的信息,因爲對評論長度的限制過於嚴格。 –

相關問題