parallel-processingfortranmpi

Why use MPI_Init() when code in front is parallel too?


I encountered a question about the use of MPI_Init().

I want to initialize random number randv only on the root processor with the code in the context below. To see if my goal is fulfilled, I have the program print out the array randv by placing a do loop immediately after the line call RANDOM_NUMBER(randv).

However, what is shown on the outcome screen is the repetition of the random number array by 8 times (given the number of processors is 8). My question is why the processors other than the root one are initialized before call MPI_Init(). If all the processors are awaken and have the same random number array before evoking MPI_Init, why bother to place call MPI_Init() for initialization?

Here is the example I use:

program main
  include 'mpif.h'
  integer :: i
  integer :: ierr
  integer :: irank
  integer :: nrow, ncol
  real, dimension(:,:), allocatable :: randv
  nrow = 4
  ncol = 2
  allocate(randv(nrow,ncol))   
  call RANDOM_SEED
  call RANDOM_NUMBER(randv)
  do i = 1, nrow
    write(*,'(2(f5.2,x))') randv(i,:)    
  enddo   
  call MPI_Init ( ierr )
  allocate(row_list(ncol), col_list(nrow))  
  call MPI_Comm_rank ( MPI_COMM_WORLD, irank, ierr )
  if( irank == 0 )then
    do i = 1, nrow
      write(*,'(2(f5.2,x))') randv(i,:)    
    enddo          
  endif
  call MPI_Finalize ( ierr ) 
  deallocate( randv )
end program

Solution

  • I think you misunderstand how MPI works. The program you wrote is executed by every process. MPI_Init initializes the MPI environment s.t. those processes can interact. After initialization every process is uniquely identified by its rank. You have to make sure that, based on these ranks, each process works on different portions of your data, or performs different tasks.

    Typically, you should run MPI_Init before anything else in your program.

    Using MPI_Comm_rank you can obtain the ID of the current process (its rank). The first process always has the rank 0. Therefore, if you want to run parts of the code on the "master" process only, you can test for irank == 0:

    program main
      include 'mpif.h'
      integer :: i
      integer :: ierr
      integer :: irank
      integer :: nrow, ncol
      real, dimension(:,:), allocatable :: randv
    
      ! Initialize MPI
      call MPI_Init ( ierr )
      ! Get process ID
      call MPI_Comm_rank ( MPI_COMM_WORLD, irank, ierr )
    
      ! Executed on all processes
      nrow = 4
      ncol = 2
      allocate(randv(nrow,ncol))   
    
      ! Only exectued on the master process
      if ( irank == 0 ) then
        call RANDOM_SEED
        call RANDOM_NUMBER(randv)
        do i = 1, nrow
          write(*,'(2(f5.2,x))') randv(i,:)    
        enddo   
      endif
    
      ! Executed on all threads
      allocate(row_list(ncol), col_list(nrow))  
    
      ! Only exectued on the master process
      if ( irank == 0 ) then
        do i = 1, nrow
          write(*,'(2(f5.2,x))') randv(i,:)    
        enddo          
      endif
    
      deallocate( randv )
    
      ! Finalize MPI, should always be executed last
      call MPI_Finalize ( ierr ) 
    end program