tags:

views:

278

answers:

2

I'm trying to run this MPI Fortran code. There are several problems:

1) when I run this code I expect the program to write 'Enter the number of intervals: (0 quits) ' to screen then ask me n. Instead it asks me n first!!! why?

2) if I don't comment out the line 'goto 10', the program keeps asking me n for ever and does not show me anything else!!!

3) if I comment out 'goto 10' the program ask me n and then writes results. But, problem is every time the program write part of the result not the complete results. It truncate the output!! below are output for three consecutive time I ran the program:

> mpiexec -n 40 ./a.out
10000000
 Enter the number of intervals: (0 quits)
 pi is    3.14159265358978      Error is   1.287858708565182E-014
 time is   1.687502861022949E-002  seconds

> mpiexec -n 40 ./a.out
10000000
 Enter the number of intervals: (0 quits)
 pi is    3.14159265358978      Error is   1.287858708565182E-014
 time is   1.68750286102

> mpiexec -n 40 ./a.out
10000000
 Enter the number of intervals: (0 quits)
 pi is    3.14159265358978      Error is   1.287858708565182E-014
 time is   1.687502861022949E-002  se

Anyone has any idea what's going on? I appreciate your help in advance.

      program main
      use mpi
      double precision starttime, endtime
      double precision  PI25DT
      parameter        (PI25DT = 3.141592653589793238462643d0)
      double precision  mypi, pi, h, sum, x, f, a
      double precision starttime, endtime
      integer n, myid, numprocs, i, ierr

      f(a) = 4.d0 / (1.d0 + a*a)   !   function to integrate

      call MPI_INIT(ierr)
      call MPI_COMM_RANK(MPI_COMM_WORLD, myid, ierr)
      call MPI_COMM_SIZE(MPI_COMM_WORLD, numprocs, ierr)

 10   if ( myid .eq. 0 ) then
         print *, 'Enter the number of intervals: (0 quits) '
         read(*,*) n
      endif
      starttime = MPI_WTIME()
!                                 broadcast n
      call MPI_BCAST(n,1,MPI_INTEGER,0,MPI_COMM_WORLD,ierr)
!                                 check for quit signal
      if ( n .le. 0 ) goto 30
!                                 calculate the interval size
      h   = 1.0d0/n
      sum = 0.0d0
      do 20 i = myid+1, n, numprocs
         x   = h * (dble(i) - 0.5d0)
         sum = sum + f(x)
 20   continue
      mypi = h * sum
!                                 collect all the partial sums
      call MPI_REDUCE(mypi,pi,1,MPI_DOUBLE_PRECISION,MPI_SUM,0, &
                      MPI_COMM_WORLD,ierr)
!                                 node 0 prints the answer.
      endtime = MPI_WTIME()
      if (myid .eq. 0) then
         print *, 'pi is ', pi, 'Error is ', abs(pi - PI25DT)
         print *, 'time is ', endtime-starttime, ' seconds'
      endif
      go to 10
 30   call MPI_FINALIZE(ierr)
      stop
      end
A: 

you have to explicitly flush your output. I do not remember if fortran has standard flush function, if flush does not work, try flush_.

Basically what happens, your process zero buffers output, and unless the explicitly tell it to display, you end up a funny stuff

aaa
Thank you, it worked! But how does it solve the goto problem? Do you have any idea?
Bahman
Fortran 2003 includes a flush statement. Many compilers already include it. Some had it or variations before the 2003 language standard. I've never had to use it. Is it necessary because of MPI?
M. S. B.
@ Bahman flash makes sure output buffers are forced to print before program finishes. Fortran output and C (mpi is written in c) interact in strange ways.
aaa
@M. S. B. fortran and c/mpi output streams are not synchronized. basically output becomes asynchronous in parallel program.
aaa
+2  A: 

This program is designed to loop via the "goto 10" at the end. The only way to break out of this is for n to have a value <= 0, which will activate the "goto 30" and branch past the "goto 10". Additional clues that this is the intent are the comment "check for quit signal" and that the prompt for the input of n includes "(0 quits)". So try inputting 0!

This is not a good example of modern Fortran. Despite clearly using a Fortran 90 or more recent compiler (the "use" statement shows this), it is written in the style of FORTRAN 77 or earlier. Fixed-source layout, with the source lines apparently starting in column 7. Comment characters in the first column (old Fortran required a C in the first column). "Double Precision". Heavy use of gotos for the program logic. (In my opinion, and others may disagree, there is a place for the goto statement, but not for the basic control flow of a program.) Obsolete Fortran (in my opinion).

The modern Fortran way to express the basic flow:

MainLoop: do
   .....
   if (n .le. 0) exit MainLoop
   ....
end do MainLoop
M. S. B.