      program calc_pi
      include 'mpif.h'
      integer i, n
      double precision w, gsum, sum
      double precision v
      integer np, myid, ierr
      real*8 time, mflops, time1, time2, dsecnd 
c Инициализация MPI и определение процессорной конфигурации
      call MPI_INIT( ierr )
      call MPI_COMM_RANK( MPI_COMM_WORLD, myid, ierr )
      call MPI_COMM_SIZE( MPI_COMM_WORLD, np, ierr ) 
c Информацию с клавиатуры считывает 0-й процессор
      if ( myid .eq. 0 ) then
      n = 400000000	
      time1 = MPI_Wtime()
      endif 
c Рассылка числа точек разбиения всем процессорам
      call MPI_BCAST(n, 1, MPI_INTEGER, 0, MPI_COMM_WORLD, ierr)
c Вычисление частичной суммы на процессоре
      w = 1.0 / n
      sum = 0.0d0

c Вычисление процессом своей части суммы
      do i = myid+1, n, np
      v = (i - 0.5d0 ) * w
      v = 4.0d0 / (1.0d0 + v * v)
      sum = sum + v
      end do 
c Суммирование частичных сумм с сохранением результата в 0-м
c процессоре
      call MPI_REDUCE(sum, gsum, 1, MPI_DOUBLE_PRECISION,
     $                MPI_SUM, 0, MPI_COMM_WORLD, ierr)
c Печать выходной информации с 0-го процессора
      if (myid .eq. 0) then
      time2 = MPI_Wtime()
      time   = time2 - time1
      mflops = 9 * n / (1000000.0 * time)
      print *, 'pi is approximated with ', gsum *w
      print *, 'time = ', time, ' seconds'
      print *, 'mflops = ', mflops, ' on ', np, ' processors'
      print *, 'mflops = ', mflops/np, ' for one processor'
      endif 
c Закрытие MPI
      call MPI_FINALIZE(ierr)
      end
