2012-03-30 84 views
4

我有一個FORTRAN MPI代碼來解決流場問題。MPI-FORTRAN的文件IO

在開始時,我想從文件讀取數據並將其分發給參與進程。

數據由多個三維數組(空間x,y,z中的速度)組成。

每個進程只存儲數組的一部分。

因此,如果每個進程都要讀取文件(我認爲最簡單的方法),它不會起作用,因爲它只會存儲文件的第一部分,該部分對應於進程可以保存的數組數量。

MPI Bcast可以用於3D數組嗎?但事情變得複雜。

還是有更簡單的方法嗎?

回答

4

從廣義上講,根據您的平臺,您有2或3種選擇。

  1. 一個進程讀取輸入數據並將其發送(部分)到其他進程。我通常不會使用廣播,因爲這是一個集體操作,所有流程都必須參與。我通常只是將必要的信息發送到每個過程。如果方便(而不是內存問題),你當然可以將所有輸入數據廣播給所有進程,但這不僅僅是我使用或看到的很多操作模式。
  2. 所有進程都會讀取它們需要的數據。這可能涉及讀取整個輸入文件並僅存儲它所需的部分的過程。但是如果你有非常大的輸入文件,你可以編寫例程來只讀入每個進程的內存空間中的必要部分。這種方法可能涉及競爭磁盤訪問的進程,這在相對意義上只是緩慢的:如果您正在運行大規模並且長時間運行的並行計算,等待幾秒鐘,而所有進程獲取其數據並不是很大的開銷。
  3. 如果您有一個並行文件系統,那麼您可以使用MPI的並行I/O例程,以便每個進程只讀取它需要的那些輸入數據部分。
+0

有第二種選擇,我可以看任何的例子嗎? – 2017-10-09 05:22:39

3

在MPI這樣的I/O模式的規範的方法要麼是

  • 閱讀等級0中的數據,然後使用MPI_Scatter分發它。或者如果內存緊張,請按塊進行,或者使用1對1通信而不是MPI_Scatter。

  • 使用MPI-I/O,並讓每個等級都讀取它自己的數據文件的子集(這很有用,當然這需要一個文件格式,您可以在沒有先讀取整個文件的情況下找出邊界)。

對於極端的可擴展性,可結合這兩種方法,也就是處理的子集(比如,SQRT(N)作爲一個粗略的規則)使用MPI I/O,並且每個MPI進程發送數據到它自己的IO進程。

3

如果您使用良好的文件系統(例如Lustre)在少於1000個內核上運行代碼,那麼只需使用Fortran I/O,其中每個等級打開文件並讀取所需的數據(跳過其餘部分)。是的,這需要幾分鐘的時間,但您只在開始時閱讀文件一次。MPI I/O(僅適用於二進制文件)並不重要,通常情況下,使用HDF5或並行NetCDF等更高級別的庫文件通常會更好。性能將取決於數據的讀取方式(連續與非連續等)。以下鏈接可能會有所幫助......

+0

感謝您提供HDF5或Parallel-NetCDF:今天很少有理由讓新代碼直接使用MPI-IO。 – 2014-08-26 14:07:19