我正在尝试运行此MPI Fortran代码。有几个问题:
1)当我运行这段代码时,我希望程序写入'输入间隔数:( 0退出)'到屏幕,然后问我。相反,它首先问我!为什么呢?
2)如果我没有注释掉'goto 10'这一行,程序会一直问我n并且没有给我任何其他的东西!!!
3)如果我评论'goto 10',程序会问我n然后写出结果。但是,问题是每次程序写入结果的一部分而不是完整的结果。它会截断输出!!以下是我连续三次输出程序:
> 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
任何人都知道发生了什么事吗?我提前感谢您的帮助。
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
答案 0 :(得分:3)
该程序旨在通过最后的“转到10”进行循环。打破这种情况的唯一方法是使n具有值 这不是现代Fortran的好例子。尽管显然使用了Fortran 90或更新版本的编译器(“use”语句显示了这一点),但它是以FORTRAN 77或更早版本的风格编写的。固定源布局,源代码行显然从第7列开始。在第一列中注释字符(旧Fortran在第一列中需要C)。 “双精度”。对程序逻辑大量使用gotos。 (在我看来,其他人可能不同意,goto语句有一个位置,但不适用于程序的基本控制流程。)过时的Fortran(在我看来)。 现代Fortran表达基本流程的方式:MainLoop: do
.....
if (n .le. 0) exit MainLoop
....
end do MainLoop
答案 1 :(得分:1)
您必须明确刷新输出。我不记得fortran是否有标准的冲洗功能,如果冲洗不起作用,请尝试冲洗_。
基本上会发生什么,你的进程零缓冲输出,除非明确告诉它显示,你最终会有趣的东西