2013-06-21 47 views
1

我在Fortran中遇到了MPI_BCAST問題。我使用MPI_CART_CREATE創建了一個新的通信器(比如'COMM_NEW')。當我使用舊的通信器(即MPI_COMM_WORLD)從根廣播數據時,它工作正常。但是,當我使用,我只是創造了新的傳播者它給人的錯誤:與MPI_CART_CREATE一起使用MPI_BCAST時遇到問題

[compute-4-15.local:15298] *** An error occurred in MPI_Bcast 
[compute-4-15.local:15298] *** on communicator MPI_COMM_WORLD 
[compute-4-15.local:15298] *** MPI_ERR_COMM: invalid communicator 
[compute-4-15.local:15298] *** MPI_ERRORS_ARE_FATAL (your MPI job will now abort) 

它會從已參與COMM_NEW處理器,並且還出現上述錯誤的結果,認爲這個問題是與其他處理器不包括在COMM_NEW中,但存在於MPI_COMM_WORLD中。任何幫助將不勝感激。是因爲COMM_NEW中的處理器數量少於總處理器數量?如果是的話,我如何在一組處理器之間進行廣播,而這些處理器的總數還不到。謝謝。 我的示例代碼:

!PROGRAM TO BROADCAST THE DATA FROM ROOT TO DEST PROCESSORS 
PROGRAM MAIN 
IMPLICIT NONE 
INCLUDE 'mpif.h' 
!____________________________________________________________________________________ 
!-------------------------------DECLARE VARIABLES------------------------------------ 
INTEGER :: ERROR, RANK, NPROCS, I 
INTEGER :: SOURCE, TAG, COUNT, NDIMS, COMM_NEW 
INTEGER :: A(10), DIMS(1) 
LOGICAL :: PERIODS(1), REORDER 
!____________________________________________________________________________________ 
!-------------------------------DEFINE VARIABLES------------------------------------- 
SOURCE = 0; TAG = 1; COUNT = 10 
PERIODS(1) = .FALSE. 
REORDER = .FALSE. 
NDIMS = 1 
DIMS(1) = 6 
!____________________________________________________________________________________ 
!--------------------INITIALIZE MPI, DETERMINE SIZE AND RANK------------------------- 
CALL MPI_INIT(ERROR) 
CALL MPI_COMM_SIZE(MPI_COMM_WORLD, NPROCS, ERROR) 
CALL MPI_COMM_RANK(MPI_COMM_WORLD, RANK, ERROR) 
! 
CALL MPI_CART_CREATE(MPI_COMM_WORLD, NDIMS, DIMS, PERIODS, REORDER, COMM_NEW, ERROR) 

IF(RANK==SOURCE)THEN 
DO I=1,10 
    A(I) = I 
END DO 
END IF 
!____________________________________________________________________________________ 
!----------------BROADCAST VECTOR A FROM ROOT TO DESTINATIONS------------------------ 

CALL MPI_BCAST(A,10,MPI_INTEGER,SOURCE,COMM_NEW,ERROR) 

!PRINT*, RANK 
!WRITE(*, "(10I5)") A 

CALL MPI_FINALIZE(ERROR) 

END PROGRAM 

回答

2

我想你給你的問題頂端的錯誤不與代碼底部,因爲它在抱怨上MPI_COMM_WORLD一個BCAST匹配起來,你實際上並不在你的代碼中做一個。

無論如何,如果您運行的維度比維度更多,某些進程將不會包含在COMM_NEW中。相反,當對MPI_CART_CREATE的調用返回時,它們將獲得COMM_NEW的MPI_COMM_NULL,而不是具有拓撲的新通信器。你只需要做一個檢查,以確保你有一個真正的傳播者,而不是MPI_COMM_NULL之前做Bcast(或只是所有的上面DIMS(1)的隊伍不進入Bcast。

+1

+1。 Open MPI在所有與提供的無效通信器句柄相關的錯誤消息中使用MPI_COMM_WORLD,請參閱我的答案。 –

+0

謝謝你們。正如你們所指出的那樣,我能夠找到錯誤及其錯誤。它在我使用if條件在COMM_NEW內調用MPI_BCAST時起作用。 – user2510336

2

詳細說明韋斯利布蘭德的答案並澄清錯誤消息中的明顯差異當MPI_COMM_WORLD中的MPI進程數大於創建的笛卡爾網格中的進程數時,某些進程將不會成爲新的笛卡爾傳播器的成員,並且將獲得MPI_COMM_NULL - 無效的通信器句柄 - 因此,調用一個集體通信操作需要一個有效的通信器間處理,與在點對點操作中允許使用MPI_PROC_NULL不同,在集體調用中使用無效通信器句柄是錯誤的。最後一個陳述不是明示的TLY寫在MPI標準 - 代替,所使用的語言是:

If comm is an intracommunicator, then ... If comm is an intercommunicator, then ...

由於MPI_COMM_NULL既不是幀內,也不間通信器,它不以任何的兩個類別定義的行爲的落入和因此導致錯誤狀況。由於在某些情況下(即在有效的通信器中)必須發生通信錯誤,Open MPI在調用錯誤處理程序時用MPI_COMM_WORLD替代,因此錯誤消息顯示爲「*** on communicator MPI_COMM_WORLD」。這是從ompi/mpi/c/bcast.c相關代碼段,其中MPI_Bcast實現:

if (ompi_comm_invalid(comm)) { 
    return OMPI_ERRHANDLER_INVOKE(MPI_COMM_WORLD, MPI_ERR_COMM, 
           FUNC_NAME); 
} 
... 
if (MPI_IN_PLACE == buffer) { 
    return OMPI_ERRHANDLER_INVOKE(comm, MPI_ERR_ARG, FUNC_NAME); 
} 

您的代碼觸發首先檢查裏面的錯誤處理程序。在所有其他錯誤檢查中,使用comm代替(因爲它被確定爲有效的通信器句柄)並且錯誤消息將陳述類似「*** on communicator MPI COMMUNICATOR 5 SPLIT FROM 0」的內容。

+0

感謝您的信息。 – user2510336