除了以下內容,我沒有什麼可以添加到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的過程中產卵的特點,但是這會使代碼更復雜,因爲你不得不處理對講機。
感謝您和惠普商標的有用評論。我最終只是允許額外的進程完成並從主返回。這樣可以釋放桌面上的資源,但當然,這並不是它在「真實」環境中執行操作的好指標。我將提交我的工作(在我使用的IBM Bladecenter上使用LSF)並查看會發生什麼。然而,你的高度務實的方法可能只是票據,尤其是因爲在我的情況下,我總是事先知道有多少個進程產生,只有我將運行代碼。 – synaptik