【问题标题】:MPI Fortran Code ProblemMPI Fortran 代码问题
【发布时间】:2011-01-16 18:05:38
【问题描述】:

我正在尝试运行此 MPI Fortran 代码。有几个问题:

1) 当我运行此代码时,我希望程序在屏幕上写入“输入间隔数:(0 退出)”,然后询问我 n。相反,它首先问我!为什么?

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

【问题讨论】:

  • 阅读列表中的下一篇论文应该是著名的 Dijkstra 的“反对 GO TO 声明的案例”。

标签: fortran mpi


【解决方案1】:

这个程序被设计成在结尾处通过“goto 10”循环。打破这种情况的唯一方法是让 n 的值

这不是现代 Fortran 的一个很好的例子。尽管清楚地使用了 Fortran 90 或更新的编译器(“use”语句显示了这一点),但它是以 FORTRAN 77 或更早的风格编写的。固定源代码布局,源代码行显然从第 7 列开始。第一列中的注释字符(旧的 Fortran 要求第一列中的 C)。 “双精度”。程序逻辑大量使用 goto。 (在我看来,其他人可能不同意,goto 语句有一个位置,但程序的基本控制流没有。)过时的 Fortran(在我看来)。

表达基本流程的现代Fortran方式:

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

【讨论】:

    【解决方案2】:

    您必须明确刷新您的输出。我不记得fortran有没有标准的flush功能,如果flush不行,试试flush_。

    基本上会发生什么,你的进程零缓冲区输出,除非明确告诉它显示,否则你最终会得到一个有趣的东西

    【讨论】:

    • 谢谢,成功了!但是它是如何解决goto问题的呢?你有什么想法吗?
    • Fortran 2003 包含一个刷新语句。许多编译器已经包含它。有些人在 2003 年语言标准之前有它或变体。我从来没有使用过它。因为 MPI 有必要吗?
    • @Bahman flash 确保在程序完成之前强制打印输出缓冲区。 Fortran 输出和 C(mpi 用 c 编写)以奇怪的方式交互。
    • @M. S. B. fortran 和 c/mpi 输出流不同步。基本上输出在并行程序中变得异步。
    猜你喜欢
    • 2012-01-24
    • 2014-03-02
    • 2011-08-04
    • 2018-04-25
    • 2012-10-09
    • 2018-05-05
    • 2012-08-10
    • 2015-02-15
    • 2020-07-16
    相关资源
    最近更新 更多