Reputation: 13
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
Upvotes: 1
Views: 1712
Reputation: 29401
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
Upvotes: 3
Reputation: 51565
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
Upvotes: 1