2016-01-13 73 views
2

我正在研究一個更大的程序,我正在與MPI_Gather進行鬥爭。MPI_Gather在最基本的代碼中給出了seg錯誤

我寫了一個最小的示例代碼,見下文。

program test 
    use MPI 
    integer :: ierr, rank, size 
    double precision, allocatable, dimension(:) :: send, recv 

    call MPI_Init(ierr) 

    call MPI_Comm_size(MPI_COMM_WORLD, size, ierr) 
    if (ierr /= 0) print *, 'Error in MPI_Comm_size' 
    call MPI_Comm_rank(MPI_COMM_WORLD, rank, ierr) 
    if (ierr /= 0) print *, 'Error in MPI_Comm_size' 

    allocate(send(1), recv(size)) 

    send(1) = rank 

    call MPI_Gather(send, 1, MPI_DOUBLE_PRECISION, & 
        recv, 1, MPI_DOUBLE_PRECISION, 0, MPI_COMM_WORLD) 
    print *, recv 
    call MPI_Finalize(ierr) 
end program test 

當(有2個節點)時,我得到以下錯誤輸出。

[jorvik:13887] *** Process received signal *** 
[jorvik:13887] Signal: Segmentation fault (11) 
[jorvik:13887] Signal code: Address not mapped (1) 
[jorvik:13887] Failing at address: (nil) 
[jorvik:13888] *** Process received signal *** 
[jorvik:13888] Signal: Segmentation fault (11) 
[jorvik:13888] Signal code: Address not mapped (1) 
[jorvik:13888] Failing at address: (nil) 
[jorvik:13887] [ 0] /lib/x86_64-linux-gnu/libc.so.6(+0x36150) [0x7f6ab77f8150] 
[jorvik:13887] [ 1] /usr/lib/libmpi_f77.so.0(PMPI_GATHER+0x12d) [0x7f6ab7ebca9d] 
[jorvik:13887] [ 2] ./test() [0x4011a3] 
[jorvik:13887] [ 3] ./test(main+0x34) [0x401283] 
[jorvik:13887] [ 4] /lib/x86_64-linux-gnu/libc.so.6(__libc_start_main+0xed) [0x7f6ab77e376d] 
[jorvik:13887] [ 5] ./test() [0x400d59] 
[jorvik:13887] *** End of error message *** 
[jorvik:13888] [ 0] /lib/x86_64-linux-gnu/libc.so.6(+0x36150) [0x7f0ca067d150] 
[jorvik:13888] [ 1] /usr/lib/libmpi_f77.so.0(PMPI_GATHER+0x12d) [0x7f0ca0d41a9d] 
[jorvik:13888] [ 2] ./test() [0x4011a3] 
[jorvik:13888] [ 3] ./test(main+0x34) [0x401283] 
[jorvik:13888] [ 4] /lib/x86_64-linux-gnu/libc.so.6(__libc_start_main+0xed) [0x7f0ca066876d] 
[jorvik:13888] [ 5] ./test() [0x400d59] 
[jorvik:13888] *** End of error message *** 

我在做什麼錯? MPI肯定是安裝在我正在使用的機器上運行的。

+0

它運行在一個進程上嗎?如果是這樣,請通過GDB和/或Valgrind運行。 – Jeff

回答

4

最大的問題是你沒有在MPI_Gather的調用中包含最後的參數。 doc說

Fortran中的所有MPI例程(MPI_WTIME和MPI_WTICK除外)在參數列表的末尾都有一個額外的參數ierr。

除此之外,我的建議是始終堅持良好的做法:不要使用固有的函數名稱作爲變量,例如size

program test 
    use MPI 
    integer :: ierr, rank, nProc 
    double precision, allocatable, dimension(:) :: send, recv 

    call MPI_Init(ierr) 
    if (ierr /= 0) print *, 'Error in MPI_Init' 

    call MPI_Comm_size(MPI_COMM_WORLD, nProc, ierr) 
    if (ierr /= 0) print *, 'Error in MPI_Comm_size' 
    call MPI_Comm_rank(MPI_COMM_WORLD, rank, ierr) 
    if (ierr /= 0) print *, 'Error in MPI_Comm_size' 

    allocate(send(1), recv(nProc)) 

    send(1) = rank 

    call MPI_Gather(send, 1, MPI_DOUBLE_PRECISION, & 
        recv, 1, MPI_DOUBLE_PRECISION, 0, MPI_COMM_WORLD, ierr) 
    if (ierr /= 0) print *, 'Error in MPI_Gather' 
    print *, recv 
    call MPI_Finalize(ierr) 
end program test 
+0

謝謝,現在完美! – Marcel

3

你忘了返回錯誤代碼添加到調用MPI_Gather作爲最後一個參數。返回碼的值正被寫入未映射的地址。

它應該在編譯階段讀

call MPI_Gather(send, 1, MPI_DOUBLE_PRECISION, & recv, 1, MPI_DOUBLE_PRECISION, 0, MPI_COMM_WORLD, ierr)

ifort捕獲此。它看起來像你的編譯器(gfortran?)不是

+0

這是MPI庫比編譯器更多的問題。 –

+0

謝謝,那是問題所在。古芙蘭確實沒有捕捉到這一點。 – Marcel