2012-12-08 43 views
2

我正在使用OpenMPI和C綁定。在我的代碼中,需要一些進程。如果MPI執行時會打開比所需更多的進程,我希望終止或終止額外的進程。我怎樣才能做到這一點?MPI殺死不需要的進程

當我嘗試這樣做,幾種方法我能想到的,我得到以下錯誤:

mpirun has exited due to process rank 3 with PID 24388 on 
node pc15-373 exiting without calling "finalize". This may 
have caused other processes in the application to be 
terminated by signals sent by mpirun (as reported here). 

回答

4

除了以下內容,我沒有什麼可以添加到High Performance Mark已經寫入的內容。您實際上可以撥打MPI_FINALIZE並退出過程,但您必須意識到這樣做的事實,即這會干擾世界通信器MPI_COMM_WORLD上的所有進一步的集體操作 - 其中大多數操作都不會完成(使用MPI_BARRIER即可肯定掛)。爲了防止這種情況,你可能需要先創建一個新的溝通,排除一切不必要的進程:

int rank, size;  
MPI_Comm_rank(MPI_COMM_WORLD, &rank); 
MPI_Comm_size(MPI_COMM_WORLD, &size); 

// Obtain the group of processes in the world communicator 
MPI_Group world_group; 
MPI_Comm_group(MPI_COMM_WORLD, &world_group); 

// Remove all unnecessary ranks 
MPI_Group new_group; 
int ranges[3] = { process_limit, size-1, 1 }; 
MPI_Group_range_excl(world_group, 1, ranges, &new_group); 

// Create a new communicator 
MPI_Comm newworld; 
MPI_Comm_create(MPI_COMM_WORLD, new_group, &newworld); 

if (newworld == MPI_COMM_NULL) 
{ 
    // Bye bye cruel world 
    MPI_Finalize(); 
    exit(0); 
} 

// From now on use newworld instead of MPI_COMM_WORLD 

此代碼首先獲得該組的MPI_COMM_WORLD過程,然後創建排除從process_limit起所有進程的新組。然後它從新的過程組創建一個新的傳播者。 MPI_COMM_CREATE操作將在這些不屬於新組的組件中返回MPI_COMM_NULL,並且此事實用於終止此類過程。考慮到在此之後,一些進程將從MPI_COMM_WORLD「消失」,它不再可用於廣播,障礙等集體操作,而應該使用newworld

另外,正如Mark指出的,在某些體系結構中,即使從main返回後,額外的進程可能實際上仍然存在。例如,在Blue Gene或Cray或任何其他使用硬件分區管理MPI作業的系統上,在整個MPI作業完成之前,纔會釋放額外的資源。如果程序在資源管理器(例如SGE,LSF,扭矩,PBS,SLURM等)的控制下在羣集或其他系統上運行,則也是這種情況。

我通常的做法這樣的情況是非常務實:

int size, rank; 

MPI_Comm_rank(MPI_COMM_WORLD, &rank); 
MPI_Comm_size(MPI_COMM_WORLD, &size); 
if (size != process_limit) 
{ 
    if (rank == 0) 
     printf("Please run this program with %d MPI processes\n", process_limit); 
    MPI_Finalize(); 
    exit(1); 
} 

你也可以使用MPI_Abort(MPI_COMM_WORLD, 0);而不是MPI_Finalize()騷擾用戶:)

您還可以使用MPI的過程中產卵的特點,但是這會使代碼更復雜,因爲你不得不處理對講機。

+0

感謝您和惠普商標的有用評論。我最終只是允許額外的進程完成並從主返回。這樣可以釋放桌面上的資源,但當然,這並不是它在「真實」環境中執行操作的好指標。我將提交我的工作(在我使用的IBM Bladecenter上使用LSF)並查看會發生什麼。然而,你的高度務實的方法可能只是票據,尤其是因爲在我的情況下,我總是事先知道有多少個進程產生,只有我將運行代碼。 – synaptik

3

這或許是一個擴展的意見,而不是一個答案,但直到里斯託·利維走來這可能幫助...

我不確定你可以做你想做的。我相信,如果您嘗試使用非MPI功能(例如Linux kill)殺死MPI進程,那麼MPI運行時會因爲其中一個進程意外退出而崩潰。您報告的錯誤消息往往支持我的想法。

您可以在不需要的進程上調用MPI_FINALIZE,但請注意,MPI標準不要求底層操作系統進程(或線程或其他)停止。對MPI_FINALIZE的調用完成未決的MPI操作,並阻止進一步調用該過程中的(幾乎所有)MPI功能。這可能不是你想要的。我想你可能會運氣好一個已經完成的過程,MPI的運行時間可能不會崩潰;這不是我曾經嘗試過的。

您可以採取不同的方法並使用MPI的功能spawn新進程;在一個進程中啓動程序,然後用MPI_SPAWN_PROCESS及其關係產生您的程序使用的號碼。除了MPI例程之外,您還需要調查產卵與平臺流程管理之間的相互作用。您可能會發現系統未配置爲通過運行MPI作業來允許動態進程管理。

+0

我感到受寵若驚:) –

+0

謝謝惠普馬克。我前天剛開始學習MPI,聽到很明顯有很多經驗的人很棒。 – synaptik