Проблема кода MPI Фортран - PullRequest
       6

Проблема кода MPI Фортран

1 голос
/ 14 февраля 2010

Я пытаюсь запустить этот код MPI Fortran. Есть несколько проблем:

1) когда я запускаю этот код, я ожидаю, что программа выведет на экран «Введите количество интервалов: (0 выходов)», затем спросите меня n. Вместо этого он спрашивает меня первым !!! почему?

2) если я не закомментирую строку 'goto 10', программа будет постоянно спрашивать меня n и больше ничего не показывает !!!

3) если я закомментирую «Перейти к 10», программа спросит меня, а затем запишет результаты. Но проблема в том, что каждый раз, когда программа записывает часть результата, а не полные результаты. Это усекать вывод !! ниже выводятся три раза подряд запущенные мной программы:

> 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

Ответы [ 2 ]

3 голосов
/ 15 февраля 2010

Эта программа предназначена для петли через «Перейти 10» в конце. Единственный способ избежать этого состоит в том, чтобы n имело значение <= 0, что активирует «goto 30» и разветвляется после «goto 10». Дополнительные подсказки о том, что это и есть намерение, - это комментарий «проверить наличие сигнала выхода» и подсказка для ввода n включает «(0 выходов)». Поэтому попробуйте ввести 0! </p>

Это не хороший пример современного Фортрана. Несмотря на то, что явно используется Fortran 90 или более поздний компилятор (это видно из выражения «use»), он написан в стиле FORTRAN 77 или более ранних версий. Компоновка с фиксированным исходным кодом, строки исходного кода, по-видимому, начинаются в столбце 7. Комментируйте символы в первом столбце (старому Фортрану требовался символ C в первом столбце). "Двойная точность". Интенсивное использование gotos для логики программы. (По моему мнению, и другие могут не согласиться, есть место для утверждения goto, но не для основного потока управления программой.) Устаревший Fortran (по моему мнению).

Современный Fortran способ выразить основной поток:

MainLoop: do
   .....
   if (n .le. 0) exit MainLoop
   ....
end do MainLoop
1 голос
/ 14 февраля 2010

вы должны явно сбросить ваш вывод. Я не помню, есть ли в Фортране стандартная функция очистки, если очистка не работает, попробуйте выполнить очистку _.

По сути, что происходит, ваш процесс обнуляет выходные данные буфера, и если явно не указать, что он будет отображаться, вы получите забавные вещи

...