2011-04-13 33 views
5

我有一個並行Fortran代碼,我只希望rank = 0進程能夠寫入標準輸出,但我不想讓代碼亂丟:Fortran MPI代碼中的標準輸出

if(rank==0) write(*,*) ... 

所以我想知道如果做下面的事情會是一個好主意,或者是否有更好的方法?

program test 

    use mpi 

    implicit none 

    integer :: ierr 
    integer :: nproc 
    integer :: rank 

    integer :: stdout 

    call mpi_init(ierr) 
    call mpi_comm_rank(mpi_comm_world, rank, ierr) 
    call mpi_comm_size(mpi_comm_world, nproc, ierr) 

    select case(rank) 
    case(0) 
    stdout = 6 
    case default 
    stdout = 7 
    open(unit=stdout, file='/dev/null') 
    end select 

    write(stdout,*) "Hello from rank=", rank 

    call mpi_finalize(ierr) 

end program test 

這給:

$ mpirun -n 10 ./a.out 
Hello from rank=   0 

感謝您的諮詢!

回答

11

有兩個缺點您的解決方案:

  1. 這種「聰明」的解決方案實際上掩蓋了代碼,因爲它位於:stdout不是標準輸出了。如果有人閱讀代碼,他/她會認爲所有進程都寫入標準輸出,而實際上他們不是。
  2. 如果您希望某些時候所有進程都可以寫入stdout,那麼您會做什麼?添加更多技巧?

如果你真的想堅持這一招,請不要使用「標準輸出」作爲單位編號的變量,但例如, 「主」或任何表明你沒有真正寫入標準輸出的東西。此外,你應該知道6並不總是stdout。 Fortran 2003允許你檢查stdout的單元號,所以你應該使用它,如果可以的話。

我的建議是留在if(rank==0)聲明。他們清楚地表明代碼中發生了什麼。如果您使用大量類似的I/O語句,則可以編寫僅用於等級0或所有進程的子例程。這些可以具有有意義的名稱,表明預期的用途。

0

我並不十分關心steabert提到的兩個缺點。我們可以通過引入另一個文件描述符來解決這個問題,該文件描述符清楚地表明它只是在主進程中是stdout, stdout - >stdout0

但是我的擔心在這裏:/ dev/null將在類UNIX環境中工作。它可以在Windows環境下工作嗎?時髦的BlueGene系統如何?

1

mpirun帶有將每個進程的stdout重定向到單獨文件的選項。例如,-output-filename out會導致out.1.0,out.1.1,...然後您可以使用任何您喜歡的方式監視(我使用tail -f)。在if(rank.eq.0)旁邊,這是我認爲最乾淨的解決方案。